001package apps.gui3.lccpro;
002
003import java.io.File;
004import javax.swing.AbstractAction;
005
006import apps.gui3.Apps3;
007import apps.gui3.FirstTimeStartUpWizard;
008import apps.gui3.FirstTimeStartUpWizardAction;
009
010import jmri.InstanceManager;
011import jmri.util.JmriJFrame;
012import jmri.util.FileUtil;
013
014/**
015 * The JMRI application for configuring an LCC network.
016 * <p>
017 * Inserts LccPro interface elements stored in xml/config/parts/jmri/
018 * that are also used in the web server interface.
019 *
020 * @author Bob Jacobsen Copyright 2024
021 */
022public class LccPro extends Apps3 {
023
024    private static String menuFile = null;
025    private static String toolbarFile = null;
026    private static final String applicationName = "LccPro";
027
028    public LccPro(String[] args) {
029        super(applicationName, "LccProConfig.xml", args);
030    }
031
032    public synchronized static String getMenuFile() {
033        if (menuFile == null) {
034            menuFile = "lccpro/Gui3Menus.xml";
035            File file = new File(menuFile);
036            // decide whether name is absolute or relative
037            if (!file.isAbsolute()) {
038                // must be relative, but we want it to
039                // be relative to the preferences directory
040                menuFile = FileUtil.getUserFilesPath() + "lccpro/Gui3Menus.xml";
041                file = new File(menuFile);
042            }
043            if (!file.exists()) {
044                menuFile = "xml/config/parts/apps/gui3/lccpro/LccProFrameMenu.xml";
045            } else {
046                log.info("Found user created menu structure this will be used instead of the system default");
047            }
048        }
049        return menuFile;
050    }
051
052    public synchronized static String getToolbarFile() {
053        if (toolbarFile == null) {
054            toolbarFile = "lccpro/Gui3MainToolBar.xml";
055            File file = new File(toolbarFile);
056            // decide whether name is absolute or relative
057            if (!file.isAbsolute()) {
058                // must be relative, but we want it to
059                // be relative to the preferences directory
060                toolbarFile = FileUtil.getUserFilesPath() + "lccpro/Gui3MainToolBar.xml";
061                file = new File(toolbarFile);
062            }
063            if (!file.exists()) {
064                toolbarFile = "xml/config/parts/apps/gui3/lccpro/LccProFrameToolBar.xml";
065            } else {
066                log.info("Found user created toolbar structure this will be used instead of the system default");
067            }
068        }
069        return toolbarFile;
070    }
071
072    /** If we don't have the right kind of connection, launch the
073     * start up wizard.
074     */
075    @Override
076    protected boolean wizardLaunchCheck() {
077        var memo = jmri.InstanceManager.getNullableDefault(jmri.jmrix.can.CanSystemConnectionMemo.class);
078        return memo == null;
079    }
080
081    /**
082     * Provide a custom first-time wizard
083     */
084    @Override
085    public void launchFirstTimeStartupWizard() {
086        FirstTimeStartUpWizardAction prefsAction = new FirstTimeStartUpWizardAction("Start Up Wizard"){
087            @Override
088            public FirstTimeStartUpWizard makeWizard(JmriJFrame f, Apps3 app) {
089                f.setTitle("LccPro Wizard");
090                return new FirstTimeStartUpWizard(f, app){
091                    @Override
092                    protected void customizeConnection() {
093                        connectionConfigPane.manuBox.setSelectedItem("LCC");
094                        connectionConfigPane.manuBox.setEnabled(false);
095                    }
096                    @Override
097                    protected String firstPrompt() {
098                        return "Next you need to configure your LCC connection.\n\nThen select the serial port or enter in the IP address of the device";
099                    }
100                };
101            }      
102        };
103        prefsAction.setApp(this);
104        prefsAction.actionPerformed(null);
105    }
106
107    @Override
108    protected void createMainFrame() {
109        // create and populate main window
110        mainFrame = new LccProWindow(getMenuFile(), getToolbarFile());
111    }
112
113    /**
114     * Force our test size. Superclass method set to max size, filling real
115     * window.
116     *
117     * @param d size to use (ignored in this case)
118     */
119    @Override
120    protected void displayMainFrame(java.awt.Dimension d) {
121        jmri.UserPreferencesManager p = InstanceManager.getDefault(jmri.UserPreferencesManager.class);
122        if (!p.hasProperties(mainFrame.getWindowFrameRef())) {
123            mainFrame.setSize(new java.awt.Dimension(1024, 600));
124            mainFrame.setPreferredSize(new java.awt.Dimension(1024, 600));
125        }
126
127        mainFrame.setVisible(true);
128    }
129
130    // Main entry point
131    public static void main(String[] args) {
132        preInit(args);
133        LccPro app = new LccPro(args);
134        app.start();
135    }
136
137    static public void preInit(String[] args) {
138        apps.gui3.Apps3.preInit(applicationName);
139        apps.gui3.Apps3.setConfigFilename("LccProConfig.xml", args);
140    }
141
142    /**
143     * Final actions before releasing control of app to user
144     */
145    @Override
146    protected void start() {
147        super.start();
148
149        if ((!configOK) || (!configDeferredLoadOK)) {
150            if (preferenceFileExists) {
151                //if the preference file already exists then we will launch the normal preference window
152                AbstractAction prefsAction = new apps.gui3.tabbedpreferences.TabbedPreferencesAction(Bundle.getMessage("MenuItemPreferences"));
153                prefsAction.actionPerformed(null);
154            }
155        }
156
157        // kick off update of decoder index if needed
158        jmri.util.ThreadingUtil.runOnGUI(() -> {
159            try {
160                jmri.jmrit.decoderdefn.DecoderIndexFile.updateIndexIfNeeded();
161            } catch (org.jdom2.JDOMException| java.io.IOException e) {
162                log.error("Exception trying to pre-load decoderIndex", e);
163            }
164        });
165    }
166
167    private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LccPro.class);
168
169}