001package jmri.jmrix.can.cbus; 002 003import java.util.EnumSet; 004import javax.annotation.CheckForNull; 005import javax.annotation.Nonnull; 006import jmri.jmrix.AbstractMessage; 007import jmri.jmrix.can.CanFrame; 008 009/** 010 * ENUM to represent various CBUS OPC Filters. 011 * 012 * @author Steve Young (C) 2020 013 */ 014public enum CbusFilterType { 015 CFIN(Bundle.getMessage("Incoming"),null) { 016 @Override 017 public int action(AbstractMessage m, CbusFilter cf) { 018 if (m instanceof jmri.jmrix.can.CanReply) { 019 return super.action(m,cf); 020 } 021 return -1; 022 } }, 023 CFOUT(Bundle.getMessage("Outgoing"),null) { 024 @Override 025 public int action(AbstractMessage m, CbusFilter cf) { 026 if (m instanceof jmri.jmrix.can.CanMessage) { 027 return super.action(m, cf); 028 } 029 return -1; 030 } }, 031 CFEVENT(Bundle.getMessage("CbusEvents"),null), 032 CFEVENTMIN(Bundle.getMessage("MinEvent"),CFEVENT) { 033 @Override 034 public int action(AbstractMessage m, CbusFilter cf) { 035 if ( CbusMessage.getEvent(m) < cf.getEvMin()) { 036 return super.action(m,cf); 037 } 038 CbusFilter.incrementCount(ordinal(),cf); 039 return -1; 040 } }, 041 CFEVENTMAX(Bundle.getMessage("MaxEvent"),CFEVENT) { 042 @Override 043 public int action(AbstractMessage m, CbusFilter cf) { 044 if ( CbusMessage.getEvent(m) > cf.getEvMax()){ 045 return super.action(m,cf); 046 } 047 CbusFilter.incrementCount(ordinal(),cf); 048 return -1; 049 } }, 050 CFON(Bundle.getMessage("CbusOnEvents"),CFEVENT), 051 CFOF(Bundle.getMessage("CbusOffEvents"),CFEVENT), 052 CFSHORT(Bundle.getMessage("ShortEvents"),CFEVENT), 053 CFLONG(Bundle.getMessage("LongEvents"),CFEVENT), 054 CFSTD(Bundle.getMessage("StandardEvents"),CFEVENT), 055 CFREQUEST(Bundle.getMessage("RequestEvents"),CFEVENT), 056 CFRESPONSE(Bundle.getMessage("ResponseEvents"),CFEVENT), 057 CFED0(Bundle.getMessage("EVD0"),CFEVENT), 058 CFED1(Bundle.getMessage("EVD1"),CFEVENT), 059 CFED2(Bundle.getMessage("EVD2"),CFEVENT), 060 CFED3(Bundle.getMessage("EVD3"),CFEVENT), 061 062 CFNODE(Bundle.getMessage("CbusNodes"),null) { 063 @Override 064 public int action(AbstractMessage m, CbusFilter cf) { 065 return CbusFilter.checknode(CbusMessage.getNodeNumber(m),cf); 066 } }, 067 CFNODEMIN(Bundle.getMessage("MinNode"),CFNODE) { 068 @Override 069 public int action(AbstractMessage m, CbusFilter cf) { 070 if ( CbusMessage.getNodeNumber(m) < cf.getNdMin()){ 071 return super.action(m, cf); 072 } 073 CbusFilter.incrementCount(ordinal(),cf); 074 return -1; 075 } }, 076 CFNODEMAX(Bundle.getMessage("MaxNode"),CFNODE) { 077 @Override 078 public int action(AbstractMessage m, CbusFilter cf) { 079 if ( CbusMessage.getNodeNumber(m) > cf.getNdMax()){ 080 return super.action(m, cf); 081 } 082 CbusFilter.incrementCount(ordinal(),cf); 083 return -1; 084 } }, 085 CFNODES(Bundle.getMessage("CbusNodes"),CFNODE) { 086 @Override 087 public int action(AbstractMessage m, CbusFilter cf) { 088 return -1; 089 } }, 090 091 CFDATA(Bundle.getMessage("OPC_DA"),null), 092 CFACDAT("ACDAT",CFDATA), 093 CFDDES("DDES + DDWS",CFDATA), 094 CFRQDAT("RQDAT",CFDATA), 095 CFARDAT("ARDAT",CFDATA), 096 CFDDRS("DDRS",CFDATA), 097 CFRQDDS("RQDDS",CFDATA), 098 CFCABDAT("CABDAT",CFDATA), 099 100 CFCS(Bundle.getMessage("CommandStation"),null), 101 CFCSAQRL(Bundle.getMessage("LocoCommands"),CFCS), 102 CFCSKA(Bundle.getMessage("KeepAlive"),CFCS), 103 CFCSDSPD(Bundle.getMessage("SpeedDirection"),CFCS), 104 CFCSFUNC(Bundle.getMessage("Functions"),CFCS), 105 CFCSPROG(Bundle.getMessage("Programming"),CFCS), 106 CFCSLC(Bundle.getMessage("LayoutCommands"),CFCS), 107 CFCSC(Bundle.getMessage("CommandStationControl"),CFCS), 108 109 CFNDCONFIG(Bundle.getMessage("NodeConfiguration"),null), 110 CFNDSETUP(Bundle.getMessage("GeneralNodeSetup"),CFNDCONFIG), 111 CFNDVAR(Bundle.getMessage("NodeVariables"),CFNDCONFIG), 112 CFNDEV(Bundle.getMessage("NodeEvents"),CFNDCONFIG), 113 CFNDNUM(Bundle.getMessage("NodeNumbers"),CFNDCONFIG), 114 115 CFMISC(Bundle.getMessage("Misc"),null), 116 CFEXTRTR("Extended / RTR",CFMISC){ 117 @Override 118 public int action(AbstractMessage m, CbusFilter cf) { 119 if (m instanceof CanFrame && ((CanFrame) m).extendedOrRtr() ) { 120 if ( cf.getActiveFilters().get(ordinal()) ){ 121 return ordinal(); 122 } else { 123 CbusFilter.incrementCount(ordinal(),cf); 124 return -2; // special return as unable to contiinue filtering if extended or rtr 125 } 126 } 127 return -1; 128 } }, 129 CFNETWK(Bundle.getMessage("NetworkCommands"),CFMISC), 130 CFCLOCK(Bundle.getMessage("CBUS_FCLK"),CFMISC), 131 CFOTHER(Bundle.getMessage("Others"),CFMISC), 132 CFUNKNOWN(Bundle.getMessage("Unknown"),CFMISC); 133 134 /** 135 * Perform Filter check for a particular message. 136 * Can be overridden by specific filters. 137 * 138 * @param m CanMessage or CanReply 139 * @param cf main CbusFilter instance 140 * @return Filter category which blocked, else -1 or -2 if passed 141 */ 142 public int action(AbstractMessage m, CbusFilter cf){ 143 if ( cf.getActiveFilters().get(ordinal()) ){ 144 return ordinal(); 145 } else { 146 CbusFilter.incrementCount(ordinal(),cf); 147 return -1; 148 } 149 } 150 151 private final String _bundleString; 152 private final CbusFilterType _category; 153 154 /** 155 * Create new CbusFilterType. 156 */ 157 CbusFilterType(String bundle, CbusFilterType category) { 158 this._bundleString=bundle; 159 this._category = category; 160 } 161 162 /** 163 * Get Filter Name 164 * @return Filter Name 165 */ 166 public final String getName(){ 167 return _bundleString; 168 } 169 170 /** 171 * Get Filter Category 172 * @return Filter Category, else null if Category Head 173 */ 174 @CheckForNull 175 public final CbusFilterType getCategory() { 176 return _category; 177 } 178 179 /** 180 * Get an EnumSet of Category Heads 181 * @return set 182 */ 183 public final static EnumSet<CbusFilterType> getCatHeads() { 184 EnumSet<CbusFilterType> catSet = EnumSet.noneOf(CbusFilterType.class); 185 catSet.add(CFEVENT); 186 catSet.add(CFNODE); 187 catSet.add(CFDATA); 188 catSet.add(CFCS); 189 catSet.add(CFNDCONFIG); 190 catSet.add(CFMISC); 191 return catSet; 192 } 193 194 /** 195 * Is the Filter a parent of a category? 196 * @return true if category parent 197 */ 198 public final boolean isCategoryHead() { 199 return getCatHeads().contains(this); 200 } 201 202 /** 203 * Should the Filter always be displayed? 204 * @return true if category head or in / out filter. 205 */ 206 public final boolean alwaysDisplay() { 207 EnumSet<CbusFilterType> alwaysDisplay = getCatHeads(); 208 alwaysDisplay.add(CFIN); 209 alwaysDisplay.add(CFOUT); 210 return alwaysDisplay.contains(this); 211 } 212 213 /** 214 * Get if the Filter needs to display a number spinner 215 * @return true to display a spinner 216 */ 217 public final boolean showSpinners() { 218 EnumSet<CbusFilterType> spinnerSet = EnumSet.noneOf(CbusFilterType.class); 219 spinnerSet.addAll(EnumSet.of(CFEVENTMIN,CFEVENTMAX,CFNODEMIN,CFNODEMAX)); 220 return spinnerSet.contains(this); 221 } 222 223 /** 224 * Get All Filters for a particular OPC 225 * @param opc OPC to get Filter List for 226 * @return set of Filters to use for the OPC. 227 */ 228 @Nonnull 229 public final static EnumSet<CbusFilterType> allFilters(int opc) { 230 EnumSet<CbusFilterType> mergedSet = EnumSet.noneOf(CbusFilterType.class); 231 mergedSet.addAll(EnumSet.of(CFIN,CFOUT,CFEXTRTR)); 232 mergedSet.addAll(CbusOpCodes.getOpcFilters(opc)); 233 if (mergedSet.contains(CbusFilterType.CFEVENT)){ 234 mergedSet.addAll(EnumSet.of(CbusFilterType.CFEVENTMIN,CbusFilterType.CFEVENTMAX)); 235 } 236 if (mergedSet.contains(CbusFilterType.CFNODE)){ 237 mergedSet.addAll(EnumSet.of(CbusFilterType.CFNODEMIN,CbusFilterType.CFNODEMAX)); 238 } 239 return mergedSet; 240 } 241 242 /** 243 * Get ToolTip Text for the Filter 244 * @return HMTL list of OPCs with description, may be null if no ToolTip 245 */ 246 @CheckForNull 247 public final String getToolTip(){ 248 StringBuilder t = new StringBuilder(); 249 for ( int i=0 ; (i < 257) ; i++) { 250 if (CbusOpCodes.getOpcFilters(i).contains(this) 251 && !CbusOpCodes.getOpcName(i).isEmpty()){ 252 t.append(CbusOpCodes.getOpcName(i)) 253 .append(" : ") 254 .append(Bundle.getMessage("CBUS_" + CbusOpCodes.getOpcName(i))) 255 .append(" : ") 256 .append(Bundle.getMessage("CTIP_" + CbusOpCodes.getOpcName(i))) 257 .append("<br>"); 258 } 259 } 260 if (!t.toString().isEmpty()){ 261 t.insert(0,"<html>"); 262 t.append("<html>"); 263 return t.toString(); 264 } 265 return null; 266 } 267}