001package jmri.jmrix.dccpp; 002 003import static jmri.jmrix.dccpp.DCCppConstants.MAX_TURNOUT_ADDRESS; 004import java.util.ArrayList; 005import java.util.List; 006import javax.annotation.Nonnull; 007import java.util.Locale; 008import jmri.Light; 009import jmri.NamedBean; 010import jmri.NamedBeanPropertyDescriptor; 011import jmri.SelectionPropertyDescriptor; 012import jmri.managers.AbstractLightManager; 013 014/** 015 * Implement LightManager for DCC-EX systems. 016 * <p> 017 * System names are "DxppSnnn", where Dx is the system prefix and nnn is the sensor number without padding. 018 * <p> 019 * Based in part on SerialLightManager.java 020 * 021 * @author Paul Bender Copyright (C) 2008 022 * @author Mark Underwood Copyright (C) 2015 023 */ 024public class DCCppLightManager extends AbstractLightManager { 025 026 private DCCppTrafficController tc = null; 027 028 /** 029 * Create an new DCC-EX LightManager. 030 * Has to register for DCC-EX events. 031 * 032 * @param memo the supporting system connection memo 033 */ 034 public DCCppLightManager(DCCppSystemConnectionMemo memo) { 035 super(memo); 036 this.tc = memo.getDCCppTrafficController(); 037 } 038 039 /** 040 * {@inheritDoc} 041 */ 042 @Override 043 @Nonnull 044 public DCCppSystemConnectionMemo getMemo() { 045 return (DCCppSystemConnectionMemo) memo; 046 } 047 048 /** 049 * Create a new Light based on the system name. 050 * Assumes calling method has checked that a Light with this 051 * system name does not already exist. 052 * 053 * @return null if the system name is not in a valid format 054 */ 055 @Override 056 @Nonnull 057 protected Light createNewLight(String systemName, String userName) throws IllegalArgumentException { 058 // check if the output bit is available 059 int bitNum = getBitFromSystemName(systemName); 060 if (bitNum == 0) { 061 throw new IllegalArgumentException("Invalid Bit from System Name: " + systemName); 062 } 063 // Normalize the systemName 064 String sName = getSystemNamePrefix() + bitNum; // removes any leading zeros 065 // make the new Light object 066 return new DCCppLight(tc, this, sName, userName); 067 } 068 069 /** 070 * {@inheritDoc} 071 */ 072 @Override 073 public NameValidity validSystemNameFormat(@Nonnull String systemName) { 074 return (getBitFromSystemName(systemName) != 0) ? NameValidity.VALID : NameValidity.INVALID; 075 } 076 077 /** 078 * {@inheritDoc} 079 */ 080 @Override 081 @Nonnull 082 public String validateSystemNameFormat(@Nonnull String systemName, @Nonnull Locale locale) { 083 return validateIntegerSystemNameFormat(systemName, 1, MAX_TURNOUT_ADDRESS, locale); 084 } 085 086 /** 087 * Get the bit address from the system name. 088 * @param systemName a valid Light System Name 089 * @return the light number extracted from the system name 090 */ 091 public int getBitFromSystemName(String systemName) { 092 try { 093 validateSystemNameFormat(systemName, Locale.getDefault()); 094 } catch (IllegalArgumentException ex) { 095 return 0; 096 } 097 return Integer.parseInt(systemName.substring(getSystemNamePrefix().length())); 098 } 099 100 /** 101 * {@inheritDoc} 102 */ 103 @Override 104 public boolean allowMultipleAdditions(@Nonnull String systemName) { 105 return true; 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 @Override 112 public String getEntryToolTip() { 113 return Bundle.getMessage("AddOutputEntryToolTip"); 114 } 115 116 public static final String DCCPP_LIGHT_MODE_KEY = "LightMode"; // NOI18N 117 118 private static final String[] DCCPP_LIGHT_MODE_TIPS = { 119 "Standard DCC accessory decoder command <a>", // NOI18N 120 "CS VPIN pin control <z> (DCC-EX v4.2.35+)" // NOI18N 121 }; 122 123 @Override 124 @Nonnull 125 public List<NamedBeanPropertyDescriptor<?>> getKnownBeanProperties() { 126 List<NamedBeanPropertyDescriptor<?>> l = new ArrayList<>(); 127 l.add(new SelectionPropertyDescriptor( 128 DCCPP_LIGHT_MODE_KEY, DCCppLight.MODE_NAMES, DCCPP_LIGHT_MODE_TIPS, 129 DCCppLight.MODE_NAMES[0]) { 130 @Override 131 public String getColumnHeaderText() { 132 return "Mode"; 133 } 134 @Override 135 public boolean isEditable(NamedBean bean) { 136 return (bean instanceof DCCppLight); 137 } 138 }); 139 return l; 140 } 141 142}