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());
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._function.getDescription());
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                true);
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            for (Function f : module._functions) {
190                list.add(new SortableFunction(f.getName(), f));
191            }
192            Collections.sort(list);
193            for (SortableFunction function : list) {
194                _functionComboBox.addItem(function);
195            }
196            JComboBoxUtil.setupComboBoxMaxRows(_functionComboBox);
197        }
198    }
199    
200    
201    
202    
203    private static class Module implements Comparable<Module> {
204        
205        private final String _name;
206        private final List<Function> _functions = new ArrayList<>();
207        
208        private Module(String name) {
209            _name = name;
210        }
211        
212        @Override
213        public boolean equals(Object o) {
214            return (o instanceof Module) && _name.equals(((Module)o)._name);
215        }
216        
217        @Override
218        public int hashCode() {
219            int hash = 7;
220            hash = 47 * hash + Objects.hashCode(this._name);
221            return hash;
222        }
223        
224        @Override
225        public int compareTo(Module o) {
226            return _name.compareTo(o._name);
227        }
228        
229        @Override
230        public String toString() {
231            return _name;
232        }
233    }
234    
235    private static class SortableFunction implements Comparable<SortableFunction> {
236        
237        private final String _name;
238        private final Function _function;
239        
240        private SortableFunction(String name, Function function) {
241            _name = name;
242            _function = function;
243        }
244        
245        @Override
246        public boolean equals(Object o) {
247            return (o instanceof SortableFunction) && _name.equals(((SortableFunction)o)._name);
248        }
249        
250        @Override
251        public int hashCode() {
252            int hash = 7;
253            hash = 47 * hash + Objects.hashCode(this._name);
254            return hash;
255        }
256        
257        @Override
258        public int compareTo(SortableFunction o) {
259            return _name.compareTo(o._name);
260        }
261        
262        @Override
263        public String toString() {
264            return _name;
265        }
266    }
267    
268}