001package armyc2.c5isr.renderer.utilities; 002 003import android.content.Context; 004 005import java.io.BufferedReader; 006import java.io.IOException; 007import java.io.InputStream; 008import java.io.InputStreamReader; 009import java.util.ArrayList; 010import java.util.HashMap; 011import java.util.List; 012import java.util.Map; 013 014import armyc2.c5isr.renderer.R; 015 016public class C2DLookup { 017 018 private static C2DLookup _instance = null; 019 private static Boolean _initCalled = false; 020 021 private static Map<String, String[]> _C2DLookup = null; 022 023 private String TAG = "C2DLookup"; 024 025 026 private C2DLookup() { 027 028 } 029 030 public static synchronized C2DLookup getInstance() { 031 if (_instance == null) { 032 _instance = new C2DLookup(); 033 } 034 return _instance; 035 } 036 037 public final synchronized void init(Context context) 038 { 039 if (_initCalled == false) 040 { 041 _C2DLookup = new HashMap<>(); 042 String[] temp = null; 043 String delimiter = "\t"; 044 045 try { 046 InputStream is = context.getResources().openRawResource(R.raw.c2d); 047 048 BufferedReader br = new BufferedReader(new InputStreamReader(is)); 049 050 051 String line = br.readLine(); 052 while (line != null) { 053 //parse first line 054 temp = line.split(delimiter); 055 056 if(temp.length >= 3) { 057 _C2DLookup.put(temp[0], temp); 058 } 059 060 //read next line for next loop 061 line = br.readLine(); 062 } 063 064 _initCalled = true; 065 } catch (IOException ioe) { 066 System.out.println(ioe.getMessage()); 067 } catch (Exception e) { 068 System.out.println(e.getMessage()); 069 } 070 } 071 } 072 073 /** 074 * Take a complete 15 character 2525C symbol code and converts it to 2525D if there is a match. 075 * Returns null if no match. 076 * @param symbolID 15 character 2525C symbol code. 077 * @return 30 character 2525D code or null if no matching symbol 078 */ 079 public String getDCode(String symbolID) 080 { 081 return getDCode(symbolID, true); 082 } 083 084 /** 085 * Take a complete 15 character 2525C symbol code and converts it to 2525D if there is a match. 086 * Returns null if no match. 087 * @param symbolID 15 character 2525C symbol code. 088 * @param includeCountryCode 2525C symbols don't display the country label so set to false if you don't want it displayed. 089 * @return 30 character 2525D code or null if no matching symbol. 090 */ 091 public String getDCode(String symbolID, boolean includeCountryCode) 092 { 093 String basicID = SymbolUtilities.getBasicSymbolID2525C(symbolID); 094 String newCode = "110000000000000000000000000000"; 095 096 String[] parts = _C2DLookup.get(basicID); 097 if(parts==null) 098 return null; 099 100 //set symbol set 101 newCode = SymbolID.setSymbolSet(newCode, Integer.parseInt(parts[1])); 102 //set entity code 103 newCode = SymbolID.setEntityCode(newCode, Integer.parseInt(parts[2])); 104 //set sector modifier 1 105 if(!parts[3].isEmpty()) 106 newCode = SymbolID.setModifier1(newCode, (parts[3])); 107 //set sector modifier 2 108 if(!parts[4].isEmpty()) 109 newCode = SymbolID.setModifier1(newCode, (parts[4])); 110 111 //get affiliation to set context and affiliation 112 char aff = symbolID.charAt(1); 113 114 switch (aff) 115 { 116 case 'G': 117 case 'W': 118 case 'M': 119 case 'D': 120 case 'L': 121 case 'J': 122 case 'K': 123 newCode = SymbolID.setContext(newCode, SymbolID.StandardIdentity_Context_Exercise); 124 break; 125 default: 126 newCode = SymbolID.setContext(newCode, SymbolID.StandardIdentity_Context_Reality); 127 } 128 129 //set affiliation 130 if(aff=='F' || aff=='D') 131 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Friend); 132 else if(aff=='H' || aff=='K') 133 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Hostile_Faker); 134 else if(aff=='N' || aff=='L') 135 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Neutral); 136 else if(aff=='P' || aff=='G') 137 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Pending); 138 else if(aff=='S' || aff=='J') 139 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Suspect_Joker); 140 else if(aff=='A' || aff=='M') 141 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_AssumedFriend); 142 else if(aff=='U' || aff=='W') 143 newCode = SymbolID.setAffiliation(newCode, SymbolID.StandardIdentity_Affiliation_Unknown); 144 145 //set status 146 char status = symbolID.charAt(3); 147 148 if(status == 'A') 149 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Planned_Anticipated_Suspect); 150 if(status == 'P') 151 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Present); 152 if(status == 'C') 153 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Present_FullyCapable); 154 if(status == 'D') 155 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Present_Damaged); 156 if(status == 'X') 157 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Present_Destroyed); 158 if(status == 'F') 159 newCode = SymbolID.setStatus(newCode, SymbolID.Status_Present_FullToCapacity); 160 161 String modifier = symbolID.substring(10,12); 162 if(modifier.charAt(0)!='H' &&//installation 163 modifier.charAt(0)!='M' && //mobility 164 modifier.charAt(0)!='N') //towed array 165 { 166 switch(modifier.charAt(1)) 167 { 168 case 'A': 169 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Team_Crew); 170 break; 171 case 'B': 172 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Squad); 173 break; 174 case 'C': 175 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Section); 176 break; 177 case 'D': 178 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Platoon_Detachment); 179 break; 180 case 'E': 181 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Company_Battery_Troop); 182 break; 183 case 'F': 184 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Battalion_Squadron); 185 break; 186 case 'G': 187 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Regiment_Group); 188 break; 189 case 'H': 190 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Brigade); 191 break; 192 case 'I': 193 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Division); 194 break; 195 case 'J': 196 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Corps_MEF); 197 break; 198 case 'K': 199 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Army); 200 break; 201 case 'L': 202 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_ArmyGroup_Front); 203 break; 204 case 'M': 205 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Region_Theater); 206 break; 207 case 'N': 208 newCode = SymbolID.setAmplifierDescriptor(newCode,SymbolID.Echelon_Region_Command); 209 break; 210 211 } 212 213 switch (modifier.charAt(0)) 214 { 215 case 'A': 216 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_Headquarters); 217 break; 218 case 'B': 219 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_TaskForce_Headquarters); 220 break; 221 case 'C': 222 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_FeintDummy_Headquarters); 223 break; 224 case 'D': 225 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_FeintDummy_TaskForce_Headquarters); 226 break; 227 case 'E': 228 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_TaskForce); 229 break; 230 case 'F': 231 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_FeintDummy); 232 break; 233 case 'G': 234 newCode = SymbolID.setHQTFD(newCode,SymbolID.HQTFD_FeintDummy_TaskForce); 235 break; 236 } 237 } 238 else 239 { 240 if(modifier.equals("HB")) 241 SymbolID.setHQTFD(newCode,SymbolID.HQTFD_FeintDummy); 242 else if(modifier.charAt(0)=='M') 243 { 244 switch(modifier.charAt(1)) 245 { 246 case 'O': 247 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_WheeledLimitedCrossCountry); 248 break; 249 case 'P': 250 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_WheeledCrossCountry); 251 break; 252 case 'Q': 253 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Tracked); 254 break; 255 case 'R': 256 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Wheeled_Tracked); 257 break; 258 case 'S': 259 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Towed); 260 break; 261 case 'T': 262 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Rail); 263 break; 264 case 'U': 265 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_OverSnow); 266 break; 267 case 'V': 268 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Sled); 269 break; 270 case 'W': 271 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_PackAnimals); 272 break; 273 case 'X': 274 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Barge); 275 break; 276 case 'Y': 277 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_Amphibious); 278 break; 279 } 280 } 281 else if(modifier.charAt(0)=='N') 282 { 283 switch(modifier.charAt(1)) { 284 case 'S': 285 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_ShortTowedArray); 286 break; 287 case 'L': 288 newCode = SymbolID.setAmplifierDescriptor(newCode, SymbolID.Mobility_LongTowedArray); 289 break; 290 } 291 } 292 } 293 294 switch(SymbolID.getEntityCode(newCode)) 295 { 296 case 151406://Axis of Advance for a Feint 297 case 140605://Direction of attack feint 298 case 270705://Dummy Minefield 299 case 270706://Dummy Minefield, Dynamic 300 case 270900://Decoy Mined Area 301 case 270901://Decoy Mined Area, Fenced 302 newCode = SymbolID.setVersion(newCode,10); 303 break; 304 default: 305 break; 306 } 307 308 //country code 309 if(includeCountryCode) 310 newCode = newCode.substring(0,27) + GENCLookup.getInstance().get3DigitCode(symbolID.substring(12,14)); 311 312 return newCode; 313 } 314 315} 316