001package jmri.jmrit.ctc.ctcserialdata; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.HashSet; 006 007import jmri.Turnout; 008 009/** 010 * 011 * @author Gregory J. Bedlek Copyright (C) 2018, 2019 012 */ 013public class CTCSerialData { 014 015 private OtherData _mOtherData; 016 private ArrayList<CodeButtonHandlerData> _mCodeButtonHandlerDataArrayList; 017 018 /** 019 * "Return" value from function "getCTCTurnoutData": 020 */ 021 public static class CTCTurnoutData { 022 public final String _mOSSectionText; 023 public final int _mUniqueID; 024 public CTCTurnoutData(String OSSectionText, int uniqueID) { 025 _mOSSectionText = OSSectionText; 026 _mUniqueID = uniqueID; 027 } 028 } 029 030 public CTCSerialData() { 031 _mOtherData = new OtherData(); 032 _mCodeButtonHandlerDataArrayList = new ArrayList<>(); 033 } 034 035 public OtherData getOtherData() { 036 return _mOtherData; 037 } 038 039 public int getUniqueNumber() { 040 return _mOtherData.getNextUniqueNumber(); 041 } 042 043 public CodeButtonHandlerData getCodeButtonHandlerDataViaUniqueID(int uniqueID) { 044 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 045 if (codeButtonHandlerData._mUniqueID == uniqueID) { 046 return codeButtonHandlerData; 047 } 048 } 049 return null; // In case it's not found. 050 } 051 052 public String getMyShortStringNoCommaViaUniqueID(int uniqueID) { 053 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 054 if (codeButtonHandlerData._mUniqueID == uniqueID) { 055 return codeButtonHandlerData.myShortStringNoComma(); 056 } 057 } 058 return "UNKNOWN"; // In case it's not found. 059 } 060 061 public int getIndexOfUniqueID(int uniqueID) { 062 for (int index = 0; index < _mCodeButtonHandlerDataArrayList.size(); index++) { 063 if (_mCodeButtonHandlerDataArrayList.get(index)._mUniqueID == uniqueID) { 064 return index; // That's it. 065 } 066 } 067 return -1; // not found. 068 } 069 070 public void setOtherData(OtherData otherData) { 071 _mOtherData = otherData; 072 } 073 074 public ArrayList<CodeButtonHandlerData> getCodeButtonHandlerDataArrayList() { 075 return _mCodeButtonHandlerDataArrayList; 076 } 077 078 public void addCodeButtonHandlerData(CodeButtonHandlerData codeButtonHandlerData) { 079 _mCodeButtonHandlerDataArrayList.add(codeButtonHandlerData); 080 } 081 082 public void removeCodeButtonHandlerData(int index) { 083 _mCodeButtonHandlerDataArrayList.remove(index); 084 } 085 086 public CodeButtonHandlerData getCodeButtonHandlerData(int index) { 087 return _mCodeButtonHandlerDataArrayList.get(index); 088 } 089 090 public int getCodeButtonHandlerDataSize() { 091 return _mCodeButtonHandlerDataArrayList.size(); 092 } 093 094 public void moveUp(int index) { 095 try { 096 Collections.swap(_mCodeButtonHandlerDataArrayList, index, index - 1); 097 } catch (IndexOutOfBoundsException e) { 098 } // Do NOTHING in this case! Technically should never happen, since buttons aren't enabled for such possibilities 099 } 100 101 public void moveDown(int index) { 102 try { 103 Collections.swap(_mCodeButtonHandlerDataArrayList, index, index + 1); 104 } catch (IndexOutOfBoundsException e) { 105 } // Do NOTHING in this case! Technically should never happen, since buttons aren't enabled for such possibilities 106 } 107 108 /** 109 * Change the identifying attributes with the exception of the uniqueID. The potential 110 * primary changes are the switch and signal numbers. 111 * @param index The row being changed. 112 * @param newSwitchNumber The new switch number which is always odd. 113 * @param newSignalEtcNumber The new signal number which is always one more than the switch number. 114 * @param newGUIColumnNumber The location on the panel. Used by the GUI export process. 115 * @param newGUIGeneratedAtLeastOnceAlready A flag to indicate whether the GUI export should include this column. 116 */ 117 public void updateSwitchAndSignalEtcNumbersEverywhere(int index, int newSwitchNumber, int newSignalEtcNumber, int newGUIColumnNumber, boolean newGUIGeneratedAtLeastOnceAlready) { 118 CodeButtonHandlerData codeButtonHandlerData = _mCodeButtonHandlerDataArrayList.get(index); 119 codeButtonHandlerData._mSwitchNumber = newSwitchNumber; 120 codeButtonHandlerData._mSignalEtcNumber = newSignalEtcNumber; 121 codeButtonHandlerData._mGUIColumnNumber = newGUIColumnNumber; 122 codeButtonHandlerData._mGUIGeneratedAtLeastOnceAlready = newGUIGeneratedAtLeastOnceAlready; 123 int UniqueIDBeingModified = codeButtonHandlerData._mUniqueID; 124 String replacementString = codeButtonHandlerData.myShortStringNoComma(); 125 for (CodeButtonHandlerData temp : _mCodeButtonHandlerDataArrayList) { 126 updateTrlUserText(temp._mTRL_LeftTrafficLockingRules, UniqueIDBeingModified, replacementString); 127 updateTrlUserText(temp._mTRL_RightTrafficLockingRules, UniqueIDBeingModified, replacementString); 128 } 129 } 130 131 /** 132 * Update the text description of entries in the traffic locking rules located in TrafficLockingData. 133 * Each alignment entry in each rule is checked for match on uniqueID. If so, the text is replaced. 134 * @param rulesToFix An array of TrafficLockingData entries. Each entry is a rule. 135 * @param uniqueIDBeingModified The uniqueID being checked. 136 * @param replacementString The new sw/sig string. 137 */ 138 private void updateTrlUserText(ArrayList<TrafficLockingData> rulesToFix, int uniqueIDBeingModified, String replacementString) { 139 rulesToFix.forEach(rule -> { 140 rule._mSwitchAlignments.forEach(alignment -> { 141 if (uniqueIDBeingModified == alignment._mUniqueID) { 142 alignment._mUserText = replacementString; 143 } 144 }); 145 }); 146 } 147 148 public void setCodeButtonHandlerData(int index, CodeButtonHandlerData codeButtonHandlerData) { 149 _mCodeButtonHandlerDataArrayList.set(index, codeButtonHandlerData); 150 } 151 152// If none are found, return -1 (which we'll then increment by 2 to 1, which is a good "add" default starting point): 153 public int findHighestSwitchNumberUsedSoFar() { 154 int highestSwitchNumber = -1; 155 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 156 if (codeButtonHandlerData._mSwitchNumber > highestSwitchNumber) { 157 highestSwitchNumber = codeButtonHandlerData._mSwitchNumber; 158 } 159 } 160 return highestSwitchNumber; 161 } 162 163// If none are found, return 0 (which we'll then increment by 1 to 1, which is a good "add" default starting point): 164 public int findHighestColumnNumberUsedSoFar() { 165 int highestColumnNumber = 0; 166 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 167 if (codeButtonHandlerData._mGUIColumnNumber > highestColumnNumber) { 168 highestColumnNumber = codeButtonHandlerData._mGUIColumnNumber; 169 } 170 } 171 return highestColumnNumber; 172 } 173 174 /** 175 * Routine to search our _mCodeButtonHandlerDataArrayList for the O.S. section 176 * that contains the passed turnout. 177 * 178 * @param turnout The turnout to search for in our table. 179 * @return CTCTurnoutData, else if turnout not found, null. 180 */ 181 public CTCTurnoutData getCTCTurnoutData(Turnout turnout) { 182 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 183 if (codeButtonHandlerData._mSWDI_Enabled) { // Only if it has one: 184 if (codeButtonHandlerData._mSWDI_ExternalTurnout.getBean().equals(turnout)) { // Ah match, this is us: 185 return new CTCTurnoutData(codeButtonHandlerData.myShortStringNoComma(), codeButtonHandlerData._mUniqueID); 186 } 187 } 188 } 189 return null; 190 } 191 192 /** 193 * This routine is used to support FrmTUL.java. It generates a HashSet (which 194 * prevents duplicate strings) of all such locked turnouts, EXCLUDING the 195 * passed "excludedOne", since that one will be handled locally in the calling 196 * code. 197 * 198 * @param excludedOne The one to NOT include in the returned information. 199 * @return All locked turnouts NOT INCLUDING excludedOne. 200 */ 201 public HashSet<String> getHashSetOfAllLockedTurnoutsExcludingPassedOne(CodeButtonHandlerData excludedOne) { 202 HashSet<String> lockedTurnouts = new HashSet<>(); 203 for (CodeButtonHandlerData codeButtonHandlerData : _mCodeButtonHandlerDataArrayList) { 204 if (codeButtonHandlerData != excludedOne) { // Process this one: 205 if (codeButtonHandlerData._mTUL_ExternalTurnout.valid()) { lockedTurnouts.add(codeButtonHandlerData._mTUL_ExternalTurnout.getHandleName()); } 206 if (codeButtonHandlerData._mTUL_AdditionalExternalTurnout1.valid()) { lockedTurnouts.add(codeButtonHandlerData._mTUL_AdditionalExternalTurnout1.getHandleName()); } 207 if (codeButtonHandlerData._mTUL_AdditionalExternalTurnout2.valid()) { lockedTurnouts.add(codeButtonHandlerData._mTUL_AdditionalExternalTurnout2.getHandleName()); } 208 if (codeButtonHandlerData._mTUL_AdditionalExternalTurnout3.valid()) { lockedTurnouts.add(codeButtonHandlerData._mTUL_AdditionalExternalTurnout3.getHandleName()); } 209 } 210 } 211 return lockedTurnouts; 212 } 213 214}