001package com.studentgui.app;
002
003import java.awt.BorderLayout;
004import java.awt.FlowLayout;
005import java.awt.Font;
006import java.awt.Frame;
007
008import javax.swing.JButton;
009import javax.swing.JCheckBox;
010import javax.swing.JDialog;
011import javax.swing.JLabel;
012import javax.swing.JPanel;
013import javax.swing.JTextField;
014
015import com.studentgui.apphelpers.Settings;
016
017/**
018 * Simple modal preferences dialog exposing a few runtime toggles that
019 * affect chart rendering. Preferences are persisted via
020 * {@link com.studentgui.apphelpers.Settings} and listeners are notified
021 * through {@link Main#notifySettingsChanged()}.
022 */
023public final class PreferencesDialog {
024    private PreferencesDialog() { throw new AssertionError(); }
025
026    /**
027     * Show the modal preferences dialog. The dialog persists changes to
028     * {@link com.studentgui.apphelpers.Settings} and notifies runtime
029     * listeners via {@link Main#notifySettingsChanged()}.
030     *
031     * @param owner optional parent frame for dialog positioning
032     */
033    public static void showDialog(final Frame owner) {
034        final JDialog dlg = new JDialog(owner, "Preferences", true);
035        dlg.setLayout(new BorderLayout());
036
037        JPanel center = new JPanel(new FlowLayout(FlowLayout.LEFT));
038        boolean jitterEnabled = Boolean.parseBoolean(Settings.get("jitter.enabled", "true"));
039        boolean deterministic = Boolean.parseBoolean(Settings.get("jitter.deterministic", "false"));
040        String seed = Settings.get("jitter.seed", "");
041    boolean dumpsEnabled = Boolean.parseBoolean(Settings.get("dump.enabled", "false"));
042
043        final JCheckBox jitterCb = new JCheckBox("Enable jitter", jitterEnabled);
044        final JCheckBox detCb = new JCheckBox("Deterministic (seeded)", deterministic);
045        final JTextField seedField = new JTextField(seed == null ? "" : seed, 12);
046    final JCheckBox dumpsCb = new JCheckBox("Enable per-page data dumps", dumpsEnabled);
047
048        center.add(jitterCb);
049        center.add(detCb);
050    center.add(dumpsCb);
051        JLabel seedLabel = new JLabel("Seed:");
052        seedLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 24));
053        center.add(seedLabel);
054        center.add(seedField);
055
056        JPanel south = new JPanel(new FlowLayout(FlowLayout.RIGHT));
057        JButton save = new JButton("Save");
058        JButton cancel = new JButton("Cancel");
059
060        save.addActionListener(e -> {
061            Settings.put("jitter.enabled", String.valueOf(jitterCb.isSelected()));
062            Settings.put("jitter.deterministic", String.valueOf(detCb.isSelected()));
063            Settings.put("jitter.seed", seedField.getText().trim());
064            Settings.put("dump.enabled", String.valueOf(dumpsCb.isSelected()));
065            // notify runtime listeners
066            Main.notifySettingsChanged();
067            dlg.dispose();
068        });
069
070        cancel.addActionListener(e -> dlg.dispose());
071        south.add(cancel);
072        south.add(save);
073
074        dlg.add(center, BorderLayout.CENTER);
075        dlg.add(south, BorderLayout.SOUTH);
076        dlg.pack();
077        dlg.setLocationRelativeTo(owner);
078        dlg.setVisible(true);
079    }
080}