001package jmri.jmrit.conditional;
002
003import java.util.TreeSet;
004
005import javax.swing.JPanel;
006import javax.swing.JTextField;
007
008import jmri.*;
009import jmri.util.swing.JmriJOptionPane;
010
011/**
012 * Basis for ConditionalListEdit and ConditionalListCopy
013 *
014 * @author Pete Cressman Copyright (C) 2020
015 */
016abstract public class ConditionalList extends ConditionalEditBase {
017
018    Conditional _curConditional = null;
019    ConditionalFrame _conditionalFrame = null;
020    boolean _newConditional = false;
021    TreeSet<String> _oldTargetNames = new TreeSet<>();
022
023    /**
024     * Create a new Conditional List View editor.
025     *
026     * @param sName name of the Logix being edited
027     */
028    public ConditionalList(String sName) {
029        super(sName);
030    }
031
032    public ConditionalList() {
033    }
034
035    // ------------ Methods for Edit Conditional Pane ------------
036
037    Conditional makeNewConditional(Logix logix) {
038        log.debug("makeNewConditional(Logix)");
039        // make system name for new conditional
040        int num = logix.getNumConditionals() + 1;
041        Conditional conditional = null;
042        String cName = null;
043        while (conditional == null) {
044            cName = logix.getSystemName() + "C" + Integer.toString(num);
045            conditional = _conditionalManager.createNewConditional(cName, "");
046            num++;
047            if (num == 1000) {
048                break;
049            }
050        }
051        _newConditional = (conditional != null);
052        return conditional;
053    }
054
055    /**
056     * Make the bottom panel for _conditionalFrame to hold buttons for
057     * Update/Save, Cancel, Delete/FullEdit
058     *
059     * @return the panel
060     */
061    abstract JPanel makeBottomPanel();
062
063    abstract void updateConditionalTableModel();
064
065    /**
066     * Update _curConditional, the current Conditional.
067     * Checks for being well formed rules and registers its usage.
068     *
069     * @param uName Conditiona's user name
070     * @param logicType Logic type od antecedent
071     * @param trigger Trigger on variablr change action choice
072     * @param antecedent the antecedent
073     * @return true, if update is made
074     */
075    abstract boolean updateConditional(String uName, Conditional.AntecedentOperator logicType, boolean trigger, String antecedent);
076
077    boolean updateConditional(String uName, Logix logix,
078            Conditional.AntecedentOperator logicType, boolean trigger, String antecedent) {
079        log.debug("updateConditional");
080
081        // Check if the User Name has been changed
082        if (!uName.equals(_curConditional.getUserName())) {
083            // user name has changed - check if already in use
084            if (!checkConditionalUserName(uName, logix)) {
085                return false;
086            }
087            // user name is unique or blank, change it
088            _curConditional.setUserName(uName);
089        }
090        if (_conditionalFrame._variableList.size() <= 0 && !_suppressReminder) {
091            JmriJOptionPane.showMessageDialog(_editLogixFrame,
092                    Bundle.getMessage("Warn5", _curConditional.getUserName(), _curConditional.getSystemName()),
093                    Bundle.getMessage("WarningTitle"), // NOI18N
094                    JmriJOptionPane.WARNING_MESSAGE);
095        }
096        // complete update
097        _curConditional.setStateVariables(_conditionalFrame._variableList);
098        _curConditional.setAction(_conditionalFrame._actionList);
099        _curConditional.setTriggerOnChange(trigger);
100        _curConditional.setLogicType(logicType, antecedent);
101
102        if (_newConditional) {
103            // add to Logix at the end of the calculate order
104            logix.addConditional(_curConditional.getSystemName(), -1);
105            _showReminder = true;
106            _newConditional = false;
107            updateConditionalTableModel();
108        }
109        TreeSet<String> newTargetNames = new TreeSet<String>();
110        loadReferenceNames(_conditionalFrame._variableList, newTargetNames);
111        updateWhereUsed(_oldTargetNames, newTargetNames, _curConditional.getSystemName());
112        closeConditionalFrame();
113        return true;
114    }
115
116    PickSingleListener getPickSingleListener(JTextField textField, Conditional.ItemType itemType) {
117        return new PickSingleListener(textField, itemType);
118    }
119
120    abstract void closeConditionalFrame();
121
122    void closeConditionalFrame(Logix logix) {
123        log.debug("closeConditionalFrame(Logix)");
124        try {
125            logix.activateLogix();
126        } catch (NumberFormatException nfe) {
127            log.debug("NumberFormatException on activation of Logix ", nfe);  // NOI18N
128            JmriJOptionPane.showMessageDialog(_editLogixFrame,
129                    Bundle.getMessage("Error4") + nfe.toString() + Bundle.getMessage("Error7"), // NOI18N
130                    Bundle.getMessage("ErrorTitle"),
131                    JmriJOptionPane.ERROR_MESSAGE);  // NOI18N
132        }
133        if (_pickTables != null) {
134            _pickTables.dispose();
135            _pickTables = null;
136        }
137        // when user uses the escape key and returns to editing, interaction with
138        // window closing event create strange environment
139
140        if (_conditionalFrame != null) {
141            _conditionalFrame.dispose();
142            _conditionalFrame = null;
143        }
144        if (_editLogixFrame != null) {
145            _editLogixFrame.setVisible(true);
146        }
147    }
148
149    @Override
150    protected String getClassName() {
151        return ConditionalListEdit.class.getName();
152    }
153
154    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ConditionalList.class);
155
156}