001package jmri.jmrit.etcs; 002 003import java.awt.image.BufferedImage; 004import java.util.Objects; 005 006import javax.annotation.CheckForNull; 007import javax.swing.ImageIcon; 008 009import jmri.jmrit.etcs.dmi.swing.DmiPanel; 010 011import org.apiguardian.api.API; 012 013/** 014 * Class to represent DMI Track Points of Interest, 015 * i.e. Announcements and Orders. 016 * @author Steve Young Copyright (C) 2024 017 */ 018@API(status=API.Status.EXPERIMENTAL) 019public class TrackCondition { 020 021 private final boolean isOrder; 022 private int distanceFromStart; 023 private final BufferedImage smallImage; 024 private final String largeImageOrder; 025 private final String largeImageNotOrder; 026 protected final String descript; 027 private int slotNum =0; 028 private final String actionCommand; 029 030 protected TrackCondition( int distance, boolean order, 031 String ordSmlPath, String notOrdSmlPath, 032 String ordLrgPath, String notOrdLrgPath, 033 String description, String command ) { 034 distanceFromStart = distance; 035 isOrder = order; 036 descript = description; 037 largeImageOrder = ordLrgPath; 038 largeImageNotOrder = notOrdLrgPath; 039 String smlIconPath = ( order ? ordSmlPath : notOrdSmlPath ); 040 if ( ! smlIconPath.isBlank() ) { 041 smlIconPath += ".bmp"; 042 } 043 actionCommand = command; 044 smallImage = ResourceUtil.getTransparentImage(smlIconPath); 045 } 046 047 /** 048 * Get if the Track Condition is an order, 049 * i.e. the Condition requires an acknowledgement from driver. 050 * @return true if order, else false if informational. 051 */ 052 public boolean getIsOrder(){ 053 return isOrder; 054 } 055 056 /** 057 * Get the Distance to the start of the Track Condition. 058 * @return the distance. 059 */ 060 public int getDistanceFromStart() { 061 return distanceFromStart; 062 } 063 064 protected void setDistanceFromStart(int distance) { 065 distanceFromStart = distance; 066 } 067 068 /** 069 * Get a small icon to display in the Planning area? 070 * @return small icon. 071 */ 072 public BufferedImage getSmlImage(){ 073 return smallImage; 074 } 075 076 /** 077 * Get a larger image to display in a button. 078 * @param isOrder true if requires acknowledgement, false if informational. 079 * @return Large image. 080 */ 081 @CheckForNull 082 public ImageIcon getLargeIcon(boolean isOrder){ 083 var tst = getLargeImage(isOrder); 084 if ( tst == null ) { 085 return null; 086 } 087 return new ImageIcon(tst); 088 } 089 090 @CheckForNull 091 private BufferedImage getLargeImage(boolean isOrder){ 092 String lrgIconPath = ( isOrder ? largeImageOrder : largeImageNotOrder ); 093 if (!lrgIconPath.isEmpty()) { 094 lrgIconPath += ".bmp"; 095 } 096 log.debug("getting image for {}", lrgIconPath); 097 return ResourceUtil.getTransparentImage(lrgIconPath); 098 } 099 100 /** 101 * Get Description of Track Condition. 102 * @return if is driver action or informational, along with description. 103 */ 104 public String getDescription(){ 105 return Bundle.getMessage(getIsOrder() ? "DriverAction" : "DriverInfo",descript); 106 } 107 108 /** 109 * If this is an order, get the acknowledgement String for when 110 * the driver clicks the button. 111 * These can be listened for via adding a changeListener to DmiPanel. 112 * @return the Acknowledgement String for the Condition. 113 */ 114 public String getAckString(){ 115 return actionCommand; 116 } 117 118 /** 119 * Get the Column Number for a Condition in the PASP Planning area. 120 * @return column number, 0 if unset. 121 */ 122 public int getColumnNum(){ 123 return slotNum; 124 } 125 126 /** 127 * Set the Column Number for the PASP column. 128 * @param newCol column number. 129 */ 130 public void setColumnNum(int newCol) { 131 slotNum = newCol; 132 } 133 134 @Override 135 public boolean equals(Object o){ 136 return o instanceof TrackCondition && 137 ((TrackCondition)o).descript.equals(this.descript); 138 } 139 140 @Override 141 public int hashCode() { 142 return 29 + Objects.hashCode(descript); 143 } 144 145 @Override 146 public String toString(){ 147 return this.getDescription(); 148 } 149 150 /** 151 * Get a new Level Crossing Track Condition. 152 * No acknowledgement element. 153 * @param distance distance until the Track Condition. 154 * @return a Level Crossing Track Condition. 155 */ 156 public static TrackCondition levelCrossing(int distance ) { 157 return new TrackCondition(distance, false, 158 "", "","","LX_01", 159 "Level Crossing, not protected", ""); 160 } 161 162 /** 163 * Get a new Radio Hole Track Condition. 164 * No acknowledgement element. 165 * @param distance distance until the Track Condition. 166 * @return a Radio Hole Track Condition. 167 */ 168 public static TrackCondition radioHole(int distance ) { 169 return new TrackCondition(distance, false, 170 "", "PL_10","","TC_12", 171 "Radio hole", ""); 172 } 173 174 /** 175 * Get a new Radio Hole Track Condition. 176 * Always contains acknowledgement element. 177 * @param distance distance until the Track Condition. 178 * @return a Radio Hole Track Condition. 179 */ 180 public static TrackCondition soundHorn(int distance) { 181 return new TrackCondition(distance, true, 182 "PL_24", "","TC_35","", 183 "Sound Horn", DmiPanel.PROP_CHANGE_SOUND_HORN_ACK); 184 } 185 186 /** 187 * Get a new Radio Hole Track Condition. 188 * No acknowledgement element. 189 * No distance element as used for displaying symbol. 190 * @return a Radio Hole Track Condition. 191 */ 192 public static TrackCondition pantographIsLowered() { 193 return new TrackCondition(0, false, 194 "", "","","TC_01", 195 "Pantograph Lowered",""); 196 } 197 198 /** 199 * Get a new Lower Pantograph Track Condition. 200 * @param distance distance until the Track Condition. 201 * @param order true if acknowledgement required, else false. 202 * @return a Lower Pantograph Track Condition. 203 */ 204 public static TrackCondition pantographLower(int distance, boolean order) { 205 return new TrackCondition(distance, order, 206 "PL_02", "PL_01","TC_03","TC_02", 207 "Lower Pantograph", DmiPanel.PROP_CHANGE_LOWER_PANT_ACK); 208 } 209 210 /** 211 * Get a new Raise Pantograph Track Condition. 212 * @param distance distance until the Track Condition. 213 * @param order true if acknowledgement required, else false. 214 * @return a Raise Pantograph Track Condition. 215 */ 216 public static TrackCondition pantographRaise(int distance, boolean order) { 217 return new TrackCondition(distance, order, 218 "PL_04", "PL_03","TC_05","TC_04", 219 "Raise Pantograph", DmiPanel.PROP_CHANGE_RAISE_PANT_ACK); 220 } 221 222 /** 223 * Get a new Close Air Conditioning Track Condition. 224 * @param distance distance until the Track Condition. 225 * @param order true if acknowledgement required, else false. 226 * @return a Close Air Conditioning Track Condition. 227 */ 228 public static TrackCondition airConClose(int distance, boolean order) { 229 return new TrackCondition(distance, order, 230 "PL_19", "PL_17","TC_21","TC_19", 231 "Close air conditioning intake", DmiPanel.PROP_CHANGE_AIRCON_CLOSE_ACK); 232 } 233 234 /** 235 * Get a new Open Air Conditioning Track Condition. 236 * @param distance distance until the Track Condition. 237 * @param order true if acknowledgement required, else false. 238 * @return an Open Air Conditioning Track Condition. 239 */ 240 public static TrackCondition airConOpen(int distance, boolean order) { 241 return new TrackCondition(distance, order, 242 "PL_20", "PL_18","TC_22","TC_20", 243 "Open air conditioning intake", DmiPanel.PROP_CHANGE_AIRCON_OPEN_ACK); 244 } 245 246 /** 247 * Get a Start of Neutral Section Track Condition. 248 * @param distance distance until the Track Condition. 249 * @param order true if acknowledgement required, else false. 250 * @return a start of Neutral Section Track Condition. 251 */ 252 public static TrackCondition neutralSection(int distance, boolean order) { 253 return new TrackCondition(distance, order, 254 "PL_06", "PL_05","TC_07","TC_06", 255 "Neutral Section", DmiPanel.PROP_CHANGE_NEUTRAL_START_ACK); 256 } 257 258 /** 259 * Get an End of Neutral Section Track Condition. 260 * @param distance distance until the Track Condition. 261 * @param order true if acknowledgement required, else false. 262 * @return an end of Neutral Section Track Condition. 263 */ 264 public static TrackCondition neutralSectionEnd(int distance, boolean order) { 265 return new TrackCondition(distance, order, 266 "PL_08", "PL_07","TC_09","TC_08", 267 "End of Neutral Section", DmiPanel.PROP_CHANGE_NEUTRAL_END_ACK); 268 } 269 270 /** 271 * Get a Non Stopping Area Track Condition. 272 * @param distance distance until the Track Condition. 273 * @param order true if acknowledgement required, else false. 274 * Always true when used in a TrackSection 275 * @return a Non Stopping Area Track Condition. 276 */ 277 public static TrackCondition nonStoppingArea(int distance, boolean order ) { 278 return new TrackCondition(distance, order, 279 "PL_09", "PL_09","TC_11","TC_10", 280 "Non stopping area", DmiPanel.PROP_CHANGE_NONSTOP_ACK); 281 } 282 283 /** 284 * Get an Inhibit Magnetic Shoe Brake Track Condition. 285 * @param distance distance until the Track Condition. 286 * @param order true if acknowledgement required, else false. 287 * @return an Inhibit Magnetic Shoe Brake Track Condition. 288 */ 289 public static TrackCondition inhibitMagShoeBrake(int distance, boolean order) { 290 return new TrackCondition(distance, order, 291 "PL_12", "PL_11","TC_14","TC_13", 292 "Inhibition of Magnetic Shoe Brake", DmiPanel.PROP_CHANGE_INHIBIT_MAG_BRAKE_ACK); 293 } 294 295 /** 296 * Get an Inhibit Eddy Current Brake Track Condition. 297 * @param distance distance until the Track Condition. 298 * @param order true if acknowledgement required, else false. 299 * @return an Inhibit Eddy Current Brake Track Condition. 300 */ 301 public static TrackCondition inhibitEddyCurrentBrake(int distance, boolean order) { 302 return new TrackCondition(distance, order, 303 "PL_14", "PL_13","TC_16","TC_15", 304 "Inhibition of eddy current Brake", DmiPanel.PROP_CHANGE_INHIBIT_EDDY_BRAKE_ACK); 305 } 306 307 /** 308 * Get an Inhibit Regenerative Brake Track Condition. 309 * @param distance distance until the Track Condition. 310 * @param order true if acknowledgement required, else false. 311 * @return an Inhibit Regenerative Brake Track Condition. 312 */ 313 public static TrackCondition inhibitRegenerativeBrake(int distance, boolean order) { 314 return new TrackCondition(distance, order, 315 "PL_16", "PL_15","TC_18", "TC_17", 316 "Inhibition of regenerative Brake", DmiPanel.PROP_CHANGE_INHIBIT_REGEN_BRAKE_ACK); 317 } 318 319 /** 320 * Get a No Traction Track Condition. 321 * @param distance distance until the Track Condition. 322 * @param order true if acknowledgement required, else false. 323 * @return a No Traction Track Condition. 324 */ 325 public static TrackCondition tractionChange0(int distance, boolean order) { 326 return new TrackCondition(distance, order, 327 "PL_26", "PL_25","TC_24","TC_23", 328 "No traction system", DmiPanel.PROP_CHANGE_TRACTION_0_ACK); 329 } 330 331 /** 332 * Get a Traction Change to 25kV Track Condition. 333 * @param distance distance until the Track Condition. 334 * @param order true if acknowledgement required, else false. 335 * @return a Traction Change to 25kV Track Condition. 336 */ 337 public static TrackCondition tractionChange25000(int distance, boolean order) { 338 return new TrackCondition(distance, order, 339 "PL_28", "PL_27","TC_26","TC_25", 340 "Traction System : AC 25 kV 50 Hz", DmiPanel.PROP_CHANGE_TRACTION_25KV_ACK); 341 } 342 343 /** 344 * Get a Traction Change to 25kV Track Condition. 345 * @param distance distance until the Track Condition. 346 * @param order true if acknowledgement required, else false. 347 * @return a Traction Change to 25kV Track Condition. 348 */ 349 public static TrackCondition tractionChange15000(int distance, boolean order) { 350 return new TrackCondition(distance, order, 351 "PL_30", "PL_29","TC_28","TC_27", 352 "Traction System : AC 15 kV 16.7 Hz", DmiPanel.PROP_CHANGE_TRACTION_15KV_ACK); 353 } 354 355 /** 356 * Get a Traction Change to 3kV DC Track Condition. 357 * @param distance distance until the Track Condition. 358 * @param order true if acknowledgement required, else false. 359 * @return a Traction Change to 3kV DC Track Condition. 360 */ 361 public static TrackCondition tractionChange3000(int distance, boolean order) { 362 return new TrackCondition(distance, order, 363 "PL_32", "PL_31","TC_30","TC_29", 364 "Traction System : DC 3 kV", DmiPanel.PROP_CHANGE_TRACTION_3KV_ACK); 365 } 366 367 /** 368 * Get a Traction Change to 1.5kV Track Condition. 369 * @param distance distance until the Track Condition. 370 * @param order true if acknowledgement required, else false. 371 * @return a Traction Change to 1.5kV Track Condition. 372 */ 373 public static TrackCondition tractionChange1500(int distance, boolean order) { 374 return new TrackCondition(distance, order, 375 "PL_34", "PL_33","TC_32","TC_31", 376 "Traction System : DC 1.5 kV", DmiPanel.PROP_CHANGE_TRACTION_1_5KV_ACK); 377 } 378 379 /** 380 * Get a Traction Change to 600V or 750V Track Condition. 381 * @param distance distance until the Track Condition. 382 * @param order true if acknowledgement required, else false. 383 * @return a Traction Change to 750V Track Condition. 384 */ 385 public static TrackCondition tractionChange750(int distance, boolean order) { 386 return new TrackCondition(distance, order, 387 "PL_36", "PL_35","TC_34","TC_33", 388 "Traction System : DC 600/750 V", DmiPanel.PROP_CHANGE_TRACTION_750V_ACK); 389 } 390 391 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrackCondition.class); 392 393}