001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package armyc2.c2sd.renderer.utilities;
006
007import java.util.ArrayList;
008
009import android.util.SparseArray;
010//import android.graphics.PointF;
011import armyc2.c2sd.graphics2d.*;
012
013/**
014 *
015 * @author michael.spinelli
016 */
017public class MilStdSymbol
018{
019
020        //private SymbolDef _symbolDefinition = null;
021    //private UnitDef _unitDefinition = null;
022    /**
023     * modifiers
024     */
025    private SparseArray<String> _Properties = null;
026
027    //for tactical graphics
028    private ArrayList<Double> _X_Altitude = null;
029    private ArrayList<Double> _AM_Distance = null;
030    private ArrayList<Double> _AN_Azimuth = null;
031
032    private String _symbolID = "";
033
034    /**
035     * unique ID for this symbol, for client use
036     */
037    private String _UUID = null;
038
039    private ArrayList<ShapeInfo> _SymbolShapes;
040
041    /**
042     * collection of shapes for the modifiers
043     */
044    private ArrayList<ShapeInfo> _ModifierShapes;
045
046    private ArrayList<Point2D> _Coordinates;
047
048    private int _UnitSize = 0;
049    private double _scale = 0;
050    private Boolean _KeepUnitRatio = true;
051
052    Integer _LineWidth = 3;
053    Color _LineColor = null;
054    Color _FillColor = null;
055    Color _TextColor = null;
056    Color _TextBackgroundColor = null;
057
058    double _Rotation = 0.0;//DEGREES
059
060    //outline singlepoint TGs
061    boolean _Outline = false;
062    //if null, renderer determines outline Color.
063    Color _OutLineColor = null;
064    int _OutLineWidth = 0;
065    TexturePaint _tp = null;
066    boolean _fs = false;
067
068    int _patternFillType = 0;
069    /**
070     * 2525Bch2 and USAS 13/14 symbology
071     */
072    public static final int Symbology_2525Bch2_USAS_13_14 = 0;
073    /**
074     * 2525C, which includes 2525Bch2 & USAS 13/14
075     */
076    public static final int Symbology_2525C = 1;
077
078    private static int _SymbologyStandard = 0;
079    
080    private static String _AltitudeMode = "";
081
082    private static DistanceUnit _AltitudeUnit = null;
083
084    private static DistanceUnit _DistanceUnit = null;
085
086    private static boolean _useDashArray = true;
087
088    private static boolean _hideOptionalLabels = false;
089
090    private static boolean _DrawAffiliationModifierAsLabel = true;
091
092    private static boolean _UseLineInterpolation = false;
093
094    /**
095     * Text is not affected by scale changes
096     */
097    public static final int TextScaleSensitive_No = 0;
098    /**
099     * Text is affected only by significant scale changes
100     */
101    public static final int TextScaleSensitive_OnSlightZoomIn = 1;
102    /**
103     * Text is affected by zoom in scale changes
104     */
105    public static final int TextScaleSensitive_OnZoomIn = 2;
106    /**
107     * Text is affected by any scale changes
108     */
109    public static final int TextScaleSensitive_OnZoomInOut = 3;
110
111    /**
112     * Symbol is not affected by scale changes
113     */
114    public static final int SymbolScaleSensitive_No = 0;
115    /**
116     * Symbol has arrow heads that are affected by scale change
117     */
118    public static final int SymbolScaleSensitive_ArrowHeads = 1;
119    /**
120     * Symbol has lines details that are affected by scale change (like FLOT)
121     */
122    public static final int SymbolScaleSensitive_DecoratedLines = 2;
123    /**
124     * Symbol has pattern fills that are affected by scale if you're not using the fill pattern image
125     * ShapeInfo.getShader() or ShapeInfo.getPatternFillImage()
126     */
127    public static final int SymbolScaleSensitive_PatternFills = 3;
128
129    Object _Tag = null;
130
131    /**
132     * Used to hold metadata for each segment of the symbol for multi-point
133     * symbols. Each segment can contain one object.
134     */
135                //private Map _segmentData;
136                // Constants for dynamic properties
137/*
138     public static final String SYMBOL_ID = "Symbol ID";
139     //public static final String SOURCE = "Source";
140     //public static final String EDITOR_CLASS_TYPE = "Editor Class Type";
141     public static final String URN = "URN";
142     public static final String UIC = "UIC";
143     public static final String ANGLE_OF_ROTATION = "Angle of Rotation";
144     public static final String LENGTH = "Length";
145     public static final String WIDTH = "Width";
146     public static final String RADIUS = "Radius";
147     public static final String SEGMENT_DATA = "Segment Data";
148     */
149
150    /*
151     public static final String GEO_POINT = "point";
152     public static final String GEO_LINE = "line";
153     public static final String GEO_POLYGON = "area";
154     public static final String GEO_TEXT = "text";
155     public static final String GEO_CIRCLE = "circle";
156     public static final String GEO_RECTANGLE = "rectangle";
157     public static final String GEO_ARC = "arc";
158     public static final String GEO_SQUARE = "square";
159     */
160    /*
161     private static final String _COORDINATES = "Coordinates";
162     private static final String _GEOMETRY = "Geometry";
163     private static final String _FILL_COLOR = "Fill Color";
164     private static final String _FILL_ALPHA = "Fill Alpha";
165     private static final String _FILL_STYLE = "Fill Style";
166     private static final String _LINE_WIDTH = "Line Width";
167     private static final String _LINE_COLOR = "Line Color";
168     private static final String _LINE_ALPHA = "Line Alpha";
169     private static final String _TEXT_BACKGROUND_COLOR = "Background Color";
170     private static final String _TEXT_FOREGROUND_COLOR = "Foreground Color";
171     private static final String _USE_FILL = "Use Fill";
172     */
173    /*
174     protected static const _COORDINATES:String = "Coordinates";
175     protected static const _GEOMETRY:String = "Geometry";
176     protected static const _FILL_COLOR:String = "Fill Color";
177     protected static const _FILL_ALPHA:String = "Fill Alpha";
178     private int _FILL_STYLE:String = "Fill Style";
179     protected static const _LINE_WIDTH:String = 0;
180     private Color _LINE_COLOR = Color.BLACK;
181     private int _LINE_ALPHA:String = 0;
182     private Color _TEXT_BACKGROUND_COLOR = Color.WHITE;
183     private Color _TEXT_FOREGROUND_COLOR = Color.BLACK;
184     private bool _USE_FILL:String = "Use Fill";*/
185    /**
186     * Creates a new MilStdSymbol.
187     *
188     * @param symbolID code, 15 characters long that represents the symbol
189     * @param uniqueUD for the client's use
190     *
191     *
192     */
193    /**
194     *
195     * @param symbolID code, 15 characters long that represents the symbol
196     * @param uniqueID for the client's use
197     * @param modifiers use keys from ModifiersTG or ModifiersUnits.
198     * @param Coordinates
199     * @throws RendererException NULL is a valid value if you have no set
200     * modifiers
201     */
202    public MilStdSymbol(String symbolID, String uniqueID, ArrayList<Point2D> Coordinates, SparseArray<String> modifiers)
203    {
204        this(symbolID, uniqueID, Coordinates, modifiers, true);
205    }
206
207    /**
208     *
209     * @param symbolID code, 15 characters long that represents the symbol
210     * @param uniqueID for the client's use
211     * @param modifiers use keys from ModifiersTG or ModifiersUnits.
212     * @param Coordinates
213     * @param keepUnitRatio - default TRUE
214     * @throws RendererException NULL is a valid value if you have no set
215     * modifiers
216     */
217    public MilStdSymbol(String symbolID, String uniqueID, ArrayList<Point2D> Coordinates, SparseArray<String> modifiers, Boolean keepUnitRatio)
218    {
219
220        if (modifiers == null)
221        {
222            _Properties = new SparseArray<String>();
223        }
224        else
225        {
226            _Properties = modifiers;
227        }
228
229        _UUID = uniqueID;
230        setCoordinates(Coordinates);
231
232        // Set the given symbol id
233        setSymbolID(symbolID);
234
235        // Set up default line and fill colors based on affiliation
236        setLineColor(SymbolUtilities.getLineColorOfAffiliation(_symbolID));
237        //if(SymbolUtilities.isWarfighting(_symbolID))
238        if (SymbolUtilities.hasDefaultFill(_symbolID))
239        {
240            setFillColor(SymbolUtilities.getFillColorOfAffiliation(_symbolID));
241        }
242            //if(SymbolUtilities.isNBC(_symbolID) && !(SymbolUtilities.isDeconPoint(symbolID)))
243        //    setFillColor(SymbolUtilities.getFillColorOfAffiliation(_symbolID));
244
245        setSymbologyStandard(RendererSettings.getInstance().getSymbologyStandard());
246
247        _DrawAffiliationModifierAsLabel = RendererSettings.getInstance().getDrawAffiliationModifierAsLabel();
248
249        _UseLineInterpolation = RendererSettings.getInstance().getUseLineInterpolation();
250
251    }
252
253    /**
254     * Controls what symbols are supported. Set this before loading the
255     * renderer.
256     *
257     * @param standard Like
258     * RendererSettings.Symbology_2525Bch2_USAS_13_14
259     */
260    public void setSymbologyStandard(int standard)
261    {
262        _SymbologyStandard = standard;
263    }
264
265    public TexturePaint getFillStyle()
266    {
267        return _tp;
268    }
269
270    public void setFillStyle(TexturePaint value)
271    {
272        _tp = value;
273    }
274
275    public boolean getUseFillPattern()
276    {
277        return _fs;
278    }
279
280    public void setUseFillPattern(boolean value)
281    {
282        _fs = value;
283    }
284
285    public int getPatternFillType()
286    {
287        return _patternFillType;
288    }
289
290    /**
291     * 0=Solid, 2=ForwardHatch, 3=BackwardHatch, 4=verticalHatch, 5=horizonalHatch, 8=CrossHatch
292     * Only affects Basic Shapes.  Will not apply to MilStd Symbology so as to not confuse some
293     * symbols with others.
294     * @param value
295     */
296    public void setPatternFillType(int value)
297    {
298        _patternFillType = value;
299    }
300
301
302    /**
303     * Current symbology standard
304     *
305     * @return symbologyStandard Like
306     * RendererSettings.Symbology_2525Bch2_USAS_13_14
307     */
308    public int getSymbologyStandard()
309    {
310        return _SymbologyStandard;
311    }
312
313    public String getAltitudeMode()
314    {
315        return _AltitudeMode;
316    }
317
318    public void setAltitudeMode(String value)
319    {
320        _AltitudeMode = value;
321    }
322
323    public DistanceUnit getAltitudeUnit(){
324        return _AltitudeUnit;
325    }
326
327    public void setAltitudeUnit(DistanceUnit unit){
328        _AltitudeUnit = unit;
329    }
330
331    public DistanceUnit getDistanceUnit(){
332        return _DistanceUnit;
333    }
334
335    public void setDistanceUnit(DistanceUnit unit){
336        _DistanceUnit = unit;
337    }
338    
339    public boolean getUseDashArray()
340    {
341        return _useDashArray;
342    }
343
344    public void setUseDashArray(boolean value)
345    {
346        _useDashArray = value;
347    }
348
349    public boolean getHideOptionalLabels()
350    {
351        return _hideOptionalLabels;
352    }
353
354    public void setHideOptionalLabels(boolean value)
355    {
356        _hideOptionalLabels = value;
357    }
358
359    public void setUseLineInterpolation(boolean value)
360    {
361        _UseLineInterpolation = value;
362    }
363
364    public boolean getUseLineInterpolation()
365    {
366        return _UseLineInterpolation;
367    }
368
369    /**
370     * Determines how to draw the Affiliation Modifier. True to draw as modifier
371     * label in the "E/F" location. False to draw at the top right corner of the
372     * symbol
373     */
374    public void setDrawAffiliationModifierAsLabel(boolean value)
375    {
376        _DrawAffiliationModifierAsLabel = value;
377    }
378
379    /**
380     * True to draw as modifier label in the "E/F" location. False to draw at
381     * the top right corner of the symbol
382     */
383    public boolean getDrawAffiliationModifierAsLabel()
384    {
385        return _DrawAffiliationModifierAsLabel;
386    }
387
388    /**
389     *
390     * @return
391     */
392    public SparseArray<String> getModifierMap()
393    {
394        return _Properties;
395    }
396
397    /**
398     *
399     * @param modifiers
400     */
401    public void setModifierMap(SparseArray<String> modifiers)
402    {
403        _Properties = modifiers;
404    }
405
406    /**
407     *
408     * @param modifier
409     * @return
410     */
411    public String getModifier(int modifier)
412    {
413        if (_Properties.indexOfKey(modifier) >= 0)
414        {
415            return _Properties.get(modifier);
416        }
417        else
418        {
419            return getModifier(modifier, 0);
420        }
421    }
422
423    /**
424     *
425     * @param modifier
426     * @param value
427     */
428    public void setModifier(int modifier, String value)
429    {
430        if (value.equals("") == false)
431        {
432            if (!(modifier == ModifiersTG.AM_DISTANCE)
433                    || modifier == (ModifiersTG.AN_AZIMUTH)
434                    || modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
435            {
436                _Properties.put(modifier, value);
437            }
438            else
439            {
440                setModifier(modifier, value, 0);
441            }
442        }
443    }
444
445    /**
446     *
447     * @param modifier
448     * @param index
449     * @return
450     */
451    public String getModifier(int modifier, int index)
452    {
453        if (_Properties.indexOfKey(modifier) >= 0)
454        {
455            return _Properties.get(modifier);
456        }
457        else if (modifier == (ModifiersTG.AM_DISTANCE)
458                || modifier == (ModifiersTG.AN_AZIMUTH)
459                || modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
460        {
461            String value = String.valueOf(getModifier_AM_AN_X(modifier, index));
462            if (value != null && !value.equalsIgnoreCase("null") && !value.equalsIgnoreCase(""))
463            {
464                return value;
465            }
466            else
467            {
468                return null;
469            }
470        }
471        else
472        {
473            return null;
474        }
475
476    }
477
478    /**
479     *
480     * @param modifier
481     * @param index
482     * @return
483     */
484    public Double getModifier_AM_AN_X(int modifier, int index)
485    {
486        ArrayList<Double> modifiers = null;
487        if (modifier == (ModifiersTG.AM_DISTANCE))
488        {
489            modifiers = _AM_Distance;
490        }
491        else if (modifier == (ModifiersTG.AN_AZIMUTH))
492        {
493            modifiers = _AN_Azimuth;
494        }
495        else if (modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
496        {
497            modifiers = _X_Altitude;
498        }
499        else
500        {
501            return null;
502        }
503
504        if (modifiers != null && modifiers.size() > index)
505        {
506            Double value = null;
507            value = modifiers.get(index);
508            if (value != null)
509            {
510                return value;
511            }
512            else
513            {
514                return null;
515            }
516        }
517        else
518        {
519            return null;
520        }
521    }
522
523    /**
524     * Modifiers must be added in order. No setting index 2 without first
525     * setting index 0 and 1. If setting out of order is attempted, the value
526     * will just be added to the end of the list.
527     *
528     * @param modifier
529     * @param value
530     * @param index
531     */
532    public void setModifier(int modifier, String value, int index)
533    {
534        if (value.equals("") == false)
535        {
536            if (!(modifier == (ModifiersTG.AM_DISTANCE)
537                    || modifier == (ModifiersTG.AN_AZIMUTH)
538                    || modifier == (ModifiersTG.X_ALTITUDE_DEPTH)))
539            {
540                _Properties.put(modifier, value);
541            }
542            else
543            {
544                Double dblValue = Double.valueOf(value);
545                if (dblValue != null)
546                {
547                    setModifier_AM_AN_X(modifier, dblValue, index);
548                }
549            }
550        }
551    }
552
553    public void setModifier_AM_AN_X(int modifier, Double value, int index)
554    {
555        if ((modifier == (ModifiersTG.AM_DISTANCE)
556                || modifier == (ModifiersTG.AN_AZIMUTH)
557                || modifier == (ModifiersTG.X_ALTITUDE_DEPTH)))
558        {
559            ArrayList<Double> modifiers = null;
560            if (modifier == (ModifiersTG.AM_DISTANCE))
561            {
562                if (_AM_Distance == null)
563                {
564                    _AM_Distance = new ArrayList<Double>();
565                }
566                modifiers = _AM_Distance;
567            }
568            else if (modifier == (ModifiersTG.AN_AZIMUTH))
569            {
570                if (_AN_Azimuth == null)
571                {
572                    _AN_Azimuth = new ArrayList<Double>();
573                }
574                modifiers = _AN_Azimuth;
575            }
576            else if (modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
577            {
578                if (_X_Altitude == null)
579                {
580                    _X_Altitude = new ArrayList<Double>();
581                }
582                modifiers = _X_Altitude;
583            }
584            if (index + 1 > modifiers.size())
585            {
586                modifiers.add(value);
587            }
588            else
589            {
590                modifiers.set(index, value);
591            }
592        }
593    }
594
595    public ArrayList<Double> getModifiers_AM_AN_X(int modifier)
596    {
597        if (modifier == (ModifiersTG.AM_DISTANCE))
598        {
599            return _AM_Distance;
600        }
601        else if (modifier == (ModifiersTG.AN_AZIMUTH))
602        {
603            return _AN_Azimuth;
604        }
605        else if (modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
606        {
607            return _X_Altitude;
608        }
609
610        return null;
611    }
612
613    public void setModifiers_AM_AN_X(int modifier, ArrayList<Double> modifiers)
614    {
615        if (modifier == (ModifiersTG.AM_DISTANCE))
616        {
617            _AM_Distance = modifiers;
618        }
619        else if (modifier == (ModifiersTG.AN_AZIMUTH))
620        {
621            _AN_Azimuth = modifiers;
622        }
623        else if (modifier == (ModifiersTG.X_ALTITUDE_DEPTH))
624        {
625            _X_Altitude = modifiers;
626        }
627    }
628
629    /**
630     *
631     * @param value
632     */
633    public void setFillColor(Color value)
634    {
635        _FillColor = value;
636    }
637
638    /**
639     *
640     * @return
641     */
642    public Color getFillColor()
643    {
644        return _FillColor;
645    }
646    
647    /**
648    *
649    * @param value
650    */
651   public void setTextColor(Color value)
652   {
653       _TextColor = value;
654   }
655
656   /**
657    *
658    * @return
659    */
660   public Color getTextColor()
661   {
662       return _TextColor;
663   }
664   
665   /**
666   *
667   * @param value
668   */
669  public void setTextBackgroundColor(Color value)
670  {
671      _TextBackgroundColor = value;
672  }
673
674  /**
675   *
676   * @return
677   */
678  public Color getTextBackgroundColor()
679  {
680      return _TextBackgroundColor;
681  }
682
683    /**
684     *
685     * @param value
686     */
687    public void setLineWidth(int value)
688    {
689        _LineWidth = value;
690    }
691
692    /**
693     *
694     * @return
695     */
696    public int getLineWidth()
697    {
698        return _LineWidth;
699    }
700
701    /**
702     *
703     * @param value
704     */
705    public void setLineColor(Color value)
706    {
707        if(value != null)
708        {
709                _LineColor = value;
710        }
711    }
712
713    /**
714     *
715     * @return
716     */
717    public Color getLineColor()
718    {
719        return _LineColor;
720    }
721
722    /**
723     * if null, renderer will use white or black for the outline based on the color
724     * of the symbol. Otherwise, it will used the passed color value.
725     *
726     * @param value
727     */
728    public void setOutlineColor(Color value)
729    {
730        _OutLineColor = value;
731    }
732
733    public Color getOutlineColor()
734    {
735        return _OutLineColor;
736    }
737
738    /**
739     * Extra value for client. defaults to null. Not used for rendering by
740     * JavaRenderer
741     *
742     * @param value
743     * @deprecated
744     */
745    public void setTag(Object value)
746    {
747        _Tag = value;
748    }
749
750    /**
751     * Extra value for client. defaults to null. Not used for rendering by
752     * JavaRenderer
753     *
754     * @return
755     */
756    public Object getTag()
757    {
758        return _Tag;
759    }
760
761    /**
762     *
763     * @param value
764     */
765    public void setCoordinates(ArrayList<Point2D> value)
766    {
767        _Coordinates = value;
768    }
769
770    /**
771     *
772     * @return
773     */
774    public ArrayList<Point2D> getCoordinates()
775    {
776        return _Coordinates;
777    }
778
779    /**
780     * Shapes that represent the symbol modifiers
781     *
782     * @param value ArrayList<Shape>
783     */
784    public void setModifierShapes(ArrayList<ShapeInfo> value)
785    {
786        _ModifierShapes = value;
787    }
788
789    /**
790     * Shapes that represent the symbol modifiers
791     *
792     * @return
793     */
794    public ArrayList<ShapeInfo> getModifierShapes()
795    {
796        return _ModifierShapes;
797    }
798
799    /**
800     * the java shapes that make up the symbol
801     *
802     * @param value ArrayList<ShapeInfo>
803     */
804    public void setSymbolShapes(ArrayList<ShapeInfo> value)
805    {
806        _SymbolShapes = value;
807    }
808
809    /**
810     * the java shapes that make up the symbol
811     *
812     * @return
813     */
814    public ArrayList<ShapeInfo> getSymbolShapes()
815    {
816        return _SymbolShapes;
817    }
818
819    /**
820     * The Symbol Id of the MilStdSymbol.
821     *
822     * @return
823     */
824    public String getSymbolID()
825    {
826        return _symbolID;
827    }
828
829    /**
830     * Unique ID of the Symbol. For client use.
831     *
832     * @return
833     */
834    public String getUUID()
835    {
836        return _UUID;
837    }
838
839    /**
840     * Unique ID of the Symbol. For client use.
841     *
842     * @param ID
843     */
844    public void setUUID(String ID)
845    {
846        _UUID = ID;
847    }
848
849    /**
850     * Sets the Symbol ID for the symbol. Should be a 15 character string from
851     * the milstd.
852     *
853     * @param value
854     * @throws RendererException
855     */
856    public void setSymbolID(String value)
857    {
858
859        String current = _symbolID;
860
861        try
862        {
863            //set symbolID
864            if (value != null && !value.equals("") && !current.equals(value))
865            {
866                _symbolID = value;
867            }
868
869            //if hostile and specific TG, need to set 'N' to "ENY"
870            if (SymbolUtilities.getAffiliation(value) == 'H')
871            {
872                String basicID = SymbolUtilities.getBasicSymbolID(value);
873                if (SymbolUtilities.isObstacle(basicID) || //any obstacle
874                        basicID.equals("G*M*NZ----****X") ||//ground zero
875                        basicID.equals("G*M*NEB---****X") ||//biological
876                        basicID.equals("G*M*NEC---****X"))//chemical )
877                {
878                    this.setModifier(ModifiersTG.N_HOSTILE, "ENY");
879                }
880            }
881
882        }// End try
883        catch (Exception e)
884        {
885            // Log Error
886            ErrorLogger.LogException("MilStdSymbol", "setSymbolID" + " - Did not fall under TG or FE", e);
887        }
888    }   // End set SymbolID
889    private boolean _wasClipped=false;
890    public void set_WasClipped(boolean value)
891    {
892        _wasClipped=value;
893    }
894    public boolean get_WasClipped()
895    {
896        return _wasClipped;
897    }
898
899    /**
900     * Determines if the symbol has integral or modifier/amplifier text that would
901     * be impacted if the maps is zoomed in or out after initial draw.
902     * @return 0=not sensitive, 1=slightly little zoom in sensitive, 2=zoom in sensitive, 3=zoom in/out sensitive
903     */
904    public int isTextScaleSensitive()
905    {
906        ArrayList<ShapeInfo> modifiers = this.getModifierShapes();
907        if(_Properties == null)
908            return 0;//no scale sensitive text
909        if (_Properties.size()==0)
910            return 0;
911        else if(_symbolID.startsWith("G"))
912        {
913            String id = SymbolUtilities.getBasicSymbolID(_symbolID);
914            SymbolDef sd = SymbolDefTable.getInstance().getSymbolDef(id, this.getSymbologyStandard());
915            if(sd != null)
916            {
917                int dr = sd.getDrawCategory();
918
919                switch (dr)
920                {
921                    case SymbolDef.DRAW_CATEGORY_ARROW:
922                        if(_Properties.indexOfKey(ModifiersTG.W_DTG_1) >= 0 ||
923                                _Properties.indexOfKey(ModifiersTG.W1_DTG_2) >= 0)
924                            return 3;
925                        else
926                            return 0;
927
928                    case SymbolDef.DRAW_CATEGORY_LINE://Linear Targets (2407##)
929                        if(id.startsWith("G*F*LT"))
930                        {
931                            if(_Properties.indexOfKey(ModifiersTG.T1_UNIQUE_DESIGNATION_2) >= 0)
932                                return 3;
933                            else if(_Properties.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0)
934                                return 2;
935                            else
936                                return 0;
937                        }
938                        break;
939
940                    case SymbolDef.DRAW_CATEGORY_RECTANGULAR_PARAMETERED_AUTOSHAPE:
941                    case SymbolDef.DRAW_CATEGORY_CIRCULAR_PARAMETERED_AUTOSHAPE:
942                        if(modifiers != null && modifiers.size() > 1)
943                            return 3;
944                        else
945                            return 0;
946
947                    default:
948                        break;
949                }
950            }
951
952            switch (id)
953            {
954
955                //A Little Zoom in sensitive (1)
956                case "G*G*GLP---****X"://Phase line, only 5% sensitive
957                case "G*G*DLF---****X"://Forward Edge of Battle, only 5% sensitive
958                case "G*S*LCM---****X"://Moving Convoy
959                case "G*S*LCH---****X"://Halted Convoy
960                    return 1;
961
962                //Zoom in sensitive (2)
963                case "G*G*GLL---****X"://Light Line
964                case "G*G*OLF---****X"://Final Coordination Line
965                case "G*G*OLL---****X"://Limit of Advance
966                case "G*G*OLT---****X"://Line of Departure
967                case "G*G*OLC---****X"://Line of Departure / Line of Contact
968                case "G*G*OLP---****X"://Probable Line of Deployment
969                case "G*G*SLB---****X"://Bridgehead Line
970                case "G*G*SLH---****X"://Holding Line
971                case "G*G*SLR---****X"://Release Line
972                case "G*G*SAN---****X"://Named Area of Interest Line (NAI)
973                case "G*S*LRM---****X"://Main Supply Route (MSR)
974                case "G*S*LRO---****X"://One Way Traffic
975                case "G*S*LRW---****X"://Two Way Traffic
976                case "G*S*LRT---****X"://Alternating Traffic
977                case "G*S*LRA---****X"://Alternate Supply Route (ASR)
978                    return 2;
979                case "G*G*GLF---****X"://FLOT
980                case "G*G*GLC---****X"://LOC
981                    if(SymbolUtilities.getAffiliation(_symbolID) == 'H')
982                        return 2;
983                    else
984                        return 1;
985
986                    //Very Zoom in/out sensitive (multi-line text) (3)
987                    //friendly and more than 1 text
988                    //Hostile and more than 3 text assuming ENY is present
989                case "G*G*GLB---****X"://boundary line
990                    if(_Properties.indexOfKey(ModifiersTG.T_UNIQUE_DESIGNATION_1) >= 0 ||
991                            _Properties.indexOfKey(ModifiersTG.T1_UNIQUE_DESIGNATION_2) >= 0)
992                        return 3;
993                    else
994                        return 0;
995
996
997                case "G*GPGAY---****X"://Limited Access Area if sector 1 modifier present
998                    if(_Properties.indexOfKey(ModifiersTG.H_ADDITIONAL_INFO_1) >= 0)
999                        return 3;
1000                    else
1001                        return 0;
1002
1003
1004                    //Labels all contained in area but can drift away from each-other or overlap
1005                case "G*G*GAG---****X": //Generic
1006                case "G*G*AAH---****X": //High-Density Airspace Control Zone
1007                case "G*G*AAR---****X": //Restricted Operations Zone (ROZ)
1008                case "G*G*AAM---****X": //Missile Engagement Zone (MEZ)
1009                case "G*G*AAML--****X": //Low (Altitude) Missile Engagement Zone (LOMEZ)
1010                case "G*G*AAMH--****X": //High (Altitude) Missile Engagement Zone (HIMEZ)
1011                case "G*G*AAF---****X": //Short Range Air Defense Engagement Zone (SHORADEZ)
1012                case "G*G*AAW---****X": //Weapons Free Zone
1013                case "G*F*ACAI--****X": //Airspace Coordination Area (ACA) - Irregular
1014                case "G*F*ACFI--****X": //Free Fire Area (FFA) - Irregular
1015                case "G*F*ACNI--****X": //No Fire Area (NFA) - Irregular
1016                case "G*F*ACRI--****X": //Restricted Fire Area (RFA) - Irregular
1017                case "G*F*ATS---****X": //Smoke
1018                case "G*F*ACSI--****X"://Fire Support Area - Irregular
1019                case "G*F*AZII--****X": //Artillery Target Intelligence Zone (ATI), - Irregular
1020                case "G*F*AZXI--****X": //Call For Fire Zone (CFFZ) - Irregular
1021                case "G*F*AZCI--****X": //Censor Zone, - Irregular
1022                case "G*F*AZFI--****X": //Critical Friendly Zone (CFZ), - Irregular
1023                case "G*F*ACDI--****X": //Dead Space Area (DA), - Irregular
1024                case "G*F*ACEI--****X": //Sensor Zone, Irregular
1025                case "G*F*ACBI--****X": //Target Build-up Area, Irregular
1026                case "G*F*ACVI--****X": //Target Value Area, Irregular
1027                case "G*F*ACZI--****X": //Zone of Responsibility, Irregular
1028                    //case "G*F*ACT---****X": //Terminally Guided Munition Footprint (TGMF)
1029                case "G*F*AKBI--****X": //Blue Kill Box, Irregular
1030                case "G*F*AKPI--****X": //Purple Kill Box, Irregular
1031                case "G*M*OGF---****X": //Obstacle Free Zone
1032                case "G*M*BCL---****X": //Lane
1033                case "G*S*AD----****X": //Detainee Holding Area
1034                case "G*S*AE----****X": //Enemy Prisoner of War Holding Area
1035                case "G*S*AR----****X": //Forward Arming and Refueling Point (FARP)
1036                case "G*S*AH----****X": //Refugee Holding Area
1037                case "G*S*ASR---****X": //Regimental Support Area (RSA)
1038                case "G*G*ALC---****X": //Air Corridor
1039                case "G*G*ALM---****X": //MRR
1040                case "G*G*ALS---****X": //SAAFR
1041                case "G*G*ALU---****X": //UA
1042                case "G*G*ALL---****X": //LLTR
1043                    if(modifiers != null && modifiers.size()>1)
1044                        return 3;
1045                    else
1046                        return 0;
1047
1048                case "G*F*LCF---****X"://Fire Support Coordination Line (FSCL)
1049                case "G*F*LCC---****X"://Coordinated Fire Line (CFL)
1050                case "G*F*LCN---****X"://No Fire Line
1051                case "G*F*LCR---****X"://Restrictive Fire Line
1052                    if(_Properties.indexOfKey(ModifiersTG.W_DTG_1) >= 0 ||
1053                            _Properties.indexOfKey(ModifiersTG.W1_DTG_2) >= 0)
1054                        return 3;
1055                    else
1056                        return 2;
1057
1058                case "G*F*LCM---****X"://Munition Flight Path
1059                case "G*T*L-----****X"://Delay
1060                    if(_Properties.indexOfKey(ModifiersTG.W_DTG_1) >= 0 ||
1061                            _Properties.indexOfKey(ModifiersTG.W1_DTG_2) >= 0)
1062                        return 2;
1063                    else
1064                        return 0;
1065
1066
1067                default://No Scale Sensitive text
1068                    return 0;
1069            }
1070        }
1071
1072        return 0;
1073    }
1074
1075    /**
1076     * Checks if the symbol has features that make it scale aware and would require a refresh
1077     * on zooming in or out.
1078     * @return 0=No,1=arrowheads,2=decoratedLines,3=patternFills
1079     */
1080    public int isSymbolScaleSensitive()
1081    {
1082        //return SymbolUtilities.isScaleAware(this._symbolID);
1083        String id = SymbolUtilities.getBasicSymbolID(_symbolID);
1084
1085        switch (id)
1086        {
1087            //ArrowHead or smaller detail
1088            case "G*G*OAF---****X"://Attack By Fire
1089            case "G*G*OAS---****X"://Support By Fire
1090            case "G*G*GAS---****X"://Search Area/Reconnaissance Area
1091            case "G*G*SLA---****X"://Ambush
1092            case "G*G*OLKA--****X"://Airborne/Aviation
1093            case "G*G*OLKGM-****X"://Direction of Main attack
1094            case "G*G*OLKGS-****X"://Direction of Supporting attack
1095            case "G*F*LT----****X"://Linear Target
1096            case "G*F*LTS---****X"://Linear Smoke Target
1097            case "G*F*LTF---****X"://Final Protective Fire
1098            case "G*T*T-----****X"://Disrupt
1099            case "G*M*OET---****X"://Turn
1100            case "G*M*BDE---****X"://Obstacle Bypass Easy
1101            case "G*M*BDD---****X"://Obstacle Bypass Difficult
1102            case "G*M*BDI---****X"://Obstacle Bypass Impossible
1103            case "G*M*BCB---****X"://Bridge or Gap?
1104            case "G*M*BCA---****X"://Assault Crossing?
1105            case "G*M*OS----****X"://Abatis?
1106            case "G*M*BCL---****X"://?Lane?
1107            case "G*M*BCF---****X"://Ferry
1108            case "G*M*BCR---****X"://Raft Site
1109            case "G*T*H-----****X"://Breach
1110            case "G*T*Y-----****X"://Bypass
1111            case "G*T*C-----****X"://Canalize
1112            case "G*T*X-----****X"://Clear
1113            case "G*T*L-----****X"://Delay
1114            case "G*M*OED---****X"://Disrupt
1115            case "G*T*A-----****X"://Follow and Assume
1116            case "G*T*AS----****X"://Follow and Support
1117                //case "G*T*O-----****X"://Occupy, details relative to size
1118                //case "G*T*P-----****X"://Penetrate, details relative to size
1119                //case "G*T*R-----****X"://Relief in Place (RIP), details relative to size
1120                //case "G*T*M-----****X"://Retire/Retirement, details relative to size
1121            case "G*T*S-----****X"://Secure, details relative to size
1122            case "G*T*UC----****X"://Cover, details relative to size
1123            case "G*T*UG----****X"://Guard, details relative to size
1124            case "G*T*US----****X"://Screen, details relative to size
1125            case "G*T*Z-----****X"://Seize, details relative to size
1126            case "G*T*W-----****X"://Withdraw, details relative to size
1127            case "G*T*WP----****X"://Withdraw under pressure, details relative to size
1128                return 1;//arrowhead
1129
1130            //Decorated Lines
1131            case "G*G*GLF---****X"://FLOT
1132            case "G*G*GLC---****X"://Line of Contact
1133                //case 140500://?Principal Direction of Fire?
1134            case "G*G*GAF---****X"://Fortified Area
1135            case "G*G*SAE---****X"://Encirclement
1136            case "G*M*SP----****X"://Strong Point
1137            case "G*G*DABP--****X"://Battle Position Prepared (P) but not Occupied
1138            case "G*T*J-----****X"://Contain
1139            case "G*T*Q-----****X"://Retain
1140            case "G*M*OGB---****X"://Obstacle Belt
1141            case "G*M*OGL---****X"://Obstacle Line
1142            case "G*M*OGZ---****X"://Obstacle Zone
1143            case "G*M*OGF---****X"://Obstacle Free Area
1144            case "G*M*OGR---****X"://Obstacle Restricted Area
1145                //case "G*MPOEF---****X"://Fix?
1146            case "G*G*PY----****X"://Mined Area, Fenced
1147            case "G*M*OHO---****X"://Overhead Wire
1148            case "G*M*OADU--****X"://Ditch Under Construction
1149            case "G*M*OADC--****X"://Ditch Completed
1150            case "G*M*OAR---****X"://Ditch Reinforced
1151            case "G*M*OAW---****X"://Antitank Wall
1152            case "G*M*OWU---****X"://Wire Obstacles, Unspecified
1153            case "G*M*OWS---****X"://Wire Obstacles, Single Fence
1154            case "G*M*OWD---****X"://Wire Obstacles, Double Fence
1155            case "G*M*OWA---****X"://Wire Obstacles, Double Apron Fence
1156            case "G*M*OWL---****X"://Wire Obstacles, Low Wire Fence
1157            case "G*M*OWH---****X"://Wire Obstacles, High Wire Fence
1158            case "G*M*OWCS--****X"://Wire Obstacles, Single Concertina
1159            case "G*M*OWCD--****X"://Wire Obstacles, Double Strand Concertina
1160            case "G*M*OWCT--****X"://Wire Obstacles, Triple Strand Concertina
1161            case "G*M*SL----****X"://Fortified Line
1162            case "G*S*LCM---****X"://Moving Convoy
1163            case "G*S*LCH---****X"://Halted Convoy
1164            case "G*S*LRO---****X"://MSR One Way Traffic
1165            case "G*S*LRW---****X"://MSR Two Way Traffic
1166            case "G*S*LRT---****X"://MSR Alternating Traffic
1167            case "G*T*F-----****X"://Fix
1168                //case 341500://Isolate, most detail contained inside
1169                //case 342600://Cordon and Knock, most detail contained inside
1170                //case 342700://Cordon and Search, most detail contained inside
1171                return 2;//decoration
1172
1173            //Areas with Pattern Fill
1174            case "G*G*GAY---****X"://Limited Access Area
1175            case "G*G*AAW---****X"://Weapons Free Zone
1176            case "G*F*ACNI--****X"://NFA Irregular
1177            case "G*F*ACNR--****X"://NFA Rectangular
1178            case "G*F*ACNC--****X"://NFA Circular
1179            case "G*M*NB----****X"://Bio Contaminated Area
1180            case "G*M*NC----****X"://Chem Contaminated Area
1181            case "G*M*NR----****X"://Rad Contaminated Area
1182                if(!this.getUseFillPattern())
1183                    return 3;//pattern fill
1184                else
1185                    return 0;
1186            default:
1187                return 0;
1188        }
1189    }
1190}