001package jmri.jmrit.operations.locations;
002
003import java.awt.Color;
004import java.awt.GridBagLayout;
005
006import javax.swing.*;
007
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011import jmri.InstanceManager;
012import jmri.jmrit.operations.locations.schedules.*;
013import jmri.jmrit.operations.locations.tools.AlternateTrackAction;
014import jmri.jmrit.operations.locations.tools.ChangeTrackTypeAction;
015import jmri.jmrit.operations.setup.Control;
016import jmri.util.swing.JmriJOptionPane;
017
018/**
019 * Frame for user edit of a spur.
020 *
021 * @author Dan Boudreau Copyright (C) 2008, 2011, 2023
022 */
023public class SpurEditFrame extends TrackEditFrame {
024
025    // labels, buttons, etc. for spurs
026    JLabel textSchedule = new JLabel(Bundle.getMessage("DeliverySchedule"));
027    JLabel textSchError = new JLabel();
028    JButton editScheduleButton = new JButton();
029    JComboBox<Schedule> comboBoxSchedules = InstanceManager.getDefault(ScheduleManager.class).getComboBox();
030
031    JPanel panelSchedule = panelOpt4;
032
033    public SpurEditFrame() {
034        super(Bundle.getMessage("AddSpur"));
035    }
036    
037    @Override
038    public void initComponents(Track track) {
039        setTitle(Bundle.getMessage("EditSpur", track.getLocation().getName()));
040        initComponents(track.getLocation(), track);
041    }
042
043    @Override
044    public void initComponents(Location location, Track track) {
045        _type = Track.SPUR;
046
047        // setup the optional panel with schedule stuff
048        panelSchedule.setLayout(new GridBagLayout());
049        panelSchedule.setBorder(BorderFactory.createTitledBorder(Bundle
050                .getMessage("DeliverySchedule")));
051        addItem(panelSchedule, comboBoxSchedules, 0, 0);
052        addItem(panelSchedule, editScheduleButton, 1, 0);
053        addItem(panelSchedule, textSchError, 2, 0);
054        textSchError.setForeground(Color.RED);
055
056        super.initComponents(location, track);
057
058        _toolMenu.insert(new AlternateTrackAction(this), 0);
059        _toolMenu.insert(new ChangeTrackTypeAction(this), TOOL_MENU_OFFSET + 1);
060        addHelpMenu("package.jmri.jmrit.operations.Operations_Spurs", true); // NOI18N
061
062        // override text strings for tracks
063        panelTrainDir.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainSpur")));
064        paneCheckBoxes.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TypesSpur")));
065        deleteTrackButton.setText(Bundle.getMessage("DeleteSpur"));
066        addTrackButton.setText(Bundle.getMessage("AddSpur"));
067        saveTrackButton.setText(Bundle.getMessage("SaveSpur"));
068        
069        // tool tips
070        autoSelectButton.setToolTipText(Bundle.getMessage("TipAutoSelectSchedule"));
071
072        // setup buttons
073        addButtonAction(autoSelectButton);
074        addButtonAction(editScheduleButton);
075        addComboBoxAction(comboBoxSchedules);
076        
077        // Select the spur's Schedule
078        updateScheduleComboBox();
079
080        InstanceManager.getDefault(ScheduleManager.class).addPropertyChangeListener(this);
081        
082        // finish
083        panelOrder.setVisible(false); // Car order out of spurs is not available
084        pack();
085        setVisible(true);
086    }
087
088    @Override
089    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
090        if (ae.getSource() == autoSelectButton) {
091            autoSelectCheckboxes();
092        }
093        if (ae.getSource() == editScheduleButton) {
094            editAddSchedule();
095        }
096        super.buttonActionPerformed(ae);
097    }
098    
099    @Override
100    public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
101        removeSchedulePropertyListener();
102        updateScheduleButtonText();
103    }
104    
105    private void updateScheduleButtonText() {
106        if (comboBoxSchedules.getSelectedItem() == null) {
107            editScheduleButton.setText(Bundle.getMessage("Add"));
108        } else {
109            editScheduleButton.setText(Bundle.getMessage("ButtonEdit"));
110        }
111    }
112    
113    private void autoSelectCheckboxes() {
114        if (JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("TipAutoSelectSchedule"),
115                Bundle.getMessage("AutoSelect"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
116            for (int i = 0; i < checkBoxes.size(); i++) {
117                JCheckBox checkBox = checkBoxes.get(i);
118                if (_track != null && _track.getSchedule() != null) {
119                    Schedule schedule = _track.getSchedule();
120                    if (schedule.checkScheduleAttribute(Track.TYPE, checkBox.getText(), null)) {
121                        _track.addTypeName(checkBox.getText());
122                    } else {
123                        _track.deleteTypeName(checkBox.getText());
124                    }
125                }
126            }
127        }
128    }
129
130
131    ScheduleEditFrame sef = null;
132
133    private void editAddSchedule() {
134        log.debug("Edit/add schedule");
135        if (sef != null) {
136            sef.dispose();
137        }
138        Schedule schedule = (Schedule) comboBoxSchedules.getSelectedItem();
139        sef = new ScheduleEditFrame(schedule, _track);
140    }
141
142    @Override
143    protected void enableButtons(boolean enabled) {
144        autoSelectButton.setEnabled(enabled && _track.getSchedule() != null);
145        editScheduleButton.setEnabled(enabled);
146        comboBoxSchedules.setEnabled(enabled);
147        if (!enabled) {
148            comboBoxSchedules.setSelectedItem(null);
149        }
150        super.enableButtons(enabled);
151    }
152
153    @Override
154    protected void saveTrack(Track track) {
155        // save the schedule
156        Schedule schedule = (Schedule) comboBoxSchedules.getSelectedItem();
157        track.setSchedule(schedule);
158        textSchError.setText(track.checkScheduleValid());
159        super.saveTrack(track);
160    }
161
162    @Override
163    protected void addNewTrack() {
164        super.addNewTrack();
165        updateScheduleComboBox(); // reset schedule and error text
166    }
167    
168    @Override
169    protected void deleteTrack() {
170        removeSchedulePropertyListener();
171        super.deleteTrack();
172    }
173
174    private void updateScheduleComboBox() {
175        InstanceManager.getDefault(ScheduleManager.class).updateComboBox(comboBoxSchedules);
176        if (_track != null) {
177            Schedule sch = InstanceManager.getDefault(ScheduleManager.class).getScheduleById(_track.getScheduleId());
178            comboBoxSchedules.setSelectedItem(sch);
179            textSchError.setText(_track.checkScheduleValid());
180            if (sch != null) {
181                sch.removePropertyChangeListener(this);
182                sch.addPropertyChangeListener(this);
183            }
184        }
185    }
186
187    @Override
188    public void dispose() {
189        removeSchedulePropertyListener();
190        super.dispose();
191    }
192    
193    private void removeSchedulePropertyListener() {
194        InstanceManager.getDefault(ScheduleManager.class).removePropertyChangeListener(this);
195        if (_track != null) {
196            Schedule sch = InstanceManager.getDefault(ScheduleManager.class).getScheduleById(_track.getScheduleId());
197            if (sch != null)
198                sch.removePropertyChangeListener(this);
199        }
200    }
201
202    @Override
203    public void propertyChange(java.beans.PropertyChangeEvent e) {
204        if (Control.SHOW_PROPERTY) {
205            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
206                    .getNewValue());
207        }
208        if (e.getPropertyName().equals(ScheduleManager.LISTLENGTH_CHANGED_PROPERTY)
209                || e.getPropertyName().equals(Track.SCHEDULE_ID_CHANGED_PROPERTY)) {
210            updateScheduleComboBox();
211        }
212        if (e.getSource().getClass().equals(Schedule.class) && _track != null) {
213            textSchError.setText(_track.checkScheduleValid());
214        }
215        super.propertyChange(e);
216    }
217
218    private final static Logger log = LoggerFactory.getLogger(SpurEditFrame.class);
219}