001package jmri.jmrit.logixng;
002
003import java.io.PrintWriter;
004import java.util.Locale;
005import java.util.Map;
006
007import jmri.Manager;
008import jmri.jmrit.logixng.Base.PrintTreeSettings;
009
010import org.apache.commons.lang3.mutable.MutableInt;
011
012/**
013 * Manager for LogixNG
014 *
015 * @author Dave Duchamp       Copyright (C) 2007
016 * @author Daniel Bergqvist   Copyright (C) 2018
017 */
018public interface LogixNG_Manager extends Manager<LogixNG> {
019
020    /**
021     * Create a new LogixNG if the LogixNG does not exist.
022     *
023     * @param systemName the system name
024     * @param userName   the user name
025     * @return a new LogixNG or null if unable to create
026     */
027    LogixNG createLogixNG(String systemName, String userName)
028            throws IllegalArgumentException;
029
030    /**
031     * Create a new LogixNG if the LogixNG does not exist.
032     *
033     * @param systemName the system name
034     * @param userName   the user name
035     * @param inline     true if this LogixNG is an inline LogixNG
036     * @return a new LogixNG or null if unable to create
037     */
038    LogixNG createLogixNG(String systemName, String userName, boolean inline)
039            throws IllegalArgumentException;
040
041    /**
042     * For use with User GUI, to allow the auto generation of systemNames, where
043     * the user can optionally supply a username.
044     *
045     * @param userName the user name
046     * @return a new LogixNG or null if unable to create
047     */
048    LogixNG createLogixNG(String userName)
049            throws IllegalArgumentException;
050
051    /**
052     * For use with User GUI, to allow the auto generation of systemNames, where
053     * the user can optionally supply a username.
054     *
055     * @param userName  the user name
056     * @param inline    true if this LogixNG is an inline LogixNG
057     * @return a new LogixNG or null if unable to create
058     */
059    LogixNG createLogixNG(String userName, boolean inline)
060            throws IllegalArgumentException;
061
062    /**
063     * Locate via user name, then system name if needed. Does not create a new
064     * one if nothing found
065     *
066     * @param name User name or system name to match
067     * @return null if no match found
068     */
069    LogixNG getLogixNG(String name);
070
071    /** {@inheritDoc} */
072    @Override
073    LogixNG getByUserName(String name);
074
075    /** {@inheritDoc} */
076    @Override
077    LogixNG getBySystemName(String name);
078
079    /**
080     * Create a new system name for a LogixNG.
081     * @return a new system name
082     */
083    String getAutoSystemName();
084
085    /**
086     * Should the LogixNGs be disabled when the configuration file is loaded?
087     * @param value true if they should be disabled, false otherwise.
088     */
089    void setLoadDisabled(boolean value);
090
091    /**
092     * Should the LogixNGs be started when the configuration file is loaded?
093     * @param value true if they should be started, false otherwise.
094     */
095    void startLogixNGsOnLoad(boolean value);
096
097    /**
098     * Should the LogixNGs not be started when the configuration file is loaded?
099     * @return true if they should be started, false otherwise.
100     */
101    boolean isStartLogixNGsOnLoad();
102
103    /**
104     * Setup all LogixNGs. This method is called after a configuration file is
105     * loaded.
106     */
107    void setupAllLogixNGs();
108
109    /**
110     * Activate all LogixNGs, starts LogixNG processing by connecting all
111     * inputs that are included the ConditionalNGs in this LogixNG.
112     * <p>
113     * A LogixNG must be activated before it will calculate any of its
114     * ConditionalNGs.
115     */
116    void activateAllLogixNGs();
117
118    /**
119     * Activate all LogixNGs, starts LogixNG processing by connecting all
120     * inputs that are included the ConditionalNGs in this LogixNG.
121     * <p>
122     * A LogixNG must be activated before it will calculate any of its
123     * ConditionalNGs.
124     *
125     * @param runDelayed true if execute() should run on LogixNG thread delayed,
126     *                   false otherwise.
127     * @param runOnSeparateThread true if the activation should run on a
128     *                            separate thread, false otherwise
129     */
130    void activateAllLogixNGs(boolean runDelayed, boolean runOnSeparateThread);
131
132    /**
133     * DeActivate all LogixNGs, stops LogixNG processing by disconnecting all
134     * inputs that are included the ConditionalNGs in this LogixNG.
135     * <p>
136     * A LogixNG must be activated before it will calculate any of its
137     * ConditionalNGs.
138     */
139    void deActivateAllLogixNGs();
140
141    /**
142     * Is LogixNGs active?
143     * @return true if LogixNGs are active, false otherwise
144     */
145    boolean isActive();
146
147    /**
148     * Delete LogixNG by removing it from the manager. The LogixNG must first
149     * be deactivated so it stops processing.
150     *
151     * @param x the LogixNG to delete
152     */
153    void deleteLogixNG(LogixNG x);
154
155    /**
156     * Print the tree to a stream.
157     *
158     * @param writer the stream to print the tree to
159     * @param indent the indentation of each level
160     * @param lineNumber the line number
161     */
162    default void printTree(
163            PrintWriter writer,
164            String indent,
165            MutableInt lineNumber) {
166
167        printTree(new PrintTreeSettings(), writer, indent, lineNumber);
168    }
169
170    /**
171     * Print the tree to a stream.
172     *
173     * @param settings settings for what to print
174     * @param writer the stream to print the tree to
175     * @param indent the indentation of each level
176     * @param lineNumber the line number
177     */
178    void printTree(
179            PrintTreeSettings settings,
180            PrintWriter writer,
181            String indent,
182            MutableInt lineNumber);
183
184    /**
185     * Print the tree to a stream.
186     *
187     * @param locale The locale to be used
188     * @param writer the stream to print the tree to
189     * @param indent the indentation of each level
190     * @param lineNumber the line number
191     */
192    default void printTree(
193            Locale locale,
194            PrintWriter writer,
195            String indent,
196            MutableInt lineNumber) {
197
198        printTree(new PrintTreeSettings(), locale, writer, indent, lineNumber);
199    }
200
201    /**
202     * Print the tree to a stream.
203     *
204     * @param settings settings for what to print
205     * @param locale The locale to be used
206     * @param writer the stream to print the tree to
207     * @param indent the indentation of each level
208     * @param lineNumber the line number
209     */
210    void printTree(
211            PrintTreeSettings settings,
212            Locale locale,
213            PrintWriter writer,
214            String indent,
215            MutableInt lineNumber);
216
217    /**
218     * Test if parameter is a properly formatted system name.
219     * <P>
220     * This method should only be used by the managers of the LogixNG system.
221     *
222     * @param subSystemNamePrefix the sub system prefix
223     * @param systemName the system name
224     * @return enum indicating current validity, which might be just as a prefix
225     */
226    static NameValidity validSystemNameFormat(String subSystemNamePrefix, String systemName) {
227        // System names with digits. :AUTO: is generated system names
228        if (systemName.matches(subSystemNamePrefix+"(:AUTO:)?\\d+")) {
229            return NameValidity.VALID;
230
231        // System names with dollar sign allow any characters in the name
232        } else if (systemName.matches(subSystemNamePrefix+"\\$.+")) {
233            return NameValidity.VALID;
234
235        // System names with :JMRI: belongs to JMRI itself
236        } else if (systemName.matches(subSystemNamePrefix+":JMRI:.+")) {
237            return NameValidity.VALID;
238
239        // System names with :JMRI-LIB: belongs to software that uses JMRI as a lib
240        } else if (systemName.matches(subSystemNamePrefix+":JMRI-LIB:.+")) {
241            return NameValidity.VALID;
242
243        // Other system names are not valid
244        } else {
245//            LoggerFactory.getLogger(LogixNG_Manager.class)
246//                    .warn("system name {} is invalid for sub system prefix {}",
247//                            systemName, subSystemNamePrefix);
248            return NameValidity.INVALID;
249        }
250    }
251
252    /**
253     * Get the clipboard
254     * @return the clipboard
255     */
256    Clipboard getClipboard();
257
258    /**
259     * Register a manager for later retrieval by getManager()
260     * @param manager the manager
261     */
262    void registerManager(Manager<? extends MaleSocket> manager);
263
264    /**
265     * Get manager by class name
266     * @param className the class name of the manager
267     * @return the manager
268     */
269    Manager<? extends MaleSocket> getManager(String className);
270
271    /**
272     * Register a task to be run when setup LogixNGs
273     * @param task the task
274     */
275    void registerSetupTask(Runnable task);
276
277    /**
278     * Executes a LogixNG Module.
279     * Note that the module must be a Digital Action Module.
280     * @param module     The module to be executed
281     * @param parameter  The parameter. The module must have exactly one parameter.
282     * @throws IllegalArgumentException If module is null or if module is not a
283     *                   DigitalActionModule.
284     */
285    void executeModule(Module module, Object parameter)
286            throws IllegalArgumentException;
287
288    /**
289     * Executes a LogixNG Module.
290     * Note that the module must be a Digital Action Module.
291     * @param module      The module to be executed
292     * @param parameters  The parameters
293     * @throws IllegalArgumentException If module or parameters is null or if module
294     *                    is not a DigitalActionModule.
295     */
296    void executeModule(Module module, Map<String, Object> parameters)
297            throws IllegalArgumentException;
298
299}