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.*;
016import jmri.jmrit.operations.setup.Control;
017import jmri.jmrit.operations.setup.Setup;
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 TrackPriorityAction(_track), 1);
064        _toolMenu.insert(new ChangeTrackTypeAction(this), TOOL_MENU_OFFSET + 2);
065        addHelpMenu("package.jmri.jmrit.operations.Operations_Spurs", true); // NOI18N
066
067        // override text strings for tracks
068        panelTrainDir.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TrainSpur")));
069        paneCheckBoxes.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("TypesSpur")));
070        deleteTrackButton.setText(Bundle.getMessage("DeleteSpur"));
071        addTrackButton.setText(Bundle.getMessage("AddSpur"));
072        saveTrackButton.setText(Bundle.getMessage("SaveSpur"));
073        
074        // tool tips
075        autoSelectButton.setToolTipText(Bundle.getMessage("TipAutoSelectSchedule"));
076
077        // setup buttons
078        addButtonAction(autoSelectButton);
079        addButtonAction(editScheduleButton);
080        addComboBoxAction(comboBoxSchedules);
081        
082        // Select the spur's Schedule
083        updateScheduleComboBox();
084
085        scheduleManager.addPropertyChangeListener(this);
086        
087        // finish
088        panelOrder.setVisible(false); // Car order out of spurs is not available
089        panelQuickService.setVisible(Setup.isBuildOnTime());
090        pack();
091        setVisible(true);
092    }
093
094    @Override
095    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
096        if (ae.getSource() == autoSelectButton) {
097            autoSelectCheckboxes();
098        }
099        if (ae.getSource() == editScheduleButton) {
100            editAddSchedule();
101        }
102        super.buttonActionPerformed(ae);
103    }
104    
105    @Override
106    public void comboBoxActionPerformed(java.awt.event.ActionEvent ae) {
107        removeSchedulePropertyListener();
108        updateScheduleButtonText();
109    }
110    
111    private void updateScheduleButtonText() {
112        if (comboBoxSchedules.getSelectedItem() == null) {
113            editScheduleButton.setText(Bundle.getMessage("Add"));
114        } else {
115            editScheduleButton.setText(Bundle.getMessage("ButtonEdit"));
116        }
117    }
118    
119    private void autoSelectCheckboxes() {
120        if (JmriJOptionPane.showConfirmDialog(this, Bundle.getMessage("TipAutoSelectSchedule"),
121                Bundle.getMessage("AutoSelect"), JmriJOptionPane.YES_NO_OPTION) == JmriJOptionPane.YES_OPTION) {
122            for (int i = 0; i < checkBoxes.size(); i++) {
123                JCheckBox checkBox = checkBoxes.get(i);
124                if (_track != null && _track.getSchedule() != null) {
125                    Schedule schedule = _track.getSchedule();
126                    if (schedule.checkScheduleAttribute(Track.TYPE, checkBox.getText(), null)) {
127                        _track.addTypeName(checkBox.getText());
128                    } else {
129                        _track.deleteTypeName(checkBox.getText());
130                    }
131                }
132            }
133        }
134    }
135
136
137    ScheduleEditFrame sef = null;
138
139    private void editAddSchedule() {
140        log.debug("Edit/add schedule");
141        if (sef != null) {
142            sef.dispose();
143        }
144        Schedule schedule = (Schedule) comboBoxSchedules.getSelectedItem();
145        sef = new ScheduleEditFrame(schedule, _track);
146    }
147
148    @Override
149    protected void enableButtons(boolean enabled) {
150        autoSelectButton.setEnabled(enabled && _track.getSchedule() != null);
151        editScheduleButton.setEnabled(enabled);
152        comboBoxSchedules.setEnabled(enabled);
153        if (!enabled) {
154            comboBoxSchedules.setSelectedItem(null);
155        }
156        super.enableButtons(enabled);
157    }
158
159    @Override
160    protected void saveTrack(Track track) {
161        // save the schedule
162        Schedule schedule = (Schedule) comboBoxSchedules.getSelectedItem();
163        track.setSchedule(schedule);
164        textSchError.setText(track.checkScheduleValid());
165        super.saveTrack(track);
166    }
167
168    @Override
169    protected void addNewTrack() {
170        super.addNewTrack();
171        updateScheduleComboBox(); // reset schedule and error text
172    }
173    
174    @Override
175    protected void deleteTrack() {
176        removeSchedulePropertyListener();
177        super.deleteTrack();
178    }
179
180    private void updateScheduleComboBox() {
181        scheduleManager.updateComboBox(comboBoxSchedules);
182        if (_track != null) {
183            Schedule sch = scheduleManager.getScheduleById(_track.getScheduleId());
184            comboBoxSchedules.setSelectedItem(sch);
185            textSchError.setText(_track.checkScheduleValid());
186            if (sch != null) {
187                sch.removePropertyChangeListener(this);
188                sch.addPropertyChangeListener(this);
189            }
190        }
191    }
192
193    @Override
194    public void dispose() {
195        scheduleManager.removePropertyChangeListener(this);
196        removeSchedulePropertyListener();
197        super.dispose();
198    }
199    
200    private void removeSchedulePropertyListener() {
201        if (_track != null) {
202            Schedule sch = scheduleManager.getScheduleById(_track.getScheduleId());
203            if (sch != null)
204                sch.removePropertyChangeListener(this);
205        }
206    }
207
208    @Override
209    public void propertyChange(java.beans.PropertyChangeEvent e) {
210        if (Control.SHOW_PROPERTY) {
211            log.debug("Property change: ({}) old: ({}) new: ({})", e.getPropertyName(), e.getOldValue(), e
212                    .getNewValue());
213        }
214        if (e.getPropertyName().equals(ScheduleManager.LISTLENGTH_CHANGED_PROPERTY)
215                || e.getPropertyName().equals(Track.SCHEDULE_ID_CHANGED_PROPERTY)) {
216            updateScheduleComboBox();
217        }
218        if (e.getSource().getClass().equals(Schedule.class) && _track != null) {
219            textSchError.setText(_track.checkScheduleValid());
220        }
221        super.propertyChange(e);
222    }
223
224    private final static Logger log = LoggerFactory.getLogger(SpurEditFrame.class);
225}