001package jmri.jmrit.operations.setup.gui;
002
003import java.awt.GridBagLayout;
004import java.time.LocalDate;
005import java.time.format.DateTimeFormatter;
006import java.time.format.DateTimeParseException;
007import java.util.Hashtable;
008
009import javax.swing.*;
010
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014import jmri.InstanceManager;
015import jmri.jmrit.operations.setup.*;
016import jmri.jmrit.operations.trains.TrainManager;
017import jmri.jmrit.operations.trains.schedules.TrainScheduleManager;
018
019/**
020 * Panel for user edit of day to name mapping
021 * 
022 * @author Dan Boudreau Copyright (C) 2026
023 */
024public class EditDayToNameMapPanel extends OperationsPreferencesPanel {
025
026    // major buttons
027    JButton saveButton = new JButton(Bundle.getMessage("ButtonSave"));
028    JButton daysButton = new JButton(Bundle.getMessage("DaysOfWeek"));
029    JButton datesButton = new JButton(Bundle.getMessage("LoadDates"));
030    JButton resetButton = new JButton(Bundle.getMessage("Reset"));
031
032    protected Hashtable<Integer, JTextField> hashTableDayToName = new Hashtable<>();
033
034    public EditDayToNameMapPanel() {
035        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
036        JPanel pDays = new JPanel();
037        JScrollPane pManifestPane = new JScrollPane(pDays);
038        pManifestPane.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutDays")));
039        pDays.setLayout(new BoxLayout(pDays, BoxLayout.Y_AXIS));
040
041        for (int i = 0; i < Control.numberOfDays; i++) {
042            JPanel pDay = new JPanel();
043            pDay.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("BorderLayoutDay", i)));
044            JTextField textField = new JTextField(25);
045            pDay.add(textField);
046            pDays.add(pDay);
047            String name = Setup.getDayToName(Integer.toString(i));
048            textField.setText(name);
049            hashTableDayToName.put(i, textField);
050        }
051
052        // row 11
053        JPanel pControl = new JPanel();
054        pControl.setBorder(BorderFactory.createTitledBorder(""));
055        pControl.setLayout(new GridBagLayout());
056        addItem(pControl, resetButton, 0, 0);
057        addItem(pControl, daysButton, 1, 0);
058        addItem(pControl, datesButton, 2, 0);
059        addItem(pControl, saveButton, 3, 0);
060
061        add(pManifestPane);
062        add(pControl);
063
064        // set up buttons
065        addButtonAction(resetButton);
066        addButtonAction(daysButton);
067        addButtonAction(datesButton);
068        addButtonAction(saveButton);
069
070    }
071
072    // Save buttons
073    @Override
074    public void buttonActionPerformed(java.awt.event.ActionEvent ae) {
075        if (ae.getSource() == resetButton) {
076            hashTableDayToName.forEach((key, textField) -> {
077                textField.setText("");
078            });
079        }
080        if (ae.getSource() == daysButton) {
081            loadDays();
082        }
083        if (ae.getSource() == datesButton) {
084            loadDates();
085        }
086        if (ae.getSource() == saveButton) {
087            savePreferences();
088            var topLevelAncestor = getTopLevelAncestor();
089            if (Setup.isCloseWindowOnSaveEnabled() && topLevelAncestor instanceof EditDayToNameMapFrame) {
090                ((EditDayToNameMapFrame) topLevelAncestor).dispose();
091            }
092        }
093    }
094
095    private void loadDays() {
096        JTextField textField;
097        String[] days = InstanceManager.getDefault(TrainScheduleManager.class).getDaysOfWeek();
098        int j = 0;
099        // list days starting with the day the user entered
100        textField = hashTableDayToName.get(0);
101        if (!textField.getText().isBlank()) {
102            for (String day : days) {
103                if (day.equals(textField.getText()) || j == days.length - 1) {
104                    break;
105                }
106                j++;
107            }
108        }
109        for (int i = 0; i < Control.numberOfDays; i++) {
110            textField = hashTableDayToName.get(i);
111            textField.setText(days[j++]);
112            if (j == days.length) {
113                j = 0;
114            }
115        }
116    }
117
118    private void loadDates() {
119        JTextField textField;
120        // list dates starting with the date the user entered
121        textField = hashTableDayToName.get(0);
122        LocalDate ld = LocalDate.now();
123        String year = Setup.getYearModeled();
124        if (!year.isBlank()) {
125            // default format yyyy-MM-dd
126            try {
127            ld = LocalDate.parse(year + "-01-01");
128            } catch (DateTimeParseException e) {
129                log.error("Year {} must be four digits", year);
130            }
131        } else {
132            year = "1956";
133        }
134        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy");
135        // three date formats accepted MMMM d, yyyy or MMMM d or MM/dd/yyyy
136        if (!textField.getText().isBlank()) {
137            // try month day year format MMMM d, yyyy
138            try {
139                ld = LocalDate.parse(textField.getText(), formatter);
140            } catch (DateTimeParseException e) {
141                // try month day format
142                try {
143                    ld = LocalDate.parse(textField.getText() + ", " + year , formatter);
144                    formatter = DateTimeFormatter.ofPattern("MMMM d");
145                } catch (DateTimeParseException e2) {
146                    // try MM/dd/yyyy
147                    try {
148                        formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
149                        ld = LocalDate.parse(textField.getText(), formatter);
150                    } catch (DateTimeParseException e3) {
151                        log.error("Couldn't covert {} to date", textField.getText());
152                    }
153                }
154            }
155        }
156        
157        for (int i = 0; i < Control.numberOfDays; i++) {
158            textField = hashTableDayToName.get(i);
159            textField.setText(ld.format(formatter));
160            ld = ld.plusDays(1);
161        }
162    }
163
164    @Override
165    public String getTabbedPreferencesTitle() {
166        return Bundle.getMessage("TitleDayToNameMap");
167    }
168
169    @Override
170    public String getPreferencesTooltip() {
171        return null;
172    }
173
174    @Override
175    public void savePreferences() {
176        for (int i = 0; i < Control.numberOfDays; i++) {
177            JTextField textField = hashTableDayToName.get(i);
178            Setup.setDayToName(Integer.toString(i), textField.getText());
179        }
180        InstanceManager.getDefault(OperationsSetupXml.class).writeOperationsFile();
181        InstanceManager.getDefault(TrainManager.class).setTrainsModified();
182    }
183
184    @Override
185    public boolean isDirty() {
186        return false;
187    }
188
189    private final static Logger log = LoggerFactory.getLogger(EditDayToNameMapPanel.class);
190}