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