001package jmri.jmrit.ctc.editor.code;
002
003import static jmri.jmrit.ctc.editor.code.CreateXMLFiles.generateEpilogue;
004import static jmri.jmrit.ctc.editor.code.CreateXMLFiles.generateProlog;
005
006import java.awt.Font;
007import java.awt.font.FontRenderContext;
008import java.awt.geom.AffineTransform;
009import java.io.FileWriter;
010import java.io.IOException;
011import java.io.PrintWriter;
012import java.util.ArrayList;
013import java.util.TreeMap;
014import jmri.InstanceManager;
015import jmri.jmrit.ctc.CtcManager;
016import jmri.jmrit.ctc.ctcserialdata.CodeButtonHandlerData;
017import jmri.jmrit.ctc.ctcserialdata.OtherData;
018import jmri.jmrit.ctc.ctcserialdata.ProjectsCommonSubs;
019import jmri.jmrit.ctc.ctcserialdata.CTCSerialData;
020
021/**
022 * @author Gregory J. Bedlek Copyright (C) 2018, 2019
023 */
024public class CreateGUIObjectsXMLFile {
025    private static final int START_OFFSET = 12;
026    private static final int GIF_HORIZONTAL_SIZE = 65;
027
028    public static void writeGUIObjects() {
029
030        CTCSerialData ctcSerialData = InstanceManager.getDefault(CtcManager.class).getCTCSerialData();
031
032        TreeMap<Integer, Integer> cbhdMap = new TreeMap<>();
033        ctcSerialData.getCodeButtonHandlerDataArrayList().forEach(cbhd -> {
034            if (cbhd._mGUIColumnNumber > 0 && !cbhd._mGUIGeneratedAtLeastOnceAlready) {
035                cbhdMap.put(cbhd._mGUIColumnNumber, cbhd._mUniqueID);
036            }
037        });
038
039        PrintWriter printWriter;
040        try {
041            printWriter = new PrintWriter(new FileWriter(jmri.util.FileUtil.getUserFilesPath() + "ctc/GUIObjects.xml"));  // NOI18N
042        } catch (IOException e) {
043            log.debug("PrintWriter exception: {}", e.getMessage());
044            return;
045        }
046        generateProlog(printWriter);
047        printWriter.println("  <paneleditor class=\"jmri.jmrit.display.panelEditor.configurexml.PanelEditorXml\" name=\"Panel \" x=\"857\" y=\"437\" height=\"437\" width=\"527\" editable=\"yes\" positionable=\"no\" showtooltips=\"yes\" controlling=\"yes\" hide=\"yes\" panelmenu=\"yes\" scrollable=\"both\" redBackground=\"255\" greenBackground=\"255\" blueBackground=\"255\">"); // NOI18N
048
049//  Create "one of" objects:
050
051        OtherData otherData = ctcSerialData.getOtherData();
052        if (otherData._mGUIDesign_BuilderPlate) {
053            generateBuilderPlate(printWriter);
054        }
055
056        int oneOfItemsBottomEdge;
057        switch(otherData._mGUIDesign_VerticalSize) {
058            default:
059            case SMALL:
060                oneOfItemsBottomEdge = 718;
061                break;
062            case MEDIUM:
063                oneOfItemsBottomEdge = 850;
064                break;
065            case LARGE:
066                oneOfItemsBottomEdge = 900;
067                break;
068        }
069
070        if (otherData._mGUIDesign_AnalogClockEtc) {
071            printWriter.println("    <fastclock x=\"26\" y=\"" + (oneOfItemsBottomEdge - 186) + "\" scale=\"1.0\" color=\"black\" class=\"jmri.jmrit.display.configurexml.AnalogClock2DisplayXml\" />");    // NOI18N
072            generateToggle(96, oneOfItemsBottomEdge - 223, "ISCLOCKRUNNING", printWriter);  // NOI18N
073            generateTextPositionableLabel(87, oneOfItemsBottomEdge - 244, Bundle.getMessage("CreateGUIObjectsXMLFileClockOn"), printWriter);    // NOI18N
074        }
075        if (otherData._mGUIDesign_FleetingToggleSwitch) {
076            if (!ProjectsCommonSubs.isNullOrEmptyString(otherData._mFleetingToggleInternalSensor.getHandleName())) {
077                generateToggle(226, oneOfItemsBottomEdge - 36, otherData._mFleetingToggleInternalSensor.getHandleName(), printWriter);
078                generateTextPositionableLabel(215, oneOfItemsBottomEdge - 54, Bundle.getMessage("CreateGUIObjectsXMLFileFleetingOn"), printWriter); // NOI18N
079            }
080        }
081        if (otherData._mGUIDesign_ReloadCTCSystemButton) {
082            if (!ProjectsCommonSubs.isNullOrEmptyString(otherData._mCTCDebugSystemReloadInternalSensor.getHandleName())) {
083                generatePushButton(291, oneOfItemsBottomEdge - 36, otherData._mCTCDebugSystemReloadInternalSensor.getHandleName(), printWriter);
084                generateTextPositionableLabel(277, oneOfItemsBottomEdge - 54, Bundle.getMessage("CreateGUIObjectsXMLFileReloadCTC"), printWriter);  // NOI18N
085            }
086        }
087        if (otherData._mGUIDesign_CTCDebugOnToggle) {
088            if (!ProjectsCommonSubs.isNullOrEmptyString(otherData._mCTCDebug_TrafficLockingRuleTriggeredDisplayInternalSensor.getHandleName())) {
089                generateToggle(358, oneOfItemsBottomEdge - 36, otherData._mCTCDebug_TrafficLockingRuleTriggeredDisplayInternalSensor.getHandleName(), printWriter);
090                generateTextPositionableLabel(339, oneOfItemsBottomEdge - 54, Bundle.getMessage("CreateGUIObjectsXMLFileCTCDebugOn"), printWriter); // NOI18N
091            }
092        }
093
094//  Create all GUI objects:
095        if (!cbhdMap.isEmpty()) {
096            generatePanel(0, 0, otherData._mGUIDesign_VerticalSize, "Panel-left", printWriter); // NOI18N
097            int lastHorizontalPosition = START_OFFSET;        // Where we are now.
098            int thisObjectHorizontalPosition = START_OFFSET;
099            for (int cbhdID : cbhdMap.values()) {
100                CodeButtonHandlerData codeButtonHandlerData = ctcSerialData.getCodeButtonHandlerDataViaUniqueID(cbhdID);
101
102                boolean directionLeft = true;
103                boolean directionRight = true;
104                if (codeButtonHandlerData._mSIDI_TrafficDirection == CodeButtonHandlerData.TRAFFIC_DIRECTION.LEFT) directionRight = false;
105                if (codeButtonHandlerData._mSIDI_TrafficDirection == CodeButtonHandlerData.TRAFFIC_DIRECTION.RIGHT) directionLeft = false;
106
107                thisObjectHorizontalPosition = (codeButtonHandlerData._mGUIColumnNumber - 1) * GIF_HORIZONTAL_SIZE + START_OFFSET;
108//  Put in possible blank panels between where we left off last and the next one:
109                for ( ; lastHorizontalPosition < thisObjectHorizontalPosition; lastHorizontalPosition += GIF_HORIZONTAL_SIZE) {
110                    generatePanel(lastHorizontalPosition, 0, otherData._mGUIDesign_VerticalSize, "Panel-blank", printWriter);   // NOI18N
111                }
112                lastHorizontalPosition = thisObjectHorizontalPosition + GIF_HORIZONTAL_SIZE;
113
114//  Put appropriate type of panel in:
115                boolean generateSwitch = (codeButtonHandlerData._mSWDI_Enabled || codeButtonHandlerData._mSWDL_Enabled);
116                boolean generateSignal = (codeButtonHandlerData._mSIDI_Enabled || codeButtonHandlerData._mSIDL_Enabled);
117//  4 possibilities: Blank again, switch, signal, switch and signal:
118                String filename = "Panel-blank";  // Default if not next 3 below:
119                if (generateSwitch && generateSignal) filename = "Panel-sw-sig";    // NOI18N
120                else if (!generateSwitch && generateSignal) filename = "Panel-signal";  // NOI18N
121                else if (generateSwitch && !generateSignal) filename = "Panel-switch";  // NOI18N
122                generatePanel(thisObjectHorizontalPosition, 0, otherData._mGUIDesign_VerticalSize, filename, printWriter);
123//  CB:
124                if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mCodeButtonInternalSensor.getHandleName())) { // Always exists, but for safety:
125                    if (codeButtonHandlerData._mCodeButtonDelayTime == 0) { // Only if real one is supposed to be present:
126                        generatePushButton(thisObjectHorizontalPosition + 21, adjustCodeButtonYBySize(632, otherData._mGUIDesign_VerticalSize), codeButtonHandlerData._mCodeButtonInternalSensor.getHandleName(), printWriter);
127                    }
128                }
129//  O.S. occupancy sensor:
130                if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mOSSectionOccupiedExternalSensor.getHandleName())) {
131                    generateSensorIndicator(thisObjectHorizontalPosition + 21, 78, codeButtonHandlerData._mOSSectionOccupiedExternalSensor.getHandleName(), "Red", otherData._mGUIDesign_OSSectionUnknownInconsistentRedBlink, printWriter);    // NOI18N
132                }
133                if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mOSSectionOccupiedExternalSensor2.getHandleName())) {
134                    generateSensorIndicator(thisObjectHorizontalPosition + 21, 108, codeButtonHandlerData._mOSSectionOccupiedExternalSensor2.getHandleName(), "Red", otherData._mGUIDesign_OSSectionUnknownInconsistentRedBlink, printWriter);  // NOI18N
135                }
136//  SWDI:
137                if (codeButtonHandlerData._mSWDI_Enabled) { // Switch Indicators:
138                    int y = adjustSwitchItemsYBySize(340, otherData._mGUIDesign_VerticalSize);
139                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSWDI_NormalInternalSensor.getHandleName())) {
140                        generateSensorIndicator(thisObjectHorizontalPosition + 4, y, codeButtonHandlerData._mSWDI_NormalInternalSensor.getHandleName(), "green", false, printWriter);   // NOI18N
141                    }
142                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSWDI_ReversedInternalSensor.getHandleName())) {
143                        generateSensorIndicator(thisObjectHorizontalPosition + 38, y, codeButtonHandlerData._mSWDI_ReversedInternalSensor.getHandleName(), "amber", false, printWriter);    // NOI18N
144                    }
145                    if (otherData._mGUIDesign_TurnoutsOnPanel) {
146                        if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName())) {
147                            switch (codeButtonHandlerData._mSWDI_GUITurnoutType) {
148                                case TURNOUT:
149                                    generateTurnoutIcon(thisObjectHorizontalPosition + 9, 80, codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName(), codeButtonHandlerData._mSWDI_GUITurnoutLeftHand, printWriter);
150                                    break;
151                                case CROSSOVER:
152                                    if (codeButtonHandlerData._mSWDI_GUITurnoutLeftHand == codeButtonHandlerData._mSWDI_GUICrossoverLeftHand) {
153                                        generateTurnoutCrossoverIcon(thisObjectHorizontalPosition + 20, 40, codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName(), false, codeButtonHandlerData._mSWDI_GUICrossoverLeftHand, printWriter);
154                                    } else {
155                                        generateTurnoutIcon(thisObjectHorizontalPosition + 9, 80, codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName(), codeButtonHandlerData._mSWDI_GUITurnoutLeftHand, printWriter);
156                                        generateTurnoutIcon(thisObjectHorizontalPosition + 9, 135, codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName(), codeButtonHandlerData._mSWDI_GUICrossoverLeftHand, printWriter);
157                                    }
158                                    break;
159                                case DOUBLE_CROSSOVER:
160                                    generateTurnoutCrossoverIcon(thisObjectHorizontalPosition + 20, 80, codeButtonHandlerData._mSWDI_ExternalTurnout.getHandleName(), true, codeButtonHandlerData._mSWDI_GUICrossoverLeftHand, printWriter);
161                                    break;
162                                default:
163                                    break;
164                            }
165                        }
166                    }
167                }
168//  SWDL:
169                if (codeButtonHandlerData._mSWDL_Enabled) { // Switch Lever:
170                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSWDL_InternalSensor.getHandleName())) {
171                        generateTurnoutLever(thisObjectHorizontalPosition + 8, adjustSwitchItemsYBySize(379, otherData._mGUIDesign_VerticalSize), codeButtonHandlerData._mSWDL_InternalSensor.getHandleName(), printWriter);
172                        generateTextPositionableLabelCentered(thisObjectHorizontalPosition + 32, adjustSwitchItemsYBySize(356, otherData._mGUIDesign_VerticalSize), Integer.toString(codeButtonHandlerData._mSwitchNumber), printWriter);
173                    }
174                }
175//  SIDI:
176                if (codeButtonHandlerData._mSIDI_Enabled) { // Signal Indicators:
177                    int y = adjustSignalItemsYBySize(454, otherData._mGUIDesign_VerticalSize);
178                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSIDI_LeftInternalSensor.getHandleName())) {
179                        if (directionLeft) {
180                            generateSensorIndicator(
181                                    thisObjectHorizontalPosition + 4,
182                                    y,
183                                    codeButtonHandlerData._mSIDI_LeftInternalSensor.getHandleName(),
184                                    "green", // NOI18N
185                                    false,
186                                    printWriter);
187                        } else {
188                            generateKnockout(
189                                    thisObjectHorizontalPosition + 4,
190                                    y,
191                                    printWriter);
192                        }
193                    }
194                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSIDI_NormalInternalSensor.getHandleName())) { // Should always be present, but for safety:
195                        generateSensorIndicator(
196                                thisObjectHorizontalPosition + 22,
197                                adjustSignalItemsYBySize(440, otherData._mGUIDesign_VerticalSize),
198                                codeButtonHandlerData._mSIDI_NormalInternalSensor.getHandleName(),
199                                "red", // NOI18N
200                                false,
201                                printWriter);
202                    }
203                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSIDI_RightInternalSensor.getHandleName())) {
204                        if (directionRight) {
205                            generateSensorIndicator(
206                                    thisObjectHorizontalPosition + 38,
207                                    y,
208                                    codeButtonHandlerData._mSIDI_RightInternalSensor.getHandleName(),
209                                    "green", // NOI18N
210                                    false,
211                                    printWriter);
212                        } else {
213                            generateKnockout(
214                                    thisObjectHorizontalPosition + 38,
215                                    y,
216                                    printWriter);
217                        }
218                    }
219                    if (otherData._mGUIDesign_SignalsOnPanel == OtherData.SIGNALS_ON_PANEL.ALL) {
220                        ArrayList<String> signalsArrayListLR = ProjectsCommonSubs.getArrayListOfSignalNames(codeButtonHandlerData._mSIDI_LeftRightTrafficSignals);
221
222                        int x;
223                        x = thisObjectHorizontalPosition + 10;
224                        for (String signal : signalsArrayListLR) {
225                            switch(otherData._mSignalSystemType) {
226                                case SIGNALHEAD:
227                                    generateSignalHead(x, 120, signal, false, printWriter);
228                                    break;
229                                case SIGNALMAST:
230                                    generateSignalMast(x, 120, signal, false, printWriter);
231                                    break;
232                                default:
233                                    break;
234                            }
235                            x -= 11;
236                        }
237                        ArrayList<String> signalsArrayListRL = ProjectsCommonSubs.getArrayListOfSignalNames(codeButtonHandlerData._mSIDI_RightLeftTrafficSignals);
238                        x = thisObjectHorizontalPosition + 20;
239                        for (String signal : signalsArrayListRL) {
240                            switch(otherData._mSignalSystemType) {
241                                case SIGNALHEAD:
242                                    generateSignalHead(x, 70, signal, true, printWriter);
243                                    break;
244                                case SIGNALMAST:
245                                    generateSignalMast(x, 70, signal, true, printWriter);
246                                    break;
247                                default:
248                                    break;
249                            }
250                            x += 11;
251                        }
252// //  SpotBugs whines about "useless control flow", so I commented this out (not the comment on the next line):
253                    } /*else if (otherData._mGUIDesign_SignalsOnPanel == OtherData.SIGNALS_ON_PANEL.GREEN_OFF) {  // Future someday, as of 10/30/18 user CANNOT select this!
254                    }*/
255                }
256//  SIDL:
257                if (codeButtonHandlerData._mSIDL_Enabled) { // Signal Lever:
258                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mSIDL_NormalInternalSensor.getHandleName())) {
259                        generateSignalLever(
260                                thisObjectHorizontalPosition + 8,
261                                adjustSignalItemsYBySize(492, otherData._mGUIDesign_VerticalSize),
262                                directionLeft ? codeButtonHandlerData._mSIDL_LeftInternalSensor.getHandleName() : "",
263                                codeButtonHandlerData._mSIDL_NormalInternalSensor.getHandleName(),
264                                directionRight ? codeButtonHandlerData._mSIDL_RightInternalSensor.getHandleName() : "",
265                                printWriter);
266                        generateTextPositionableLabelCentered(thisObjectHorizontalPosition + 32, adjustSignalItemsYBySize(470, otherData._mGUIDesign_VerticalSize), Integer.toString(codeButtonHandlerData._mSignalEtcNumber), printWriter);
267                    }
268                }
269//  CO:
270                if (codeButtonHandlerData._mCO_Enabled) { // Call On:
271                    if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mCO_CallOnToggleInternalSensor.getHandleName())) {
272                        generateToggle(thisObjectHorizontalPosition + 21, adjustCallOnItemsYBySize(582, otherData._mGUIDesign_VerticalSize), codeButtonHandlerData._mCO_CallOnToggleInternalSensor.getHandleName(), printWriter);
273                        generateTextPositionableLabel(thisObjectHorizontalPosition + 48, adjustCallOnItemsYBySize(590, otherData._mGUIDesign_VerticalSize), Bundle.getMessage("CreateGUIObjectsXMLFileCallOn"), printWriter);   // NOI18N
274                    }
275                }
276//  TUL:
277                if (codeButtonHandlerData._mTUL_Enabled) { // Turnout Locking:
278                    if (codeButtonHandlerData._mTUL_GUI_IconsEnabled) {
279                        if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mTUL_DispatcherInternalSensorLockToggle.getHandleName())) {
280                            generateToggle(thisObjectHorizontalPosition + 21, adjustLockedItemsYBySize(541, otherData._mGUIDesign_VerticalSize), codeButtonHandlerData._mTUL_DispatcherInternalSensorLockToggle.getHandleName(), printWriter);
281                            generateTextPositionableLabel(thisObjectHorizontalPosition + 48, adjustLockedItemsYBySize(536, otherData._mGUIDesign_VerticalSize), Bundle.getMessage("CreateGUIObjectsXMLFileLocal"), printWriter);    // NOI18N
282                            generateTextPositionableLabel(thisObjectHorizontalPosition + 48, adjustLockedItemsYBySize(560, otherData._mGUIDesign_VerticalSize), Bundle.getMessage("CreateGUIObjectsXMLFileLocked"), printWriter);   // NOI18N
283                        }
284                        if (!ProjectsCommonSubs.isNullOrEmptyString(codeButtonHandlerData._mTUL_DispatcherInternalSensorUnlockedIndicator.getHandleName())) {
285                            generateSensorIndicator(thisObjectHorizontalPosition + 22, 200, codeButtonHandlerData._mTUL_DispatcherInternalSensorUnlockedIndicator.getHandleName(), "red", false, printWriter);  // NOI18N
286                            generateTextPositionableLabel(thisObjectHorizontalPosition + 9, 230, Bundle.getMessage("CreateGUIObjectsXMLFileUnlocked"), printWriter);    // NOI18N
287                        }
288                    }
289                }
290                thisObjectHorizontalPosition += GIF_HORIZONTAL_SIZE;   // In case this is the LAST object, and we fall out of the loop to the next line:
291            }
292
293            for (int i = 0; i < otherData._mGUIDesign_NumberOfEmptyColumnsAtEnd; i++) {
294                generatePanel(thisObjectHorizontalPosition, 0, otherData._mGUIDesign_VerticalSize, "Panel-blank", printWriter); // NOI18N
295                thisObjectHorizontalPosition += GIF_HORIZONTAL_SIZE;
296            }
297            generatePanel(thisObjectHorizontalPosition, 0, otherData._mGUIDesign_VerticalSize, "Panel-right", printWriter); // NOI18N
298        }
299
300        printWriter.println("  </paneleditor>");    // NOI18N
301        generateEpilogue(printWriter);
302        printWriter.close();
303    }
304
305/*
306    <positionablelabel x="55" y="323" level="3" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" icon="yes" class="jmri.jmrit.display.configurexml.PositionableLabelXml">
307      <tooltip>Icon</tooltip>
308      <icon url="program:resources/icons/USS/plate/base-plates/misc/USS-plate.gif" scale="1.0">
309        <rotation>0</rotation>
310      </icon>
311    </positionablelabel>
312
313*/
314    private static void generateBuilderPlate(PrintWriter printWriter) {
315        printWriter.println("    <positionablelabel x=\"55\" y=\"323\" level=\"3\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.PositionableLabelXml\">"); // NOI18N
316        printWriter.println("      <tooltip>Icon</tooltip>");   // NOI18N
317        printWriter.println("      <icon url=\"program:resources/icons/USS/plate/base-plates/misc/USS-plate.gif\" scale=\"1.0\">");   // NOI18N
318        printWriter.println("        <rotation>0</rotation>");  // NOI18N
319        printWriter.println("      </icon>");   // NOI18N
320        printWriter.println("    </positionablelabel>");    // NOI18N
321    }
322
323/*  As of 4.13.4ish:
324    <positionablelabel x="966" y="559" level="4" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" text="Lock" fontname="Dialog.plain" size="11" style="0" red="255" green="255" blue="255" hasBackground="no" justification="centre" class="jmri.jmrit.display.configurexml.PositionableLabelXml">
325      <tooltip>Text Label</tooltip>
326    </positionablelabel>
327*/
328    private static final String DIALOG_USED = "Dialog.plain";   // NOI18N
329    private static void generateTextPositionableLabel(int x, int y, String text, PrintWriter printWriter) {
330        printWriter.println("    <positionablelabel x=\"" + x + "\" y=\"" + y + "\" level=\"4\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" text=\"" + text + "\" fontname=\"" + DIALOG_USED + "\" size=\"11\" style=\"0\" red=\"255\" green=\"255\" blue=\"255\" hasBackground=\"no\" justification=\"centre\" class=\"jmri.jmrit.display.configurexml.PositionableLabelXml\">"); // NOI18N
331        printWriter.println("      <tooltip>Text Label</tooltip>");         // NOI18N
332        printWriter.println("    </positionablelabel>");        // NOI18N
333    }
334    private static void generateTextPositionableLabelCentered(int x, int y, String text, PrintWriter printWriter) {
335        generateTextPositionableLabel(centerText(x, text), y, text, printWriter);
336    }
337    private static int centerText(int originalValue, String text) {
338        AffineTransform affinetransform = new AffineTransform();
339        FontRenderContext frc = new FontRenderContext(affinetransform,true,true);
340        Font font = new Font(DIALOG_USED, Font.PLAIN, 11);     // Found Dialog.plain in the latest .xml files.  Probably the default
341        int textwidth = (int)(font.getStringBounds(text, frc).getWidth());
342        return originalValue - (textwidth / 2);
343    }
344
345/*  As of 4.13.4ish:
346    <positionablelabel x="0" y="0" level="3" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" icon="yes" class="jmri.jmrit.display.configurexml.PositionableLabelXml">
347      <tooltip>Icon</tooltip>
348      <icon url="program:resources/icons/USS/background/Panel-blank-9.gif" scale="1.0">
349        <rotation>0</rotation>
350      </icon>
351    </positionablelabel>
352*/
353    private static void generatePanel(int x, int y, OtherData.VERTICAL_SIZE verticalSize, String resourceFilename, PrintWriter printWriter) {
354//      I use other defaults here for both positionable and showtooltip = false:
355        switch(verticalSize) {
356            default:
357            case SMALL:
358                resourceFilename += "-7.gif";   // NOI18N
359                break;
360            case MEDIUM:
361                resourceFilename += "-8.gif";   // NOI18N
362                break;
363            case LARGE:
364                resourceFilename += "-9.gif";   // NOI18N
365                break;
366        }
367        printWriter.println("    <positionablelabel x=\"" + x + "\" y=\"" + y + "\" level=\"1\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"false\" showtooltip=\"false\" editable=\"true\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.PositionableLabelXml\">");  // NOI18N
368//      I don't use Tooltip, since it's false anyways...
369        printWriter.println("      <icon url=\"program:resources/icons/USS/background/" + resourceFilename + "\" scale=\"1.0\">");    // NOI18N
370        printWriter.println("        <rotation>0</rotation>");  // NOI18N
371        printWriter.println("      </icon>");   // NOI18N
372        printWriter.println("    </positionablelabel>");    // NOI18N
373    }
374
375/*  As of 4.13.4ish:
376    <sensoricon sensor="IS3:SWNI" x="0" y="0" level="10" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" momentary="false" icon="yes" class="jmri.jmrit.display.configurexml.SensorIconXml">
377      <tooltip>IS2:CB</tooltip>
378      <active url="program:resources/icons/USS/sensor/green-on.gif" scale="1.0">
379        <rotation>0</rotation>
380      </active>
381      <inactive url="program:resources/icons/USS/sensor/green-off.gif" scale="1.0">
382        <rotation>0</rotation>
383      </inactive>
384      <unknown url="program:resources/icons/USS/sensor/s-unknown.gif" scale="1.0">
385        <rotation>0</rotation>
386      </unknown>
387      <inconsistent url="program:resources/icons/USS/sensor/s-inconsistent.gif" scale="1.0">
388        <rotation>0</rotation>
389      </inconsistent>
390      <iconmaps />
391    </sensoricon>
392*/
393    private static void generateSensorIndicator(int x, int y, String sensor, String color, boolean unknownInconsistentRedBlink, PrintWriter printWriter) {
394        String unknown = unknownInconsistentRedBlink ? "blink/red-b" : "s-unknown"; // NOI18N
395        String inconsistent = unknownInconsistentRedBlink ? "blink/red-b" : "s-inconsistent";   // NOI18N
396        printWriter.println("    <sensoricon sensor=\"" + sensor + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"10\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" momentary=\"false\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.SensorIconXml\">");   // NOI18N
397        printWriter.println("      <tooltip>" + sensor + "</tooltip>"); // NOI18N
398        printWriter.println("      <active url=\"program:resources/icons/USS/sensor/" + color + "-on.gif\" scale=\"1.0\">");  // NOI18N
399        printWriter.println("        <rotation>0</rotation>");  // NOI18N
400        printWriter.println("      </active>"); // NOI18N
401        printWriter.println("      <inactive url=\"program:resources/icons/USS/sensor/" + color + "-off.gif\" scale=\"1.0\">");   // NOI18N
402        printWriter.println("        <rotation>0</rotation>");  // NOI18N
403        printWriter.println("      </inactive>");   // NOI18N
404        printWriter.println("      <unknown url=\"program:resources/icons/USS/sensor/" + unknown + ".gif\" scale=\"1.0\">");  // NOI18N
405        printWriter.println("        <rotation>0</rotation>");  // NOI18N
406        printWriter.println("      </unknown>");    // NOI18N
407        printWriter.println("      <inconsistent url=\"program:resources/icons/USS/sensor/" + inconsistent + ".gif\" scale=\"1.0\">");// NOI18N
408        printWriter.println("        <rotation>0</rotation>");  // NOI18N
409        printWriter.println("      </inconsistent>");   // NOI18N
410        printWriter.println("      <iconmaps />");  // NOI18N
411        printWriter.println("    </sensoricon>");   // NOI18N
412    }
413
414/*
415    <positionablelabel x="18" y="240" level="3" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" icon="yes" class="jmri.jmrit.display.configurexml.PositionableLabelXml">
416      <icon url="program:resources/icons/USSpanels/Panels/knockout.gif" degrees="0" scale="1.0">
417        <rotation>0</rotation>
418      </icon>
419    </positionablelabel>
420*/
421    private static void generateKnockout(int x, int y, PrintWriter printWriter) {
422        printWriter.println("    <positionablelabel x=\"" + x + "\" y=\"" + y + "\" level=\"3\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.PositionableLabelXml\">"); // NOI18N
423        printWriter.println("      <icon url=\"program:resources/icons/USSpanels/Panels/knockout.gif\" degrees=\"0\" scale=\"1.0\">");   // NOI18N
424        printWriter.println("        <rotation>0</rotation>");   // NOI18N
425        printWriter.println("      </icon>");   // NOI18N
426        printWriter.println("    </positionablelabel>");   // NOI18N
427    }
428
429/*  As of 4.13.4ish:
430Left:
431    <turnouticon turnout="LT47" x="486" y="40" level="7" forcecontroloff="true" hidden="no" positionable="true" showtooltip="false" editable="true" tristate="false" momentary="false" directControl="false" class="jmri.jmrit.display.configurexml.TurnoutIconXml">
432      <icons>
433        <closed url="program:resources/icons/USS/track/turnout/left/west/os-l-w-closed.gif" scale="1.0">
434          <rotation>0</rotation>
435        </closed>
436        <thrown url="program:resources/icons/USS/track/turnout/left/west/os-l-w-thrown.gif" scale="1.0">
437          <rotation>0</rotation>
438        </thrown>
439        <unknown url="program:resources/icons/USS/track/turnout/left/west/os-l-w-unknown.gif" scale="1.0">
440          <rotation>0</rotation>
441        </unknown>
442        <inconsistent url="program:resources/icons/USS/track/turnout/left/west/os-l-w-inconsistent.gif" scale="1.0">
443          <rotation>0</rotation>
444        </inconsistent>
445      </icons>
446      <iconmaps />
447    </turnouticon>
448Right:
449        <closed url="program:resources/icons/USS/track/turnout/right/east/os-r-e-closed.gif" scale="1.0">
450*/
451    private static void generateTurnoutIcon(int x, int y, String turnout, boolean isTurnoutLeftHanded, PrintWriter printWriter) {
452        String partialFilename = isTurnoutLeftHanded ? "left/west/os-l-w" : "right/east/os-r-e";    // NOI18N
453        printWriter.println("    <turnouticon turnout=\"" + turnout + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"7\" forcecontroloff=\"true\" hidden=\"no\" positionable=\"true\" showtooltip=\"false\" editable=\"true\" tristate=\"false\" momentary=\"false\" directControl=\"false\" class=\"jmri.jmrit.display.configurexml.TurnoutIconXml\">");  // NOI18N
454        printWriter.println("      <icons>");   // NOI18N
455        printWriter.println("        <closed url=\"program:resources/icons/USS/track/turnout/" + partialFilename + "-closed.gif\" scale=\"1.0\">");   // NOI18N
456        printWriter.println("          <rotation>0</rotation>");    // NOI18N
457        printWriter.println("        </closed>");   // NOI18N
458        printWriter.println("        <thrown url=\"program:resources/icons/USS/track/turnout/" + partialFilename + "-thrown.gif\" scale=\"1.0\">");   // NOI18N
459        printWriter.println("          <rotation>0</rotation>");    // NOI18N
460        printWriter.println("        </thrown>");   // NOI18N
461        printWriter.println("        <unknown url=\"program:resources/icons/USS/track/turnout/" + partialFilename + "-unknown.gif\" scale=\"1.0\">"); // NOI18N
462        printWriter.println("          <rotation>0</rotation>");    // NOI18N
463        printWriter.println("        </unknown>");  // NOI18N
464        printWriter.println("        <inconsistent url=\"program:resources/icons/USS/track/turnout/" + partialFilename + "-inconsistent.gif\" scale=\"1.0\">");   // NOI18N
465        printWriter.println("          <rotation>0</rotation>");    // NOI18N
466        printWriter.println("        </inconsistent>"); // NOI18N
467        printWriter.println("      </icons>");  // NOI18N
468        printWriter.println("      <iconmaps />");  // NOI18N
469        printWriter.println("    </turnouticon>");  // NOI18N
470    }
471
472/*  As of 4.13.4ish:
473    <turnouticon turnout="LT48" x="807" y="40" level="7" forcecontroloff="true" hidden="no" positionable="true" showtooltip="false" editable="true" tristate="false" momentary="false" directControl="false" class="jmri.jmrit.display.configurexml.TurnoutIconXml">
474      <icons>
475        <closed url="program:resources/icons/USS/track/crossover/left/os-l-sc-closed.gif" scale="1.0">
476          <rotation>0</rotation>
477        </closed>
478        <thrown url="program:resources/icons/USS/track/crossover/left/os-l-sc-thrown.gif" scale="1.0">
479          <rotation>0</rotation>
480        </thrown>
481        <unknown url="program:resources/icons/USS/track/crossover/left/os-l-sc-unknown.gif" scale="1.0">
482          <rotation>0</rotation>
483        </unknown>
484        <inconsistent url="program:resources/icons/USS/track/crossover/left/os-l-sc-inconsistent.gif" scale="1.0">
485          <rotation>0</rotation>
486        </inconsistent>
487      </icons>
488      <iconmaps />
489    </turnouticon>
490*/
491    private static void generateTurnoutCrossoverIcon(int x, int y, String turnout, boolean isDoubleCrossover, boolean isTurnoutLeftHanded, PrintWriter printWriter) {
492        String partialFilename;
493        if (isDoubleCrossover) { // No left or right
494            partialFilename = "double/os-dc";   // NOI18N
495        } else {
496            partialFilename = isTurnoutLeftHanded ? "left/os-l-sc" : "right/os-r-sc";   // NOI18N
497        }
498        printWriter.println("    <turnouticon turnout=\"" + turnout + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"7\" forcecontroloff=\"true\" hidden=\"no\" positionable=\"true\" showtooltip=\"false\" editable=\"true\" tristate=\"false\" momentary=\"false\" directControl=\"false\" class=\"jmri.jmrit.display.configurexml.TurnoutIconXml\">");  // NOI18N
499        printWriter.println("      <icons>");   // NOI18N
500        printWriter.println("        <closed url=\"program:resources/icons/USS/track/crossover/" + partialFilename + "-closed.gif\" scale=\"1.0\">"); // NOI18N
501        printWriter.println("          <rotation>0</rotation>");    // NOI18N
502        printWriter.println("        </closed>");   // NOI18N
503        printWriter.println("        <thrown url=\"program:resources/icons/USS/track/crossover/" + partialFilename + "-thrown.gif\" scale=\"1.0\">"); // NOI18N
504        printWriter.println("          <rotation>0</rotation>");    // NOI18N
505        printWriter.println("        </thrown>");   // NOI18N
506        printWriter.println("        <unknown url=\"program:resources/icons/USS/track/crossover/" + partialFilename + "-unknown.gif\" scale=\"1.0\">");   // NOI18N
507        printWriter.println("          <rotation>0</rotation>");    // NOI18N
508        printWriter.println("        </unknown>");  // NOI18N
509        printWriter.println("        <inconsistent url=\"program:resources/icons/USS/track/crossover/" + partialFilename + "-inconsistent.gif\" scale=\"1.0\">"); // NOI18N
510        printWriter.println("          <rotation>0</rotation>");    // NOI18N
511        printWriter.println("        </inconsistent>"); // NOI18N
512        printWriter.println("      </icons>");  // NOI18N
513        printWriter.println("      <iconmaps />");  // NOI18N
514        printWriter.println("    </turnouticon>");  // NOI18N
515    }
516
517/*
518    <signalheadicon signalhead="LH441" x="645" y="31" level="9" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" clickmode="3" litmode="false" class="jmri.jmrit.display.configurexml.SignalHeadIconXml">
519      <tooltip>LH441</tooltip>
520      <icons>
521        <held url="program:resources/icons/smallschematics/searchlights/left-held-short.gif" scale="1.0">
522          <rotation>0</rotation>
523        </held>
524        <dark url="program:resources/icons/smallschematics/searchlights/left-dark-short.gif" scale="1.0">
525          <rotation>0</rotation>
526        </dark>
527        <red url="program:resources/icons/smallschematics/searchlights/left-red-short.gif" scale="1.0">
528          <rotation>0</rotation>
529        </red>
530        <yellow url="program:resources/icons/smallschematics/searchlights/left-yellow-short.gif" scale="1.0">
531          <rotation>0</rotation>
532        </yellow>
533        <green url="program:resources/icons/smallschematics/searchlights/left-green-short.gif" scale="1.0">
534          <rotation>0</rotation>
535        </green>
536        <flashred url="program:resources/icons/smallschematics/searchlights/left-flashred-short.gif" scale="1.0">
537          <rotation>0</rotation>
538        </flashred>
539        <flashyellow url="program:resources/icons/smallschematics/searchlights/left-flashyellow-short.gif" scale="1.0">
540          <rotation>0</rotation>
541        </flashyellow>
542        <flashgreen url="program:resources/icons/smallschematics/searchlights/left-flashgreen-short.gif" scale="1.0">
543          <rotation>0</rotation>
544        </flashgreen>
545      </icons>
546      <iconmaps />
547    </signalheadicon>
548*/
549    private static void generateSignalHead(int x, int y, String signalHead, boolean isRightToLeft, PrintWriter printWriter) {
550        String direction = isRightToLeft ? "left" : "right";    // NOI18N
551        printWriter.println("    <signalheadicon signalhead=\"" + signalHead + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"9\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" clickmode=\"3\" litmode=\"false\" class=\"jmri.jmrit.display.configurexml.SignalHeadIconXml\">");   // NOI18N
552        printWriter.println("      <tooltip>" + signalHead + "</tooltip>"); // NOI18N
553        printWriter.println("      <icons>");   // NOI18N
554        generateSignalBlock(direction, "held", printWriter);    // NOI18N
555        generateSignalBlock(direction, "dark", printWriter);    // NOI18N
556        generateSignalBlock(direction, "red", printWriter); // NOI18N
557        generateSignalBlock(direction, "yellow", printWriter);  // NOI18N
558        generateSignalBlock(direction, "green", printWriter);   // NOI18N
559        generateSignalBlock(direction, "flashred", printWriter);    // NOI18N
560        generateSignalBlock(direction, "flashyellow", printWriter); // NOI18N
561        generateSignalBlock(direction, "flashgreen", printWriter);  // NOI18N
562        printWriter.println("      </icons>");  // NOI18N
563        printWriter.println("      <iconmaps />");  // NOI18N
564        printWriter.println("    </signalheadicon>");   // NOI18N
565    }
566    private static void generateSignalBlock(String direction, String color, PrintWriter printWriter) {
567        printWriter.println(generateSignalLineStart(direction, color));
568        printWriter.println("          <rotation>0</rotation>");    // NOI18N
569        printWriter.println(generateSignalLineEnd(color));
570    }
571    private static String generateSignalLineStart(String direction, String color) {
572        return "        <" + color + " url=\"program:resources/icons/smallschematics/searchlights/" + direction + "-" + color + "-short.gif\" scale=\"1.0\">";    // NOI18N
573    }
574    private static String generateSignalLineEnd(String color) {
575        return "        </" + color + ">";
576    }
577
578/*
579    <signalmasticon signalmast="SM-CS10ME" x="461" y="17" level="9" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" clickmode="0" litmode="false" scale="1.0" imageset="default" class="jmri.jmrit.display.configurexml.SignalMastIconXml">
580      <tooltip>SM-CS10ME (LF$dsm:SW-1968:SL-2(722))</tooltip>
581    </signalmasticon>
582*/
583    private static void generateSignalMast(int x, int y, String signalMast, boolean isRightToLeft, PrintWriter printWriter) {
584        String degrees = isRightToLeft ? "180" : "0";   // NOI18N
585        printWriter.println("    <signalmasticon signalmast=\"" + signalMast + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"9\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" clickmode=\"0\" litmode=\"false\" degrees=\"" + degrees + "\" scale=\"1.0\" imageset=\"default\" class=\"jmri.jmrit.display.configurexml.SignalMastIconXml\">");    // NOI18N
586        printWriter.println("      <tooltip>" + signalMast + "</tooltip>"); // NOI18N
587        printWriter.println("    </signalmasticon>");   // NOI18N
588    }
589
590/*  As of 4.13.4ish:
591    <sensoricon sensor="IS27:LEVER" x="1826" y="310" level="10" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" momentary="false" icon="yes" class="jmri.jmrit.display.configurexml.SensorIconXml">
592      <tooltip>IS27:LEVER</tooltip>
593      <active url="program:resources/icons/USS/plate/levers/l-left.gif" scale="1.0">
594        <rotation>0</rotation>
595      </active>
596      <inactive url="program:resources/icons/USS/plate/levers/l-right.gif" scale="1.0">
597        <rotation>0</rotation>
598      </inactive>
599      <unknown url="program:resources/icons/USS/plate/levers/l-unknown.gif" scale="1.0">
600        <rotation>0</rotation>
601      </unknown>
602      <inconsistent url="program:resources/icons/USS/plate/levers/l-inconsistent.gif" scale="1.0">
603        <rotation>0</rotation>
604      </inconsistent>
605      <iconmaps />
606    </sensoricon>
607*/
608    public static void generateTurnoutLever(int x, int y, String lever, PrintWriter printWriter) {
609        printWriter.println("    <sensoricon sensor=\"" + lever + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"10\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" momentary=\"false\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.SensorIconXml\">");    // NOI18N
610        printWriter.println("      <tooltip>" + lever + "</tooltip>");  // NOI18N
611        printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/lever-left-wide.gif\" scale=\"1.0\">"); // NOI18N
612        printWriter.println("        <rotation>0</rotation>");  // NOI18N
613        printWriter.println("      </active>"); // NOI18N
614        printWriter.println("      <inactive url=\"program:resources/icons/USS/plate/levers/lever-right-wide.gif\" scale=\"1.0\">");  // NOI18N
615        printWriter.println("        <rotation>0</rotation>");  // NOI18N
616        printWriter.println("      </inactive>");   // NOI18N
617        printWriter.println("      <unknown url=\"program:resources/icons/USS/plate/levers/lever-unknown-wide.gif\" scale=\"1.0\">"); // NOI18N
618        printWriter.println("        <rotation>0</rotation>");  // NOI18N
619        printWriter.println("      </unknown>");    // NOI18N
620        printWriter.println("      <inconsistent url=\"program:resources/icons/USS/plate/levers/lever-inconsistent-wide.gif\" scale=\"1.0\">");   // NOI18N
621        printWriter.println("        <rotation>0</rotation>");  // NOI18N
622        printWriter.println("      </inconsistent>");   // NOI18N
623        printWriter.println("      <iconmaps />");  // NOI18N
624        printWriter.println("    </sensoricon>");   // NOI18N
625    }
626
627/*  As of 4.13.4ish:
628    <multisensoricon x="1826" y="423" level="10" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" updown="false" class="jmri.jmrit.display.configurexml.MultiSensorIconXml">
629      <tooltip>IS28:LDGL,IS28:NGL,IS28:RDGL</tooltip>
630      <active url="program:resources/icons/USS/plate/levers/l-left.gif" scale="1.0" sensor="IS28:LDGL">
631        <rotation>0</rotation>
632      </active>
633      <active url="program:resources/icons/USS/plate/levers/l-vertical.gif" scale="1.0" sensor="IS28:NGL">
634        <rotation>0</rotation>
635      </active>
636      <active url="program:resources/icons/USS/plate/levers/l-right.gif" scale="1.0" sensor="IS28:RDGL">
637        <rotation>0</rotation>
638      </active>
639      <inactive url="program:resources/icons/USS/plate/levers/l-inactive.gif" scale="1.0">
640        <rotation>0</rotation>
641      </inactive>
642      <unknown url="program:resources/icons/USS/plate/levers/l-unknown.gif" scale="1.0">
643        <rotation>0</rotation>
644      </unknown>
645      <inconsistent url="program:resources/icons/USS/plate/levers/l-inconsistent.gif" scale="1.0">
646        <rotation>0</rotation>
647      </inconsistent>
648    </multisensoricon>
649*/
650    public static void generateSignalLever(int x, int y, String left, String vertical, String right, PrintWriter printWriter ) {
651        printWriter.println("    <multisensoricon x=\"" + x + "\" y=\"" + y + "\" level=\"10\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" updown=\"false\" class=\"jmri.jmrit.display.configurexml.MultiSensorIconXml\">");   // NOI18N
652        printWriter.println("      <tooltip>" + left + "," + vertical + "," + right + "</tooltip>");// NOI18N
653        if (!left.trim().isEmpty()) {
654            printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/lever-left-wide.gif\" scale=\"1.0\" sensor=\"" + left + "\">");// NOI18N
655            printWriter.println("        <rotation>0</rotation>");  // NOI18N
656            printWriter.println("      </active>"); // NOI18N
657        }
658        printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/lever-vertical-wide.gif\" scale=\"1.0\" sensor=\"" + vertical + "\">"); // NOI18N
659        printWriter.println("        <rotation>0</rotation>");  // NOI18N
660        printWriter.println("      </active>"); // NOI18N
661        if (!right.trim().isEmpty()) {
662            printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/lever-right-wide.gif\" scale=\"1.0\" sensor=\"" + right + "\">");// NOI18N
663            printWriter.println("        <rotation>0</rotation>");// NOI18N
664            printWriter.println("      </active>");// NOI18N
665        }
666        printWriter.println("      <inactive url=\"program:resources/icons/USS/plate/levers/lever-inactive-wide.gif\" scale=\"1.0\">");   // NOI18N
667        printWriter.println("        <rotation>0</rotation>");// NOI18N
668        printWriter.println("      </inactive>");// NOI18N
669        printWriter.println("      <unknown url=\"program:resources/icons/USS/plate/levers/lever-unknown-wide.gif\" scale=\"1.0\">"); // NOI18N
670        printWriter.println("        <rotation>0</rotation>");  // NOI18N
671        printWriter.println("      </unknown>");    // NOI18N
672        printWriter.println("      <inconsistent url=\"program:resources/icons/USS/plate/levers/lever-inconsistent-wide.gif\" scale=\"1.0\">");   // NOI18N
673        printWriter.println("        <rotation>0</rotation>");// NOI18N
674        printWriter.println("      </inconsistent>");// NOI18N
675        printWriter.println("    </multisensoricon>");// NOI18N
676    }
677
678/*  As of 4.13.4ish:
679    <sensoricon sensor="IS58:LOCKTOGGLE" x="3063" y="551" level="10" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" momentary="false" icon="yes" class="jmri.jmrit.display.configurexml.SensorIconXml">
680      <tooltip>IS:SAV_PDC_LOCKLEVER</tooltip>
681      <active url="program:resources/icons/USS/plate/levers/switch-on.gif" scale="1.0">
682        <rotation>0</rotation>
683      </active>
684      <inactive url="program:resources/icons/USS/plate/levers/switch-off.gif" scale="1.0">
685        <rotation>0</rotation>
686      </inactive>
687      <unknown url="program:resources/icons/USS/plate/levers/switch-unknown.gif" scale="1.0">
688        <rotation>0</rotation>
689      </unknown>
690      <inconsistent url="program:resources/icons/USS/plate/levers/switch-inconsistent.gif" scale="1.0">
691        <rotation>0</rotation>
692      </inconsistent>
693      <iconmaps />
694    </sensoricon>
695*/
696    public static void generateToggle(int x, int y, String sensor, PrintWriter printWriter) {
697        printWriter.println("    <sensoricon sensor=\"" + sensor + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"10\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" momentary=\"false\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.SensorIconXml\">");   // NOI18N
698        printWriter.println("      <tooltip>" + sensor + "</tooltip>");// NOI18N
699        printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/switch-on.gif\" scale=\"1.0\">");// NOI18N
700        printWriter.println("        <rotation>0</rotation>");// NOI18N
701        printWriter.println("      </active>");// NOI18N
702        printWriter.println("      <inactive url=\"program:resources/icons/USS/plate/levers/switch-off.gif\" scale=\"1.0\">");// NOI18N
703        printWriter.println("        <rotation>0</rotation>");// NOI18N
704        printWriter.println("      </inactive>");// NOI18N
705        printWriter.println("      <unknown url=\"program:resources/icons/USS/plate/levers/switch-unknown.gif\" scale=\"1.0\">");// NOI18N
706        printWriter.println("        <rotation>0</rotation>");// NOI18N
707        printWriter.println("      </unknown>");// NOI18N
708        printWriter.println("      <inconsistent url=\"program:resources/icons/USS/plate/levers/switch-inconsistent.gif\" scale=\"1.0\">");// NOI18N
709        printWriter.println("        <rotation>0</rotation>");// NOI18N
710        printWriter.println("      </inconsistent>");// NOI18N
711        printWriter.println("      <iconmaps />");// NOI18N
712        printWriter.println("    </sensoricon>");// NOI18N
713    }
714
715/*  As of 4.13.4ish:
716    <sensoricon sensor="IS80:CB" x="3388" y="632" level="10" forcecontroloff="false" hidden="no" positionable="true" showtooltip="true" editable="true" momentary="true" icon="yes" class="jmri.jmrit.display.configurexml.SensorIconXml">
717      <tooltip>IS80:CB</tooltip>
718      <active url="program:resources/icons/USS/plate/levers/code-press.gif" scale="1.0">
719        <rotation>0</rotation>
720      </active>
721      <inactive url="program:resources/icons/USS/plate/levers/code.gif" scale="1.0">
722        <rotation>0</rotation>
723      </inactive>
724      <unknown url="program:resources/icons/USS/plate/levers/code-unknown.gif" scale="1.0">
725        <rotation>0</rotation>
726      </unknown>
727      <inconsistent url="program:resources/icons/USS/plate/levers/code-inconsistent.gif" scale="1.0">
728        <rotation>0</rotation>
729      </inconsistent>
730      <iconmaps />
731    </sensoricon>
732*/
733    public static void generatePushButton(int x, int y, String sensor, PrintWriter printWriter) {
734        printWriter.println("    <sensoricon sensor=\"" + sensor + "\" x=\"" + x + "\" y=\"" + y + "\" level=\"10\" forcecontroloff=\"false\" hidden=\"no\" positionable=\"true\" showtooltip=\"true\" editable=\"true\" momentary=\"true\" icon=\"yes\" class=\"jmri.jmrit.display.configurexml.SensorIconXml\">");// NOI18N
735        printWriter.println("      <tooltip>" + sensor + "</tooltip>");// NOI18N
736        printWriter.println("      <active url=\"program:resources/icons/USS/plate/levers/code-press.gif\" scale=\"1.0\">");// NOI18N
737        printWriter.println("        <rotation>0</rotation>");// NOI18N
738        printWriter.println("      </active>");// NOI18N
739        printWriter.println("      <inactive url=\"program:resources/icons/USS/plate/levers/code.gif\" scale=\"1.0\">");// NOI18N
740        printWriter.println("        <rotation>0</rotation>");// NOI18N
741        printWriter.println("      </inactive>");// NOI18N
742        printWriter.println("      <unknown url=\"program:resources/icons/USS/plate/levers/code-unknown.gif\" scale=\"1.0\">");// NOI18N
743        printWriter.println("        <rotation>0</rotation>");// NOI18N
744        printWriter.println("      </unknown>");// NOI18N
745        printWriter.println("      <inconsistent url=\"program:resources/icons/USS/plate/levers/code-inconsistent.gif\" scale=\"1.0\">");// NOI18N
746        printWriter.println("        <rotation>0</rotation>");// NOI18N
747        printWriter.println("      </inconsistent>");// NOI18N
748        printWriter.println("      <iconmaps />");// NOI18N
749        printWriter.println("    </sensoricon>");// NOI18N
750    }
751
752    private static int adjustSwitchItemsYBySize(int y, OtherData.VERTICAL_SIZE verticalSize) {
753        switch(verticalSize) {
754            default:
755            case SMALL:
756                return y;
757            case MEDIUM:
758                return y + 6;
759            case LARGE:
760                return y + 18;
761        }
762    }
763
764    private static int adjustSignalItemsYBySize(int y, OtherData.VERTICAL_SIZE verticalSize) {
765        switch(verticalSize) {
766            default:
767            case SMALL:
768                return y;
769            case MEDIUM:
770                return y + 12;
771            case LARGE:
772                return y + 33;
773        }
774    }
775
776    private static int adjustLockedItemsYBySize(int y, OtherData.VERTICAL_SIZE verticalSize) {
777        switch(verticalSize) {
778            default:
779            case SMALL:
780                return y;
781            case MEDIUM:
782                return y + 38;
783            case LARGE:
784                return y + 82;
785        }
786    }
787
788    private static int adjustCallOnItemsYBySize(int y, OtherData.VERTICAL_SIZE verticalSize) {
789        switch(verticalSize) {
790            default:
791            case SMALL:
792                return y;
793            case MEDIUM:
794                return y + 85;
795            case LARGE:
796                return y + 134;
797        }
798    }
799
800    private static int adjustCodeButtonYBySize(int y, OtherData.VERTICAL_SIZE verticalSize) {
801        switch(verticalSize) {
802            default:
803            case SMALL:
804                return y;
805            case MEDIUM:
806                return y + 120;
807            case LARGE:
808                return y + 180;
809        }
810    }
811
812    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CreateGUIObjectsXMLFile.class);
813}