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("CancelLogixButtonHint"));      // NOI18N
147        cancel.setToolTipText("CancelLogixButtonHint");      // NOI18N
148
149        _selectItemTypeDialog.addWindowListener(new java.awt.event.WindowAdapter() {
150            @Override
151            public void windowClosing(java.awt.event.WindowEvent e) {
152                cancelAddPressed(null);
153            }
154        });
155/*
156        _create = new JButton(Bundle.getMessage("ButtonCreate"));  // NOI18N
157        panel5.add(_create);
158        _create.addActionListener((ActionEvent e) -> {
159            cancelAddPressed(null);
160
161            SwingConfiguratorInterface swingConfiguratorInterface =
162                    _swingConfiguratorComboBox.getItemAt(_swingConfiguratorComboBox.getSelectedIndex());
163//            System.err.format("swingConfiguratorInterface: %s%n", swingConfiguratorInterface.getClass().getName());
164            createAddFrame(femaleSocket, path, swingConfiguratorInterface);
165        });
166*/
167        contentPanel.add(panel5);
168
169        _selectItemTypeDialog.setMinimumSize(new Dimension(panelWidth, panelHeight));
170
171//        addLogixNGFrame.setLocationRelativeTo(component);
172        _selectItemTypeDialog.setLocationRelativeTo(null);
173        _selectItemTypeDialog.pack();
174        _selectItemTypeDialog.setVisible(true);
175    }
176
177    final protected void cancelAddPressed(ActionEvent e) {
178        _selectItemTypeDialog.setVisible(false);
179        _selectItemTypeDialog.dispose();
180        _selectItemTypeDialog = null;
181    }
182
183    private void initFunctionsComboBox() {
184        _functionComboBox.removeAllItems();
185
186        if (_moduleComboBox.getSelectedIndex() > -1) {
187            Module module = _moduleComboBox.getItemAt(_moduleComboBox.getSelectedIndex());
188            List<SortableFunction> list = new ArrayList<>();
189            if (module._constantDescriptions != null) {
190                list.add(new SortableFunction(Bundle.getMessage("FunctionsHelpDialog_Constants"), module._constantDescriptions));
191            }
192            for (Function f : module._functions) {
193                list.add(new SortableFunction(f.getName(), f.getDescription()));
194            }
195            Collections.sort(list);
196            for (SortableFunction function : list) {
197                _functionComboBox.addItem(function);
198            }
199            JComboBoxUtil.setupComboBoxMaxRows(_functionComboBox);
200        }
201    }
202
203
204
205
206    private static class Module implements Comparable<Module> {
207
208        private final String _name;
209        private final String _constantDescriptions;
210        private final List<Function> _functions = new ArrayList<>();
211
212        private Module(String name, String constantDescriptions) {
213            _name = name;
214            _constantDescriptions = constantDescriptions;
215        }
216
217        @Override
218        public boolean equals(Object o) {
219            return (o instanceof Module) && _name.equals(((Module)o)._name);
220        }
221
222        @Override
223        public int hashCode() {
224            int hash = 7;
225            hash = 47 * hash + Objects.hashCode(this._name);
226            return hash;
227        }
228
229        @Override
230        public int compareTo(Module o) {
231            return _name.compareTo(o._name);
232        }
233
234        @Override
235        public String toString() {
236            return _name;
237        }
238    }
239
240    private static class SortableFunction implements Comparable<SortableFunction> {
241
242        private final String _name;
243        private final String _functionDescr;
244
245        private SortableFunction(String name, String functionDescr) {
246            _name = name;
247            _functionDescr = functionDescr;
248        }
249
250        @Override
251        public boolean equals(Object o) {
252            return (o instanceof SortableFunction) && _name.equals(((SortableFunction)o)._name);
253        }
254
255        @Override
256        public int hashCode() {
257            int hash = 7;
258            hash = 47 * hash + Objects.hashCode(this._name);
259            return hash;
260        }
261
262        @Override
263        public int compareTo(SortableFunction o) {
264            return _name.compareTo(o._name);
265        }
266
267        @Override
268        public String toString() {
269            return _name;
270        }
271    }
272
273}