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