001package jmri.jmrit.turnoutoperations;
002
003import java.awt.Component;
004import java.awt.Container;
005import java.awt.Frame;
006import java.awt.event.ActionEvent;
007import java.beans.PropertyChangeEvent;
008import java.util.ArrayList;
009
010import javax.swing.Box;
011import javax.swing.JButton;
012import javax.swing.JDialog;
013import javax.swing.JTabbedPane;
014import javax.swing.event.ChangeEvent;
015
016import jmri.*;
017import jmri.util.swing.JmriJOptionPane;
018
019/**
020 * @author John Harper
021 *
022 */
023public class TurnoutOperationFrame extends JDialog {
024
025    TurnoutOperationConfig currentConfig = null;
026    TurnoutOperation currentOperation = null;
027    String previousSelectionName = "";
028    JTabbedPane tabPane;
029    private JButton deleteButton;
030    private JButton renameOrCopyButton;
031
032    public TurnoutOperationFrame(Frame parent) {
033        super(parent, Bundle.getMessage("TurnoutOperationEditorTitle"));
034        init();
035    }
036
037    private void init() {
038        Container contentPane = getContentPane();
039        setMinimumSize(new java.awt.Dimension(400, 165));
040        Box outerBox = Box.createVerticalBox();
041        contentPane.add(outerBox);
042        tabPane = new JTabbedPane();
043        tabPane.addChangeListener(this::changeTab);
044
045        outerBox.add(tabPane);
046        Box bottomBox = Box.createHorizontalBox();
047        bottomBox.add(Box.createHorizontalGlue());
048
049        renameOrCopyButton = new JButton("RenameOrCopy");
050        renameOrCopyButton.addActionListener(this::doRenameOrCopy);
051        bottomBox.add(renameOrCopyButton);
052
053        deleteButton = new JButton(Bundle.getMessage("ButtonDelete"));
054        deleteButton.addActionListener(this::doDelete);
055        bottomBox.add(deleteButton);
056
057        JButton cancelButton = new JButton(Bundle.getMessage("ButtonCancel"));
058        cancelButton.addActionListener((ActionEvent a) -> {
059            this.dispose();
060        });
061        bottomBox.add(cancelButton);
062        JButton okButton = new JButton(Bundle.getMessage("ButtonOK"));
063        okButton.addActionListener(this::doOK);
064        bottomBox.add(okButton);
065        outerBox.add(bottomBox);
066
067        populateTabs();
068        InstanceManager.getDefault(TurnoutOperationManager.class).addPropertyChangeListener(pcl);
069        setVisible(tabPane.getTabCount() > 0);
070    }
071
072    private final java.beans.PropertyChangeListener pcl = (PropertyChangeEvent e) -> {
073        if (e.getPropertyName().equals("Content")) {
074            populateTabs();
075        }
076    };
077
078    private void doOK(ActionEvent e) {
079        log.debug("OK clicked {}", e);
080        for(Component tab : tabPane.getComponents()) {
081            ((TurnoutOperationConfig)tab).endConfigure();
082        }
083        dispose();
084    }
085
086    private void doDelete(ActionEvent e) {
087        log.debug("Delete clicked {}", e);
088        String query = "";
089        if (currentOperation != null && !currentOperation.isDefinitive()) {
090            if (currentOperation.isInUse()) {
091                query = Bundle.getMessage("DeleteOperationInUse", currentOperation.getName())
092                        + Bundle.getMessage("DeleteRevert");
093            }
094            if (JmriJOptionPane.showConfirmDialog(this, query + Bundle.getMessage("DeleteOperationDialog", currentOperation.getName()),
095                    Bundle.getMessage("WarningTitle"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
096                currentOperation.dispose();
097                populateTabs();
098            }
099        }
100    }
101
102    private void doRenameOrCopy(ActionEvent e) {
103        log.debug("CopyOr clicked {}", e);
104        String newName = JmriJOptionPane.showInputDialog(this,
105            Bundle.getMessage("EnterNewName"), Bundle.getMessage("EnterNewNameTitle"),
106            JmriJOptionPane.QUESTION_MESSAGE);
107        
108        if (newName != null && !newName.isEmpty()) {
109            if ( currentOperation.isDefinitive() ) {
110                currentOperation.makeCopy(newName);
111            } else {
112                if (!currentOperation.rename(newName)) {
113                    JmriJOptionPane.showMessageDialog(this, ("TurnoutErrorDuplicate"),
114                            Bundle.getMessage("WarningTitle"), JmriJOptionPane.ERROR_MESSAGE);
115                    return;
116                }
117                for ( Turnout t : InstanceManager.getDefault(TurnoutManager.class).getNamedBeanSet()) {
118                    if ( currentOperation.equivalentTo(t.getTurnoutOperation()) ) {
119                        t.setTurnoutOperation(null);
120                        t.setTurnoutOperation(currentOperation);
121                    }
122                }
123            }
124            populateTabs();
125        }
126    }
127
128    private void populateTabs() {
129        TurnoutOperation[] operations = InstanceManager.getDefault(TurnoutOperationManager.class).getTurnoutOperations();
130        log.debug("found {} turnoutoperations from TurnoutOperationManager", operations.length);
131
132        Component firstPane = null;
133        tabPane.removeAll();
134        ArrayList<TurnoutOperation> definitiveOperations = new ArrayList<>(10);
135        ArrayList<TurnoutOperation> namedOperations = new ArrayList<>(50);
136
137        for (TurnoutOperation operation : operations) {
138            if (operation.isDefinitive()) {
139                definitiveOperations.add(operation);
140            } else if (!operation.isNonce()) {
141                namedOperations.add(operation);
142            }
143        }
144
145        definitiveOperations.sort(null);
146        namedOperations.sort(null);
147
148        TurnoutOperationConfig pane;
149        TurnoutOperation op;
150        for (int j = 0; j < definitiveOperations.size(); ++j) {
151            op = definitiveOperations.get(j);
152            pane = TurnoutOperationConfig.getConfigPanel(op);
153            if (pane != null) {
154                if (firstPane == null) {
155                    firstPane = pane;
156                }
157                tabPane.add(op.getName(), pane);
158                if (op.getName().equals(previousSelectionName)) {
159                    tabPane.setSelectedComponent(pane);
160                }
161            }
162        }
163        for (int k = 0; k < namedOperations.size(); ++k) {
164            op = namedOperations.get(k);
165            pane = TurnoutOperationConfig.getConfigPanel(op);
166            if (pane != null) {
167                tabPane.add(op.getName(), pane);
168                if (op.getName().equals(previousSelectionName)) {
169                    tabPane.setSelectedComponent(pane);
170                }
171            }
172        }
173        if (tabPane.getSelectedComponent() == null && firstPane != null) {
174            tabPane.setSelectedComponent(firstPane);
175        }
176        changeTab(null);
177        pack();
178    }
179
180    private void changeTab( ChangeEvent e) {
181        log.debug("tab changed {}", e);
182        currentConfig = (TurnoutOperationConfig) tabPane.getSelectedComponent();
183        if (currentConfig == null) {
184            currentOperation = null;
185            previousSelectionName = "";
186        } else {
187            currentOperation = currentConfig.getOperation();
188            previousSelectionName = currentOperation.getName();
189        }
190        deleteButton.setEnabled( currentConfig!=null && !currentConfig.getOperation().isDefinitive() );
191        renameOrCopyButton.setText( currentConfig!=null && !currentConfig.getOperation().isDefinitive()
192            ? Bundle.getMessage("Rename") : Bundle.getMessage("MenuItemCopy")
193        );
194    }
195
196    @Override
197    public void dispose() {
198        setVisible(false);
199        InstanceManager.getDefault(TurnoutOperationManager.class).removePropertyChangeListener(pcl);
200        super.dispose();
201    }
202
203    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TurnoutOperationFrame.class);
204
205}