001package jmri.jmrit.logixng.util.parser.swing;
002
003import java.awt.*;
004import static java.awt.Component.LEFT_ALIGNMENT;
005import static java.awt.Component.TOP_ALIGNMENT;
006import java.awt.event.ActionEvent;
007import java.util.*;
008import java.util.List;
009
010import javax.swing.*;
011
012import jmri.InstanceManager;
013import jmri.jmrit.logixng.util.parser.Function;
014import jmri.jmrit.logixng.util.parser.FunctionManager;
015import jmri.util.swing.JComboBoxUtil;
016
017/**
018 * Show a dialog that shows information about the functions for formula
019 *
020 * @author Daniel Bergqvist 2020
021 */
022public class FunctionsHelpDialog implements jmri.InstanceManagerAutoDefault {
023
024    private static final int panelWidth = 500;
025    private static final int panelHeight = 500;
026
027    private static final Map<String, Module> _modules = new HashMap<>();
028
029    private JDialog _selectItemTypeDialog = null;
030    private final JComboBox<Module> _moduleComboBox = new JComboBox<>();
031    private final JComboBox<SortableFunction> _functionComboBox = new JComboBox<>();
032    private final JLabel _moduleLabel = new JLabel(Bundle.getMessage("FunctionsHelpDialog_Module") + ":");  // NOI18N
033    private final JLabel _functionLabel = new JLabel(Bundle.getMessage("FunctionsHelpDialog_Function") + ":");   // NOI18N
034    private final JEditorPane _documentationEditorPane = new JEditorPane();
035
036
037    public FunctionsHelpDialog() {
038        FunctionManager fm = InstanceManager.getDefault(FunctionManager.class);
039        for (Map.Entry<String, Function> entry : fm.getFunctions().entrySet()) {
040//            System.out.format("Existing functions: %s, %s%n", entry.getValue().getModule(), entry.getValue().getName());
041            Module m = _modules.get(entry.getValue().getModule());
042            if (m == null) {
043                m = new Module(entry.getValue().getModule(), entry.getValue().getConstantDescriptions());
044                _modules.put(m._name, m);
045            }
046            m._functions.add(entry.getValue());
047        }
048    }
049
050    public void showDialog() {
051
052        if (_selectItemTypeDialog != null) {
053            _selectItemTypeDialog.requestFocus();
054            return;
055        }
056
057        _documentationEditorPane.setEditable(false);
058        _documentationEditorPane.setContentType("text/html");
059
060        _moduleComboBox.removeAllItems();
061        List<Module> list = new ArrayList<>(_modules.values());
062        Collections.sort(list);
063        for (Module module : list) {
064            _moduleComboBox.addItem(module);
065        }
066        JComboBoxUtil.setupComboBoxMaxRows(_moduleComboBox);
067        _moduleComboBox.addActionListener((ActionEvent e) -> {
068            initFunctionsComboBox();
069        });
070
071        _functionComboBox.addActionListener((ActionEvent e) -> {
072            if (_functionComboBox.getSelectedIndex() > -1) {
073                SortableFunction f = _functionComboBox
074                        .getItemAt(_functionComboBox.getSelectedIndex());
075                _documentationEditorPane.setText(f._functionDescr);
076                _documentationEditorPane.setCaretPosition(0);
077            } else {
078                _documentationEditorPane.setText("");
079            }
080        });
081
082        if (_moduleComboBox.getItemCount() > 0) {
083            _moduleComboBox.setSelectedIndex(0);
084        }
085
086        _selectItemTypeDialog  = new JDialog(
087                (JDialog)null,
088                Bundle.getMessage("FunctionsHelpDialogTitle"),
089                false);
090
091
092        Container contentPanel = _selectItemTypeDialog.getContentPane();
093        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
094
095        JPanel p;
096        p = new JPanel();
097//        p.setLayout(new FlowLayout());
098        p.setLayout(new java.awt.GridBagLayout());
099        java.awt.GridBagConstraints c = new java.awt.GridBagConstraints();
100        c.gridwidth = 1;
101        c.gridheight = 1;
102        c.gridx = 0;
103        c.gridy = 0;
104        c.anchor = java.awt.GridBagConstraints.EAST;
105        p.add(_moduleLabel, c);
106        c.gridy = 1;
107        p.add(_functionLabel, c);
108        c.gridx = 1;
109        c.gridy = 0;
110        c.anchor = java.awt.GridBagConstraints.WEST;
111        c.weightx = 1.0;
112        c.fill = java.awt.GridBagConstraints.HORIZONTAL;  // text field will expand
113        p.add(_moduleComboBox, c);
114        c.gridy = 1;
115        c.fill = java.awt.GridBagConstraints.BOTH;  // text field will expand
116        p.add(_functionComboBox, c);
117
118        c.gridx = 0;
119        c.gridy = 2;
120        c.gridwidth = 2;
121
122        JScrollPane documentationScroller = new JScrollPane(_documentationEditorPane);
123        documentationScroller.setPreferredSize(new Dimension(panelWidth, panelHeight));
124        documentationScroller.setAlignmentX(LEFT_ALIGNMENT);
125        documentationScroller.setAlignmentY(TOP_ALIGNMENT);
126        p.add(documentationScroller, c);
127
128//        _categoryComboBox.setToolTipText(jmri.jmrit.logixng.tools.swing.Bundle.getMessage("CategoryNamesHint"));    // NOI18N
129//        _swingConfiguratorComboBox.setToolTipText(jmri.jmrit.logixng.tools.swing.Bundle.getMessage("TypeNamesHint"));   // NOI18N
130        contentPanel.add(p);
131        // set up message
132        JPanel panel3 = new JPanel();
133        panel3.setLayout(new BoxLayout(panel3, BoxLayout.Y_AXIS));
134
135        contentPanel.add(panel3);
136
137        // set up create and cancel buttons
138        JPanel panel5 = new JPanel();
139        panel5.setLayout(new FlowLayout());
140        // Cancel
141        JButton cancel = new JButton(Bundle.getMessage("ButtonCancel"));    // NOI18N
142        panel5.add(cancel);
143        cancel.addActionListener((ActionEvent e) -> {
144            cancelAddPressed(null);
145        });
146        cancel.setToolTipText(Bundle.getMessage("LogixNG_CancelButtonHint"));      // NOI18N
147
148        _selectItemTypeDialog.addWindowListener(new java.awt.event.WindowAdapter() {
149            @Override
150            public void windowClosing(java.awt.event.WindowEvent e) {
151                cancelAddPressed(null);
152            }
153        });
154/*
155        _create = new JButton(Bundle.getMessage("ButtonCreate"));  // NOI18N
156        panel5.add(_create);
157        _create.addActionListener((ActionEvent e) -> {
158            cancelAddPressed(null);
159
160            SwingConfiguratorInterface swingConfiguratorInterface =
161                    _swingConfiguratorComboBox.getItemAt(_swingConfiguratorComboBox.getSelectedIndex());
162//            System.err.format("swingConfiguratorInterface: %s%n", swingConfiguratorInterface.getClass().getName());
163            createAddFrame(femaleSocket, path, swingConfiguratorInterface);
164        });
165*/
166        contentPanel.add(panel5);
167
168        _selectItemTypeDialog.setMinimumSize(new Dimension(panelWidth, panelHeight));
169
170//        addLogixNGFrame.setLocationRelativeTo(component);
171        _selectItemTypeDialog.setLocationRelativeTo(null);
172        _selectItemTypeDialog.pack();
173        _selectItemTypeDialog.setVisible(true);
174    }
175
176    final protected void cancelAddPressed(ActionEvent e) {
177        _selectItemTypeDialog.setVisible(false);
178        _selectItemTypeDialog.dispose();
179        _selectItemTypeDialog = null;
180    }
181
182    private void initFunctionsComboBox() {
183        _functionComboBox.removeAllItems();
184
185        if (_moduleComboBox.getSelectedIndex() > -1) {
186            Module module = _moduleComboBox.getItemAt(_moduleComboBox.getSelectedIndex());
187            List<SortableFunction> list = new ArrayList<>();
188            if (module._constantDescriptions != null) {
189                list.add(new SortableFunction(Bundle.getMessage("FunctionsHelpDialog_Constants"), module._constantDescriptions));
190            }
191            for (Function f : module._functions) {
192                list.add(new SortableFunction(f.getName(), f.getDescription()));
193            }
194            Collections.sort(list);
195            for (SortableFunction function : list) {
196                _functionComboBox.addItem(function);
197            }
198            JComboBoxUtil.setupComboBoxMaxRows(_functionComboBox);
199        }
200    }
201
202
203
204
205    private static class Module implements Comparable<Module> {
206
207        private final String _name;
208        private final String _constantDescriptions;
209        private final List<Function> _functions = new ArrayList<>();
210
211        private Module(String name, String constantDescriptions) {
212            _name = name;
213            _constantDescriptions = constantDescriptions;
214        }
215
216        @Override
217        public boolean equals(Object o) {
218            return (o instanceof Module) && _name.equals(((Module)o)._name);
219        }
220
221        @Override
222        public int hashCode() {
223            int hash = 7;
224            hash = 47 * hash + Objects.hashCode(this._name);
225            return hash;
226        }
227
228        @Override
229        public int compareTo(Module o) {
230            return _name.compareTo(o._name);
231        }
232
233        @Override
234        public String toString() {
235            return _name;
236        }
237    }
238
239    private static class SortableFunction implements Comparable<SortableFunction> {
240
241        private final String _name;
242        private final String _functionDescr;
243
244        private SortableFunction(String name, String functionDescr) {
245            _name = name;
246            _functionDescr = functionDescr;
247        }
248
249        @Override
250        public boolean equals(Object o) {
251            return (o instanceof SortableFunction) && _name.equals(((SortableFunction)o)._name);
252        }
253
254        @Override
255        public int hashCode() {
256            int hash = 7;
257            hash = 47 * hash + Objects.hashCode(this._name);
258            return hash;
259        }
260
261        @Override
262        public int compareTo(SortableFunction o) {
263            return _name.compareTo(o._name);
264        }
265
266        @Override
267        public String toString() {
268            return _name;
269        }
270    }
271
272}