001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005package armyc2.c5isr.JavaLineArray;
006
007import java.util.ArrayList;
008import java.util.Arrays;
009
010import armyc2.c5isr.JavaTacticalRenderer.TGLight;
011import armyc2.c5isr.renderer.utilities.ErrorLogger;
012import armyc2.c5isr.renderer.utilities.RendererException;
013import armyc2.c5isr.renderer.utilities.RendererSettings;
014import armyc2.c5isr.renderer.utilities.Color;
015import armyc2.c5isr.renderer.utilities.IPointConversion;
016import armyc2.c5isr.graphics2d.Area;
017import armyc2.c5isr.graphics2d.BasicStroke;
018import armyc2.c5isr.graphics2d.Polygon;
019import armyc2.c5isr.graphics2d.Rectangle2D;
020import armyc2.c5isr.graphics2d.Shape;
021
022/**
023 * Class to process the pixel arrays
024 */
025public final class arraysupport {
026
027    private static final double maxLength = 100;
028    private static final double minLength = 2.5;    //was 5
029    private static double dACP = 0;
030    private static final String _className = "arraysupport";
031
032//    protected static void setMinLength(double value)
033//    {
034//        minLength=value;
035//    }
036    private static void FillPoints(POINT2[] pLinePoints,
037            int counter,
038            ArrayList<POINT2> points) {
039        points.clear();
040        for (int j = 0; j < counter; j++) {
041            points.add(pLinePoints[j]);
042        }
043    }
044
045    /**
046     * This is the interface function to CELineArray from clsRenderer2 for
047     * non-channel types
048     *
049     * @param pts the client points
050     * @param shapes the symbol ShapeInfo objects
051     * @param clipBounds the rectangular clipping bounds
052     */
053    public static ArrayList<POINT2> GetLineArray2(TGLight tg,
054            ArrayList<POINT2> pts,
055            ArrayList<Shape2> shapes,
056            Rectangle2D clipBounds,
057            IPointConversion converter) {
058
059        ArrayList<POINT2> points = null;
060        try {
061            POINT2 pt = null;
062            POINT2[] pLinePoints2 = null;
063            POINT2[] pLinePoints = null;
064            int vblSaveCounter = pts.size();
065            //get the count from countsupport
066            int j = 0;
067            if (pLinePoints2 == null || pLinePoints2.length == 0)//did not get set above
068            {
069                pLinePoints = new POINT2[vblSaveCounter];
070                for (j = 0; j < vblSaveCounter; j++) {
071                    pt = (POINT2) pts.get(j);
072                    pLinePoints[j] = new POINT2(pt.x, pt.y, pt.style);
073                }
074            }
075            //get the number of points the array will require
076            int vblCounter = countsupport.GetCountersDouble(tg, vblSaveCounter, pLinePoints, clipBounds);
077
078            //resize pLinePoints and fill the first vblSaveCounter elements with the original points
079            if (vblCounter > 0) {
080                pLinePoints = new POINT2[vblCounter];
081            } else {
082                shapes = null;
083                return null;
084            }
085
086            lineutility.InitializePOINT2Array(pLinePoints);
087
088            //safeguards added 2-17-11 after CPOF client was allowed to add points to autoshapes
089            if (vblSaveCounter > pts.size()) {
090                vblSaveCounter = pts.size();
091            }
092            if (vblSaveCounter > pLinePoints.length) {
093                vblSaveCounter = pLinePoints.length;
094            }
095
096            for (j = 0; j < vblSaveCounter; j++) {
097                pt = (POINT2) pts.get(j);
098                pLinePoints[j] = new POINT2(pt.x, pt.y, pt.style);
099            }
100            //we have to adjust the autoshapes because they are instantiating with fewer points
101            points = GetLineArray2Double(tg, pLinePoints, vblCounter, vblSaveCounter, shapes, clipBounds, converter);
102
103        } catch (Exception exc) {
104            ErrorLogger.LogException(_className, "GetLineArray2",
105                    new RendererException("GetLineArray2 " + Integer.toString(tg.get_LineType()), exc));
106
107        }
108        return points;
109        //the caller can get points
110    }
111
112    /**
113     * A function to calculate the points for FORTL
114     *
115     * @param pLinePoints OUT - the points arry also used for the return points
116     * @param vblSaveCounter the number of client points
117     * @return
118     */
119    private static int GetFORTLPointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
120        int nCounter = 0;
121        try {
122            int j = 0, k = 0, bolVertical = 0;
123            int lCount = 0;
124            final double dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
125            ref<double[]> m = new ref();
126            POINT2[] pSpikePoints = null;
127            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
128
129            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
130            int numGlyphs = 0;
131            final double dGlyphSize = dIncrement / 2;
132
133            pSpikePoints = new POINT2[lCount];
134            lineutility.InitializePOINT2Array(pSpikePoints);
135
136            for (j = 0; j < vblSaveCounter - 1; j++) {
137                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
138                double dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
139                if (dLengthSegment / dIncrement < 1) {
140                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
141                    nCounter++;
142                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
143                    nCounter++;
144                    continue;
145                }
146                numGlyphs = (int) (dLengthSegment / dIncrement);
147                final double dSegIncrement = (dLengthSegment / numGlyphs);
148
149                //for (k = 0; k < dLengthSegment / 20 - 1; k++)
150                for (k = 0; k < numGlyphs; k++) {
151                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement, 0);
152                    nCounter++;
153                    //pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement - 10, 0);
154                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dSegIncrement - dSegIncrement / 2, 0);
155                    nCounter++;
156                    pt0 = new POINT2(pSpikePoints[nCounter - 1]);
157                    //pt1 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], 10);
158                    pt1 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSegIncrement / 2);
159                    //the spikes
160                    if (pLinePoints[j].x > pLinePoints[j + 1].x) {
161                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dGlyphSize);
162                        nCounter++;
163                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 3, dGlyphSize);
164                        nCounter++;
165                    }
166                    if (pLinePoints[j].x < pLinePoints[j + 1].x) {
167                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dGlyphSize);
168                        nCounter++;
169                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 2, dGlyphSize);
170                        nCounter++;
171                    }
172                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
173                        if (pLinePoints[j].y < pLinePoints[j + 1].y) {
174                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 1, dGlyphSize);
175                            nCounter++;
176                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 1, dGlyphSize);
177                            nCounter++;
178                        }
179                        if (pLinePoints[j].y > pLinePoints[j + 1].y) {
180                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 0, dGlyphSize);
181                            nCounter++;
182                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt1, 0, dGlyphSize);
183                            nCounter++;
184                        }
185                    }
186                    //pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], 10, 0);
187                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], dSegIncrement / 2, 0);
188                    nCounter++;
189                }//end for k
190                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
191                nCounter++;
192            }//end for j
193            for (j = 0; j < nCounter; j++) {
194                pLinePoints[j] = new POINT2(pSpikePoints[j]);
195            }
196
197            return nCounter;
198        } catch (Exception exc) {
199            ErrorLogger.LogException(_className, "GetFORTLPointsDouble",
200                    new RendererException("GetFORTLPointsDouble " + Integer.toString(tg.get_LineType()), exc));
201        }
202        return nCounter;
203    }
204
205    private static int GetATWallPointsDouble2(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
206        int nCounter = 0;
207        try {
208            int j = 0, k = 0;
209            int lCount = 0;
210            double dLengthSegment = 0, dIncrement = 0;
211            POINT2[] pSpikePoints = null;
212            POINT2 pt0;
213            double dSpikeSize = 0;
214            int limit = 0, numSpikes = 0;;
215
216            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
217            pSpikePoints = new POINT2[lCount];
218            lineutility.InitializePOINT2Array(pSpikePoints);
219            pSpikePoints[nCounter++] = new POINT2(pLinePoints[0]);
220            for (j = 0; j < vblSaveCounter - 1; j++) {
221                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
222                dSpikeSize = arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
223                dIncrement = 2 * dSpikeSize;
224//  diagnostic
225                numSpikes = (int) Math.round((dLengthSegment - dSpikeSize) / dIncrement);
226                dIncrement = dLengthSegment / numSpikes;
227
228                //limit = (int) (dLengthSegment / dIncrement) - 1;
229                limit = numSpikes - 1;
230//                if (limit < 1) {
231//                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
232//                    nCounter++;
233//                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
234//                    nCounter++;
235//                    continue;
236//                }
237//  end diagnostic                
238                for (k = -1; k < limit; k++)//was k=0 to limit
239                {
240                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - (dSpikeSize * 3), 0);
241                    nCounter++;
242
243                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSpikeSize / 2);
244
245                    //the spikes
246                    if (pLinePoints[j].x > pLinePoints[j + 1].x) //extend above the line
247                    {
248                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 2, dSpikeSize);
249                    }
250                    if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend below the line
251                    {
252                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 3, dSpikeSize);
253                    }
254                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
255                        pSpikePoints[nCounter] = new POINT2(pt0);
256                        if (pLinePoints[j].y < pLinePoints[j + 1].y) //extend left of line
257                        {
258                            pSpikePoints[nCounter].x = pt0.x - dSpikeSize;
259                        } else //extend right of line
260                        {
261                            pSpikePoints[nCounter].x = pt0.x + dSpikeSize;
262                        }
263                    }
264                    nCounter++;
265
266                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dSpikeSize, 0);
267                    nCounter++;
268                }
269                //use the original line point for the segment end point
270                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
271                pSpikePoints[nCounter].style = 0;
272                nCounter++;
273            }
274
275            for (j = 0; j < nCounter; j++) {
276                pLinePoints[j] = new POINT2(pSpikePoints[j]);
277            }
278
279        } catch (Exception exc) {
280            ErrorLogger.LogException(_className, "GetATWallPointsDouble",
281                    new RendererException("GetATWallPointsDouble", exc));
282        }
283        return nCounter;
284    }
285
286    public static int GetInsideOutsideDouble2(POINT2 pt0,
287            POINT2 pt1,
288            POINT2[] pLinePoints,
289            int vblCounter,
290            int index,
291            int lineType) {
292        int nDirection = 0;
293        try {
294            ref<double[]> m = new ref();
295            ref<double[]> m0 = new ref();
296
297            double b0 = 0;
298            double b2 = 0;
299
300            double b = 0;
301            double X0 = 0;      //segment midpoint X value
302            double Y0 = 0;      //segment midpoint Y value
303            double X = 0;       //X value of horiz line from left intercept with current segment
304            double Y = 0;       //Y value of vertical line from top intercept with current segment
305            int nInOutCounter = 0;
306            int j = 0, bolVertical = 0;
307            int bolVertical2 = 0;
308            int nOrientation = 0; //will use 0 for horiz line from left, 1 for vertical line from top
309
310            POINT2 pt2 = new POINT2();
311            //end declarations. will use this to determine the direction
312
313            //slope of the segment
314            bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m0);
315            if (m0.value == null) {
316                return 0;
317            }
318            //get the midpoint of the segment
319            X0 = (pt0.x + pt1.x) / 2;
320            Y0 = (pt0.y + pt1.y) / 2;
321
322            //slope is not too small or is vertical, use left to right
323            if (Math.abs(m0.value[0]) >= 1 || bolVertical == 0) {
324                nOrientation = 0;       //left to right orientation
325                for (j = 0; j < vblCounter - 1; j++) {
326                    if (index != j) {
327                        //if ((pLinePoints[j].y <= Y0 && pLinePoints[j + 1].y >= Y0) ||
328                        //      (pLinePoints[j].y >= Y0 && pLinePoints[j + 1].y <= Y0)) 
329                        if ((pLinePoints[j].y < Y0 && pLinePoints[j + 1].y > Y0)
330                                || (pLinePoints[j].y > Y0 && pLinePoints[j + 1].y < Y0)
331                                || (pLinePoints[j].y < Y0 && pLinePoints[j + 1].y == Y0)
332                                || (pLinePoints[j].y == Y0 && pLinePoints[j + 1].y < Y0)) {
333                            bolVertical2 = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
334                            if (bolVertical2 == 1 && m.value[0] == 0) //current segment is horizontal, this should not happen
335                            {   //counter unaffected
336                                nInOutCounter++;
337                                nInOutCounter--;
338                            }
339                            //current segment is vertical, it's x value must be to the left
340                            //of the current segment X0 for the horiz line from the left to cross
341                            if (bolVertical2 == 0) {
342                                if (pLinePoints[j].x < X0) {
343                                    nInOutCounter++;
344                                }
345                            }
346
347                            //current segment is not horizontal and not vertical
348                            if (m.value[0] != 0 && bolVertical2 == 1) {
349                                //get the X value of the intersection between the horiz line
350                                //from the left and the current segment
351                                //b=Y0;
352                                b = pLinePoints[j].y - m.value[0] * pLinePoints[j].x;
353                                X = (Y0 - b) / m.value[0];
354                                if (X < X0) //the horizontal line crosses the segment
355                                {
356                                    nInOutCounter++;
357                                }
358                            }
359
360                        }       //end if
361                    }
362
363                }       //end for
364            } //end if
365            else //use top to bottom to get orientation
366            {
367                nOrientation = 1;       //top down orientation
368                for (j = 0; j < vblCounter - 1; j++) {
369                    if (index != j) {
370                        //if ((pLinePoints[j].x <= X0 && pLinePoints[j + 1].x >= X0) ||
371                        //  (pLinePoints[j].x >= X0 && pLinePoints[j + 1].x <= X0)) 
372                        if ((pLinePoints[j].x < X0 && pLinePoints[j + 1].x > X0)
373                                || (pLinePoints[j].x > X0 && pLinePoints[j + 1].x < X0)
374                                || (pLinePoints[j].x < X0 && pLinePoints[j + 1].x == X0)
375                                || (pLinePoints[j].x == X0 && pLinePoints[j + 1].x < X0)) {
376                            bolVertical2 = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
377                            if (bolVertical2 == 0) //current segment is vertical, this should not happen
378                            {   //counter unaffected
379                                nInOutCounter++;
380                                nInOutCounter--;
381                            }
382                            //current segment is horizontal, it's y value must be above
383                            //the current segment Y0 for the horiz line from the left to cross
384                            if (bolVertical2 == 1 && m.value[0] == 0) {
385                                if (pLinePoints[j].y < Y0) {
386                                    nInOutCounter++;
387                                }
388                            }
389
390                            //current segment is not horizontal and not vertical
391                            if (m.value[0] != 0 && bolVertical2 == 1) {
392                                //get the Y value of the intersection between the vertical line
393                                //from the top and the current segment
394                                b = pLinePoints[j].y - m.value[0] * pLinePoints[j].x;
395                                Y = m.value[0] * X0 + b;
396                                if (Y < Y0) //the vertical line crosses the segment
397                                {
398                                    nInOutCounter++;
399                                }
400                            }
401                        }       //end if
402                    }
403                }       //end for
404            }
405
406            switch (nInOutCounter % 2) {
407                case 0:
408                    if (nOrientation == 0) {
409                        nDirection = lineutility.extend_left;
410                    } else {
411                        nDirection = lineutility.extend_above;
412                    }
413                    break;
414                case 1:
415                    if (nOrientation == 0) {
416                        nDirection = lineutility.extend_right;
417                    } else {
418                        nDirection = lineutility.extend_below;
419                    }
420                    break;
421                default:
422                    break;
423            }
424            //reverse direction for ICING
425            if (lineType == TacticalLines.ICING) {
426                nDirection = lineutility.reverseDirection(nDirection);
427            }
428        } catch (Exception exc) {
429            ErrorLogger.LogException(_className, "GetInsideOutsideDouble2",
430                    new RendererException("GetInsideOutsideDouble2", exc));
431        }
432        return nDirection;
433    }
434
435    /**
436     * BELT and others
437     *
438     * @param pLinePoints
439     * @param vblSaveCounter
440     * @return
441     */
442    protected static int GetZONEPointsDouble2(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
443        int nCounter = 0;
444        try {
445            int lineType = tg.get_LineType();
446            int j = 0, k = 0, n = 0;
447            int lCount = 0;
448            double dLengthSegment = 0;
449            POINT2 pt0 = new POINT2(pLinePoints[0]), pt1 = null, pt2 = null, pt3 = null;
450            POINT2[] pSpikePoints = null;
451            int nDirection = 0;
452            double dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
453
454            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
455            pSpikePoints = new POINT2[lCount];
456            lineutility.InitializePOINT2Array(pSpikePoints);
457            double remainder = 0;
458            for (j = 0; j < vblSaveCounter - 1; j++) {
459                pt1 = new POINT2(pLinePoints[j]);
460                pt2 = new POINT2(pLinePoints[j + 1]);
461                //get the direction for the spikes
462                nDirection = GetInsideOutsideDouble2(pt1, pt2, pLinePoints, vblSaveCounter, (int) j, lineType);
463                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
464                //reverse the direction for those lines with inward spikes
465                if (dLengthSegment < dIncrement) {
466                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
467                    nCounter++;
468                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
469                    nCounter++;
470                    continue;
471                }
472                switch (lineType) {
473                    case TacticalLines.OBSAREA:
474                    case TacticalLines.OBSFAREA:
475                        nDirection = lineutility.reverseDirection(nDirection);
476                        break;
477                    default:
478                        break;
479                }
480                n = (int) (dLengthSegment / dIncrement);
481                remainder = dLengthSegment - n * dIncrement;
482                for (k = 0; k < n; k++) {
483                    if (k > 0) {
484                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - remainder / 2, 0);//was +0
485                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dIncrement / 2 - remainder / 2, 0);//was -10
486                    } else {
487                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement, 0);//was +0
488                        pSpikePoints[nCounter++] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dIncrement / 2, 0);//was -10
489                    }
490
491                    switch (lineType) {
492                        case TacticalLines.OBSAREA:
493                        case TacticalLines.OBSFAREA:
494                        case TacticalLines.ZONE:
495                        case TacticalLines.ENCIRCLE:
496                            pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dIncrement / 4);
497                            break;
498                        case TacticalLines.STRONG:
499                        case TacticalLines.FORT_REVD:
500                        case TacticalLines.FORT:
501                            pt0 = new POINT2(pSpikePoints[nCounter - 1]);
502                            break;
503                        default:
504                            break;
505                    }
506
507                    pSpikePoints[nCounter++] = lineutility.ExtendDirectedLine(pt1, pt2, pt0, nDirection, dIncrement / 2);
508                    //nCounter++;
509                    switch (lineType) {
510                        case TacticalLines.OBSAREA:
511                        case TacticalLines.OBSFAREA:
512                        case TacticalLines.ZONE:
513                        case TacticalLines.ENCIRCLE:
514                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dIncrement / 2, 0);
515                            break;
516                        case TacticalLines.STRONG:
517                            pSpikePoints[nCounter] = new POINT2(pSpikePoints[nCounter - 2]);
518                            break;
519                        case TacticalLines.FORT_REVD:
520                        case TacticalLines.FORT:
521                            pt3 = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dIncrement / 2, 0);
522                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pt1, pt2, pt3, nDirection, dIncrement / 2);
523                            nCounter++;
524                            pSpikePoints[nCounter] = new POINT2(pt3);
525                            break;
526                        default:
527                            break;
528                    }
529                    //}
530                    nCounter++;
531                    //diagnostic
532                    if (lineType == TacticalLines.ENCIRCLE) {
533                        pSpikePoints[nCounter++] = new POINT2(pSpikePoints[nCounter - 4]);
534                    }
535                }//end for k
536                pSpikePoints[nCounter++] = new POINT2(pLinePoints[j + 1]);
537                //nCounter++;
538            }//end for j
539            for (j = 0; j < nCounter; j++) {
540                if (lineType == (long) TacticalLines.OBSAREA) {
541                    pSpikePoints[j].style = 11;
542                }
543            }
544            if (lineType == (long) TacticalLines.OBSAREA) {
545                pSpikePoints[nCounter - 1].style = 12;
546            } else {
547                if (nCounter > 0) {
548                    pSpikePoints[nCounter - 1].style = 5;
549                }
550            }
551
552            for (j = 0; j < nCounter; j++) {
553                pLinePoints[j] = new POINT2(pSpikePoints[j]);
554                if (j == nCounter - 1) {
555                    if (lineType != (long) TacticalLines.OBSAREA) {
556                        pLinePoints[j].style = 5;
557                    }
558                }
559            }
560
561        } catch (Exception exc) {
562            ErrorLogger.LogException(_className, "GetZONEPointsDouble2",
563                    new RendererException("GetZONEPointsDouble2", exc));
564        }
565        return nCounter;
566    }
567
568    private static boolean IsTurnArcReversed(POINT2[] pPoints) {
569        try {
570            if (pPoints.length < 3) {
571                return false;
572            }
573
574            POINT2[] ptsSeize = new POINT2[2];
575            ptsSeize[0] = new POINT2(pPoints[0]);
576            ptsSeize[1] = new POINT2(pPoints[1]);
577            lineutility.CalcClockwiseCenterDouble(ptsSeize);
578            double d = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[2]);
579
580            ptsSeize[0] = new POINT2(pPoints[1]);
581            ptsSeize[1] = new POINT2(pPoints[0]);
582            lineutility.CalcClockwiseCenterDouble(ptsSeize);
583            double dArcReversed = lineutility.CalcDistanceDouble(ptsSeize[0], pPoints[2]);
584
585            ptsSeize = null;
586            if (dArcReversed > d) {
587                return true;
588            } else {
589                return false;
590            }
591        } catch (Exception exc) {
592            ErrorLogger.LogException(_className, "IsTurnArcReversed",
593                    new RendererException("IsTurnArcReversed", exc));
594        }
595        return false;
596    }
597
598    private static void GetIsolatePointsDouble(POINT2[] pLinePoints,
599            int lineType,
600            IPointConversion converter) {
601        try {
602            POINT2 pt0 = new POINT2(pLinePoints[0]), pt1 = new POINT2(pLinePoints[1]), pt2 = new POINT2(pLinePoints[0]);
603            if (pt0.x == pt1.x && pt0.y == pt1.y) {
604                pt1.x += 1;
605            }
606
607            POINT2 C = new POINT2(), E = new POINT2();
608            int j = 0, k = 0, l = 0;
609            POINT2[] ptsArc = new POINT2[26];
610            POINT2[] midPts = new POINT2[7];
611            POINT2[] trianglePts = new POINT2[35];
612            POINT2[] pArrowPoints = new POINT2[3];
613            POINT2[] pArrowPoints2 = new POINT2[3];
614            double dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
615            double dLength = Math.abs(dRadius - 20);
616            if (dRadius < 40) {
617                dLength = dRadius / 1.5;
618            }
619
620            double d = lineutility.MBRDistance(pLinePoints, 2);
621            POINT2[] ptsSeize = new POINT2[2];
622            POINT2[] savepoints = new POINT2[3];
623            for (j = 0; j < 2; j++) {
624                savepoints[j] = new POINT2(pLinePoints[j]);
625            }
626
627            if (pLinePoints.length >= 3) {
628                savepoints[2] = new POINT2(pLinePoints[2]);
629            }
630
631            lineutility.InitializePOINT2Array(ptsArc);
632            lineutility.InitializePOINT2Array(midPts);
633            lineutility.InitializePOINT2Array(trianglePts);
634            lineutility.InitializePOINT2Array(pArrowPoints);
635            lineutility.InitializePOINT2Array(pArrowPoints2);
636            lineutility.InitializePOINT2Array(ptsSeize);
637
638            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
639            if (d / 7 > maxLength * DPIScaleFactor) {
640                d = 7 * maxLength * DPIScaleFactor;
641            }
642            if (d / 7 < minLength * DPIScaleFactor) {  //was minLength
643                d = 7 * minLength * DPIScaleFactor;    //was minLength
644            }
645            //change due to outsized arrow in 6.0, 11-3-10
646            if (d > 140 * DPIScaleFactor) {
647                d = 140 * DPIScaleFactor;
648            }
649            //calculation points for the SEIZE arrowhead
650            //for SEIZE calculations
651            POINT2[] ptsArc2 = new POINT2[26];
652            lineutility.InitializePOINT2Array(ptsArc2);
653
654            E.x = 2 * pt1.x - pt0.x;
655            E.y = 2 * pt1.y - pt0.y;
656            ptsArc[0] = new POINT2(pLinePoints[1]);
657            ptsArc[1] = new POINT2(E);
658            if(converter != null)
659            {
660                ptsArc[0] = new POINT2(pLinePoints[0]);
661                ptsArc[1] = new POINT2(pLinePoints[1]);
662            }
663
664            lineutility.ArcArrayDouble(ptsArc, 0, dRadius, lineType, converter);
665            for (j = 0; j < 26; j++) {
666                ptsArc[j].style = 0;
667                pLinePoints[j] = new POINT2(ptsArc[j]);
668                pLinePoints[j].style = 0;
669            }
670            if (lineType != TacticalLines.OCCUPY) {
671                lineutility.GetArrowHead4Double(ptsArc[24], ptsArc[25], (int) d / 7, (int) d / 7, pArrowPoints, 0);
672            } else {
673                lineutility.GetArrowHead4Double(ptsArc[24], ptsArc[25], (int) d / 7, (int) (1.75 * d) / 7, pArrowPoints, 0);
674            }
675
676            //second arrow
677            if(lineType == TacticalLines.CONTROL || lineType == TacticalLines.LOCATE)
678            {
679                lineutility.GetArrowHead4Double(ptsArc[1], ptsArc[0], (int) d / 7, (int) d / 7, pArrowPoints2, 0);
680            }
681
682            pLinePoints[25].style = 5;
683
684            switch (lineType) {
685                case TacticalLines.CORDONKNOCK:
686                case TacticalLines.CORDONSEARCH:
687                case TacticalLines.ISOLATE:
688                    if (dRadius > 100) {
689                        dLength = 0.8 * dRadius;
690                    }
691                    for (j = 1; j <= 23; j++) {
692                        if (j % 3 == 0) {
693                            midPts[k].x = pt0.x - (long) ((dLength / dRadius) * (pt0.x - ptsArc[j].x));
694                            midPts[k].y = pt0.y - (long) ((dLength / dRadius) * (pt0.y - ptsArc[j].y));
695                            midPts[k].style = 0;
696                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
697                            l++;
698                            trianglePts[l] = new POINT2(midPts[k]);
699                            l++;
700                            trianglePts[l] = new POINT2(ptsArc[j + 1]);
701                            trianglePts[l].style = 5;
702                            l++;
703                            k++;
704                        }
705                    }
706                    for (j = 26; j < 47; j++) {
707                        pLinePoints[j] = new POINT2(trianglePts[j - 26]);
708                    }
709                    pLinePoints[46].style = 5;
710                    for (j = 47; j < 50; j++) {
711                        pLinePoints[j] = new POINT2(pArrowPoints[j - 47]);
712                        pLinePoints[j].style = 0;
713                    }
714                    break;
715                case TacticalLines.DENY:
716                    if (dRadius > 100) {
717                        dLength = -0.2 * dRadius;
718                    }
719                    for (j = 1; j <= 23; j++) {
720                        if (j % 3 == 0) {
721                            //midPts[k].x = pt0.x + (long) ((dLength / dRadius) * (pt0.x - ptsArc[j].x));
722                            //midPts[k].y = pt0.y + (long) ((dLength / dRadius) * (pt0.y - ptsArc[j].y));
723
724                            // 1. Get the midpoint of each segment
725                            POINT2 start = new POINT2(ptsArc[j - 1]);
726                            POINT2 end = new POINT2(ptsArc[j + 1]);
727                            double midX = (start.x + end.x)/2;
728                            double midY = (start.y + end.y)/2;
729
730                            // 2. Calculate the direction vector from center to midpoint
731                            double dx = midX - pt0.x;
732                            double dy = midY - pt0.y;
733                            double distance = Math.sqrt(dx * dx + dy * dy);
734
735                            // 3. Normalize and scale to 120% of the radius
736                            double targetDistance = dRadius * 1.20;
737
738                            // Handle edge case: if midpoint is exactly at center, use start point for direction
739                            if (distance < 0.00001) {
740                                dx = start.x - pt0.x;
741                                dy = start.y - pt0.y;
742                                distance = Math.sqrt(dx * dx + dy * dy);
743                            }
744
745                            midPts[k].x = pt0.x + (dx / distance) * targetDistance;
746                            midPts[k].y = pt0.y + (dy / distance) * targetDistance;
747                            midPts[k].style = 0;
748                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
749                            l++;
750                            trianglePts[l] = new POINT2(midPts[k]);
751                            l++;
752                            trianglePts[l] = new POINT2(ptsArc[j + 1]);
753                            trianglePts[l].style = 5;
754                            l++;
755                            k++;
756                        }
757                    }
758                    for (j = 26; j < 47; j++) {
759                        pLinePoints[j] = new POINT2(trianglePts[j - 26]);
760                    }
761                    pLinePoints[46].style = 5;
762                    for (j = 47; j < 50; j++) {
763                        pLinePoints[j] = new POINT2(pArrowPoints[j - 47]);
764                        pLinePoints[j].style = 0;
765                    }
766                    break;
767                case TacticalLines.AREA_DEFENSE:
768                    if (dRadius > 100) {
769                        dLength = 0.8 * dRadius;
770                    }
771                    for (j = 1; j <= 23; j++) {
772                        if (j % 3 == 0) {
773                            midPts[k].x = pt0.x - (long) ((dRadius / dLength) * (pt0.x - ptsArc[j].x));
774                            midPts[k].y = pt0.y - (long) ((dRadius / dLength) * (pt0.y - ptsArc[j].y));
775                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
776                            trianglePts[l].style = 9;
777                            l++;
778                            trianglePts[l] = new POINT2(midPts[k]);
779                            trianglePts[l].style = 9;
780                            l++;
781                            trianglePts[l] = new POINT2(ptsArc[j + 1]);
782                            trianglePts[l].style = 9;
783                            l++;
784                            trianglePts[l] = new POINT2(ptsArc[j]);
785                            trianglePts[l].style = 9;
786                            l++;
787                            trianglePts[l] = new POINT2(ptsArc[j - 1]);
788                            trianglePts[l].style = 10;
789                            l++;
790                            k++;
791                        }
792                    }
793                    for (j = 26; j < 61; j++) {
794                        pLinePoints[j] = new POINT2(trianglePts[j - 26]);
795                    }
796                    for (j = 61; j < 64; j++) {
797                        pLinePoints[j] = new POINT2(pArrowPoints[j - 61]);
798                        pLinePoints[j].style = 0;
799                    }
800
801                    lineutility.GetArrowHead4Double(ptsArc[1], ptsArc[0], (int) d / 7, (int) d / 7, pArrowPoints, 0);
802                    pLinePoints[63].style = 5;
803                    for (j = 64; j < 67; j++) {
804                        pLinePoints[j] = new POINT2(pArrowPoints[j - 64]);
805                        pLinePoints[j].style = 0;
806                    }
807                    break;
808                case TacticalLines.OCCUPY:
809                    for (j = 26; j < 29; j++) {
810                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
811                    }
812
813                    pLinePoints[29] = lineutility.ExtendAlongLineDouble(pArrowPoints[0], pArrowPoints[1], lineutility.CalcDistanceDouble(pArrowPoints[0], pArrowPoints[1]) * 2);
814                    pLinePoints[30] = new POINT2(pArrowPoints[1]);
815                    pLinePoints[31] = lineutility.ExtendAlongLineDouble(pArrowPoints[2], pArrowPoints[1], lineutility.CalcDistanceDouble(pArrowPoints[2], pArrowPoints[1]) * 2);
816                    break;
817                case TacticalLines.SECURE:
818                    for (j = 26; j < 29; j++) {
819                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
820                        pLinePoints[j].style = 0;
821                    }
822                    pLinePoints[28].style = 5;
823                    break;
824                case TacticalLines.CONTROL:
825                case TacticalLines.LOCATE:
826                    for (j = 26; j < 29; j++) {
827                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
828                        pLinePoints[j].style = 0;
829                    }
830                    pLinePoints[28].style = 5;
831                    for (j = 29; j < 32; j++) {
832                        pLinePoints[j] = new POINT2(pArrowPoints2[j - 29]);
833                        pLinePoints[j].style = 0;
834                    }
835                    pLinePoints[31].style = 5;
836                    break;
837
838                case TacticalLines.TURN_REVD:
839                case TacticalLines.TURN:
840                    boolean changeArc = IsTurnArcReversed(savepoints);
841                    if (changeArc) //swap the points
842                    {
843                        pt0.x = pt1.x;
844                        pt0.y = pt1.y;
845                        pt1.x = pt2.x;
846                        pt1.y = pt2.y;
847                    }
848
849                    ptsSeize[0] = new POINT2(pt0);
850                    ptsSeize[1] = new POINT2(pt1);
851
852                    dRadius = lineutility.CalcClockwiseCenterDouble(ptsSeize);
853
854                    C = new POINT2(ptsSeize[0]);
855                    E = new POINT2(ptsSeize[1]);
856                    ptsArc[0] = new POINT2(pt0);
857                    ptsArc[1] = new POINT2(E);
858                    lineutility.ArcArrayDouble(ptsArc, 0, dRadius, lineType, null);
859                    for (j = 0; j < 26; j++) {
860                        ptsArc[j].style = 0;
861                        pLinePoints[j] = new POINT2(ptsArc[j]);
862                        pLinePoints[j].style = 0;
863                    }
864
865                    if (changeArc) {
866                        lineutility.GetArrowHead4Double(ptsArc[1], pt0, (int) d / 7, (int) d / 7, pArrowPoints, 5);
867                    } else {
868                        lineutility.GetArrowHead4Double(ptsArc[24], pt1, (int) d / 7, (int) d / 7, pArrowPoints, 5);
869                    }
870
871                    pLinePoints[25].style = 5;
872
873                    for (j = 26; j < 29; j++) {
874                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
875                        pLinePoints[j].style = 9;
876                    }
877                    pLinePoints[28].style = 10;
878
879                    break;
880                case TacticalLines.RETAIN:
881                    for (j = 26; j < 29; j++) {
882                        pLinePoints[j] = new POINT2(pArrowPoints[j - 26]);
883                        pLinePoints[j].style = 0;
884                    }
885                    pLinePoints[28].style = 5;
886                    //get the extended points for retain
887                    k = 29;
888                    for (j = 1; j < 24; j++) {
889                        pLinePoints[k] = new POINT2(ptsArc[j]);
890                        pLinePoints[k].style = 0;
891                        k++;
892                        pLinePoints[k] = lineutility.ExtendLineDouble(pt0, ptsArc[j], (long) d / 7);
893                        pLinePoints[k].style = 5;
894                        k++;
895                    }
896
897                    break;
898                default:
899                    break;
900            }
901        } catch (Exception exc) {
902            ErrorLogger.LogException(_className, "GetIsolatePointsDouble",
903                    new RendererException("GetIsolatePointsDouble " + Integer.toString(lineType), exc));
904        }
905    }
906
907    private static void AirfieldCenterFeature(POINT2[] pLinePoints, int vblCounter) {
908        try {
909            double d = lineutility.MBRDistance(pLinePoints, vblCounter - 5);
910            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
911            if (d > 350 * DPIScaleFactor) {
912                d = 350 * DPIScaleFactor;
913            } else if (d < 100 * DPIScaleFactor) {
914                d = 100 * DPIScaleFactor;
915            }
916
917            for (int k = 0; k < vblCounter; k++) {
918                pLinePoints[k].style = 0;
919            }
920
921            pLinePoints[vblCounter - 5] = new POINT2(pLinePoints[0]);
922            pLinePoints[vblCounter - 5].style = 5;
923            pLinePoints[vblCounter - 4] = lineutility.CalcCenterPointDouble(pLinePoints, vblCounter - 6);
924            pLinePoints[vblCounter - 4].x -= d / 10;    //was 20
925            pLinePoints[vblCounter - 4].style = 0;
926            pLinePoints[vblCounter - 3] = new POINT2(pLinePoints[vblCounter - 4]);
927            pLinePoints[vblCounter - 3].x = pLinePoints[vblCounter - 4].x + d / 5;//was 10
928            pLinePoints[vblCounter - 3].style = 5;
929            pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 4]);
930            pLinePoints[vblCounter - 2].y += d / 20;//was 40
931            pLinePoints[vblCounter - 2].style = 0;
932            pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 3]);
933            pLinePoints[vblCounter - 1].y -= d / 20;//was 40
934            pLinePoints[vblCounter - 1].style = 0;
935        } catch (Exception exc) {
936            ErrorLogger.LogException(_className, "AirfieldCenterFeature",
937                    new RendererException("AirfieldCenterFeature", exc));
938        }
939    }
940
941    private static int GetATWallPointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
942        int nCounter = 0;
943        try {
944            int lineType = tg.get_LineType();
945            int j = 0, k = 0;
946            int lCount = 0;
947            double dLengthSegment = 0, dIncrement = 0;
948            POINT2[] pSpikePoints = null;
949            POINT2 pt0;
950            double dRemainder = 0, dSpikeSize = 0;
951            int limit = 0;
952            POINT2 crossPt1, crossPt2;
953
954            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
955            pSpikePoints = new POINT2[lCount];
956            switch (lineType) {
957                case TacticalLines.CFG:
958                case TacticalLines.CFY:
959                    pSpikePoints[nCounter] = pLinePoints[0];
960                    pSpikePoints[nCounter].style = 0;
961                    nCounter++;
962                    break;
963                default:
964                    break;
965            }
966            for (j = 0; j < vblSaveCounter - 1; j++) {
967                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
968                switch (lineType) {
969                    case TacticalLines.UCF:
970                    case TacticalLines.CF:
971                    case TacticalLines.CFG:
972                    case TacticalLines.CFY:
973                        dIncrement = arraysupport.getScaledSize(60, tg.get_LineThickness(), tg.get_patternScale());
974                        dSpikeSize = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
975                        dRemainder = dLengthSegment / dIncrement - (double) ((int) (dLengthSegment / dIncrement));
976                        if (dRemainder < 0.75) {
977                            limit = (int) (dLengthSegment / dIncrement);
978                        } else {
979                            limit = (int) (dLengthSegment / dIncrement) + 1;
980                        }
981                        break;
982                    default:
983                        dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
984                        dSpikeSize = arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
985                        limit = (int) (dLengthSegment / dIncrement) - 1;
986                        break;
987                }
988                if (limit < 1) {
989                    pSpikePoints[nCounter] = pLinePoints[j];
990                    nCounter++;
991                    pSpikePoints[nCounter] = pLinePoints[j + 1];
992                    nCounter++;
993                    continue;
994                }
995
996                for (k = 0; k < limit; k++) {
997                    switch (lineType) {
998                        case TacticalLines.CFG: //linebreak for dot
999                            if (k > 0) {
1000                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
1001                                nCounter++;
1002                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), 5);  //+2
1003                                nCounter++;
1004                                //dot
1005                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(1, tg.get_LineThickness(), tg.get_patternScale()), 20);
1006                                nCounter++;
1007                                //remainder of line
1008                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 0); //-4
1009                            } else {
1010                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
1011                            }
1012                            break;
1013                        case TacticalLines.CFY: //linebreak for crossed line
1014                            if (k > 0) {
1015                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
1016                                nCounter++;
1017                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement + arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 5); //+2
1018                                nCounter++;
1019                                //dot
1020                                //replace the dot with crossed line segment
1021                                pSpikePoints[nCounter] = lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter - 1], pLinePoints[j + 1], arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 0);
1022                                nCounter++;
1023                                pSpikePoints[nCounter] = lineutility.ExtendAlongLineDouble(pSpikePoints[nCounter - 1], pLinePoints[j + 1], arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 5);
1024                                nCounter++;
1025                                crossPt1 = lineutility.ExtendDirectedLine(pSpikePoints[nCounter - 2], pSpikePoints[nCounter - 1], pSpikePoints[nCounter - 1], 3, arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 0);
1026                                crossPt2 = lineutility.ExtendDirectedLine(pSpikePoints[nCounter - 1], pSpikePoints[nCounter - 2], pSpikePoints[nCounter - 2], 2, arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 5);
1027                                pSpikePoints[nCounter] = crossPt1;
1028                                nCounter++;
1029                                pSpikePoints[nCounter] = crossPt2;
1030                                nCounter++;
1031                                //remainder of line
1032                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 0); //-4
1033                            } else {
1034                                pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(45, tg.get_LineThickness(), tg.get_patternScale()), 0);
1035                            }
1036                            break;
1037                        default:
1038                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), 0);
1039                            break;
1040                    }
1041                    if (lineType == TacticalLines.CF) {
1042                        pSpikePoints[nCounter].style = 0;
1043                    }
1044                    nCounter++;
1045                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement - dSpikeSize, 0);
1046
1047                    if (lineType == TacticalLines.CF
1048                            || lineType == TacticalLines.CFG
1049                            || lineType == TacticalLines.CFY) {
1050                        pSpikePoints[nCounter].style = 9;
1051                    }
1052
1053                    nCounter++;
1054                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j], pSpikePoints[nCounter - 1], dSpikeSize / 2);
1055
1056                    //the spikes
1057                    if (pLinePoints[j].x > pLinePoints[j + 1].x) //extend above the line
1058                    {
1059                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 2, dSpikeSize);
1060                    }
1061                    if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend below the line
1062                    {
1063                        pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pSpikePoints[nCounter - 1], pt0, 3, dSpikeSize);
1064                    }
1065                    if (pLinePoints[j].x == pLinePoints[j + 1].x) {
1066                        pSpikePoints[nCounter] = pt0;
1067                        if (pLinePoints[j].y < pLinePoints[j + 1].y) //extend left of line
1068                        {
1069                            pSpikePoints[nCounter].x = pt0.x - dSpikeSize;
1070                        } else //extend right of line
1071                        {
1072                            pSpikePoints[nCounter].x = pt0.x + dSpikeSize;
1073                        }
1074                    }
1075                    nCounter++;
1076
1077                    if (lineType == TacticalLines.CF
1078                            || lineType == TacticalLines.CFG
1079                            || lineType == TacticalLines.CFY) {
1080                        pSpikePoints[nCounter - 1].style = 9;
1081                    }
1082
1083                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 2], dSpikeSize, 0);
1084                    //need an extra point for these
1085                    switch (lineType) {
1086                        case TacticalLines.CF:
1087                            pSpikePoints[nCounter].style = 10;
1088                            break;
1089                        case TacticalLines.CFG:
1090                        case TacticalLines.CFY:
1091                            pSpikePoints[nCounter].style = 10;
1092                            nCounter++;
1093                            pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j], pSpikePoints[nCounter - 3], dSpikeSize, 0);
1094                            break;
1095                        default:
1096                            break;
1097                    }
1098                    nCounter++;
1099                }
1100
1101                //use the original line point for the segment end point
1102                pSpikePoints[nCounter] = pLinePoints[j + 1];
1103                pSpikePoints[nCounter].style = 0;
1104                nCounter++;
1105            }
1106
1107            for (j = 0; j < nCounter; j++) {
1108                pLinePoints[j] = pSpikePoints[j];
1109            }
1110            pLinePoints[nCounter - 1].style = 5;
1111
1112        } catch (Exception exc) {
1113            ErrorLogger.LogException(_className, "GetATWallPointsDouble",
1114                    new RendererException("GetATWallPointsDouble " + Integer.toString(tg.get_LineType()), exc));
1115        }
1116        return nCounter;
1117    }
1118
1119    private static int GetRidgePointsDouble(TGLight tg, POINT2[] pLinePoints, int vblSaveCounter) {
1120        int nCounter = 0;
1121        try {
1122            int j = 0, k = 0;
1123            int lCount = 0;
1124            double dLengthSegment = 0, dIncrement = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1125            ref<double[]> m = new ref();
1126            POINT2[] pSpikePoints = null;
1127            POINT2 pt0;
1128            double dSpikeSize = arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1129            int limit = 0;
1130            double d = 0;
1131            int bolVertical = 0;
1132
1133            m.value = new double[1];
1134            lCount = countsupport.GetFORTLCountDouble(tg, pLinePoints, vblSaveCounter);
1135
1136            pSpikePoints = new POINT2[lCount];
1137            lineutility.InitializePOINT2Array(pSpikePoints);
1138            //for(j=0;j<numPts2-1;j++)
1139            for (j = 0; j < vblSaveCounter - 1; j++) {
1140                bolVertical = lineutility.CalcTrueSlopeDouble(pLinePoints[j], pLinePoints[j + 1], m);
1141                dLengthSegment = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1142                limit = (int) (dLengthSegment / dIncrement);
1143                if (limit < 1) {
1144                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j]);
1145                    nCounter++;
1146                    pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
1147                    nCounter++;
1148                    continue;
1149                }
1150                for (k = 0; k < limit; k++) {
1151                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -k * dIncrement, 0);
1152                    nCounter++;
1153                    d = lineutility.CalcDistanceDouble(pLinePoints[j], pSpikePoints[nCounter - 1]);
1154                    pt0 = lineutility.ExtendLineDouble(pLinePoints[j + 1], pLinePoints[j], -d - dSpikeSize / 2);
1155
1156                    //the spikes
1157                    if (bolVertical != 0) //segment is not vertical
1158                    {
1159                        if (pLinePoints[j].x < pLinePoints[j + 1].x) //extend above the line
1160                        {
1161                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 2, dSpikeSize);
1162                        } else //extend below the line
1163                        {
1164                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 3, dSpikeSize);
1165                        }
1166                    } else //segment is vertical
1167                    {
1168                        if (pLinePoints[j + 1].y < pLinePoints[j].y) //extend left of the line
1169                        {
1170                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 0, dSpikeSize);
1171                        } else //extend right of the line
1172                        {
1173                            pSpikePoints[nCounter] = lineutility.ExtendDirectedLine(pLinePoints[j], pLinePoints[j + 1], pt0, 1, dSpikeSize);
1174                        }
1175                    }
1176                    nCounter++;
1177                    pSpikePoints[nCounter] = lineutility.ExtendLine2Double(pLinePoints[j + 1], pLinePoints[j], -d - dSpikeSize, 0);
1178                    nCounter++;
1179                }
1180                pSpikePoints[nCounter] = new POINT2(pLinePoints[j + 1]);
1181                nCounter++;
1182            }
1183
1184            for (j = 0; j < nCounter; j++) {
1185                pLinePoints[j] = new POINT2(pSpikePoints[j]);
1186            }
1187            for (j = nCounter; j < lCount; j++) {
1188                pLinePoints[j] = new POINT2(pSpikePoints[nCounter - 1]);
1189            }
1190
1191        } catch (Exception exc) {
1192            ErrorLogger.LogException(_className, "GetRidgePointsDouble",
1193                    new RendererException("GetRidgePointsDouble " + Integer.toString(tg.get_LineType()), exc));
1194        }
1195        return nCounter;
1196    }
1197
1198    protected static int GetSquallDouble(POINT2[] pLinePoints,
1199            double amplitude,
1200            int quantity,
1201            double length,
1202            int numPoints) {
1203        int counter = 0;
1204        try {
1205            int j = 0, k = 0;
1206            POINT2 StartSegPt, EndSegPt;
1207            POINT2 savePoint1 = new POINT2(pLinePoints[0]);
1208            POINT2 savePoint2 = new POINT2(pLinePoints[numPoints - 1]);
1209            ref<int[]> sign = new ref();
1210            int segQty = 0;
1211            int totalQty = countsupport.GetSquallQty(pLinePoints, quantity, length, numPoints);
1212            POINT2[] pSquallPts = new POINT2[totalQty];
1213            POINT2[] pSquallSegPts = null;
1214
1215            lineutility.InitializePOINT2Array(pSquallPts);
1216            sign.value = new int[1];
1217            sign.value[0] = -1;
1218            if (totalQty == 0) {
1219                return 0;
1220            }
1221
1222            for (j = 0; j < numPoints - 1; j++) {
1223                StartSegPt = new POINT2(pLinePoints[j]);
1224                EndSegPt = new POINT2(pLinePoints[j + 1]);
1225                segQty = countsupport.GetSquallSegQty(StartSegPt, EndSegPt, quantity, length);
1226                if (segQty > 0) {
1227                    pSquallSegPts = new POINT2[segQty];
1228                    lineutility.InitializePOINT2Array(pSquallSegPts);
1229                } else {
1230                    pSquallPts[counter].x = StartSegPt.x;
1231                    pSquallPts[counter++].y = StartSegPt.y;
1232                    pSquallPts[counter].x = EndSegPt.x;
1233                    pSquallPts[counter++].y = EndSegPt.y;
1234                    continue;
1235                }
1236                sign.value[0] = -1;
1237                lineutility.GetSquallSegment(StartSegPt, EndSegPt, pSquallSegPts, sign, amplitude, quantity, length);
1238                for (k = 0; k < segQty; k++) {
1239                    pSquallPts[counter].x = pSquallSegPts[k].x;
1240                    pSquallPts[counter].y = pSquallSegPts[k].y;
1241                    if (k == 0) {
1242                        pSquallPts[counter] = new POINT2(pLinePoints[j]);
1243                    }
1244                    if (k == segQty - 1) {
1245                        pSquallPts[counter] = new POINT2(pLinePoints[j + 1]);
1246                    }
1247                    pSquallPts[counter].style = 0;
1248                    counter++;
1249                }
1250            }
1251            //load the squall points into the linepoints array
1252            for (j = 0; j < counter; j++) {
1253                if (j < totalQty) {
1254                    pLinePoints[j].x = pSquallPts[j].x;
1255                    pLinePoints[j].y = pSquallPts[j].y;
1256                    if (j == 0) {
1257                        pLinePoints[j] = new POINT2(savePoint1);
1258                    }
1259                    if (j == counter - 1) {
1260                        pLinePoints[j] = new POINT2(savePoint2);
1261                    }
1262                    pLinePoints[j].style = pSquallPts[j].style;
1263                }
1264            }
1265            if (counter == 0) {
1266                for (j = 0; j < pLinePoints.length; j++) {
1267                    if (j == 0) {
1268                        pLinePoints[j] = new POINT2(savePoint1);
1269                    } else {
1270                        pLinePoints[j] = new POINT2(savePoint2);
1271                    }
1272                }
1273                counter = pLinePoints.length;
1274            }
1275        } catch (Exception exc) {
1276            ErrorLogger.LogException(_className, "GetSquallDouble",
1277                    new RendererException("GetSquallDouble", exc));
1278        }
1279        return counter;
1280    }
1281
1282    protected static int GetSevereSquall(POINT2[] pLinePoints,
1283            double length,
1284            int numPoints) {
1285        int l = 0;
1286        try {
1287            int quantity = 5, j = 0, k = 0;
1288            int totalQty = countsupport.GetSquallQty(pLinePoints, quantity, length, numPoints) + 2 * numPoints;
1289            POINT2[] squallPts = new POINT2[totalQty];
1290            POINT2 pt0 = new POINT2(), pt1 = new POINT2(), pt2 = new POINT2(),
1291                    pt3 = new POINT2(), pt4 = new POINT2(), pt5 = new POINT2(), pt6 = new POINT2(),
1292                    pt7 = new POINT2(), pt8 = new POINT2();
1293            int segQty = 0;
1294            double dist = 0;
1295
1296            lineutility.InitializePOINT2Array(squallPts);
1297            //each segment looks like this: --- V
1298            for (j = 0; j < numPoints - 1; j++) {
1299                dist = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
1300                segQty = (int) (dist / length);
1301                for (k = 0; k < segQty; k++) {
1302                    pt0 = lineutility.ExtendAlongLineDouble2(pLinePoints[j], pLinePoints[j + 1], k * length);
1303                    pt1 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length / 6 * 4);
1304                    pt1.style = 5;
1305                    squallPts[l++] = new POINT2(pt0);
1306                    squallPts[l++] = new POINT2(pt1);
1307                    pt5 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length / 6 * 5);
1308                    pt6 = lineutility.ExtendAlongLineDouble(pLinePoints[j], pLinePoints[j + 1], k * length + length);
1309                    pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 2, length / 6, 0);   //extend above line
1310                    pt3 = lineutility.ExtendDirectedLine(pt0, pt5, pt5, 3, length / 6, 0);   //extend below line
1311                    pt4 = lineutility.ExtendDirectedLine(pt0, pt6, pt6, 2, length / 6, 5);   //extend above line
1312                    pt4.style = 5;
1313                    squallPts[l++] = new POINT2(pt2);
1314                    squallPts[l++] = new POINT2(pt3);
1315                    squallPts[l++] = new POINT2(pt4);
1316                }
1317                //segment remainder
1318                squallPts[l++] = new POINT2(pLinePoints[j + 1]);
1319                pt0 = lineutility.ExtendAlongLineDouble(pLinePoints[j + 1], pLinePoints[j], dist - segQty * length);
1320                pt0.style = 5;
1321                squallPts[l++] = new POINT2(pt0);
1322            }
1323            if (l > pLinePoints.length) {
1324                l = pLinePoints.length;
1325            }
1326
1327            for (j = 0; j < l; j++) {
1328                if (j < totalQty) {
1329                    pLinePoints[j] = new POINT2(squallPts[j]);
1330                } else {
1331                    break;
1332                }
1333            }
1334
1335        } catch (Exception exc) {
1336            ErrorLogger.LogException(_className, "GetSevereSquall",
1337                    new RendererException("GetSevereSquall", exc));
1338        }
1339        return l;
1340    }
1341
1342    private static int GetConvergencePointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1343        int counter = vblCounter;
1344        try {
1345            int j = 0, k = 0;
1346            double d = 0;
1347            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
1348            POINT2[] tempPts = new POINT2[vblCounter];
1349            POINT2 tempPt = new POINT2();
1350            int numJags = 0;
1351            //save the original points
1352            for (j = 0; j < vblCounter; j++) {
1353                tempPts[j] = new POINT2(pLinePoints[j]);
1354            }
1355
1356            //result points begin with the original points,
1357            //set the last one's linestyle to 5;
1358            pLinePoints[vblCounter - 1].style = 5;
1359            for (j = 0; j < vblCounter - 1; j++) {
1360
1361                pt0 = new POINT2(tempPts[j]);
1362                pt1 = new POINT2(tempPts[j + 1]);
1363                d = lineutility.CalcDistanceDouble(pt0, pt1);
1364                numJags = (int) (d / length);
1365                //we don't want too small a remainder
1366                if (d - numJags * length < 5) {
1367                    numJags -= 1;
1368                }
1369
1370                //each section has two spikes: one points above the line
1371                //the other spike points below the line
1372                for (k = 0; k < numJags; k++) {
1373                    //the first spike
1374                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, k * length + length / 2, 0);
1375                    pLinePoints[counter++] = new POINT2(tempPt);
1376                    tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length / 2);
1377                    tempPt = lineutility.ExtendDirectedLine(pt0, tempPt, tempPt, 2, length / 2, 5);
1378                    pLinePoints[counter++] = new POINT2(tempPt);
1379                    //the 2nd spike
1380                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, (k + 1) * length, 0);
1381                    pLinePoints[counter++] = new POINT2(tempPt);
1382                    tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length / 2);
1383                    tempPt = lineutility.ExtendDirectedLine(pt0, tempPt, tempPt, 3, length / 2, 5);
1384                    pLinePoints[counter++] = new POINT2(tempPt);
1385                }
1386            }
1387        } catch (Exception exc) {
1388            ErrorLogger.LogException(_className, "GetConvergencePointsDouble",
1389                    new RendererException("GetConvergencePointsDouble", exc));
1390        }
1391        return counter;
1392    }
1393
1394    // Dashes are 2/3*length and spaces are 1/3*length.
1395    private static int GetITDPointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1396        int counter = 0;
1397        try {
1398            int j = 0, k = 0;
1399            double d = 0;
1400            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
1401            POINT2[] tempPts = new POINT2[vblCounter];
1402            POINT2 tempPt = new POINT2();
1403            int numJags = 0, lineStyle = 19;
1404            //save the original points
1405            for (j = 0; j < vblCounter; j++) {
1406                tempPts[j] = new POINT2(pLinePoints[j]);
1407            }
1408
1409            //result points begin with the original points,
1410            //set the last one's linestyle to 5;
1411            //pLinePoints[vblCounter-1].style=5;
1412            for (j = 0; j < vblCounter - 1; j++) {
1413                pt0 = new POINT2(tempPts[j]);
1414                pt1 = new POINT2(tempPts[j + 1]);
1415                d = lineutility.CalcDistanceDouble(pt0, pt1);
1416                numJags = (int) (d / length);
1417                //we don't want too small a remainder
1418                if (d - numJags * length / 3 * 2 < length / 3) {
1419                    numJags -= 1;
1420                }
1421                if (numJags == 0) {
1422                    pt0.style = 19;
1423                    pLinePoints[counter++] = new POINT2(pt0);
1424                    pt1.style = 5;
1425                    pLinePoints[counter++] = new POINT2(pt1);
1426                }
1427
1428                for (k = 0; k < numJags; k++) {
1429                    tempPt = lineutility.ExtendAlongLineDouble(pt0, pt1, k * length + length / 3, lineStyle);
1430                    pLinePoints[counter++] = new POINT2(tempPt);
1431
1432                    if (k < numJags - 1) {
1433                        tempPt = lineutility.ExtendAlongLineDouble(tempPt, pt1, length * 2 / 3, 5);
1434                    } else {
1435                        tempPt = new POINT2(tempPts[j + 1]);
1436                        tempPt.style = 5;
1437                    }
1438                    pLinePoints[counter++] = new POINT2(tempPt);
1439                    if (lineStyle == 19) {
1440                        lineStyle = 25;
1441                    } else {
1442                        lineStyle = 19;
1443                    }
1444                }
1445            }
1446        } catch (Exception exc) {
1447            ErrorLogger.LogException(_className, "GetITDPointsDouble",
1448                    new RendererException("GetITDPointsDouble", exc));
1449        }
1450        return counter;
1451    }
1452
1453    private static int GetXPoints(POINT2[] pOriginalLinePoints, POINT2[] XPoints, double segmentLength, int vblCounter) {
1454        int xCounter = 0;
1455        try {
1456            int j = 0, k = 0;
1457            double d = 0;
1458            POINT2 pt0, pt1, pt2, pt3 = new POINT2(), pt4 = new POINT2(), pt5 = new POINT2(), pt6 = new POINT2();
1459            int numThisSegment = 0;
1460            double distInterval = 0;
1461            double xSize = segmentLength / 6;
1462            for (j = 0; j < vblCounter - 1; j++) {
1463                d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1464                numThisSegment = (int) ((d - segmentLength) / segmentLength);
1465
1466                //added 4-19-12
1467                distInterval = d / numThisSegment;
1468                for (k = 0; k < numThisSegment; k++) {
1469                    //pt0=lineutility.ExtendAlongLineDouble(pOriginalLinePoints[j],pOriginalLinePoints[j+1], 10+20*k);
1470                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalLinePoints[j], pOriginalLinePoints[j + 1], distInterval / 2 + distInterval * k);
1471                    pt1 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalLinePoints[j + 1], xSize);
1472                    pt2 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalLinePoints[j + 1], -xSize);
1473
1474                    pt3 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt1, pt1, 2, xSize);
1475                    pt4 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt1, pt1, 3, xSize);
1476                    pt4.style = 5;
1477                    pt5 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt2, pt2, 2, xSize);
1478                    pt6 = lineutility.ExtendDirectedLine(pOriginalLinePoints[j], pt2, pt2, 3, xSize);
1479                    pt6.style = 5;
1480                    XPoints[xCounter++] = new POINT2(pt3);
1481                    XPoints[xCounter++] = new POINT2(pt6);
1482                    XPoints[xCounter++] = new POINT2(pt5);
1483                    XPoints[xCounter++] = new POINT2(pt4);
1484                }
1485            }
1486        } catch (Exception exc) {
1487            ErrorLogger.LogException(_className, "GetXPointsDouble",
1488                    new RendererException("GetXPointsDouble", exc));
1489        }
1490        return xCounter;
1491    }
1492
1493    /**
1494     * returns a 37 point ellipse
1495     *
1496     * @param ptCenter
1497     * @param ptWidth
1498     * @param ptHeight
1499     * @return
1500     */
1501    private static POINT2[] getEllipsePoints(POINT2 ptCenter, POINT2 ptWidth, POINT2 ptHeight) {
1502        POINT2[] pEllipsePoints = null;
1503        try {
1504            pEllipsePoints = new POINT2[37];
1505            int l = 0;
1506            double dFactor = 0;
1507            double a = lineutility.CalcDistanceDouble(ptCenter, ptWidth);
1508            double b = lineutility.CalcDistanceDouble(ptCenter, ptHeight);
1509            lineutility.InitializePOINT2Array(pEllipsePoints);
1510            for (l = 1; l < 37; l++) {
1511                dFactor = (10.0 * l) * Math.PI / 180.0;
1512                pEllipsePoints[l - 1].x = ptCenter.x + (int) (a * Math.cos(dFactor));
1513                pEllipsePoints[l - 1].y = ptCenter.y + (int) (b * Math.sin(dFactor));
1514                pEllipsePoints[l - 1].style = 0;
1515            }
1516            pEllipsePoints[36] = new POINT2(pEllipsePoints[0]);
1517        } catch (Exception exc) {
1518            ErrorLogger.LogException(_className, "GetEllipsePoints",
1519                    new RendererException("GetEllipsePoints", exc));
1520        }
1521        return pEllipsePoints;
1522    }
1523
1524    /**
1525     * Calculate an ellipse and rotate about it's center by azimuth in degrees
1526     *
1527     * @param ptCenter
1528     * @param ptWidth
1529     * @param ptHeight
1530     * @param azimuth
1531     * @return
1532     */
1533    private static POINT2[] getRotatedEllipsePoints(POINT2 ptCenter, POINT2 ptWidth, POINT2 ptHeight, double azimuth, int lineType) {
1534        POINT2[] pResultPoints = null;
1535        try {
1536            POINT2[] pEllipsePoints = new POINT2[36];
1537            int l = 0, j = 0;
1538            double dFactor = 0;
1539            double a = lineutility.CalcDistanceDouble(ptCenter, ptWidth);
1540            double b = lineutility.CalcDistanceDouble(ptCenter, ptHeight);
1541            lineutility.InitializePOINT2Array(pEllipsePoints);
1542            for (l = 1; l < 37; l++) {
1543                dFactor = (10.0 * l) * Math.PI / 180.0;
1544                //pEllipsePoints[l - 1].x = ptCenter.x + (int) (a * Math.cos(dFactor));
1545                //pEllipsePoints[l - 1].y = ptCenter.y + (int) (b * Math.sin(dFactor));
1546                pEllipsePoints[l - 1].x = ptCenter.x + a * Math.cos(dFactor);
1547                pEllipsePoints[l - 1].y = ptCenter.y + b * Math.sin(dFactor);
1548                pEllipsePoints[l - 1].style = 0;
1549            }
1550            lineutility.RotateGeometryDouble(pEllipsePoints, 36, azimuth - 90);
1551            pResultPoints = new POINT2[37];
1552            for (j = 0; j < 36; j++) {
1553                pResultPoints[j] = pEllipsePoints[j];
1554            }
1555            pResultPoints[36] = pEllipsePoints[0];
1556        } catch (Exception exc) {
1557            ErrorLogger.LogException(_className, "GetRotatedEllipsePoints",
1558                    new RendererException("GetRotatedEllipsePoints", exc));
1559        }
1560        return pResultPoints;
1561    }
1562
1563    private static int GetLVOPoints(POINT2[] pOriginalLinePoints, POINT2[] pLinePoints, double ovalWidth, double segmentLength, int vblCounter) {
1564        int lEllipseCounter = 0;
1565        try {
1566            double dAngle = 0, d = 0, ovalLength = ovalWidth * 2, dFactor = 0;
1567            int lHowManyThisSegment = 0, j = 0, k = 0, l = 0, t = 0;
1568            POINT2 ptCenter = new POINT2();
1569            POINT2[] pEllipsePoints2 = new POINT2[37];
1570
1571            double distInterval = 0;
1572            //end declarations
1573            for (j = 0; j < vblCounter - 1; j++) {
1574                lineutility.InitializePOINT2Array(pEllipsePoints2);
1575                d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1576                lHowManyThisSegment = (int) ((d - segmentLength) / segmentLength);
1577
1578                distInterval = d / lHowManyThisSegment;
1579
1580                dAngle = lineutility.CalcSegmentAngleDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1581                dAngle = dAngle + Math.PI / 2;
1582                for (k = 0; k < lHowManyThisSegment; k++) {
1583                    ptCenter = lineutility.ExtendAlongLineDouble2(pOriginalLinePoints[j], pOriginalLinePoints[j + 1], k * distInterval);
1584                    for (l = 1; l < 37; l++) {
1585                        //dFactor = (10.0 * l) * Math.PI / 180.0;
1586                        dFactor = (20.0 * l) * Math.PI / 180.0;
1587                        pEllipsePoints2[l - 1].x = ptCenter.x + (int) (ovalWidth * Math.cos(dFactor));
1588                        pEllipsePoints2[l - 1].y = ptCenter.y + (int) (ovalLength * Math.sin(dFactor));
1589                        pEllipsePoints2[l - 1].style = 0;
1590                    }
1591                    lineutility.RotateGeometryDouble(pEllipsePoints2, 36, (int) (dAngle * 180 / Math.PI));
1592                    pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
1593                    pEllipsePoints2[36].style = 5;
1594                    for (l = 0; l < 37; l++) {
1595                        pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
1596                        lEllipseCounter++;
1597                    }
1598                }//end k loop
1599                //extra ellipse on the final segment at the end of the line
1600                if (j == vblCounter - 2) {
1601                    ptCenter = pOriginalLinePoints[j + 1];
1602
1603                    for (l = 1; l < 37; l++) {
1604                        dFactor = (20.0 * l) * Math.PI / 180.0;
1605                        pEllipsePoints2[l - 1].x = ptCenter.x + (int) (ovalWidth * Math.cos(dFactor));
1606                        pEllipsePoints2[l - 1].y = ptCenter.y + (int) (ovalLength * Math.sin(dFactor));
1607                        pEllipsePoints2[l - 1].style = 0;
1608                    }
1609                    lineutility.RotateGeometryDouble(pEllipsePoints2, 36, (int) (dAngle * 180 / Math.PI));
1610                    pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
1611                    pEllipsePoints2[36].style = 5;
1612                    for (l = 0; l < 37; l++) {
1613                        pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
1614                        lEllipseCounter++;
1615                    }
1616                }
1617            }
1618        } catch (Exception exc) {
1619            ErrorLogger.LogException(_className, "GetLVOPointsDouble",
1620                    new RendererException("GetLVOPointsDouble", exc));
1621        }
1622        return lEllipseCounter;
1623    }
1624
1625    private static int GetIcingPointsDouble(POINT2[] pLinePoints, double length, int vblCounter) {
1626        int counter = 0;
1627        try {
1628            int j = 0;
1629            POINT2[] origPoints = new POINT2[vblCounter];
1630            int nDirection = -1;
1631            int k = 0, numSegments = 0;
1632            POINT2 pt0 = new POINT2(), pt1 = new POINT2(), midPt = new POINT2(), pt2 = new POINT2();
1633            //save the original points
1634            for (j = 0; j < vblCounter; j++) {
1635                origPoints[j] = new POINT2(pLinePoints[j]);
1636            }
1637            double distInterval = 0;
1638            for (j = 0; j < vblCounter - 1; j++) {
1639                //how many segments for this line segment?
1640                numSegments = (int) lineutility.CalcDistanceDouble(origPoints[j], origPoints[j + 1]);
1641                numSegments /= length;
1642                //4-19-12
1643                distInterval = lineutility.CalcDistanceDouble(origPoints[j], origPoints[j + 1]) / numSegments;
1644                //get the direction and the quadrant
1645                nDirection = GetInsideOutsideDouble2(origPoints[j], origPoints[j + 1], origPoints, vblCounter, j, TacticalLines.ICING);
1646                for (k = 0; k < numSegments; k++) {
1647                    //get the parallel segment
1648                    if (k == 0) {
1649                        pt0 = new POINT2(origPoints[j]);
1650                    } else {
1651                        pt0 = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval, 0);
1652                    }
1653
1654                    pt1 = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval + length * 2 / 3, 5);
1655                    midPt = lineutility.ExtendAlongLineDouble(origPoints[j], origPoints[j + 1], k * distInterval + length / 3, 0);
1656                    //get the perpendicular segment
1657                    pt2 = lineutility.ExtendDirectedLine(origPoints[j], origPoints[j + 1], midPt, nDirection, length / 3, 5);
1658                    pLinePoints[counter] = new POINT2(pt0);
1659                    pLinePoints[counter + 1] = new POINT2(pt1);
1660                    pLinePoints[counter + 2] = new POINT2(midPt);
1661                    pLinePoints[counter + 3] = new POINT2(pt2);
1662                    counter += 4;
1663                }
1664            }
1665        } catch (Exception exc) {
1666            ErrorLogger.LogException(_className, "GetIcingPointsDouble",
1667                    new RendererException("GetIcingPointsDouble", exc));
1668        }
1669        return counter;
1670    }
1671
1672    protected static int GetAnchorageDouble(POINT2[] vbPoints2, double floatDiameter, int numPts) {
1673        int lFlotCounter = 0;
1674        try {
1675            int j = 0, k = 0, l = 0;
1676            int x1 = 0, y1 = 0;
1677            int numSegPts = -1;
1678            int lFlotCount = 0;
1679            int lNumSegs = 0;
1680            double dDistance = 0;
1681            int[] vbPoints = null;
1682            int[] points = null;
1683            int[] points2 = null;
1684            POINT2 pt = new POINT2();
1685            POINT2 pt1 = new POINT2(), pt2 = new POINT2();
1686
1687            lFlotCount = flot.GetAnchorageCountDouble(vbPoints2, floatDiameter, numPts);
1688            vbPoints = new int[2 * numPts];
1689
1690            for (j = 0; j < numPts; j++) {
1691                vbPoints[k] = (int) vbPoints2[j].x;
1692                k++;
1693                vbPoints[k] = (int) vbPoints2[j].y;
1694                k++;
1695            }
1696            k = 0;
1697
1698            ref<int[]> bFlip = new ref();
1699            bFlip.value = new int[1];
1700            ref<int[]> lDirection = new ref();
1701            lDirection.value = new int[1];
1702            ref<int[]> lLastDirection = new ref();
1703            lLastDirection.value = new int[1];
1704            for (l = 0; l < numPts - 1; l++) {
1705                pt1.x = vbPoints[2 * l];
1706                pt1.y = vbPoints[2 * l + 1];
1707                pt2.x = vbPoints[2 * l + 2];
1708                pt2.y = vbPoints[2 * l + 3];
1709                //for all segments after the first segment we shorten
1710                //the line by floatDiameter so the flots will not abut
1711                if (l > 0) {
1712                    pt1 = lineutility.ExtendAlongLineDouble(pt1, pt2, floatDiameter);
1713                }
1714
1715                dDistance = lineutility.CalcDistanceDouble(pt1, pt2);
1716
1717                lNumSegs = (int) (dDistance / floatDiameter);
1718
1719                if (lNumSegs > 0) {
1720                    points2 = new int[lNumSegs * 32];
1721                    numSegPts = flot.GetAnchorageFlotSegment(vbPoints, (int) pt1.x, (int) pt1.y, (int) pt2.x, (int) pt2.y, l, floatDiameter, points2, bFlip, lDirection, lLastDirection);
1722                    points = new int[numSegPts];
1723
1724                    for (j = 0; j < numSegPts; j++) {
1725                        points[j] = points2[j];
1726                    }
1727
1728                    for (j = 0; j < numSegPts / 3; j++) //only using half the flots
1729                    {
1730                        x1 = points[k];
1731                        y1 = points[k + 1];
1732                        k += 3;
1733                        if (j % 10 == 0) {
1734                            pt.x = x1;
1735                            pt.y = y1;
1736                            pt.style = 5;
1737                        } else if ((j + 1) % 10 == 0) {
1738                            if (lFlotCounter < lFlotCount) {
1739                                vbPoints2[lFlotCounter].x = x1;
1740                                vbPoints2[lFlotCounter++].y = y1;
1741                                vbPoints2[lFlotCounter++] = new POINT2(pt);
1742                                continue;
1743                            } else {
1744                                break;
1745                            }
1746                        }
1747                        if (lFlotCounter < lFlotCount) {
1748                            vbPoints2[lFlotCounter].x = x1;
1749                            vbPoints2[lFlotCounter].y = y1;
1750                            lFlotCounter++;
1751                        } else {
1752                            break;
1753                        }
1754                    }
1755                    k = 0;
1756                    points = null;
1757                } else {
1758                    if (lFlotCounter < lFlotCount) {
1759                        vbPoints2[lFlotCounter].x = vbPoints[2 * l];
1760                        vbPoints2[lFlotCounter].y = vbPoints[2 * l + 1];
1761                        lFlotCounter++;
1762                    }
1763                }
1764            }
1765            for (j = lFlotCounter - 1; j < lFlotCount; j++) {
1766                vbPoints2[j].style = 5;
1767            }
1768
1769        } catch (Exception exc) {
1770            ErrorLogger.LogException(_className, "GetAnchorageDouble",
1771                    new RendererException("GetAnchorageDouble", exc));
1772        }
1773        return lFlotCounter;
1774    }
1775
1776    private static int GetPipePoints(POINT2[] pLinePoints,
1777            double length,
1778            int vblCounter) {
1779        int counter = 0;
1780        try {
1781            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1782            POINT2 pt0 = new POINT2();
1783            POINT2 pt1 = new POINT2();
1784            POINT2 pt2 = new POINT2();
1785            POINT2[] xPoints = new POINT2[pLinePoints.length];
1786            int xCounter = 0;
1787            int j = 0, k = 0;
1788            for (j = 0; j < vblCounter; j++) {
1789                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1790            }
1791            int numSegs = 0;
1792            double d = 0;
1793
1794            lineutility.InitializePOINT2Array(xPoints);
1795            for (j = 0; j < vblCounter - 1; j++) {
1796                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1797                numSegs = (int) (d / length);
1798                for (k = 0; k < numSegs; k++) {
1799                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1800                    pt0.style = 0;
1801                    pt1 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length / 2);
1802                    pt1.style = 5;
1803                    pt2 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length / 2);
1804                    pt2.style = 20;     //for filled circle
1805                    pLinePoints[counter++] = new POINT2(pt0);
1806                    pLinePoints[counter++] = new POINT2(pt1);
1807                    xPoints[xCounter++] = new POINT2(pt2);
1808                }
1809                if (numSegs == 0) {
1810                    pLinePoints[counter] = new POINT2(pOriginalPoints[j]);
1811                    pLinePoints[counter++].style = 0;
1812                    pLinePoints[counter] = new POINT2(pOriginalPoints[j + 1]);
1813                    pLinePoints[counter++].style = 5;
1814                } else {
1815                    pLinePoints[counter] = new POINT2(pLinePoints[counter - 1]);
1816                    pLinePoints[counter++].style = 0;
1817                    pLinePoints[counter] = new POINT2(pOriginalPoints[j + 1]);
1818                    pLinePoints[counter++].style = 5;
1819                }
1820            }
1821            //load the circle points
1822            for (k = 0; k < xCounter; k++) {
1823                pLinePoints[counter++] = new POINT2(xPoints[k]);
1824            }
1825            //add one more circle
1826            pLinePoints[counter++] = new POINT2(pLinePoints[counter]);
1827
1828            pOriginalPoints = null;
1829            xPoints = null;
1830        } catch (Exception exc) {
1831            ErrorLogger.LogException(_className, "GetPipePoints",
1832                    new RendererException("GetPipePoints", exc));
1833        }
1834        return counter;
1835    }
1836
1837    private static int GetReefPoints(POINT2[] pLinePoints,
1838            double length,
1839            int vblCounter) {
1840        int counter = 0;
1841        try {
1842            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1843            POINT2 pt0 = new POINT2();
1844            POINT2 pt1 = new POINT2();
1845            POINT2 pt2 = new POINT2();
1846            POINT2 pt3 = new POINT2();
1847            POINT2 pt4 = new POINT2();
1848            //POINT2 pt5=new POINT2();
1849            for (int j = 0; j < vblCounter; j++) {
1850                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1851            }
1852
1853            int numSegs = 0, direction = 0;
1854            double d = 0;
1855            for (int j = 0; j < vblCounter - 1; j++) {
1856                if (pOriginalPoints[j].x < pOriginalPoints[j + 1].x) {
1857                    direction = 2;
1858                } else {
1859                    direction = 3;
1860                }
1861
1862                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1863                numSegs = (int) (d / length);
1864                for (int k = 0; k < numSegs; k++) {
1865                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1866
1867                    pt1 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .35);
1868                    pt1 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt1, direction, length);//was 2
1869
1870                    pt2 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .4);
1871                    pt2 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, direction, length * .6);//was 2
1872
1873                    pt3 = lineutility.ExtendAlongLineDouble2(pt0, pOriginalPoints[j + 1], length * .75);
1874                    pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt3, direction, length * 1.35);//was 2
1875
1876                    pt4 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * (k + 1));
1877                    pLinePoints[counter++] = new POINT2(pt0);
1878                    pLinePoints[counter++] = new POINT2(pt1);
1879                    pLinePoints[counter++] = new POINT2(pt2);
1880                    pLinePoints[counter++] = new POINT2(pt3);
1881                    pLinePoints[counter++] = new POINT2(pt4);
1882                }
1883                if (numSegs == 0) {
1884                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j]);
1885                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j + 1]);
1886                }
1887            }
1888            pLinePoints[counter++] = new POINT2(pOriginalPoints[vblCounter - 1]);
1889            pOriginalPoints = null;
1890        } catch (Exception exc) {
1891            ErrorLogger.LogException(_className, "GetReefPoints",
1892                    new RendererException("GetReefPoints", exc));
1893        }
1894        return counter;
1895    }
1896
1897    private static int GetRestrictedAreaPoints(POINT2[] pLinePoints,
1898            double length,
1899            int vblCounter) {
1900        int counter = 0;
1901        try {
1902            POINT2[] pOriginalPoints = new POINT2[vblCounter];
1903            POINT2 pt0 = new POINT2();
1904            POINT2 pt1 = new POINT2();
1905            POINT2 pt2 = new POINT2();
1906            POINT2 pt3 = new POINT2();
1907            for (int j = 0; j < vblCounter; j++) {
1908                pOriginalPoints[j] = new POINT2(pLinePoints[j]);
1909            }
1910            int direction = 0;
1911            int numSegs = 0;
1912            double d = 0;
1913            for (int j = 0; j < vblCounter - 1; j++) {
1914                d = lineutility.CalcDistanceDouble(pOriginalPoints[j], pOriginalPoints[j + 1]);
1915                numSegs = (int) (d / length);
1916                if (pOriginalPoints[j].x < pOriginalPoints[j + 1].x) {
1917                    direction = 3;
1918                } else {
1919                    direction = 2;
1920                }
1921                for (int k = 0; k < numSegs; k++) {
1922                    pt0 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k);
1923                    pt0.style = 0;
1924                    pt1 = lineutility.ExtendAlongLineDouble2(pOriginalPoints[j], pOriginalPoints[j + 1], length * k + length * 2 / 3);
1925                    pt1.style = 5;
1926                    pt2 = lineutility.MidPointDouble(pt0, pt1, 0);
1927                    //pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, 3, 10);
1928                    pt3 = lineutility.ExtendDirectedLine(pOriginalPoints[j], pOriginalPoints[j + 1], pt2, direction, length * 2 / 3);
1929                    pt3.style = 5;
1930                    pLinePoints[counter++] = new POINT2(pt2);
1931                    pLinePoints[counter++] = new POINT2(pt3);
1932                    pLinePoints[counter++] = new POINT2(pt0);
1933                    pLinePoints[counter++] = new POINT2(pt1);
1934                }
1935                if (numSegs == 0) {
1936                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j]);
1937                    pLinePoints[counter++] = new POINT2(pOriginalPoints[j + 1]);
1938                }
1939            }
1940            pLinePoints[counter - 1].style = 0;
1941            pLinePoints[counter++] = new POINT2(pOriginalPoints[vblCounter - 1]);
1942        } catch (Exception exc) {
1943            ErrorLogger.LogException(_className, "GetRestrictedAreaPoints",
1944                    new RendererException("GetRestrictedAreaPoints", exc));
1945        }
1946        return counter;
1947    }
1948
1949    //there should be two linetypes depending on scale
1950    private static int getOverheadWire(TGLight tg, POINT2[] pLinePoints, int vblCounter) {
1951        int counter = 0;
1952        try {
1953            int j = 0;
1954            POINT2 pt = null, pt2 = null;
1955            ArrayList<POINT2> pts = new ArrayList();
1956            for (j = 0; j < vblCounter; j++) {
1957                pt = new POINT2(pLinePoints[j]);
1958                //tower
1959                pt2 = new POINT2(pt);
1960                pt2.y -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1961                pts.add(pt2);
1962                pt2 = new POINT2(pt);
1963                pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1964                pts.add(pt2);
1965                pt2 = new POINT2(pt);
1966                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1967                pts.add(pt2);
1968                pt2 = new POINT2(pt);
1969                pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1970                pts.add(pt2);
1971                pt2 = new POINT2(pt);
1972                pt2.y -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1973                pt2.style = 5;
1974                pts.add(pt2);
1975                //low cross piece
1976                pt2 = new POINT2(pt);
1977                pt2.x -= arraysupport.getScaledSize(2, tg.get_LineThickness(), tg.get_patternScale());
1978                pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1979                pts.add(pt2);
1980                pt2 = new POINT2(pt);
1981                pt2.x += arraysupport.getScaledSize(2, tg.get_LineThickness(), tg.get_patternScale());
1982                pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
1983                pt2.style = 5;
1984                pts.add(pt2);
1985                //high cross piece
1986                pt2 = new POINT2(pt);
1987                pt2.x -= arraysupport.getScaledSize(7, tg.get_LineThickness(), tg.get_patternScale());
1988                pt2.y -= arraysupport.getScaledSize(17, tg.get_LineThickness(), tg.get_patternScale());
1989                pts.add(pt2);
1990                pt2 = new POINT2(pt);
1991                pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1992                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1993                pts.add(pt2);
1994                pt2 = new POINT2(pt);
1995                pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
1996                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
1997                pts.add(pt2);
1998                pt2 = new POINT2(pt);
1999                pt2.x += arraysupport.getScaledSize(7, tg.get_LineThickness(), tg.get_patternScale());
2000                pt2.y -= arraysupport.getScaledSize(17, tg.get_LineThickness(), tg.get_patternScale());
2001                pt2.style = 5;
2002                pts.add(pt2);
2003                //angle piece
2004                pt2 = new POINT2(pt);
2005                pt2.y -= arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale());
2006                pts.add(pt2);
2007                pt2 = new POINT2(pt);
2008                pt2.x += arraysupport.getScaledSize(8, tg.get_LineThickness(), tg.get_patternScale());
2009                pt2.y -= arraysupport.getScaledSize(12, tg.get_LineThickness(), tg.get_patternScale());
2010                pt2.style = 5;
2011                pts.add(pt2);
2012            }
2013            //connect the towers
2014            for (j = 0; j < vblCounter - 1; j++) {
2015                pt = new POINT2(pLinePoints[j]);
2016                pt2 = new POINT2(pLinePoints[j + 1]);
2017                if (pt.x < pt2.x) {
2018                    pt.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
2019                    pt.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
2020                    pt2.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
2021                    pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
2022                    pt2.style = 5;
2023                } else {
2024                    pt.x -= arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
2025                    pt.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
2026                    pt2.x += arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale());
2027                    pt2.y -= arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
2028                    pt2.style = 5;
2029                }
2030                pts.add(pt);
2031                pts.add(pt2);
2032            }
2033            for (j = 0; j < pts.size(); j++) {
2034                pLinePoints[j] = pts.get(j);
2035                counter++;
2036            }
2037            for (j = counter; j < pLinePoints.length; j++) {
2038                pLinePoints[j] = new POINT2(pLinePoints[counter - 1]);
2039            }
2040        } catch (Exception exc) {
2041            ErrorLogger.LogException(_className, "GetOverheadWire",
2042                    new RendererException("GetOverheadWire", exc));
2043        }
2044        return counter;
2045    }
2046
2047    //private static int linetype=-1; //use for BLOCK, CONTIAN
2048    /**
2049     * Calculates the points for the non-channel symbols. The points will be
2050     * stored in the original POINT2 array in pixels, pLinePoints. The client
2051     * points occupy the first vblSaveCounter positions in pLinePoints and will
2052     * be overwritten by the symbol points.
2053     *
2054     * @param pLinePoints - OUT - an array of POINT2
2055     * @param vblCounter the number of points allocated
2056     * @param vblSaveCounter the number of client points
2057     *
2058     * @return the symbol point count
2059     */
2060    private static ArrayList<POINT2> GetLineArray2Double(TGLight tg,
2061            POINT2[] pLinePoints,
2062            int vblCounter,
2063            int vblSaveCounter,
2064            ArrayList<Shape2> shapes,
2065            Rectangle2D clipBounds,
2066            IPointConversion converter) {
2067        ArrayList<POINT2> points = new ArrayList();
2068        try {
2069            int lineType = tg.get_LineType();
2070            String client = CELineArray.getClient();
2071            if (pLinePoints == null || pLinePoints.length < 2) {
2072                return null;
2073            }
2074            int[] segments = null;
2075            double dMRR = 0;
2076            int n = 0, bolVertical = 0;
2077            double dExtendLength = 0;
2078            double dWidth = 0;
2079            int nQuadrant = 0;
2080            int lLinestyle = 0, pointCounter = 0;
2081            ref<double[]> offsetX = new ref(), offsetY = new ref();
2082            double b = 0, b1 = 0, dRadius = 0, d1 = 0, d = 0;
2083            ref<double[]> m = new ref();
2084            int direction = 0;
2085            int nCounter = 0;
2086            int j = 0, k = 0, middleSegment = -1;
2087            double dMBR = lineutility.MBRDistance(pLinePoints, vblSaveCounter);
2088            POINT2 pt0 = new POINT2(pLinePoints[0]), //calculation points for autoshapes
2089                    pt1 = new POINT2(pLinePoints[1]),
2090                    pt2 = new POINT2(pLinePoints[1]),
2091                    pt3 = new POINT2(pLinePoints[0]),
2092                    pt4 = new POINT2(pLinePoints[0]),
2093                    pt5 = new POINT2(pLinePoints[0]),
2094                    pt6 = new POINT2(pLinePoints[0]),
2095                    pt7 = new POINT2(pLinePoints[0]),
2096                    pt8 = new POINT2(pLinePoints[0]),
2097                    ptYIntercept = new POINT2(pLinePoints[0]),
2098                    ptYIntercept1 = new POINT2(pLinePoints[0]),
2099                    ptCenter = new POINT2(pLinePoints[0]);
2100            POINT2[] pArrowPoints = new POINT2[3],
2101                    arcPts = new POINT2[26],
2102                    circlePoints = new POINT2[100],
2103                    pts = null, pts2 = null;
2104            POINT2 midpt = new POINT2(pLinePoints[0]), midpt1 = new POINT2(pLinePoints[0]);
2105
2106            POINT2[] pOriginalLinePoints = null;
2107            POINT2[] pUpperLinePoints = null;
2108            POINT2[] pLowerLinePoints = null;
2109            POINT2[] pUpperLowerLinePoints = null;
2110
2111            POINT2 calcPoint0 = new POINT2(),
2112                    calcPoint1 = new POINT2(),
2113                    calcPoint2 = new POINT2(),
2114                    calcPoint3 = new POINT2(),
2115                    calcPoint4 = new POINT2();
2116            POINT2 ptTemp = new POINT2(pLinePoints[0]);
2117            int acCounter = 0;
2118            POINT2[] acPoints = new POINT2[6];
2119            int lFlotCount = 0;
2120            //end declarations
2121
2122            //Bearing line and others only have 2 points
2123            if (vblCounter > 2) {
2124                pt2 = new POINT2(pLinePoints[2]);
2125            }
2126            pt0.style = 0;
2127            pt1.style = 0;
2128            pt2.style = 0;
2129
2130            //set jaggylength in clsDISMSupport before the points get bounded
2131            ArrayList xPoints = null;
2132            pOriginalLinePoints = new POINT2[vblSaveCounter];
2133            for (j = 0; j < vblSaveCounter; j++) {
2134                pOriginalLinePoints[j] = new POINT2(pLinePoints[j]);
2135            }
2136
2137            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
2138
2139            //resize the array and get the line array
2140            //for the specified non-channel line type
2141            switch (lineType) {
2142                case TacticalLines.BBS_AREA:
2143                    lineutility.getExteriorPoints(pLinePoints, vblSaveCounter, lineType, false);
2144                    acCounter = vblSaveCounter;
2145                    break;
2146                case TacticalLines.BS_CROSS:
2147                    pt0 = new POINT2(pLinePoints[0]);
2148                    pLinePoints[0] = new POINT2(pt0);
2149                    pLinePoints[0].x -= 10;
2150                    pLinePoints[1] = new POINT2(pt0);
2151                    pLinePoints[1].x += 10;
2152                    pLinePoints[1].style = 10;
2153                    pLinePoints[2] = new POINT2(pt0);
2154                    pLinePoints[2].y += 10;
2155                    pLinePoints[3] = new POINT2(pt0);
2156                    pLinePoints[3].y -= 10;
2157                    acCounter = 4;
2158                    break;
2159                case TacticalLines.BS_RECTANGLE:
2160                    lineutility.CalcMBRPoints(pLinePoints, pLinePoints.length, pt0, pt2);   //pt0=ul, pt1=lr
2161                    pt1 = new POINT2(pt0);
2162                    pt1.x = pt2.x;
2163                    pt3 = new POINT2(pt0);
2164                    pt3.y = pt2.y;
2165                    pLinePoints = new POINT2[5];
2166                    pLinePoints[0] = new POINT2(pt0);
2167                    pLinePoints[1] = new POINT2(pt1);
2168                    pLinePoints[2] = new POINT2(pt2);
2169                    pLinePoints[3] = new POINT2(pt3);
2170                    pLinePoints[4] = new POINT2(pt0);
2171                    acCounter = 5;
2172                    break;
2173                case TacticalLines.BBS_RECTANGLE:
2174                    //double xmax=pLinePoints[0].x,xmin=pLinePoints[1].x,ymax=pLinePoints[0].y,ymin=pLinePoints[1].y;
2175                    //double xmax=pLinePoints[2].x,xmin=pLinePoints[0].x,ymax=pLinePoints[2].y,ymin=pLinePoints[0].y;
2176                    double buffer = pLinePoints[0].style;
2177
2178                    pOriginalLinePoints = new POINT2[5];
2179                    pOriginalLinePoints[0] = new POINT2(pLinePoints[0]);
2180                    pOriginalLinePoints[1] = new POINT2(pLinePoints[1]);
2181                    pOriginalLinePoints[2] = new POINT2(pLinePoints[2]);
2182                    pOriginalLinePoints[3] = new POINT2(pLinePoints[3]);
2183                    pOriginalLinePoints[4] = new POINT2(pLinePoints[0]);
2184
2185                    //clockwise orientation
2186                    pt0 = pLinePoints[0];
2187                    pt0.x -= buffer;
2188                    pt0.y -= buffer;
2189                    pt1 = pLinePoints[1];
2190                    pt1.x += buffer;
2191                    pt1.y -= buffer;
2192                    pt2 = pLinePoints[2];
2193                    pt2.x += buffer;
2194                    pt2.y += buffer;
2195                    pt3 = pLinePoints[3];
2196                    pt3.x -= buffer;
2197                    pt3.y += buffer;
2198                    pLinePoints = new POINT2[5];
2199                    pLinePoints[0] = new POINT2(pt0);
2200                    pLinePoints[1] = new POINT2(pt1);
2201                    pLinePoints[2] = new POINT2(pt2);
2202                    pLinePoints[3] = new POINT2(pt3);
2203                    pLinePoints[4] = new POINT2(pt0);
2204                    vblSaveCounter = 5;
2205                    acCounter = 5;
2206                    break;
2207                case TacticalLines.BS_ELLIPSE:
2208                    pt0 = pLinePoints[0];//the center of the ellipse
2209                    pt1 = pLinePoints[1];//the width of the ellipse
2210                    pt2 = pLinePoints[2];//the height of the ellipse
2211                    //pLinePoints=getEllipsePoints(pt0,pt1,pt2);
2212                    double azimuth = pLinePoints[3].x;
2213                    pLinePoints = getRotatedEllipsePoints(pt0, pt1, pt2, azimuth, lineType);
2214                    acCounter = 37;
2215                    break;
2216                case TacticalLines.OVERHEAD_WIRE:
2217                    acCounter = getOverheadWire(tg, pLinePoints, vblSaveCounter);
2218                    break;
2219                case TacticalLines.BOUNDARY:
2220                case TacticalLines.TRIP:
2221                    acCounter = pLinePoints.length;
2222                    break;
2223                case TacticalLines.REEF:
2224                    vblCounter = GetReefPoints(pLinePoints, arraysupport.getScaledSize(40, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2225                    acCounter = vblCounter;
2226                    break;
2227                case TacticalLines.RESTRICTED_AREA:
2228                    vblCounter = GetRestrictedAreaPoints(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2229                    acCounter = vblCounter;
2230                    break;
2231                case TacticalLines.TRAINING_AREA:
2232                    dMBR = lineutility.MBRDistance(pLinePoints, vblSaveCounter);
2233                    d = 20 * DPIScaleFactor;
2234                    if (dMBR < 60 * DPIScaleFactor) {
2235                        d = dMBR / 4;
2236                    }
2237                    if (d < 5 * DPIScaleFactor) {
2238                        d = 5 * DPIScaleFactor;
2239                    }
2240                    for (j = 0; j < vblSaveCounter; j++) {
2241                        pLinePoints[j].style = 1;
2242                    }
2243                    pLinePoints[vblSaveCounter - 1].style = 5;
2244                    pt0 = lineutility.CalcCenterPointDouble(pLinePoints, vblSaveCounter - 1);
2245                    //lineutility.CalcCircleDouble(pt0, 20, 26, arcPts, 0);
2246                    lineutility.CalcCircleDouble(pt0, d, 26, arcPts, 0);
2247
2248                    for (j = vblSaveCounter; j < vblSaveCounter + 26; j++) {
2249                        pLinePoints[j] = new POINT2(arcPts[j - vblSaveCounter]);
2250                    }
2251                    pLinePoints[j - 1].style = 5;
2252
2253                    //! inside the circle
2254                    if (dMBR < 50 * DPIScaleFactor) {
2255                        //d was used as the circle radius
2256                        d *= 0.6;
2257                    } else {
2258                        d = 12 * DPIScaleFactor;
2259                    }
2260
2261                    pt1 = new POINT2(pt0);
2262                    pt1.y -= d;
2263                    pt1.style = 0;
2264                    pt2 = new POINT2(pt1);
2265                    pt2.y += d;
2266                    pt2.style = 5;
2267                    pt3 = new POINT2(pt2);
2268                    pt3.y += d / 4 + tg.get_LineThickness();
2269                    pt3.style = 0;
2270                    pt4 = new POINT2(pt3);
2271                    pt4.y += d / 4;
2272                    pLinePoints[j++] = new POINT2(pt1);
2273                    pLinePoints[j++] = new POINT2(pt2);
2274                    pLinePoints[j++] = new POINT2(pt3);
2275                    pt4.style = 5;
2276                    pLinePoints[j++] = new POINT2(pt4);
2277                    vblCounter = j;
2278                    acCounter = vblCounter;
2279                    break;
2280                case TacticalLines.PIPE:
2281                    vblCounter = GetPipePoints(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2282                    acCounter = vblCounter;
2283                    break;
2284                case TacticalLines.ANCHORAGE_AREA:
2285                    //get the direction and quadrant of the first segment
2286                    n = GetInsideOutsideDouble2(pLinePoints[0], pLinePoints[1], pLinePoints, vblSaveCounter, 0, lineType);
2287                    nQuadrant = lineutility.GetQuadrantDouble(pLinePoints[0], pLinePoints[1]);
2288                    //if the direction and quadrant are not compatible with GetFlotDouble then
2289                    //reverse the points
2290                    switch (nQuadrant) {
2291                        case 4:
2292                            switch (n) {
2293                                case 1: //extend left
2294                                case 2: //extend below
2295                                    break;
2296                                case 0: //extend right
2297                                case 3: //extend above
2298                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2299                                    break;
2300                                default:
2301                                    break;
2302                            }
2303                            break;
2304                        case 1:
2305                            switch (n) {
2306                                case 1: //extend left
2307                                case 3: //extend above
2308                                    break;
2309                                case 0: //extend right
2310                                case 2: //extend below
2311                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2312                                    break;
2313                                default:
2314                                    break;
2315                            }
2316                            break;
2317                        case 2:
2318                            switch (n) {
2319                                case 1: //extend left
2320                                case 2: //extend below
2321                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2322                                    break;
2323                                case 0: //extend right
2324                                case 3: //extend above
2325                                    break;
2326                                default:
2327                                    break;
2328                            }
2329                            break;
2330                        case 3:
2331                            switch (n) {
2332                                case 1: //extend left
2333                                case 3: //extend above
2334                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2335                                    break;
2336                                case 0: //extend right
2337                                case 2: //extend above
2338                                    break;
2339                                default:
2340                                    break;
2341                            }
2342                            break;
2343                        default:
2344                            break;
2345                    }
2346                    lFlotCount = GetAnchorageDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2347                    acCounter = lFlotCount;
2348                    break;
2349                case TacticalLines.ANCHORAGE_LINE:
2350                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2351                    acCounter = GetAnchorageDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2352                    break;
2353                case TacticalLines.LRO:
2354                    int xCount = countsupport.GetXPointsCount(pOriginalLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2355                    POINT2[] xPoints2 = new POINT2[xCount];
2356                    int lvoCount = countsupport.GetLVOCount(pOriginalLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2357                    POINT2[] lvoPoints = new POINT2[lvoCount];
2358                    xCount = GetXPoints(pOriginalLinePoints, xPoints2, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2359                    lvoCount = GetLVOPoints(pOriginalLinePoints, lvoPoints, arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2360                    for (k = 0; k < xCount; k++) {
2361                        pLinePoints[k] = new POINT2(xPoints2[k]);
2362                    }
2363                    if (xCount > 0) {
2364                        pLinePoints[xCount - 1].style = 5;
2365                    }
2366                    for (k = 0; k < lvoCount; k++) {
2367                        pLinePoints[xCount + k] = new POINT2(lvoPoints[k]);
2368                    }
2369                    acCounter = xCount + lvoCount;
2370                    break;
2371                case TacticalLines.UNDERCAST:
2372                    if (pLinePoints[0].x < pLinePoints[1].x) {
2373                        lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2374                    }
2375
2376                    lFlotCount = flot.GetFlotDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2377                    acCounter = lFlotCount;
2378                    break;
2379                case TacticalLines.LVO:
2380                    acCounter = GetLVOPoints(pOriginalLinePoints, pLinePoints, arraysupport.getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2381                    break;
2382                case TacticalLines.ICING:
2383                    vblCounter = GetIcingPointsDouble(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2384                    acCounter = vblCounter;
2385                    break;
2386                case TacticalLines.MVFR:
2387                    //get the direction and quadrant of the first segment
2388                    n = GetInsideOutsideDouble2(pLinePoints[0], pLinePoints[1], pLinePoints, vblSaveCounter, 0, lineType);
2389                    nQuadrant = lineutility.GetQuadrantDouble(pLinePoints[0], pLinePoints[1]);
2390                    //if the direction and quadrant are not compatible with GetFlotDouble then
2391                    //reverse the points
2392                    switch (nQuadrant) {
2393                        case 4:
2394                            switch (n) {
2395                                case 0: //extend left
2396                                case 3: //extend below
2397                                    break;
2398                                case 1: //extend right
2399                                case 2: //extend above
2400                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2401                                    break;
2402                                default:
2403                                    break;
2404                            }
2405                            break;
2406                        case 1:
2407                            switch (n) {
2408                                case 0: //extend left
2409                                case 2: //extend above
2410                                    break;
2411                                case 1: //extend right
2412                                case 3: //extend below
2413                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2414                                    break;
2415                                default:
2416                                    break;
2417                            }
2418                            break;
2419                        case 2:
2420                            switch (n) {
2421                                case 0: //extend left
2422                                case 3: //extend below
2423                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2424                                    break;
2425                                case 1: //extend right
2426                                case 2: //extend above
2427                                    break;
2428                                default:
2429                                    break;
2430                            }
2431                            break;
2432                        case 3:
2433                            switch (n) {
2434                                case 0: //extend left
2435                                case 2: //extend above
2436                                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2437                                    break;
2438                                case 1: //extend right
2439                                case 3: //extend above
2440                                    break;
2441                                default:
2442                                    break;
2443                            }
2444                            break;
2445                        default:
2446                            break;
2447                    }
2448                    lFlotCount = flot.GetFlotDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2449                    acCounter = lFlotCount;
2450                    break;
2451                case TacticalLines.ITD:
2452                    acCounter = GetITDPointsDouble(pLinePoints, arraysupport.getScaledSize(15, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2453                    break;
2454                case TacticalLines.CONVERGENCE:
2455                    acCounter = GetConvergencePointsDouble(pLinePoints, arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2456                    break;
2457                case TacticalLines.RIDGE:
2458                    vblCounter = GetRidgePointsDouble(tg, pLinePoints, vblSaveCounter);
2459                    acCounter = vblCounter;
2460                    break;
2461                case TacticalLines.TROUGH:
2462                case TacticalLines.UPPER_TROUGH:
2463                case TacticalLines.INSTABILITY:
2464                case TacticalLines.SHEAR:
2465                    vblCounter = GetSquallDouble(pLinePoints, arraysupport.getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale()), 6, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2466                    acCounter = vblCounter;
2467                    break;
2468                case TacticalLines.CABLE:
2469                    vblCounter = GetSquallDouble(pLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), 6, arraysupport.getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2470                    acCounter = vblCounter;
2471                    break;
2472                case TacticalLines.SQUALL:
2473                    vblCounter = GetSevereSquall(pLinePoints, arraysupport.getScaledSize(30, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
2474                    acCounter = vblCounter;
2475                    break;
2476                case TacticalLines.SF:
2477                case TacticalLines.USF:
2478                case TacticalLines.SFG:
2479                case TacticalLines.SFY:
2480                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2481                    vblCounter = flot.GetSFPointsDouble(tg, pLinePoints, vblSaveCounter);
2482                    acCounter = vblCounter;
2483                    break;
2484                case TacticalLines.OFY:
2485                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2486                    vblCounter = flot.GetOFYPointsDouble(tg, pLinePoints, vblSaveCounter);
2487                    acCounter = vblCounter;
2488                    break;
2489                case TacticalLines.OCCLUDED:
2490                case TacticalLines.UOF:
2491                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2492                    vblCounter = flot.GetOccludedPointsDouble(tg, pLinePoints, vblSaveCounter);
2493                    for (j = 0; j < vblSaveCounter; j++) {
2494                        pLinePoints[vblCounter + j] = pOriginalLinePoints[j];
2495                    }
2496                    vblCounter += vblSaveCounter;
2497                    acCounter = vblCounter;
2498                    break;
2499                case TacticalLines.WF:
2500                case TacticalLines.UWF:
2501                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2502                    lFlotCount = flot.GetFlot2Double(tg, pLinePoints, vblSaveCounter);
2503                    for (j = 0; j < vblSaveCounter; j++) {
2504                        pLinePoints[vblCounter - vblSaveCounter + j] = pOriginalLinePoints[j];
2505                    }
2506                    acCounter = lFlotCount + vblSaveCounter;
2507                    break;
2508                case TacticalLines.WFG:
2509                case TacticalLines.WFY:
2510                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
2511                    lFlotCount = flot.GetFlot2Double(tg, pLinePoints, vblSaveCounter);
2512                    acCounter = lFlotCount;
2513                    break;
2514                case TacticalLines.CFG:
2515                case TacticalLines.CFY:
2516                    vblCounter = GetATWallPointsDouble(tg, pLinePoints, vblSaveCounter);
2517                    acCounter = vblCounter;
2518                    break;
2519                case TacticalLines.CF:
2520                case TacticalLines.UCF:
2521                    vblCounter = GetATWallPointsDouble(tg, pLinePoints, vblSaveCounter);
2522                    pLinePoints[vblCounter - 1].style = 5;
2523                    for (j = 0; j < vblSaveCounter; j++) {
2524                        pLinePoints[vblCounter + j] = pOriginalLinePoints[j];
2525                    }
2526                    vblCounter += vblSaveCounter;
2527                    pLinePoints[vblCounter - 1].style = 5;
2528                    acCounter = vblCounter;
2529                    break;
2530                case TacticalLines.IL:
2531                case TacticalLines.PLANNED:
2532                case TacticalLines.ESR1:
2533                case TacticalLines.ESR2:
2534                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt0, pt1);
2535                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pt0);
2536                    pt4 = lineutility.ExtendLineDouble(pt0, pLinePoints[0], d);
2537                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pt4, pt2, pt3);
2538                    pLinePoints[0] = new POINT2(pt0);
2539                    pLinePoints[1] = new POINT2(pt1);
2540                    pLinePoints[2] = new POINT2(pt3);
2541                    pLinePoints[3] = new POINT2(pt2);
2542                    switch (lineType) {
2543                        case TacticalLines.IL:
2544                        case TacticalLines.ESR2:
2545                            pLinePoints[0].style = 0;
2546                            pLinePoints[1].style = 5;
2547                            pLinePoints[2].style = 0;
2548                            break;
2549                        case TacticalLines.PLANNED:
2550                            pLinePoints[0].style = 1;
2551                            pLinePoints[1].style = 5;
2552                            pLinePoints[2].style = 1;
2553                            break;
2554                        case TacticalLines.ESR1:
2555                            pLinePoints[1].style = 5;
2556                            if (pt0.x <= pt1.x) {
2557                                if (pLinePoints[1].y <= pLinePoints[2].y) {
2558                                    pLinePoints[0].style = 0;
2559                                    pLinePoints[2].style = 1;
2560                                } else {
2561                                    pLinePoints[0].style = 1;
2562                                    pLinePoints[2].style = 0;
2563                                }
2564                            } else {
2565                                if (pLinePoints[1].y >= pLinePoints[2].y) {
2566                                    pLinePoints[0].style = 0;
2567                                    pLinePoints[2].style = 1;
2568                                } else {
2569                                    pLinePoints[0].style = 1;
2570                                    pLinePoints[2].style = 0;
2571                                }
2572                            }
2573                            break;
2574                        default:
2575                            break;
2576                    }
2577                    acCounter = 4;
2578                    break;
2579                case TacticalLines.FORDSITE:
2580                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt0, pt1);
2581                    pLinePoints[0].style = 1;
2582                    pLinePoints[1].style = 5;
2583                    pLinePoints[2] = new POINT2(pt0);
2584                    pLinePoints[2].style = 1;
2585                    pLinePoints[3] = new POINT2(pt1);
2586                    pLinePoints[3].style = 5;
2587                    acCounter = 4;
2588                    break;
2589                case TacticalLines.ROADBLK:
2590                    pts = new POINT2[4];
2591                    for (j = 0; j < 4; j++) {
2592                        pts[j] = new POINT2(pLinePoints[j]);
2593                    }
2594                    dRadius = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
2595                    d = lineutility.CalcDistanceToLineDouble(pLinePoints[0], pLinePoints[1], pLinePoints[2]);
2596
2597                    //first two lines
2598                    pLinePoints[0] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[1], d, 0);
2599                    pLinePoints[1] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[0], d, 5);
2600                    pLinePoints[2] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[1], -d, 0);
2601                    pLinePoints[3] = lineutility.ExtendTrueLinePerpDouble(pts[0], pts[1], pts[0], -d, 5);
2602
2603                    midpt = lineutility.MidPointDouble(pts[0], pts[1], 0);
2604                    //move the midpoint
2605                    midpt = lineutility.ExtendLineDouble(pts[0], midpt, d);
2606
2607                    //the next line
2608                    pLinePoints[4] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, 105, dRadius / 2);
2609                    pLinePoints[5] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, -75, dRadius / 2);
2610                    pLinePoints[5].style = 5;
2611
2612                    //recompute the original midpt because it was moved
2613                    midpt = lineutility.MidPointDouble(pts[0], pts[1], 0);
2614                    //move the midpoint
2615                    midpt = lineutility.ExtendLineDouble(pts[1], midpt, d);
2616
2617                    //the last line
2618                    pLinePoints[6] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, 105, dRadius / 2);
2619                    pLinePoints[7] = lineutility.ExtendAngledLine(pts[0], pts[1], midpt, -75, dRadius / 2);
2620                    pLinePoints[7].style = 5;
2621
2622                    acCounter = 8;
2623                    break;
2624                case TacticalLines.AIRFIELD:
2625                    AirfieldCenterFeature(pLinePoints, vblCounter);
2626                    acCounter = vblCounter;
2627                    //FillPoints(pLinePoints,acCounter,points);
2628                    break;
2629                case TacticalLines.PNO:
2630                case TacticalLines.PLD:
2631                case TacticalLines.CFL:
2632                    for (j = 0; j < vblCounter; j++) {
2633                        pLinePoints[j].style = 1;
2634                    }
2635
2636                    acCounter = vblCounter;
2637                    break;
2638                case TacticalLines.FENCED:
2639                    FillPoints(pLinePoints, vblCounter, points);
2640                    xPoints = lineutility.LineOfXPoints(tg, pOriginalLinePoints);
2641                    for (j = 0; j < xPoints.size(); j++) {
2642                        points.add((POINT2) xPoints.get(j));
2643                    }
2644
2645                    acCounter = points.size();
2646                    break;
2647                case TacticalLines.FOXHOLE:
2648                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
2649
2650                    if (bolVertical == 0) //line is vertical
2651                    {
2652                        if (pt0.y > pt1.y) {
2653                            direction = 0;
2654                        } else {
2655                            direction = 1;
2656                        }
2657                    }
2658                    if (bolVertical != 0 && m.value[0] <= 1) {
2659                        if (pt0.x < pt1.x) {
2660                            direction = 3;
2661                        } else {
2662                            direction = 2;
2663                        }
2664                    }
2665                    if (bolVertical != 0 && m.value[0] > 1) {
2666                        if (pt0.x < pt1.x && pt0.y > pt1.y) {
2667                            direction = 1;
2668                        }
2669                        if (pt0.x < pt1.x && pt0.y < pt1.y) {
2670                            direction = 0;
2671                        }
2672
2673                        if (pt0.x > pt1.x && pt0.y > pt1.y) {
2674                            direction = 1;
2675                        }
2676                        if (pt0.x > pt1.x && pt0.y < pt1.y) {
2677                            direction = 0;
2678                        }
2679                    }
2680
2681                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
2682                        dMBR = 20 * maxLength * DPIScaleFactor;
2683                    }
2684                    if (dMBR / 20 < minLength * DPIScaleFactor) {
2685                        dMBR = 20 * minLength * DPIScaleFactor;
2686                    }
2687                    if (dMBR < 250 * DPIScaleFactor) {
2688                        dMBR = 250 * DPIScaleFactor;
2689                    }
2690                    if (dMBR > 500 * DPIScaleFactor) {
2691                        dMBR = 500 * DPIScaleFactor;
2692                    }
2693
2694                    pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, direction, dMBR / 20);
2695                    pLinePoints[1] = new POINT2(pt0);
2696                    pLinePoints[2] = new POINT2(pt1);
2697                    pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, direction, dMBR / 20);
2698                    acCounter = 4;
2699                    break;
2700                case TacticalLines.ISOLATE:
2701                case TacticalLines.CORDONKNOCK:
2702                case TacticalLines.CORDONSEARCH:
2703                case TacticalLines.DENY:
2704                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2705                    acCounter = 50;
2706                    break;
2707                case TacticalLines.AREA_DEFENSE:
2708                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2709                    acCounter = 67;
2710                    break;
2711                case TacticalLines.OCCUPY:
2712                case TacticalLines.CONTROL:
2713                case TacticalLines.LOCATE:
2714                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2715                    acCounter = 32;
2716                    break;
2717                case TacticalLines.RETAIN:
2718                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2719                    acCounter = 75;
2720                    break;
2721                case TacticalLines.SECURE:
2722                    GetIsolatePointsDouble(pLinePoints, lineType, converter);
2723                    acCounter = 29;
2724                    break;
2725                case TacticalLines.TURN_REVD:
2726                case TacticalLines.TURN:
2727                    // Switch first and last point. Order changed in 2525C
2728                    POINT2 swapPt = pLinePoints[0];
2729                    pLinePoints[0] = pLinePoints[1];
2730                    pLinePoints[1] = swapPt;
2731                    GetIsolatePointsDouble(pLinePoints, lineType, null);
2732                    acCounter = 29;
2733                    break;
2734                case TacticalLines.ENCIRCLE:
2735                case TacticalLines.ZONE:
2736                case TacticalLines.OBSAREA:
2737                case TacticalLines.OBSFAREA:
2738                case TacticalLines.STRONG:
2739                case TacticalLines.FORT_REVD:
2740                case TacticalLines.FORT:
2741                    acCounter = GetZONEPointsDouble2(tg, pLinePoints, vblSaveCounter);
2742                    break;
2743                case TacticalLines.ATWALL:
2744                case TacticalLines.LINE:  //7-9-07
2745                    acCounter = GetATWallPointsDouble2(tg, pLinePoints, vblSaveCounter);
2746                    break;
2747                case TacticalLines.SC:
2748                case TacticalLines.MRR:
2749                case TacticalLines.SL:
2750                case TacticalLines.TC:
2751                case TacticalLines.LLTR:        //added 5-4-07
2752                case TacticalLines.SAAFR:       //these have multiple segments
2753                case TacticalLines.AC:
2754                    boolean bolSegmentAC = false;
2755                    //uncomment the next line if the air corridor is segmented
2756                    bolSegmentAC = true;
2757                    dMRR = dACP;
2758                    lineutility.InitializePOINT2Array(acPoints);
2759                    lineutility.InitializePOINT2Array(arcPts);
2760                    acCounter = 0;
2761                    if (!bolSegmentAC) {
2762                        for (j = 0; j < vblSaveCounter; j++) {
2763                            if (pOriginalLinePoints[j].style <= 0) {
2764                                pOriginalLinePoints[j].style = 1; //was 14
2765                            }
2766                        }
2767                    }
2768                    //get the SAAFR segments
2769                    for (j = 0; j < vblSaveCounter - 1; j++) {
2770                        //diagnostic: use style member for dMBR
2771                        dMBR = pOriginalLinePoints[j].style;
2772                        acPoints[0] = new POINT2(pOriginalLinePoints[j]);
2773                        acPoints[1] = new POINT2(pOriginalLinePoints[j + 1]);
2774                        lineutility.GetSAAFRSegment(acPoints, lineType, dMBR);//was dMRR
2775                        for (k = 0; k < 6; k++) {
2776                            pLinePoints[acCounter] = new POINT2(acPoints[k]);
2777                            acCounter++;
2778                        }
2779                    }
2780                    //get the circles
2781                    int currentCircleSize = 0;
2782                    if (!bolSegmentAC) 
2783                    {
2784                        for (j = 0; j < vblSaveCounter - 1; j++) {
2785                            currentCircleSize = pOriginalLinePoints[j].style;
2786                            //nextCircleSize=pOriginalLinePoints[j+1].style;                        
2787
2788                            //draw the circle at the segment front end
2789                            arcPts[0] = new POINT2(pOriginalLinePoints[j]);
2790                            //diagnostic: use style member for dMBR
2791                            dMBR = currentCircleSize;
2792                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);//was dMRR
2793                            arcPts[25].style = 5;
2794                            for (k = 0; k < 26; k++) {
2795                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2796                                acCounter++;
2797                            }
2798
2799                            //draw the circle at the segment back end
2800                            arcPts[0] = new POINT2(pOriginalLinePoints[j + 1]);
2801                            dMBR = currentCircleSize;
2802                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);//was dMRR
2803                            arcPts[25].style = 5;
2804                            for (k = 0; k < 26; k++) {
2805                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2806                                acCounter++;
2807                            }
2808                        }
2809                    } 
2810                    else    //segmented air corridors 
2811                    {
2812                        int lastCircleSize = 0;
2813                        POINT2 lastCirclePoint = null;
2814                        for (j = 0; j < vblSaveCounter; j++) {
2815                            currentCircleSize = pOriginalLinePoints[j].style;
2816                            if (j == 0) {
2817                                lastCircleSize = currentCircleSize;
2818                                lastCirclePoint = pOriginalLinePoints[j];
2819                                continue;
2820                            }
2821                            if (currentCircleSize < 0) {
2822                                continue;
2823                            }
2824                            //the current circle point
2825                            arcPts[0] = new POINT2(pOriginalLinePoints[j]);
2826                            dMBR = lastCircleSize;
2827                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);
2828                            arcPts[25].style = 5;
2829                            for (k = 0; k < 26; k++) {
2830                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2831                                acCounter++;
2832                            }
2833                            //the previous circle point
2834                            arcPts[0] = new POINT2(lastCirclePoint);
2835                            lineutility.CalcCircleDouble(arcPts[0], dMBR, 26, arcPts, 0);
2836                            arcPts[25].style = 5;
2837                            for (k = 0; k < 26; k++) {
2838                                pLinePoints[acCounter] = new POINT2(arcPts[k]);
2839                                acCounter++;
2840                            }
2841                            //set the last values
2842                            lastCircleSize = currentCircleSize;
2843                            lastCirclePoint = pOriginalLinePoints[j];
2844                        }
2845                    }
2846                    break;
2847                case TacticalLines.MINED:
2848                case TacticalLines.UXO:
2849                case TacticalLines.ACOUSTIC:
2850                case TacticalLines.ACOUSTIC_AMB:
2851                case TacticalLines.BEARING:
2852                case TacticalLines.BEARING_J:
2853                case TacticalLines.BEARING_RDF:
2854                case TacticalLines.ELECTRO:
2855                case TacticalLines.BEARING_EW:
2856                case TacticalLines.TORPEDO:
2857                case TacticalLines.OPTICAL:
2858                    acCounter = vblCounter;
2859                    break;
2860                case TacticalLines.MSDZ:
2861                    lineutility.InitializePOINT2Array(circlePoints);
2862                    pt3 = new POINT2(pLinePoints[3]);
2863                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
2864                    if(converter==null)
2865                    {
2866                        dRadius = lineutility.CalcDistanceDouble(pt0, pt1);
2867                        lineutility.CalcCircleDouble(pt0, dRadius, 100,
2868                                circlePoints, 0);
2869                    }
2870                    else    //use the converter
2871                        lineutility.CalcCircleDouble2(pt0, pt1, 100,
2872                            circlePoints, converter);
2873                    for (j = 0; j < 100; j++) {
2874                        pLinePoints[j] = new POINT2(circlePoints[j]);
2875                    }
2876                    pLinePoints[99].style = 5;
2877                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt2);
2878                    if(converter==null)
2879                    {
2880                        dRadius = lineutility.CalcDistanceDouble(pt0, pt2);
2881                        lineutility.CalcCircleDouble(pt0, dRadius, 100,
2882                            circlePoints, 0);
2883                    }
2884                    else
2885                        lineutility.CalcCircleDouble2(pt0, pt2, 100,
2886                            circlePoints, converter);
2887                    for (j = 0; j < 100; j++) {
2888                        pLinePoints[100 + j] = new POINT2(circlePoints[j]);
2889                    }
2890                    pLinePoints[199].style = 5;
2891                    //dRadius = lineutility.CalcDistanceDouble(pt0, pt3);
2892                   if (vblSaveCounter == 4) {
2893                       if (converter == null) {
2894                           dRadius = lineutility.CalcDistanceDouble(pt0, pt3);
2895                           lineutility.CalcCircleDouble(pt0, dRadius, 100,
2896                                   circlePoints, 0);
2897                       } else
2898                           lineutility.CalcCircleDouble2(pt0, pt3, 100,
2899                                   circlePoints, converter);
2900                       for (j = 0; j < 100; j++) {
2901                           pLinePoints[200 + j] = new POINT2(circlePoints[j]);
2902                       }
2903                   }
2904                    acCounter = vblCounter;
2905                    //FillPoints(pLinePoints,acCounter,points);
2906                    break;
2907                case TacticalLines.CONVOY:
2908                    if (dMBR < 150 * DPIScaleFactor) {
2909                        dMBR = 150 * DPIScaleFactor;
2910                    }
2911                    if (dMBR > 500 * DPIScaleFactor) {
2912                        dMBR = 500 * DPIScaleFactor;
2913                    }
2914                    dWidth = dMBR / 25;
2915
2916                    pt0 = new POINT2(pLinePoints[0]);
2917                    pt1 = new POINT2(pLinePoints[1]);
2918
2919                    bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt0, m);
2920                    pt0 = lineutility.ExtendLine2Double(pt1, pt0, -dWidth*3, 0);
2921                    if (m.value[0] < 1) {
2922                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 2, dWidth);
2923                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 2, dWidth);
2924                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 3, dWidth);
2925                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 3, dWidth);
2926                    } else {
2927                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 0, dWidth);
2928                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 0, dWidth);
2929                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt0, pt1, pt1, 1, dWidth);
2930                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt0, pt1, pt0, 1, dWidth);
2931                    }
2932                    pt2 = lineutility.ExtendLineDouble(pt1, pt0, dWidth * 3);
2933                    lineutility.GetArrowHead4Double(pt0, pt2, (int) (dWidth * 3), (int) (dWidth * 3), pArrowPoints, 0);
2934
2935                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pArrowPoints[0]);
2936                    d1 = lineutility.CalcDistanceDouble(pLinePoints[3], pArrowPoints[0]);
2937                    pLinePoints[3].style = 5;
2938                    if (d < d1) {
2939                        pLinePoints[4] = new POINT2(pLinePoints[0]);
2940                        pLinePoints[4].style = 0;
2941                        pLinePoints[5] = new POINT2(pArrowPoints[0]);
2942                        pLinePoints[5].style = 0;
2943                        pLinePoints[6] = new POINT2(pArrowPoints[1]);
2944                        pLinePoints[6].style = 0;
2945                        pLinePoints[7] = new POINT2(pArrowPoints[2]);
2946                        pLinePoints[7].style = 0;
2947                        pLinePoints[8] = new POINT2(pLinePoints[3]);
2948                    } else {
2949                        pLinePoints[4] = pLinePoints[3];
2950                        pLinePoints[4].style = 0;
2951                        pLinePoints[5] = pArrowPoints[0];
2952                        pLinePoints[5].style = 0;
2953                        pLinePoints[6] = pArrowPoints[1];
2954                        pLinePoints[6].style = 0;
2955                        pLinePoints[7] = pArrowPoints[2];
2956                        pLinePoints[7].style = 0;
2957                        pLinePoints[8] = pLinePoints[0];
2958                    }
2959
2960                    acCounter = 9;
2961                    //FillPoints(pLinePoints,acCounter,points);
2962                    break;
2963                case TacticalLines.HCONVOY:
2964                    if (dMBR < 150 * DPIScaleFactor) {
2965                        dMBR = 150 * DPIScaleFactor;
2966                    }
2967                    if (dMBR > 500 * DPIScaleFactor) {
2968                        dMBR = 500 * DPIScaleFactor;
2969                    }
2970                    dWidth = dMBR / 25;
2971
2972                    pt0 = new POINT2(pLinePoints[0]);
2973                    pt1 = new POINT2(pLinePoints[1]);
2974
2975                    pt2 = lineutility.ExtendAlongLineDouble(pt0, pt1, dWidth * 2); // Arrow point
2976                    lineutility.GetArrowHead4Double(pt0, pt2, (int) dWidth * 2, (int) dWidth * 2, pArrowPoints, 0);
2977
2978                    bolVertical = lineutility.CalcTrueSlopeDouble(pt1, pt2, m);
2979                    if (m.value[0] < 1) {
2980                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_above, dWidth);
2981                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_above, dWidth);
2982                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_below, dWidth);
2983                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_below, dWidth);
2984                    } else {
2985                        pLinePoints[0] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_left, dWidth);
2986                        pLinePoints[1] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_left, dWidth);
2987                        pLinePoints[2] = lineutility.ExtendDirectedLine(pt2, pt1, pt1, lineutility.extend_right, dWidth);
2988                        pLinePoints[3] = lineutility.ExtendDirectedLine(pt2, pt1, pt2, lineutility.extend_right, dWidth);
2989                    }
2990
2991                    pLinePoints[4] = new POINT2(pLinePoints[0]);
2992                    pLinePoints[5] = new POINT2(pt2);
2993                    pLinePoints[5].style = 0;
2994
2995                    pLinePoints[6] = new POINT2(pArrowPoints[1]);
2996                    pLinePoints[7] = new POINT2(pArrowPoints[0]);
2997                    pLinePoints[8] = new POINT2(pArrowPoints[2]);
2998                    pLinePoints[8].style = 0;
2999                    pLinePoints[9] = new POINT2(pArrowPoints[1]);
3000
3001                    acCounter = 10;
3002                    //FillPoints(pLinePoints,acCounter,points);
3003                    break;
3004                case TacticalLines.MSR_ONEWAY:
3005                case TacticalLines.MSR_TWOWAY:
3006                case TacticalLines.MSR_ALT:
3007                case TacticalLines.ASR_ONEWAY:
3008                case TacticalLines.ASR_TWOWAY:
3009                case TacticalLines.ASR_ALT:
3010                case TacticalLines.TRAFFIC_ROUTE_ONEWAY:
3011                case TacticalLines.TRAFFIC_ROUTE_ALT:
3012                    nCounter = (int) vblSaveCounter;
3013                    pLinePoints[vblSaveCounter - 1].style = 5;
3014                    for (j = 0; j < vblSaveCounter - 1; j++) {
3015                        d = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
3016                        if (d < 20) //too short
3017                        {
3018                            continue;
3019                        }
3020                        pt0 = new POINT2(pLinePoints[j]);
3021                        pt1 = new POINT2(pLinePoints[j + 1]);
3022                        pt2 = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -3 * d / 4, 0);
3023                        pt3 = lineutility.ExtendLine2Double(pLinePoints[j], pLinePoints[j + 1], -1 * d / 4, 5);
3024                        double distFromLine = 10 * DPIScaleFactor;
3025                        direction = SupplyRouteArrowSide(pLinePoints[j], pLinePoints[j + 1]);
3026                        pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt2, direction, distFromLine);
3027                        pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt3, direction, distFromLine);
3028                        pLinePoints[nCounter] = new POINT2(pt2);
3029                        nCounter++;
3030                        pLinePoints[nCounter] = new POINT2(pt3);
3031                        nCounter++;
3032
3033                        d = distFromLine;
3034                        if (dMBR / 20 < minLength * DPIScaleFactor) {
3035                            d = 5 * DPIScaleFactor;
3036                        }
3037
3038                        lineutility.GetArrowHead4Double(pt2, pt3, (int) d, (int) d,
3039                                pArrowPoints, 0);
3040
3041                        for (k = 0; k < 3; k++) {
3042                            pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
3043                            nCounter++;
3044                        }
3045
3046                        if (lineType == TacticalLines.MSR_ALT || lineType == TacticalLines.ASR_ALT || lineType == TacticalLines.TRAFFIC_ROUTE_ALT) {
3047                            lineutility.GetArrowHead4Double(pt3, pt2, (int) d, (int) d,
3048                                    pArrowPoints, 0);
3049
3050                            for (k = 0; k < 3; k++) {
3051                                pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
3052                                nCounter++;
3053                            }
3054                        }
3055                        if (lineType == TacticalLines.MSR_TWOWAY || lineType == TacticalLines.ASR_TWOWAY) {
3056                            distFromLine = 15 * DPIScaleFactor;
3057                            pt2 = lineutility.ExtendDirectedLine(pt0, pt1, pt2, direction, distFromLine);
3058                            pt3 = lineutility.ExtendDirectedLine(pt0, pt1, pt3, direction, distFromLine);
3059
3060                            pLinePoints[nCounter] = new POINT2(pt2);
3061                            nCounter++;
3062                            pLinePoints[nCounter] = new POINT2(pt3);
3063                            nCounter++;
3064                            lineutility.GetArrowHead4Double(pt3, pt2, (int) d, (int) d,
3065                                    pArrowPoints, 0);
3066
3067                            for (k = 0; k < 3; k++) {
3068                                pLinePoints[nCounter] = new POINT2(pArrowPoints[k]);
3069                                nCounter++;
3070                            }
3071                        }
3072                    }
3073                    acCounter = nCounter;
3074                    break;
3075                case TacticalLines.FORDIF:
3076                    lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pLinePoints[2], pt4, pt5);   //as pt2,pt3
3077                    pLinePoints[2] = new POINT2(pt5);//was pt3
3078                    pLinePoints[3] = new POINT2(pt4);//was pt2
3079
3080                    for (j = 0; j < vblCounter; j++) {
3081                        pLinePoints[j].style = 1;
3082                    }
3083
3084                    pt0 = lineutility.MidPointDouble(pLinePoints[0], pLinePoints[1], 0);
3085                    pt1 = lineutility.MidPointDouble(pLinePoints[2], pLinePoints[3], 0);
3086                    POINT2[] savepoints = null;
3087                    Boolean drawJaggies = true;
3088                    if (clipBounds != null) {
3089                        POINT2 ul = new POINT2(clipBounds.getMinX(), clipBounds.getMinY());
3090                        POINT2 lr = new POINT2(clipBounds.getMaxX(), clipBounds.getMaxY());
3091                        savepoints = lineutility.BoundOneSegment(pt0, pt1, ul, lr);
3092                        if (savepoints != null && savepoints.length > 1) {
3093                            pt0 = savepoints[0];
3094                            pt1 = savepoints[1];
3095                        } else {
3096                            savepoints = new POINT2[2];
3097                            savepoints[0] = new POINT2(pt0);
3098                            savepoints[1] = new POINT2(pt1);
3099                            drawJaggies = false;
3100                        }
3101                    }
3102
3103                    midpt = lineutility.MidPointDouble(pt0, pt1, 0);
3104                    double dist0 = lineutility.CalcDistanceDouble(midpt, pt0);
3105                    double dist1 = lineutility.CalcDistanceDouble(midpt, pt1);
3106
3107                    if (dist0 > dist1) {
3108                        lineutility.LineRelativeToLine(pLinePoints[2], pLinePoints[3], pt0, pt4, pt5);
3109                        pLinePoints[0] = new POINT2(pt5.x, pt5.y, 1);
3110                        pLinePoints[1] = new POINT2(pt4.x, pt4.y, 1);
3111                    } else {
3112                        lineutility.LineRelativeToLine(pLinePoints[0], pLinePoints[1], pt1, pt4, pt5);
3113                        pLinePoints[2] = new POINT2(pt5.x, pt5.y, 1);
3114                        pLinePoints[3] = new POINT2(pt4.x, pt4.y, 1);
3115                    }
3116
3117                    //end section
3118                    //calculate start, end points for upper and lower lines
3119                    //across the middle
3120                    double spikeLength = getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
3121                    pt2 = lineutility.ExtendLine2Double(pLinePoints[0], pt0, -spikeLength, 0);
3122                    pt3 = lineutility.ExtendLine2Double(pLinePoints[3], pt1, -spikeLength, 0);
3123                    pt4 = lineutility.ExtendLine2Double(pLinePoints[0], pt0, spikeLength, 0);
3124                    pt5 = lineutility.ExtendLine2Double(pLinePoints[3], pt1, spikeLength, 0);
3125
3126                    dWidth = lineutility.CalcDistanceDouble(pt0, pt1);
3127
3128                    pointCounter = 4;
3129                    n = 1;
3130                    pLinePoints[pointCounter] = new POINT2(pt0);
3131                    pLinePoints[pointCounter].style = 0;
3132                    pointCounter++;
3133                    if (drawJaggies) {
3134                        while (dExtendLength < dWidth - spikeLength) {
3135                            dExtendLength = (double) n * spikeLength / 2;
3136                            pLinePoints[pointCounter] = lineutility.ExtendLine2Double(pt2, pt3, dExtendLength - dWidth, 0);
3137                            pointCounter++;
3138                            n++;
3139                            //dExtendLength = (double) n * 10;
3140                            dExtendLength = (double) n * spikeLength / 2;
3141                            pLinePoints[pointCounter] = lineutility.ExtendLine2Double(pt4, pt5, dExtendLength - dWidth, 0);
3142                            pointCounter++;
3143                            if (pointCounter >= pLinePoints.length - 1) {
3144                                break;
3145                            }
3146                            n++;
3147                        }
3148                    }
3149                    pLinePoints[pointCounter] = new POINT2(pt1);
3150                    pLinePoints[pointCounter].style = 5;
3151                    pointCounter++;
3152                    acCounter = pointCounter;
3153                    break;
3154                case TacticalLines.ATDITCH:
3155                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3156                    break;
3157                case (int) TacticalLines.ATDITCHC:      //extra Points were calculated by a function
3158                    pLinePoints[0].style = 9;
3159                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3160                    //pLinePoints[vblCounter-1].style=10;
3161                    break;
3162                case TacticalLines.ATDITCHM:
3163                    lineutility.ReversePointsDouble2(
3164                            pLinePoints,
3165                            vblSaveCounter);
3166                    pLinePoints[0].style = 9;
3167                    acCounter = lineutility.GetDitchSpikeDouble(tg, pLinePoints, vblSaveCounter, 0);
3168                    break;
3169                case TacticalLines.DIRATKGND:
3170                    //was 20
3171                    if (dMBR / 30 > maxLength * DPIScaleFactor) {
3172                        dMBR = 30 * maxLength * DPIScaleFactor;
3173                    }
3174                    if (dMBR / 30 < minLength * DPIScaleFactor) {
3175                        dMBR = 30 * minLength * DPIScaleFactor;
3176                    }
3177                    if (dMBR < 150 * DPIScaleFactor) {
3178                        dMBR = 150 * DPIScaleFactor;
3179                    }
3180                    if (dMBR > 500 * DPIScaleFactor) {
3181                        dMBR = 500 * DPIScaleFactor;
3182                    }
3183
3184                    d = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
3185                    if (d < dMBR / 40) {
3186                        pLinePoints[1] = lineutility.ExtendLineDouble(pLinePoints[0], pLinePoints[1], dMBR / 40 + 1);
3187                    }
3188
3189                    pLinePoints[0] = lineutility.ExtendAlongLineDouble(pLinePoints[0], pLinePoints[1], dMBR / 40);
3190
3191                    //reverse the points
3192                    lineutility.ReversePointsDouble2(
3193                            pLinePoints,
3194                            vblSaveCounter);
3195
3196                    pt0 = new POINT2(pLinePoints[vblCounter - 12]);
3197                    pt1 = new POINT2(pLinePoints[vblCounter - 11]);
3198                    pt2 = lineutility.ExtendLineDouble(pt0, pt1, dMBR / 40);
3199                    lineutility.GetArrowHead4Double(pt0, pt1, (int) dMBR / 20, (int) dMBR / 20,
3200                            pArrowPoints, 0);
3201
3202                    for (j = 0; j < 3; j++) {
3203                        pLinePoints[vblCounter - 10 + j] = new POINT2(pArrowPoints[j]);
3204                    }
3205                    lineutility.GetArrowHead4Double(pt0, pt2, (int) (dMBR / 13.33), (int) (dMBR / 13.33),
3206                            pArrowPoints, 0);
3207
3208                    for (j = 0; j < 3; j++) {
3209                        pLinePoints[vblCounter - 7 + j] = new POINT2(pArrowPoints[j]);
3210                    }
3211
3212                    pLinePoints[vblCounter - 4] = new POINT2(pLinePoints[vblCounter - 10]);
3213                    pLinePoints[vblCounter - 4].style = 0;
3214                    pLinePoints[vblCounter - 3] = new POINT2(pLinePoints[vblCounter - 7]);
3215                    pLinePoints[vblCounter - 3].style = 5;
3216
3217                    pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 8]);
3218                    pLinePoints[vblCounter - 2].style = 0;
3219                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 5]);
3220                    pLinePoints[vblCounter - 1].style = 5;
3221                    acCounter = vblCounter;
3222                    break;
3223                case TacticalLines.MFLANE:
3224                case TacticalLines.RAFT:
3225                    pt2 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 8], pLinePoints[vblCounter - 7], dMBR / 2);
3226                    pt3 = new POINT2(pLinePoints[vblCounter - 7]);
3227                    pt1 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 2);
3228
3229                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3230                        dMBR = 10 * maxLength * DPIScaleFactor;
3231                    }
3232                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3233                        dMBR = 10 * minLength * DPIScaleFactor;
3234                    }
3235                    if (dMBR > 250 * DPIScaleFactor) {
3236                        dMBR = 250 * DPIScaleFactor;
3237                    }
3238
3239                    lineutility.GetArrowHead4Double(pt2, pt3, (int) dMBR / 10, (int) dMBR / 5,
3240                            pArrowPoints, 0);
3241
3242                    for (k = 0; k < 3; k++) {
3243                        pLinePoints[vblCounter - 6 + k] = new POINT2(pArrowPoints[k]);
3244                    }
3245
3246                    lineutility.GetArrowHead4Double(pt1, pt0, (int) dMBR / 10, (int) dMBR / 5,
3247                            pArrowPoints, 0);
3248
3249                    for (k = 0; k < 3; k++) {
3250                        pLinePoints[vblCounter - 3 + k] = new POINT2(pArrowPoints[k]);
3251                    }
3252                    pLinePoints[vblSaveCounter - 1].style = 5;
3253                    acCounter = vblCounter;
3254                    break;
3255                case TacticalLines.DIRATKAIR:
3256                    lineutility.ReversePointsDouble2(
3257                            pLinePoints,
3258                            vblSaveCounter);
3259
3260                    for (k = vblSaveCounter - 1; k > 0; k--) {
3261                        d += lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k - 1]);
3262                        if (d > 60) {
3263                            break;
3264                        }
3265                    }
3266                    if (d > 60) {
3267                        middleSegment = k;
3268                        pt2 = pLinePoints[middleSegment];
3269                        if (middleSegment >= 1) {
3270                            pt3 = pLinePoints[middleSegment - 1];
3271                        }
3272                    } else {
3273                        if (vblSaveCounter <= 3) {
3274                            middleSegment = 1;
3275                        } else {
3276                            middleSegment = 2;
3277                        }
3278
3279                        pt2 = pLinePoints[middleSegment];
3280                        if (middleSegment >= 1) {
3281                            pt3 = pLinePoints[middleSegment - 1];
3282                        }
3283                    }
3284
3285                    pt0 = new POINT2(pLinePoints[0]);
3286
3287                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3288                        dMBR = 20 * maxLength * DPIScaleFactor;
3289                    }
3290                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3291                        dMBR = 20 * minLength * DPIScaleFactor;
3292                    }
3293                    if (dMBR < 150 * DPIScaleFactor) {
3294                        dMBR = 150 * DPIScaleFactor;
3295                    }
3296
3297                    if (dMBR > 250 * DPIScaleFactor) {
3298                        dMBR = 250 * DPIScaleFactor;
3299                    }
3300
3301                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 11], pLinePoints[vblCounter - 10], (int) dMBR / 20, (int) dMBR / 20,
3302                            pArrowPoints, 0);
3303
3304                    for (j = 0; j < 3; j++) {
3305                        pLinePoints[vblCounter - 9 + j] = new POINT2(pArrowPoints[j]);
3306                    }
3307
3308                    pLinePoints[vblCounter - 6].x = (pLinePoints[vblCounter - 11].x + pLinePoints[vblCounter - 10].x) / 2;
3309                    pLinePoints[vblCounter - 6].y = (pLinePoints[vblCounter - 11].y + pLinePoints[vblCounter - 10].y) / 2;
3310                    pt0 = new POINT2(pLinePoints[vblCounter - 6]);
3311                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 11], pt0, (int) dMBR / 20, (int) dMBR / 20,
3312                            pArrowPoints, 9);
3313
3314                    if (middleSegment >= 1) {
3315                        pt0 = lineutility.MidPointDouble(pt2, pt3, 0);
3316                        lineutility.GetArrowHead4Double(pt3, pt0, (int) dMBR / 20, (int) dMBR / 20,
3317                                pArrowPoints, 9);
3318                    }
3319
3320                    for (j = 0; j < 3; j++) {
3321                        pLinePoints[vblCounter - 6 + j] = new POINT2(pArrowPoints[j]);
3322                    }
3323
3324                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 10], pt0, (int) dMBR / 20, (int) dMBR / 20,
3325                            pArrowPoints, 9);
3326                    if (middleSegment >= 1) {
3327                        pt0 = lineutility.MidPointDouble(pt2, pt3, 0);
3328                        lineutility.GetArrowHead4Double(pt2, pt0, (int) dMBR / 20, (int) dMBR / 20,
3329                                pArrowPoints, 9);
3330                    }
3331                    for (j = 0; j < 3; j++) {
3332                        pLinePoints[vblCounter - 3 + j] = new POINT2(pArrowPoints[j]);
3333                    }
3334
3335                    //this section was added to remove fill from the bow tie feature
3336                    ArrayList<POINT2> airPts = new ArrayList();
3337                    pLinePoints[middleSegment - 1].style = 5;
3338                    //pLinePoints[middleSegment].style=14;
3339                    if (vblSaveCounter == 2) {
3340                        pLinePoints[1].style = 5;
3341                    }
3342
3343                    for (j = 0; j < vblCounter; j++) {
3344                        airPts.add(new POINT2(pLinePoints[j]));
3345                    }
3346
3347                    midpt = lineutility.MidPointDouble(pLinePoints[middleSegment - 1], pLinePoints[middleSegment], 0);
3348                    pt0 = lineutility.ExtendAlongLineDouble(midpt, pLinePoints[middleSegment], dMBR / 20, 0);
3349                    airPts.add(pt0);
3350                    pt1 = new POINT2(pLinePoints[middleSegment]);
3351                    pt1.style = 5;
3352                    airPts.add(pt1);
3353
3354                    pt0 = lineutility.ExtendAlongLineDouble(midpt, pLinePoints[middleSegment - 1], dMBR / 20, 0);
3355                    airPts.add(pt0);
3356                    pt1 = new POINT2(pLinePoints[middleSegment - 1]);
3357                    pt1.style = 5;
3358                    airPts.add(pt1);
3359
3360                    //re-dimension pLinePoints so that it can hold the
3361                    //the additional points required by the shortened middle segment
3362                    //which has the bow tie feature
3363                    vblCounter = airPts.size();
3364                    pLinePoints = new POINT2[airPts.size()];
3365                    for (j = 0; j < airPts.size(); j++) {
3366                        pLinePoints[j] = new POINT2(airPts.get(j));
3367                    }
3368                    //end section
3369
3370                    acCounter = vblCounter;
3371                    //FillPoints(pLinePoints,vblCounter,points);
3372                    break;
3373                case TacticalLines.PDF:
3374                    pt0 = new POINT2(pLinePoints[1]);
3375                    pt1 = new POINT2(pLinePoints[0]);
3376                    pLinePoints[0] = new POINT2(pt0);
3377                    pLinePoints[1] = new POINT2(pt1);
3378                    pts2 = new POINT2[3];
3379                    pts2[0] = new POINT2(pt0);
3380                    pts2[1] = new POINT2(pt1);
3381                    pts2[2] = new POINT2(pt2);
3382                    lineutility.GetPixelsMin(pts2, 3,
3383                            offsetX,
3384                            offsetY);
3385                    if (offsetX.value[0] < 0) {
3386                        offsetX.value[0] = offsetX.value[0] - 100;
3387                    } else {
3388                        offsetX.value[0] = 0;
3389                    }
3390
3391                    pLinePoints[2].style = 5;
3392
3393                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3394                        dMBR = 20 * maxLength * DPIScaleFactor;
3395                    }
3396                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3397                        dMBR = 20 * minLength * DPIScaleFactor;
3398                    }
3399                    if (dMBR > 500 * DPIScaleFactor) {
3400                        dMBR = 500 * DPIScaleFactor;
3401                    }
3402
3403                    double rectWidth = getScaledSize(2, tg.get_LineThickness() / 2.0, tg.get_patternScale());
3404
3405                    pt2 = lineutility.ExtendLineDouble(pt0, pt1, -dMBR / 10);
3406                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3407                    if (bolVertical != 0 && m.value[0] != 0) {
3408                        b = pt2.y + (1 / m.value[0]) * pt2.x;
3409                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3410                        ptYIntercept.x = offsetX.value[0];
3411                        ptYIntercept.y = b1;
3412                        pLinePoints[3] = lineutility.ExtendLineDouble(ptYIntercept, pt2, -rectWidth);
3413                        pLinePoints[3].style = 0;
3414                        pLinePoints[4] = lineutility.ExtendLineDouble(ptYIntercept, pt2, rectWidth);
3415                        pLinePoints[4].style = 0;
3416                    }
3417                    if (bolVertical != 0 && m.value[0] == 0) {
3418                        pLinePoints[3] = new POINT2(pt2);
3419                        pLinePoints[3].y = pt2.y - rectWidth;
3420                        pLinePoints[3].style = 0;
3421                        pLinePoints[4] = new POINT2(pt2);
3422                        pLinePoints[4].y = pt2.y + rectWidth;
3423                        pLinePoints[4].style = 0;
3424                    }
3425                    if (bolVertical == 0) {
3426                        pLinePoints[3] = new POINT2(pt2);
3427                        pLinePoints[3].x = pt2.x - rectWidth;
3428                        pLinePoints[3].style = 0;
3429                        pLinePoints[4] = new POINT2(pt2);
3430                        pLinePoints[4].x = pt2.x + rectWidth;
3431                        pLinePoints[4].style = 0;
3432                    }
3433
3434                    pt2 = lineutility.ExtendLineDouble(pt1, pt0, -dMBR / 10);
3435                    if (bolVertical != 0 && m.value[0] != 0) {
3436                        b = pt2.y + (1 / m.value[0]) * pt2.x;
3437                        //get the Y intercept at x=offsetX
3438                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3439                        ptYIntercept.x = offsetX.value[0];
3440                        ptYIntercept.y = b1;
3441                        pLinePoints[5] = lineutility.ExtendLineDouble(ptYIntercept, pt2, rectWidth);
3442                        pLinePoints[5].style = 0;
3443                        pLinePoints[6] = lineutility.ExtendLineDouble(ptYIntercept, pt2, -rectWidth);
3444                    }
3445                    if (bolVertical != 0 && m.value[0] == 0) {
3446                        pLinePoints[5] = new POINT2(pt2);
3447                        pLinePoints[5].y = pt2.y + rectWidth;
3448                        pLinePoints[5].style = 0;
3449                        pLinePoints[6] = new POINT2(pt2);
3450                        pLinePoints[6].y = pt2.y - rectWidth;
3451                    }
3452                    if (bolVertical == 0) {
3453                        pLinePoints[5] = new POINT2(pt2);
3454                        pLinePoints[5].x = pt2.x + rectWidth;
3455                        pLinePoints[5].style = 0;
3456                        pLinePoints[6] = new POINT2(pt2);
3457                        pLinePoints[6].x = pt2.x - rectWidth;
3458                    }
3459
3460                    pLinePoints[6].style = 0;
3461                    pLinePoints[7] = new POINT2(pLinePoints[3]);
3462                    pLinePoints[7].style = 5;
3463                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[0], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3464                    for (j = 0; j < 3; j++) {
3465                        pLinePoints[8 + j] = new POINT2(pArrowPoints[j]);
3466                    }
3467                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[2], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3468                    for (j = 0; j < 3; j++) {
3469                        pLinePoints[11 + j] = new POINT2(pArrowPoints[j]);
3470                        pLinePoints[11 + j].style = 0;
3471                    }
3472                    acCounter = 14;
3473                    break;
3474                case TacticalLines.DIRATKSPT:
3475                    if (lineType == TacticalLines.DIRATKSPT) {
3476                        //reverse the points
3477                        lineutility.ReversePointsDouble2(
3478                                pLinePoints,
3479                                vblSaveCounter);
3480                    }
3481                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3482                        dMBR = 20 * maxLength * DPIScaleFactor;
3483                    }
3484                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3485                        dMBR = 20 * minLength * DPIScaleFactor;
3486                    }
3487                    if (dMBR < 150 * DPIScaleFactor) {
3488                        dMBR = 150 * DPIScaleFactor;
3489                    }
3490                    if (dMBR > 500 * DPIScaleFactor) {
3491                        dMBR = 500 * DPIScaleFactor;
3492                    }
3493
3494                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 5], pLinePoints[vblCounter - 4], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3495                    for (k = 0; k < 3; k++) {
3496                        pLinePoints[vblCounter - k - 1] = new POINT2(pArrowPoints[k]);
3497                    }
3498                    acCounter = vblCounter;
3499                    break;
3500                case TacticalLines.EXFILTRATION:
3501                case TacticalLines.INFILTRATION:
3502
3503                    if (dMBR / 20 > maxLength * DPIScaleFactor) {
3504                        dMBR = 20 * maxLength * DPIScaleFactor;
3505                    }
3506                    if (dMBR / 20 < minLength * DPIScaleFactor) {
3507                        dMBR = 20 * minLength * DPIScaleFactor;
3508                    }
3509                    if (dMBR < 150 * DPIScaleFactor) {
3510                        dMBR = 150 * DPIScaleFactor;
3511                    }
3512                    if (dMBR > 500 * DPIScaleFactor) {
3513                        dMBR = 500 * DPIScaleFactor;
3514                    }
3515
3516                    pLinePoints = DISMSupport.GetInfiltrationDouble(pLinePoints);
3517                    vblCounter = pLinePoints.length;;
3518
3519                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 5], pLinePoints[vblCounter - 4], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3520                    for (k = 0; k < 3; k++) {
3521                        pLinePoints[vblCounter - k - 1] = new POINT2(pArrowPoints[k]);
3522                    }
3523                    points =  new ArrayList<>(Arrays.asList(pLinePoints));//set pixels to be used for integral modifier placement
3524                    acCounter = vblCounter;
3525                    break;
3526                case TacticalLines.EXPLOIT:
3527                    // Convert arrows to 90 degrees with the hypotenuse distance = distance between pt1 and pt2
3528                    int triBiSector = (int) (lineutility.CalcDistanceDouble(pt1, pt2) / Math.sqrt(2));
3529
3530                    // Arrow at pt1
3531                    lineutility.GetArrowHead4Double(pt1, pt0, triBiSector, triBiSector * 2, pArrowPoints, 0);
3532                    for (k = 0; k < 3; k++) {
3533                        pLinePoints[k+2] = new POINT2(pArrowPoints[k]);
3534                    }
3535
3536                    // Dashed tail at pt2
3537                    lineutility.GetArrowHead4Double(lineutility.ExtendLineDouble(pt0, pt1, 10), pt1, triBiSector, triBiSector * 2, pArrowPoints, 1);
3538                    for (k = 0; k < 3; k++) {
3539                        pLinePoints[k+5] = new POINT2(pArrowPoints[k]);
3540                    }
3541                    acCounter = vblCounter;
3542                    break;
3543                case TacticalLines.ABATIS:
3544                    //must use an x offset for ptYintercept because of extending from it
3545                    pts2 = new POINT2[2];
3546                    pts2[0] = new POINT2(pt0);
3547                    pts2[1] = new POINT2(pt1);
3548                    lineutility.GetPixelsMin(pts2, 2,
3549                            offsetX,
3550                            offsetY);
3551                    if (offsetX.value[0] <= 0) {
3552                        offsetX.value[0] = offsetX.value[0] - 100;
3553                    } else {
3554                        offsetX.value[0] = 0;
3555                    }
3556                    if (dMBR > 300 * DPIScaleFactor) {
3557                        dMBR = 300 * DPIScaleFactor;
3558                    }
3559
3560                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -dMBR / 10);
3561                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3562                    midpt.x = (pt0.x + pLinePoints[0].x) / 2;
3563                    midpt.y = (pt0.y + pLinePoints[0].y) / 2;
3564                    pLinePoints[vblCounter - 3] = new POINT2(pt0);
3565                    pLinePoints[vblCounter - 4].style = 5;
3566                    pLinePoints[vblCounter - 3].style = 0;
3567                    if (bolVertical != 0 && m.value[0] != 0) {
3568                        b = midpt.y + (1 / m.value[0]) * midpt.x;       //the line equation
3569                        //get Y intercept at x=offsetX
3570                        b1 = (-1 / m.value[0]) * offsetX.value[0] + b;
3571                        ptYIntercept.x = offsetX.value[0];
3572                        ptYIntercept.y = b1;
3573                        pLinePoints[vblCounter - 2] = lineutility.ExtendLineDouble(ptYIntercept, midpt, dMBR / 20);
3574                        if (pLinePoints[vblCounter - 2].y >= midpt.y) {
3575                            pLinePoints[vblCounter - 2] = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dMBR / 20);
3576                        }
3577                    }
3578                    if (bolVertical != 0 && m.value[0] == 0) //horizontal line
3579                    {
3580                        pLinePoints[vblCounter - 2] = new POINT2(midpt);
3581                        pLinePoints[vblCounter - 2].y = midpt.y - dMBR / 20;
3582                    }
3583                    if (bolVertical == 0) {
3584                        pLinePoints[vblCounter - 2] = new POINT2(midpt);
3585                        pLinePoints[vblCounter - 2].x = midpt.x - dMBR / 20;
3586                    }
3587                    pLinePoints[vblCounter - 2].style = 0;
3588                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[0]);
3589
3590                    //FillPoints(pLinePoints,vblCounter,points);
3591                    acCounter = vblCounter;
3592                    //FillPoints(pLinePoints,acCounter,points);
3593                    break;
3594                case TacticalLines.CLUSTER:
3595                    //must use an x offset for ptYintercept because of extending from it
3596                    pts2 = new POINT2[2];
3597
3598                    //for some reason occulus puts the points on top of one another
3599                    if (Math.abs(pt0.y - pt1.y) < 1) {
3600                        pt1.y = pt0.y + 1;
3601                    }
3602
3603                    pts2[0] = new POINT2(pt0);
3604                    pts2[1] = new POINT2(pt1);
3605
3606                    pts = new POINT2[26];
3607                    dRadius = lineutility.CalcDistanceDouble(pt0, pt1) / 2;
3608                    midpt.x = (pt1.x + pt0.x) / 2;
3609                    midpt.y = (pt1.y + pt0.y) / 2;
3610                    bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
3611                    if (bolVertical != 0 && m.value[0] != 0) //not vertical or horizontal
3612                    {
3613                        b = midpt.y + (1 / m.value[0]) * midpt.x;       //normal y intercept at x=0
3614                        ptYIntercept.x = 0;
3615                        ptYIntercept.y = b;
3616                        pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, dRadius);
3617                        if (pLinePoints[0].x <= pLinePoints[1].x) {
3618                            if (pt2.y >= midpt.y) {
3619                                pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dRadius);
3620                            }
3621                        } else {
3622                            if (pt2.y <= midpt.y) {
3623                                pt2 = lineutility.ExtendLineDouble(ptYIntercept, midpt, -dRadius);
3624                            }
3625                        }
3626
3627                    }
3628                    if (bolVertical != 0 && m.value[0] == 0) //horizontal line
3629                    {
3630                        pt2 = midpt;
3631                        if (pLinePoints[0].x <= pLinePoints[1].x) {
3632                            pt2.y = midpt.y - dRadius;
3633                        } else {
3634                            pt2.y = midpt.y + dRadius;
3635                        }
3636                    }
3637                    if (bolVertical == 0) //vertical line
3638                    {
3639                        pt2 = midpt;
3640                        if (pLinePoints[0].y <= pLinePoints[1].y) {
3641                            pt2.x = midpt.x + dRadius;
3642                        } else {
3643                            pt2.x = midpt.x - dRadius;
3644                        }
3645                    }
3646
3647                    pt1 = lineutility.ExtendLineDouble(midpt, pt2, 100);
3648
3649                    pts[0] = new POINT2(pt2);
3650                    pts[1] = new POINT2(pt1);
3651
3652                    lineutility.ArcArrayDouble(
3653                            pts,
3654                            0, dRadius,
3655                            lineType,
3656                            null);
3657                    pLinePoints[0].style = 1;
3658                    pLinePoints[1].style = 5;
3659                    for (j = 0; j < 26; j++) {
3660                        pLinePoints[2 + j] = new POINT2(pts[j]);
3661                        pLinePoints[2 + j].style = 1;
3662                    }
3663                    acCounter = 28;
3664                    break;
3665                case TacticalLines.FOLLA:
3666                    //reverse the points
3667                    lineutility.ReversePointsDouble2(pLinePoints, vblSaveCounter);
3668
3669                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3670                        dMBR = 10 * maxLength * DPIScaleFactor;
3671                    }
3672                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3673                        dMBR = 10 * minLength * DPIScaleFactor;
3674                    }
3675                    if (dMBR > 150 * DPIScaleFactor) {
3676                        dMBR = 150 * DPIScaleFactor;
3677                    }
3678
3679                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -2 * dMBR / 10);
3680
3681                    for (k = 0; k < vblCounter - 14; k++) {
3682                        pLinePoints[k].style = 18;
3683                    }
3684                    pLinePoints[vblCounter - 15].style = 5;
3685
3686                    pt0 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], 5 * dMBR / 10);
3687
3688                    lineutility.GetArrowHead4Double(pt0, pLinePoints[0], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3689                    for (k = 0; k < 3; k++) {
3690                        pLinePoints[vblCounter - 14 + k] = new POINT2(pArrowPoints[k]);
3691                    }
3692
3693                    pt3 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 10);
3694
3695                    lineutility.GetArrowHead4Double(pt0, pt3, (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3696                    pLinePoints[vblCounter - 12].style = 0;
3697                    pLinePoints[vblCounter - 11] = new POINT2(pArrowPoints[2]);
3698                    pLinePoints[vblCounter - 11].style = 0;
3699                    pLinePoints[vblCounter - 10] = new POINT2(pArrowPoints[0]);
3700                    pLinePoints[vblCounter - 10].style = 0;
3701                    pLinePoints[vblCounter - 9] = new POINT2(pLinePoints[vblCounter - 14]);
3702                    pLinePoints[vblCounter - 9].style = 5;
3703
3704                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, 0);
3705
3706                    for (k = 0; k < 3; k++) {
3707                        pLinePoints[vblCounter - 8 + k] = new POINT2(pArrowPoints[k]);
3708                    }
3709                    pLinePoints[vblCounter - 6].style = 0;
3710
3711                    //diagnostic to make first point tip of arrowhead    6-14-12
3712                    //pt3 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], 0.75 * dMBR / 10);
3713                    pt3 = lineutility.ExtendLineDouble(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], -0.75 * dMBR / 10);
3714                    pLinePoints[1] = pt3;
3715                    pLinePoints[1].style = 5;
3716                    //lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pt3, (int) (1.25 * dMBR / 10), (int) (1.25 * dMBR / 10), pArrowPoints, 0);
3717                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pt3, (int) (dMBR / 10), (int) (dMBR / 10), pArrowPoints, 0);
3718                    //end section
3719
3720                    for (k = 0; k < 3; k++) {
3721                        pLinePoints[vblCounter - 5 + k] = new POINT2(pArrowPoints[2 - k]);
3722                    }
3723                    pLinePoints[vblCounter - 5].style = 0;
3724
3725                    pLinePoints[vblCounter - 2] = new POINT2(pLinePoints[vblCounter - 8]);
3726                    pLinePoints[vblCounter - 2].style = 5;
3727                    pLinePoints[vblCounter - 1] = new POINT2(pLinePoints[vblCounter - 7]);
3728                    acCounter = 16;
3729                    break;
3730                case TacticalLines.FOLSP:
3731                    lineutility.ReversePointsDouble2(
3732                            pLinePoints,
3733                            vblSaveCounter);
3734
3735                    if (dMBR / 15 > maxLength * DPIScaleFactor) {
3736                        dMBR = 15 * maxLength * DPIScaleFactor;
3737                    }
3738                    if (dMBR / 15 < minLength * DPIScaleFactor) {
3739                        dMBR = 15 * minLength * DPIScaleFactor;
3740                    }
3741                    if (dMBR < 100 * DPIScaleFactor) {
3742                        dMBR = 100 * DPIScaleFactor;
3743                    }
3744                    if (dMBR > 500 * DPIScaleFactor) {
3745                        dMBR = 500 * DPIScaleFactor;
3746                    }
3747
3748                    //make tail larger 6-10-11 m. Deutch
3749                    pLinePoints[0] = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], -dMBR / 8.75);
3750
3751                    pLinePoints[vblCounter - 15].style = 5;
3752                    pt0 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 4);
3753
3754                    lineutility.GetArrowHead4Double(pt0, pLinePoints[0], (int) dMBR / 20, (int) dMBR / 20,
3755                            pArrowPoints, 0);
3756
3757                    for (k = 0; k < 3; k++) {
3758                        pLinePoints[vblCounter - 14 + k] = new POINT2(pArrowPoints[k]);
3759                    }
3760
3761                    pLinePoints[vblCounter - 12].style = 0;
3762
3763                    //make tail larger 6-10-11 m. Deutch
3764                    pt3 = lineutility.ExtendLineDouble(pLinePoints[1], pLinePoints[0], dMBR / 15);
3765
3766                    lineutility.GetArrowHead4Double(pt0, pt3, (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 0);
3767
3768                    for (k = 0; k < 3; k++) {
3769                        pLinePoints[vblCounter - 11 + k] = new POINT2(pArrowPoints[2 - k]);
3770                        pLinePoints[vblCounter - 11 + k].style = 0;
3771                    }
3772                    pLinePoints[vblCounter - 8] = new POINT2(pLinePoints[vblCounter - 14]);
3773                    pLinePoints[vblCounter - 8].style = 5;
3774
3775                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 16], pLinePoints[vblCounter - 15], (int) dMBR / 20, (int) dMBR / 20, pArrowPoints, 9);
3776
3777                    for (k = 0; k < 3; k++) {
3778                        pLinePoints[vblCounter - 7 + k] = new POINT2(pArrowPoints[k]);
3779                    }
3780                    for (k = 4; k > 0; k--) {
3781                        pLinePoints[vblCounter - k].style = 5;
3782                    }
3783                    acCounter = 12;
3784                    break;
3785                case TacticalLines.FERRY:
3786                    lLinestyle = 9;
3787                    if (dMBR / 10 > maxLength * DPIScaleFactor) {
3788                        dMBR = 10 * maxLength * DPIScaleFactor;
3789                    }
3790                    if (dMBR / 10 < minLength * DPIScaleFactor) {
3791                        dMBR = 10 * minLength * DPIScaleFactor;
3792                    }
3793                    if (dMBR > 250 * DPIScaleFactor) {
3794                        dMBR = 250 * DPIScaleFactor;
3795                    }
3796
3797                    lineutility.GetArrowHead4Double(pLinePoints[vblCounter - 8], pLinePoints[vblCounter - 7], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, lLinestyle);
3798                    for (k = 0; k < 3; k++) {
3799                        pLinePoints[vblCounter - 6 + k] = new POINT2(pArrowPoints[k]);
3800                    }
3801                    lineutility.GetArrowHead4Double(pLinePoints[1], pLinePoints[0], (int) dMBR / 10, (int) dMBR / 10, pArrowPoints, lLinestyle);
3802                    for (k = 0; k < 3; k++) {
3803                        pLinePoints[vblCounter - 3 + k] = new POINT2(pArrowPoints[k]);
3804                    }
3805
3806                    acCounter = 8;
3807                    break;
3808                case TacticalLines.NAVIGATION:
3809                    double extensionLength = getScaledSize(10, tg.get_LineThickness(), tg.get_patternScale());
3810                    pt3 = lineutility.ExtendLine2Double(pt1, pt0, -extensionLength, 0);
3811                    pt4 = lineutility.ExtendLine2Double(pt0, pt1, -extensionLength, 0);
3812
3813                    pt5 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt3, extensionLength, 0);
3814                    pt6 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt3, -extensionLength, 0);
3815                    pt7 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt4, extensionLength, 0);
3816                    pt8 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt4, -extensionLength, 0);
3817                    if (pt5.y < pt6.y) {
3818                        pLinePoints[0] = new POINT2(pt5);
3819                    } else {
3820                        pLinePoints[0] = new POINT2(pt6);
3821                    }
3822                    if (pt7.y > pt8.y) {
3823                        pLinePoints[3] = new POINT2(pt7);
3824                    } else {
3825                        pLinePoints[3] = new POINT2(pt8);
3826                    }
3827                    pLinePoints[1] = new POINT2(pt0);
3828                    pLinePoints[2] = new POINT2(pt1);
3829                    acCounter = 4;
3830                    break;
3831                case TacticalLines.FORTL:
3832                    acCounter = GetFORTLPointsDouble(tg, pLinePoints, vblSaveCounter);
3833                    break;
3834                case TacticalLines.CANALIZE:
3835                    acCounter = DISMSupport.GetDISMCanalizeDouble(pLinePoints, lineType);
3836                    break;
3837                case TacticalLines.BREACH:
3838                    acCounter = DISMSupport.GetDISMBreachDouble(pLinePoints, lineType);
3839                    break;
3840                case TacticalLines.SCREEN:
3841                case TacticalLines.GUARD:
3842                case TacticalLines.COVER:
3843                    if (vblSaveCounter == 4) {
3844                        acCounter = DISMSupport.GetDISMCoverDoubleRevC(pLinePoints, lineType, vblSaveCounter);
3845                    } else {
3846                        acCounter = DISMSupport.GetDISMCoverDouble(pLinePoints, lineType);
3847                    }
3848                    break;
3849                case TacticalLines.ESCORT:
3850                {
3851                    acCounter = DISMSupport.GetDISMEscortDouble(tg, pLinePoints, TacticalLines.ESCORT);
3852                    break;
3853                }
3854                case TacticalLines.SARA:
3855                    acCounter = DISMSupport.GetDISMCoverDouble(pLinePoints, lineType);
3856                    //reorder pLinePoints
3857                    POINT2[] saraPts = new POINT2[16];
3858                    for (j = 0; j < 4; j++) {
3859                        saraPts[j] = pLinePoints[j];  //0-3
3860                    }
3861                    for (j = 4; j < 8; j++) {
3862                        saraPts[j] = pLinePoints[j + 4];    //8-11
3863                    }
3864                    for (j = 8; j < 12; j++) {
3865                        saraPts[j] = pLinePoints[j - 4];    //4-7
3866                    }
3867                    for (j = 12; j < 16; j++) {
3868                        saraPts[j] = pLinePoints[j];  //12-15
3869                    }
3870                    pLinePoints = saraPts;
3871                    //acCounter=14;
3872                    break;
3873                case TacticalLines.DISRUPT:
3874                    acCounter = DISMSupport.GetDISMDisruptDouble(pLinePoints, lineType);
3875                    break;
3876                case TacticalLines.CONTAIN:
3877                    acCounter = DISMSupport.GetDISMContainDouble(pLinePoints, lineType);
3878                    break;
3879                case TacticalLines.PENETRATE:
3880                    DISMSupport.GetDISMPenetrateDouble(pLinePoints, lineType);
3881                    acCounter = 7;
3882                    break;
3883                case TacticalLines.MNFLDBLK:
3884                case TacticalLines.BLOCK:
3885                    DISMSupport.GetDISMBlockDouble2(
3886                            pLinePoints,
3887                            lineType);
3888                    acCounter = 4;
3889                    break;
3890                case TacticalLines.LINTGT:
3891                case TacticalLines.LINTGTS:
3892                case TacticalLines.FPF:
3893                    acCounter = DISMSupport.GetDISMLinearTargetDouble(pLinePoints, lineType, vblCounter);
3894                    break;
3895                case TacticalLines.GAP:
3896                case TacticalLines.ASLTXING:
3897                    DISMSupport.GetDISMGapDouble(
3898                            pLinePoints,
3899                            lineType);
3900                    acCounter = 12;
3901                    break;
3902                case TacticalLines.MNFLDDIS:
3903                    acCounter = DISMSupport.GetDISMMinefieldDisruptDouble(pLinePoints, lineType);
3904                    break;
3905                case TacticalLines.SPTBYFIRE:
3906                    acCounter = DISMSupport.GetDISMSupportByFireDouble(pLinePoints, lineType);
3907                    break;
3908                case TacticalLines.ATKBYFIRE:
3909                    acCounter = DISMSupport.GetDISMATKBYFIREDouble(pLinePoints, lineType);
3910                    break;
3911                case TacticalLines.BYIMP:
3912                    acCounter = DISMSupport.GetDISMByImpDouble(pLinePoints, lineType);
3913                    break;
3914                case TacticalLines.CLEAR:
3915                    acCounter = DISMSupport.GetDISMClearDouble(pLinePoints, lineType);
3916                    break;
3917                case TacticalLines.BYDIF:
3918                    acCounter = DISMSupport.GetDISMByDifDouble(pLinePoints, lineType, clipBounds);
3919                    break;
3920                case TacticalLines.SEIZE:
3921                case TacticalLines.CAPTURE:
3922                case TacticalLines.EVACUATE:
3923                    double radius = 0;
3924                    if (vblSaveCounter == 4) {
3925                        radius = lineutility.CalcDistanceDouble(pLinePoints[0], pLinePoints[1]);
3926                        pLinePoints[1] = new POINT2(pLinePoints[3]);
3927                        pLinePoints[2] = new POINT2(pLinePoints[2]);
3928                    }
3929                    acCounter = DISMSupport.GetDISMSeizeDouble(pLinePoints, lineType, radius);
3930                    break;
3931                case TacticalLines.FIX:
3932                case TacticalLines.MNFLDFIX:
3933                    acCounter = DISMSupport.GetDISMFixDouble(pLinePoints, lineType, clipBounds);
3934                    break;
3935                case TacticalLines.RIP:
3936                case TacticalLines.DEMONSTRATE:
3937                    acCounter = DISMSupport.GetDISMRIPDouble(pLinePoints, lineType);
3938                    break;
3939                case TacticalLines.MOBILE_DEFENSE:
3940                    pLinePoints[2] = lineutility.PointRelativeToLine(pt0, pt1, pt1, pt2);
3941                    pLinePoints[3] =  lineutility.PointRelativeToLine(pt0, pt1, pt0, pt2);
3942                    acCounter = DISMSupport.GetDISMRIPDouble(pLinePoints, lineType);
3943                    // Add spikes
3944                    POINT2[] trianglePts = new POINT2[18];
3945                    lineutility.InitializePOINT2Array(trianglePts);
3946                    int l = 0;
3947                    dRadius = lineutility.CalcDistanceDouble(pLinePoints[1], pLinePoints[2]) / 2;
3948                    POINT2 arcCenter = lineutility.MidPointDouble(pLinePoints[1], pLinePoints[2], 0);
3949                    double dLength = Math.abs(dRadius - 20);
3950                    if (dRadius < 40) {
3951                        dLength = dRadius / 1.5;
3952                    }
3953                    if (dRadius > 100) {
3954                        dLength = 0.8 * dRadius;
3955                    }
3956
3957                    POINT2 tmpPt = new POINT2();
3958                    tmpPt.x = arcCenter.x - (long) ((dRadius / dLength) * (arcCenter.x - pLinePoints[10].x));
3959                    tmpPt.y = arcCenter.y - (long) ((dRadius / dLength) * (arcCenter.y - pLinePoints[10].y));
3960                    trianglePts[l] = new POINT2(pLinePoints[10 - 1]);
3961                    trianglePts[l].style = 9;
3962                    l++;
3963                    trianglePts[l] = new POINT2(tmpPt);
3964                    trianglePts[l].style = 9;
3965                    l++;
3966                    trianglePts[l] = new POINT2(pLinePoints[10 + 1]);
3967                    trianglePts[l].style = 9;
3968                    l++;
3969                    trianglePts[l] = new POINT2(pLinePoints[10]);
3970                    trianglePts[l].style = 9;
3971                    l++;
3972                    trianglePts[l] = new POINT2(pLinePoints[10 - 1]);
3973                    trianglePts[l].style = 10;
3974                    l++;
3975
3976                    tmpPt.x = arcCenter.x - (long) ((dRadius / dLength) * (arcCenter.x - pLinePoints[22].x));
3977                    tmpPt.y = arcCenter.y - (long) ((dRadius / dLength) * (arcCenter.y - pLinePoints[22].y));
3978                    trianglePts[l] = new POINT2(pLinePoints[22 - 1]);
3979                    trianglePts[l].style = 9;
3980                    l++;
3981                    trianglePts[l] = new POINT2(tmpPt);
3982                    trianglePts[l].style = 9;
3983                    l++;
3984                    trianglePts[l] = new POINT2(pLinePoints[22 + 1]);
3985                    trianglePts[l].style = 9;
3986                    l++;
3987                    trianglePts[l] = new POINT2(pLinePoints[22]);
3988                    trianglePts[l].style = 9;
3989                    l++;
3990                    trianglePts[l] = new POINT2(pLinePoints[22 - 1]);
3991                    trianglePts[l].style = 10;
3992                    l++;
3993
3994                    double triangleBaseLen = lineutility.CalcDistanceDouble(trianglePts[0], trianglePts[2]);
3995                    double triangleHeight = lineutility.CalcDistanceDouble(trianglePts[1], trianglePts[3]);
3996                    trianglePts[l] = lineutility.ExtendAlongLineDouble(pLinePoints[3], pLinePoints[2], lineutility.CalcDistanceDouble(pt0, pt1) / 8, 9);
3997                    trianglePts[l].style = 9;
3998                    l++;
3999
4000                    trianglePts[l] = lineutility.ExtendAlongLineDouble2(trianglePts[l-1], pLinePoints[2], triangleBaseLen);
4001                    trianglePts[l].style = 9;
4002                    l++;
4003
4004                    trianglePts[l] = lineutility.ExtendDirectedLine(trianglePts[l-2], trianglePts[l-1],
4005                            lineutility.MidPointDouble(trianglePts[l-2], trianglePts[l-1], 0), lineutility.extend_above, triangleHeight);
4006                    trianglePts[l].style = 9;
4007                    l++;
4008
4009                    trianglePts[l] = new POINT2(trianglePts[l-3]);
4010                    trianglePts[l].style = 10;
4011                    l++;
4012
4013                    trianglePts[l] = lineutility.ExtendAlongLineDouble(pLinePoints[0], pLinePoints[1], lineutility.CalcDistanceDouble(pt0, pt1) / 8, 9);
4014                    trianglePts[l].style = 9;
4015                    l++;
4016
4017                    trianglePts[l] = lineutility.ExtendAlongLineDouble2(trianglePts[l-1], pLinePoints[1], triangleBaseLen);
4018                    trianglePts[l].style = 9;
4019                    l++;
4020
4021                    trianglePts[l] = lineutility.ExtendDirectedLine(trianglePts[l-2], trianglePts[l-1],
4022                            lineutility.MidPointDouble(trianglePts[l-2], trianglePts[l-1], 0), lineutility.extend_below, triangleHeight);
4023                    trianglePts[l].style = 9;
4024                    l++;
4025
4026                    trianglePts[l] = new POINT2(trianglePts[l-3]);
4027                    trianglePts[l].style = 10;
4028
4029                    for (j = 0; j < 18; j++) {
4030                        pLinePoints[acCounter] = new POINT2(trianglePts[j]);
4031                        acCounter++;
4032                    }
4033                    break;
4034                case TacticalLines.DELAY:
4035                case TacticalLines.WITHDRAW:
4036                case TacticalLines.DISENGAGE:
4037                case TacticalLines.WDRAWUP:
4038                case TacticalLines.RETIRE:
4039                case TacticalLines.FPOL:
4040                case TacticalLines.RPOL:
4041                case TacticalLines.PURSUIT:
4042                    acCounter = DISMSupport.GetDelayGraphicEtcDouble(pLinePoints, lineType);
4043                    break;
4044                case TacticalLines.ENVELOPMENT:
4045                    acCounter = DISMSupport.GetEnvelopmentGraphicDouble(pLinePoints);
4046                    break;
4047                case TacticalLines.EASY:
4048                    acCounter = DISMSupport.GetDISMEasyDouble(pLinePoints, lineType);
4049                    break;
4050                case TacticalLines.DECEIVE:
4051                    DISMSupport.GetDISMDeceiveDouble(pLinePoints);
4052                    acCounter = 4;
4053                    break;
4054                case TacticalLines.BYPASS:
4055                    acCounter = DISMSupport.GetDISMBypassDouble(pLinePoints, lineType);
4056                    break;
4057                case TacticalLines.AMBUSH:
4058                    acCounter = DISMSupport.AmbushPointsDouble(pLinePoints);
4059                    break;
4060                case TacticalLines.FLOT:
4061                    acCounter = flot.GetFlotDouble(pLinePoints, getScaledSize(20, tg.get_LineThickness(), tg.get_patternScale()), vblSaveCounter);
4062                    break;
4063                default:
4064                    acCounter = vblSaveCounter;
4065                    break;
4066            }
4067            switch (lineType) {
4068                case TacticalLines.BOUNDARY:
4069                    FillPoints(pLinePoints, acCounter, points);
4070                    return points;
4071                case TacticalLines.CONTAIN:
4072                case TacticalLines.BLOCK:
4073                case TacticalLines.COVER:
4074                case TacticalLines.SCREEN:  //note: screen, cover, guard are getting their modifiers before the call to getlinearray
4075                case TacticalLines.GUARD:
4076                case TacticalLines.ESCORT:
4077                case TacticalLines.PAA_RECTANGULAR:
4078                case TacticalLines.RECTANGULAR_TARGET:
4079                case TacticalLines.FOLSP:
4080                case TacticalLines.FOLLA:
4081                //add these for rev c   3-12-12
4082                case TacticalLines.BREACH:
4083                case TacticalLines.BYPASS:
4084                case TacticalLines.CANALIZE:
4085                case TacticalLines.CLEAR:
4086                case TacticalLines.DISRUPT:
4087                case TacticalLines.FIX:
4088                case TacticalLines.ISOLATE:
4089                case TacticalLines.OCCUPY:
4090                case TacticalLines.PENETRATE:
4091                case TacticalLines.RETAIN:
4092                case TacticalLines.SECURE:
4093                case TacticalLines.CONTROL:
4094                case TacticalLines.LOCATE:
4095                case TacticalLines.AREA_DEFENSE:
4096                case TacticalLines.SEIZE:
4097                case TacticalLines.CAPTURE:
4098                case TacticalLines.EVACUATE:
4099                case TacticalLines.TURN:
4100                case TacticalLines.BS_RECTANGLE:
4101                case TacticalLines.BBS_RECTANGLE:
4102                //add these
4103                case TacticalLines.AIRFIELD:
4104                case TacticalLines.CORDONKNOCK:
4105                case TacticalLines.CORDONSEARCH:
4106                case TacticalLines.DENY:
4107                case TacticalLines.MSDZ:
4108                case TacticalLines.CONVOY:
4109                case TacticalLines.HCONVOY:
4110                case TacticalLines.MFLANE:
4111                case TacticalLines.DIRATKAIR:
4112                case TacticalLines.ABATIS:
4113                case TacticalLines.MOBILE_DEFENSE:
4114                case TacticalLines.ENVELOPMENT:
4115                    FillPoints(pLinePoints, acCounter, points);
4116                    break;
4117                default:
4118                    //if shapes is null then it is a non-CPOF client, dependent upon pixels
4119                    //instead of shapes
4120                    if (shapes == null) {
4121                        FillPoints(pLinePoints, acCounter, points);
4122                        return points;
4123                    }
4124                    break;
4125            }
4126
4127            //the shapes require pLinePoints
4128            //if the shapes are null then it is a non-CPOF client,
4129            if (shapes == null) {
4130                return points;
4131            }
4132
4133            Shape2 shape = null;
4134            Shape gp = null;
4135            Shape2 redShape = null, blueShape = null, paleBlueShape = null, whiteShape = null;
4136            Shape2 redFillShape = null, blueFillShape = null, blackShape = null;
4137            BasicStroke blueStroke, paleBlueStroke;
4138            Area blueArea = null;
4139            Area paleBlueArea = null;
4140            Area whiteArea = null;
4141            boolean beginLine = true;
4142            Polygon poly = null;
4143            POINT2[] secondPoly;
4144
4145            //a loop for the outline shapes
4146            switch (lineType) {
4147                case TacticalLines.PDF:
4148                    // Lines
4149                    addPolyline(pLinePoints, 3, shapes);
4150
4151                    // Rectangle
4152                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4153                    shape.moveTo(pLinePoints[3]);
4154                    for (k = 4; k < 8; k++) {
4155                        shape.lineTo(pLinePoints[k]);
4156                    }
4157                    shapes.add(shape);
4158
4159                    // Arrows
4160                    secondPoly = new POINT2[6];
4161                    for (int i = 0; i < 6; i++) {
4162                        secondPoly[i] = pLinePoints[i + 8];
4163                    }
4164                    addPolyline(secondPoly, 6, shapes);
4165                    break;
4166                case TacticalLines.BBS_AREA:
4167                case TacticalLines.BBS_RECTANGLE:
4168                    shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4169                    shape.moveTo(pLinePoints[0]);
4170                    for (j = 0; j < vblSaveCounter; j++) {
4171                        shape.lineTo(pLinePoints[j]);
4172                    }
4173                    shapes.add(shape);
4174
4175                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4176                    shape.moveTo(pOriginalLinePoints[0]);
4177                    for (j = 1; j < vblSaveCounter; j++) {
4178                        shape.lineTo(pOriginalLinePoints[j]);
4179                    }
4180                    shapes.add(shape);
4181
4182                    break;
4183                case TacticalLines.DIRATKGND:
4184                    //create two shapes. the first shape is for the line
4185                    //the second shape is for the arrow
4186                    //renderer will know to use a skinny stroke for the arrow shape
4187
4188                    //the line shape
4189                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4190                    shape.moveTo(pLinePoints[0]);
4191                    for (j = 0; j < acCounter - 10; j++) {
4192                        shape.lineTo(pLinePoints[j]);
4193                    }
4194
4195                    shapes.add(shape);
4196
4197                    //the arrow shape
4198                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4199                    shape.moveTo(pLinePoints[acCounter - 10]);
4200
4201                    for (j = 9; j > 0; j--) {
4202                        if (pLinePoints[acCounter - j - 1].style == 5) {
4203                            shape.moveTo(pLinePoints[acCounter - j]);
4204                        } else {
4205                            shape.lineTo(pLinePoints[acCounter - j]);
4206                        }
4207                    }
4208
4209                    shapes.add(shape);
4210                    break;
4211                case TacticalLines.DEPTH_AREA:
4212                    whiteShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4213                    whiteShape.setFillColor(Color.WHITE);
4214                    BasicStroke whiteStroke = new BasicStroke((float) arraysupport.getScaledSize(28, tg.get_LineThickness(), tg.get_patternScale()));
4215
4216                    blueShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4217                    blueShape.setFillColor(new Color(30, 144, 255));
4218
4219                    paleBlueStroke = new BasicStroke(whiteStroke.getLineWidth() / 2);
4220                    paleBlueShape = new Shape2(Shape2.SHAPE_TYPE_FILL);//use for symbol
4221                    paleBlueShape.setFillColor(new Color(153, 204, 255));
4222
4223                    poly = new Polygon();
4224
4225                    for (k = 0; k < vblSaveCounter; k++) {
4226                        poly.addPoint((int) pLinePoints[k].x, (int) pLinePoints[k].y);
4227                        if (k == 0) {
4228                            whiteShape.moveTo(pLinePoints[k]);
4229                        } else {
4230                            whiteShape.lineTo(pLinePoints[k]);
4231                        }
4232                    }
4233
4234                    blueArea = new Area(poly);
4235                    blueShape.setShape(blueArea);
4236
4237                    whiteArea = new Area((Shape) whiteStroke.createStrokedShape(poly));
4238                    whiteShape.setShape(lineutility.createStrokedShape(whiteArea));
4239
4240                    paleBlueArea = new Area((Shape) paleBlueStroke.createStrokedShape(poly));
4241                    paleBlueShape.setShape(lineutility.createStrokedShape(paleBlueArea));
4242
4243                    shapes.add(blueShape);
4244                    shapes.add(paleBlueShape);
4245                    shapes.add(whiteShape);
4246                    break;
4247                case TacticalLines.TRAINING_AREA:
4248                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);//use for outline
4249                    redShape.set_Style(1);
4250                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);//use for symbol
4251                    blueShape.set_Style(0);
4252
4253                    redShape.moveTo(pLinePoints[0]);
4254                    for (k = 1; k < vblSaveCounter; k++) {
4255                        redShape.lineTo(pLinePoints[k]);
4256                    }
4257
4258                    beginLine = true;
4259                    for (k = vblSaveCounter; k < acCounter; k++) {
4260                        if (pLinePoints[k].style == 0) {
4261                            if (beginLine) {
4262                                blueShape.moveTo(pLinePoints[k]);
4263                                beginLine = false;
4264                            } else {
4265                                blueShape.lineTo(pLinePoints[k]);
4266                            }
4267                        }
4268                        if (pLinePoints[k].style == 5) {
4269                            blueShape.lineTo(pLinePoints[k]);
4270                            beginLine = true;
4271                        }
4272                    }
4273                    shapes.add(redShape);
4274                    shapes.add(blueShape);
4275                    break;
4276                case TacticalLines.ITD:
4277                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4278                    redShape.setLineColor(Color.RED);
4279                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4280                    blueShape.setLineColor(Color.GREEN);
4281                    for (k = 0; k < acCounter - 1; k++) {
4282                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4283                            redShape.moveTo(pLinePoints[k]);
4284                            redShape.lineTo(pLinePoints[k + 1]);
4285                        } else if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4286                            blueShape.moveTo(pLinePoints[k]);
4287                            blueShape.lineTo(pLinePoints[k + 1]);
4288                        }
4289                    }
4290                    shapes.add(redShape);
4291                    shapes.add(blueShape);
4292                    tg.set_lineCap(BasicStroke.CAP_BUTT);
4293                    break;
4294                case TacticalLines.SFY:
4295                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4296                    redShape.setLineColor(Color.RED);
4297                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4298                    blueShape.setLineColor(Color.BLUE);
4299                    //flots and spikes (triangles)
4300                    for (k = 0; k < acCounter - 1; k++) {
4301                        if (pLinePoints[k].style == 23) //red flots
4302                        {
4303                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);    //1-3-12
4304                            redFillShape.setFillColor(Color.RED);
4305                            redFillShape.moveTo(pLinePoints[k - 9]);
4306                            for (int l = k - 8; l <= k; l++) {
4307                                redFillShape.lineTo(pLinePoints[l]);
4308                            }
4309                            shapes.add(redFillShape);   //1-3-12
4310                        }
4311                        if (pLinePoints[k].style == 24)//blue spikes
4312                        {
4313                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);   //1-3-12
4314                            blueFillShape.setFillColor(Color.BLUE);
4315                            blueFillShape.moveTo(pLinePoints[k - 2]);
4316                            blueFillShape.lineTo(pLinePoints[k - 1]);
4317                            blueFillShape.lineTo(pLinePoints[k]);
4318                            shapes.add(blueFillShape);  //1-3-12
4319                        }
4320                    }
4321                    //the corners
4322                    for (k = 0; k < vblSaveCounter; k++) {
4323                        if (k == 0) {
4324                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4325                            redShape.moveTo(pOriginalLinePoints[0]);
4326                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[0], pOriginalLinePoints[1]);
4327                            if (d1 < d) {
4328                                d = d1;
4329                            }
4330
4331                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[0], pOriginalLinePoints[1], d);
4332                            redShape.lineTo(pt0);
4333                        } else if (k > 0 && k < vblSaveCounter - 1) {
4334                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4335                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1]);
4336                            if (d1 < d) {
4337                                d = d1;
4338                            }
4339
4340                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1], d);
4341                            pt1 = pOriginalLinePoints[k];
4342
4343                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4344                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1]);
4345                            if (d1 < d) {
4346                                d = d1;
4347                            }
4348
4349                            pt2 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1], d);
4350                            redShape.moveTo(pt0);
4351                            redShape.lineTo(pt1);
4352                            redShape.lineTo(pt2);
4353                        } else //last point
4354                        {
4355                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4356                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2]);
4357                            if (d1 < d) {
4358                                d = d1;
4359                            }
4360
4361                            redShape.moveTo(pOriginalLinePoints[vblSaveCounter - 1]);
4362                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2], d);
4363                            redShape.lineTo(pt0);
4364                        }
4365                    }
4366                    //red and blue short segments (between the flots)
4367                    for (k = 0; k < vblCounter - 1; k++) {
4368                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4369                            redShape.moveTo(pLinePoints[k]);
4370                            redShape.lineTo(pLinePoints[k + 1]);
4371                        } else if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4372                            blueShape.moveTo(pLinePoints[k]);
4373                            blueShape.lineTo(pLinePoints[k + 1]);
4374                        }
4375                    }
4376                    shapes.add(redShape);
4377                    shapes.add(blueShape);
4378                    break;
4379                case TacticalLines.SFG:
4380                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4381                    redShape.setLineColor(Color.RED);
4382                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4383                    blueShape.setLineColor(Color.BLUE);
4384                    for (k = 0; k < acCounter - 1; k++) {
4385                        if (pLinePoints[k].style == 23) //red flots
4386                        {
4387                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);    //1-3-12
4388                            redFillShape.setFillColor(Color.RED);
4389                            redFillShape.moveTo(pLinePoints[k - 9]);
4390                            for (int l = k - 8; l <= k; l++) {
4391                                redFillShape.lineTo(pLinePoints[l]);
4392                            }
4393                            shapes.add(redFillShape);   //1-3-12
4394                        }
4395                        if (pLinePoints[k].style == 24)//blue spikes red outline
4396                        {
4397                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);   //1-3-12
4398                            blueFillShape.setFillColor(Color.BLUE);
4399                            blueFillShape.moveTo(pLinePoints[k - 2]);
4400                            blueFillShape.lineTo(pLinePoints[k - 1]);
4401                            blueFillShape.lineTo(pLinePoints[k]);
4402                            shapes.add(blueFillShape);   //1-3-12
4403                        }
4404                    }
4405                    //the corners
4406                    for (k = 0; k < vblSaveCounter; k++) {
4407                        if (k == 0) {
4408                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4409                            redShape.moveTo(pOriginalLinePoints[0]);
4410                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[0], pOriginalLinePoints[1]);
4411                            if (d1 < d) {
4412                                d = d1;
4413                            }
4414
4415                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[0], pOriginalLinePoints[1], d);
4416                            redShape.lineTo(pt0);
4417                        } else if (k > 0 && k < vblSaveCounter - 1) {
4418                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4419                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1]);
4420                            if (d1 < d) {
4421                                d = d1;
4422                            }
4423
4424                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k - 1], d);
4425                            pt1 = pOriginalLinePoints[k];
4426
4427                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4428                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1]);
4429                            if (d1 < d) {
4430                                d = d1;
4431                            }
4432
4433                            pt2 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[k], pOriginalLinePoints[k + 1], d);
4434                            redShape.moveTo(pt0);
4435                            redShape.lineTo(pt1);
4436                            redShape.lineTo(pt2);
4437                        } else //last point
4438                        {
4439                            d = arraysupport.getScaledSize(50, tg.get_LineThickness(), tg.get_patternScale());
4440                            d1 = lineutility.CalcDistanceDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2]);
4441                            if (d1 < d) {
4442                                d = d1;
4443                            }
4444
4445                            redShape.moveTo(pOriginalLinePoints[vblSaveCounter - 1]);
4446                            pt0 = lineutility.ExtendAlongLineDouble(pOriginalLinePoints[vblSaveCounter - 1], pOriginalLinePoints[vblSaveCounter - 2], d);
4447                            redShape.lineTo(pt0);
4448                        }
4449                    }
4450                    shapes.add(redShape);
4451                    //the dots
4452                    for (k = 0; k < acCounter; k++) {
4453                        if (pLinePoints[k].style == 22) {
4454                            POINT2[] CirclePoints = new POINT2[8];
4455                            redShape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4456                            redShape.setFillColor(Color.RED);
4457                            if (redShape != null && redShape.getShape() != null) {
4458                                shapes.add(redShape);
4459                            }
4460                        }
4461                        if (pLinePoints[k].style == 20) {
4462                            POINT2[] CirclePoints = new POINT2[8];
4463                            blueShape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4464                            blueShape.setFillColor(Color.BLUE);
4465                            if (blueShape != null && blueShape.getShape() != null) {
4466                                shapes.add(blueShape);
4467                            }
4468                        }
4469                    }
4470                    break;
4471                case TacticalLines.USF:
4472                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4473                    redShape.setLineColor(Color.RED);
4474                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4475                    blueShape.setLineColor(Color.BLUE);
4476                    beginLine = true;
4477                    //int color=0;//red
4478                    for (k = 0; k < acCounter - 1; k++) {
4479                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4480                            redShape.moveTo(pLinePoints[k]);
4481                            redShape.lineTo(pLinePoints[k + 1]);
4482                            //color=0;
4483                        }
4484                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 19) {
4485                            redShape.moveTo(pLinePoints[k]);
4486                            redShape.lineTo(pLinePoints[k + 1]);
4487                            //color=0;
4488                        }
4489                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4490                            blueShape.moveTo(pLinePoints[k]);
4491                            blueShape.lineTo(pLinePoints[k + 1]);
4492                            //color=1;
4493                        }
4494                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 25) {
4495                            blueShape.moveTo(pLinePoints[k]);
4496                            blueShape.lineTo(pLinePoints[k + 1]);
4497                            //color=1;
4498                        }
4499                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4500                            redShape.moveTo(pLinePoints[k]);
4501                            redShape.lineTo(pLinePoints[k + 1]);
4502                        }
4503
4504                    }
4505                    shapes.add(redShape);
4506                    shapes.add(blueShape);
4507                    break;
4508                case TacticalLines.SF:
4509                    redShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4510                    redShape.setLineColor(Color.RED);
4511                    blueShape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4512                    blueShape.setLineColor(Color.BLUE);
4513                    redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4514                    redFillShape.setLineColor(Color.RED);
4515                    redFillShape.setFillColor(Color.RED);
4516                    blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4517                    blueFillShape.setLineColor(Color.BLUE);
4518                    blueFillShape.setFillColor(Color.BLUE);
4519                    for (k = 0; k < acCounter - 1; k++) {
4520                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 5) {
4521                            redShape.moveTo(pLinePoints[k]);
4522                            redShape.lineTo(pLinePoints[k + 1]);
4523                        }
4524                        if (pLinePoints[k].style == 19 && pLinePoints[k + 1].style == 19) {
4525                            if (redFillShape.getPoints().isEmpty()) {
4526                                redFillShape.moveTo(pLinePoints[k + 9]);
4527                                for (int l = k + 9; l >= k; l--) {
4528                                    redFillShape.lineTo(pLinePoints[l]);
4529                                }
4530                            } else {
4531                                redFillShape.moveTo(pLinePoints[k]);
4532                                for (int l = k; l < k + 10; l++) {
4533                                    redFillShape.lineTo(pLinePoints[l]);
4534                                }
4535                            }
4536                            k+=9;
4537                            shapes.add(redFillShape);
4538                            redFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4539                            redFillShape.setLineColor(Color.RED);
4540                            redFillShape.setFillColor(Color.RED);
4541                        }
4542                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 5) {
4543                            blueShape.moveTo(pLinePoints[k]);
4544                            blueShape.lineTo(pLinePoints[k + 1]);
4545                        }
4546                        if (pLinePoints[k].style == 25 && pLinePoints[k + 1].style == 25) {
4547                            if (blueFillShape.getPoints().isEmpty()) {
4548                                blueFillShape.moveTo(pLinePoints[k + 2]);
4549                                blueFillShape.lineTo(pLinePoints[k + 1]);
4550                                blueFillShape.lineTo(pLinePoints[k]);
4551                            } else {
4552                                blueFillShape.moveTo(pLinePoints[k]);
4553                                blueFillShape.lineTo(pLinePoints[k + 1]);
4554                                blueFillShape.lineTo(pLinePoints[k + 2]);
4555                            }
4556                            shapes.add(blueFillShape);
4557                            blueFillShape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4558                            blueFillShape.setLineColor(Color.BLUE);
4559                            blueFillShape.setFillColor(Color.BLUE);
4560                        }
4561                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4562                            redShape.moveTo(pLinePoints[k]);
4563                            redShape.lineTo(pLinePoints[k + 1]);
4564                        }
4565                    }
4566                    shapes.add(redShape);
4567                    shapes.add(blueShape);
4568                    break;
4569                case TacticalLines.WFG:
4570                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4571                    for (k = 0; k < acCounter - 1; k++) {
4572                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4573                            shape.moveTo(pLinePoints[k]);
4574                            shape.lineTo(pLinePoints[k + 1]);
4575                        }
4576                    }
4577                    shapes.add(shape);
4578
4579                    //the dots
4580                    for (k = 0; k < acCounter; k++) {
4581                        if (pLinePoints[k].style == 20) {
4582                            POINT2[] CirclePoints = new POINT2[8];
4583                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4584                            if (shape != null && shape.getShape() != null) {
4585                                shapes.add(shape);
4586                            }
4587                        }
4588                    }
4589                    break;
4590                case TacticalLines.FOLLA:
4591                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4592                    shape.set_Style(1); //dashed line
4593                    shape.moveTo(pLinePoints[0]);
4594                    shape.lineTo(pLinePoints[1]);
4595                    shapes.add(shape);
4596
4597                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4598                    shape.set_Style(0); //dashed line
4599                    for (j = 2; j < vblCounter; j++) {
4600                        if (pLinePoints[j - 1].style != 5) {
4601                            shape.lineTo(pLinePoints[j]);
4602                        } else {
4603                            shape.moveTo(pLinePoints[j]);
4604                        }
4605                    }
4606                    shapes.add(shape);
4607                    break;
4608                case TacticalLines.CFG:
4609                    for (k = 0; k < acCounter; k++) {
4610                        if (pLinePoints[k].style == 20) {
4611                            POINT2[] CirclePoints = new POINT2[8];
4612                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(3, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4613                            if (shape != null && shape.getShape() != null) {
4614                                shapes.add(shape);
4615                            }
4616                            continue;
4617                        }
4618                    }
4619                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4620                    for (k = 0; k < acCounter - 1; k++) {
4621                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4622                            shape.moveTo(pLinePoints[k]);
4623                            shape.lineTo(pLinePoints[k + 1]);
4624                        }
4625                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 9) {
4626                            shape.moveTo(pLinePoints[k]);
4627                            shape.lineTo(pLinePoints[k + 1]);
4628                        }
4629
4630                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4631                            d = lineutility.CalcDistanceDouble(pLinePoints[k], pLinePoints[k + 1]);
4632                            pt0 = lineutility.ExtendAlongLineDouble(pLinePoints[k], pLinePoints[k + 1], d - arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()));
4633                            shape.moveTo(pLinePoints[k]);
4634                            shape.lineTo(pt0);
4635                        }
4636
4637                        if (pLinePoints[k].style == 0 && k == acCounter - 2) {
4638                            shape.moveTo(pLinePoints[k]);
4639                            shape.lineTo(pLinePoints[k + 1]);
4640                        }
4641                    }
4642                    shapes.add(shape);
4643                    break;
4644                case TacticalLines.PIPE:
4645                    for (k = 0; k < acCounter; k++) {
4646                        if (pLinePoints[k].style == 20) {
4647                            POINT2[] CirclePoints = new POINT2[8];
4648                            shape = lineutility.CalcCircleShape(pLinePoints[k], arraysupport.getScaledSize(5, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);
4649                            if (shape != null && shape.getShape() != null) {
4650                                shapes.add(shape);
4651                            }
4652                        }
4653                    }
4654                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4655                    for (k = 0; k < acCounter - 1; k++) {
4656                        if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4657                            shape.moveTo(pLinePoints[k]);
4658                            shape.lineTo(pLinePoints[k + 1]);
4659                        }
4660                    }
4661                    shapes.add(shape);
4662                    break;
4663                case TacticalLines.ATDITCHM:
4664                    for (k = 0; k < acCounter; k++) {
4665                        if (pLinePoints[k].style == 20) {
4666                            POINT2[] CirclePoints = new POINT2[8];
4667                            shape = lineutility.CalcCircleShape(pLinePoints[k], getScaledSize(4, tg.get_LineThickness(), tg.get_patternScale()), 8, CirclePoints, 9);//was 3
4668                            if (shape != null && shape.getShape() != null) {
4669                                shapes.add(shape);
4670                            }
4671                            continue;
4672                        }
4673                        if (k < acCounter - 2) {
4674                            if (pLinePoints[k].style != 0 && pLinePoints[k + 1].style == 0) {
4675                                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4676                                shape.set_Style(pLinePoints[k].style);
4677                                shape.moveTo(pLinePoints[k]);
4678                                shape.lineTo(pLinePoints[k]);
4679                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4680                                shape.moveTo(pLinePoints[k]);
4681                                shape.lineTo(pLinePoints[k + 1]);
4682                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 10) {
4683                                shape.moveTo(pLinePoints[k]);
4684                                shape.lineTo(pLinePoints[k + 1]);
4685                                shapes.add(shape);
4686                            }
4687                        }
4688                        if (k < acCounter - 2) {
4689                            if (pLinePoints[k].style == 5 && pLinePoints[k + 1].style == 0) {
4690                                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4691                                shape.set_Style(pLinePoints[k].style);
4692                                shape.moveTo(pLinePoints[k]);
4693                                //shape.lineTo(pLinePoints[k]);
4694                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 0) {
4695                                shape.lineTo(pLinePoints[k + 1]);
4696                            } else if (pLinePoints[k].style == 0 && pLinePoints[k + 1].style == 5) {
4697                                shape.lineTo(pLinePoints[k + 1]);
4698                                shapes.add(shape);
4699                            }
4700                        }
4701                    }//end for
4702                    break;
4703                case TacticalLines.ESR1:
4704                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4705                    shape.set_Style(pLinePoints[0].style);
4706                    shape.moveTo(pLinePoints[0]);
4707                    shape.lineTo(pLinePoints[1]);
4708                    //if(shape !=null && shape.get_Shape() != null)
4709                    shapes.add(shape);
4710                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4711                    shape.set_Style(pLinePoints[2].style);
4712                    shape.moveTo(pLinePoints[2]);
4713                    shape.lineTo(pLinePoints[3]);
4714                    //if(shape !=null && shape.get_Shape() != null)
4715                    shapes.add(shape);
4716                    break;
4717                case TacticalLines.FORDIF:
4718                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4719                    shape.set_Style(pLinePoints[0].style);
4720                    shape.moveTo(pLinePoints[0]);
4721                    shape.lineTo(pLinePoints[1]);
4722                    shape.moveTo(pLinePoints[2]);
4723                    shape.lineTo(pLinePoints[3]);
4724                    shapes.add(shape);
4725                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4726                    shape.set_Style(pLinePoints[4].style);
4727                    shape.moveTo(pLinePoints[4]);
4728                    for (k = 5; k < acCounter; k++) {
4729                        if (pLinePoints[k - 1].style != 5) {
4730                            shape.lineTo(pLinePoints[k]);
4731                        }
4732                    }
4733
4734                    if (shape != null && shape.getShape() != null) {
4735                        shapes.add(shape);
4736                    }
4737                    break;
4738                case TacticalLines.FENCED:
4739                    //first shape is the original points
4740                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4741                    shape.set_Style(points.get(0).style);
4742                    shape.moveTo(points.get(0));
4743                    for (k = 1; k < vblCounter; k++) {
4744                        shape.lineTo(points.get(k));
4745                    }
4746                    if (shape != null && shape.getShape() != null) {
4747                        shapes.add(shape);
4748                    }
4749
4750                    //second shape are the xpoints
4751                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4752                    beginLine = true;
4753                    for (k = vblCounter; k < points.size(); k++) {
4754                        if (beginLine) {
4755                            if (k == 0) {
4756                                shape.set_Style(points.get(k).style);
4757                            }
4758
4759                            if (k > 0) //doubled points with linestyle=5
4760                            {
4761                                if (points.get(k).style == 5 && points.get(k - 1).style == 5) {
4762                                    shape.lineTo(points.get(k));
4763                                }
4764                            }
4765
4766                            shape.moveTo(points.get(k));
4767                            beginLine = false;
4768                        } else {
4769                            shape.lineTo(points.get(k));
4770                            if (points.get(k).style == 5 || points.get(k).style == 10) {
4771                                beginLine = true;
4772                                //unless there are doubled points with style=5
4773                            }
4774                        }
4775                        if (k == points.size() - 1) //non-LC should only have one shape
4776                        {
4777                            if (shape != null && shape.getShape() != null) {
4778                                shapes.add(shape);
4779                            }
4780                        }
4781                    }
4782                    break;
4783                case TacticalLines.AIRFIELD:
4784                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4785                    shape.moveTo(pLinePoints[0]);
4786                    for (k = 1; k < acCounter - 5; k++) {
4787                        shape.lineTo(pLinePoints[k]);
4788                    }
4789
4790                    shapes.add(shape);
4791
4792                    shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4793                    shape.moveTo(pLinePoints[acCounter - 4]);
4794                    shape.lineTo(pLinePoints[acCounter - 3]);
4795                    shape.moveTo(pLinePoints[acCounter - 2]);
4796                    shape.lineTo(pLinePoints[acCounter - 1]);
4797                    shapes.add(shape);
4798                    break;
4799                case TacticalLines.STRIKWARN:
4800                    addPolyline(pLinePoints, acCounter / 2, shapes);
4801                    secondPoly = new POINT2[acCounter / 2];
4802                    for (int i = 0; i < acCounter / 2; i++) {
4803                        secondPoly[i] = pLinePoints[i + acCounter / 2];
4804                    }
4805                    addPolyline(secondPoly, acCounter / 2, shapes);
4806                    break;
4807                case TacticalLines.DIRATKAIR:
4808                    secondPoly = new POINT2[9];
4809                    for (int i = 0; i < 4 ; i++) {
4810                        secondPoly[i] = pLinePoints[pLinePoints.length - 4 + i];
4811                    }
4812                    addPolyline(secondPoly, 4, shapes); // Main line
4813                    addPolyline(pLinePoints, acCounter - 13, shapes); // Main line extension
4814                    for (int i = 0; i < 9 ; i++) {
4815                        secondPoly[i] = pLinePoints[pLinePoints.length - 13 + i];
4816                    }
4817                    addPolyline(secondPoly, 9, shapes); // Arrow and bowtie
4818                    break;
4819                case TacticalLines.DIRATKSPT:
4820                case TacticalLines.EXFILTRATION:
4821                case TacticalLines.INFILTRATION:
4822                    addPolyline(pLinePoints, acCounter - 3, shapes); // Main line
4823                    secondPoly = new POINT2[3];
4824                    for (int i = 0; i < 3; i++) {
4825                        secondPoly[i] = pLinePoints[pLinePoints.length - 3 + i];
4826                    }
4827                    addPolyline(secondPoly, 3, shapes); // Arrow
4828                    break;
4829                case TacticalLines.EXPLOIT:
4830                    addPolyline(pLinePoints, 2, shapes); // Main line
4831                    secondPoly = new POINT2[3];
4832                    for (int i = 0; i < 3; i++) {
4833                        secondPoly[i] = pLinePoints[i + 2];
4834                    }
4835                    addPolyline(secondPoly, 3, shapes); // Arrow at pt1
4836                    secondPoly = new POINT2[3];
4837                    for (int i = 0; i < 3; i++) {
4838                        secondPoly[i] = pLinePoints[i + 5];
4839                    }
4840                    addPolyline(secondPoly, 3, shapes); // Dashed tail at pt2
4841                    break;
4842                default:
4843                    addPolyline(pLinePoints, acCounter, shapes);
4844                    break;
4845            }//end switch
4846            //a loop for arrowheads with fill
4847            //these require a separate shape for fill
4848            switch (lineType) {
4849                case TacticalLines.AC:
4850                case TacticalLines.SAAFR:
4851                case TacticalLines.MRR:
4852                case TacticalLines.SL:
4853                case TacticalLines.TC:
4854                case TacticalLines.SC:
4855                case TacticalLines.LLTR:
4856                    for (j = 0; j < vblSaveCounter - 1; j++) {
4857                        dMBR = pOriginalLinePoints[j].style;
4858                        acPoints[0] = new POINT2(pOriginalLinePoints[j]);
4859                        acPoints[1] = new POINT2(pOriginalLinePoints[j + 1]);
4860                        lineutility.GetSAAFRFillSegment(acPoints, dMBR);//was dMRR
4861                        shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4862                        shape.moveTo(acPoints[0]);
4863                        shape.lineTo(acPoints[1]);
4864                        shape.lineTo(acPoints[2]);
4865                        shape.lineTo(acPoints[3]);
4866                        shapes.add(0, shape);
4867                    }
4868                    break;
4869                case TacticalLines.DIRATKAIR:
4870                    //added this section to not fill the bow tie and instead
4871                    //add a shape to close what had been the bow tie fill areas with
4872                    //a line segment for each one
4873                    int outLineCounter = 0;
4874                    POINT2[] ptOutline = new POINT2[4];
4875                    for (k = 0; k < acCounter; k++) {
4876                        if (pLinePoints[k].style == 10) {
4877                            shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4878                            shape.moveTo(pLinePoints[k - 2]);
4879                            shape.lineTo(pLinePoints[k]);
4880                            if (shape != null && shape.getShape() != null) {
4881                                shapes.add(shape);
4882                            }
4883
4884                            //collect these four points
4885                            ptOutline[outLineCounter++] = pLinePoints[k - 2];
4886                            ptOutline[outLineCounter++] = pLinePoints[k];
4887                        }
4888                    }//end for
4889                    break;
4890                case TacticalLines.OFY:
4891                case TacticalLines.OCCLUDED:
4892                case TacticalLines.WF:
4893                case TacticalLines.WFG:
4894                case TacticalLines.WFY:
4895                case TacticalLines.CF:
4896                case TacticalLines.CFY:
4897                case TacticalLines.CFG:
4898                case TacticalLines.SARA:
4899                case TacticalLines.FERRY:
4900                case TacticalLines.EASY:
4901                case TacticalLines.BYDIF:
4902                case TacticalLines.BYIMP:
4903                case TacticalLines.FOLSP:
4904                case TacticalLines.ATDITCHC:
4905                case TacticalLines.ATDITCHM:
4906                case TacticalLines.MNFLDFIX:
4907                case TacticalLines.TURN_REVD:
4908                case TacticalLines.TURN:
4909                case TacticalLines.MNFLDDIS:
4910                case TacticalLines.AREA_DEFENSE:
4911                case TacticalLines.MOBILE_DEFENSE:
4912                    //POINT2 initialFillPt=null;
4913                    for (k = 0; k < acCounter; k++) {
4914                        if (k == 0) {
4915                            if (pLinePoints[k].style == 9) {
4916                                shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4917                                shape.set_Style(pLinePoints[k].style);
4918                                shape.moveTo(pLinePoints[k]);
4919                            }
4920                        } else //k>0
4921                        {
4922                            if (pLinePoints[k].style == 9 && pLinePoints[k - 1].style != 9) {
4923                                shape = new Shape2(Shape2.SHAPE_TYPE_FILL);
4924                                shape.set_Style(pLinePoints[k].style);
4925                                shape.moveTo(pLinePoints[k]);
4926                            }
4927                            if (pLinePoints[k].style == 9 && pLinePoints[k - 1].style == 9) //9,9,...,9,10
4928                            {
4929                                shape.lineTo(pLinePoints[k]);
4930                            }
4931                        }
4932                        if (pLinePoints[k].style == 10) {
4933                            shape.lineTo(pLinePoints[k]);
4934                            if (shape != null && shape.getShape() != null) {
4935                                if (lineType == TacticalLines.AREA_DEFENSE)
4936                                    shapes.add(shape);
4937                                else
4938                                    shapes.add(0, shape);
4939                            }
4940                        }
4941                    }//end for
4942                    break;
4943                default:
4944                    break;
4945            }
4946        } catch (Exception exc) {
4947            ErrorLogger.LogException(_className, "GetLineArray2Double",
4948                    new RendererException("GetLineArray2Double " + Integer.toString(tg.get_LineType()), exc));
4949        }
4950        return points;
4951    }
4952
4953    private static void addPolyline(POINT2[] pLinePoints, int acCounter, ArrayList<Shape2> shapes) {
4954        Shape2 shape = null;
4955        boolean beginLine = true;
4956        for (int k = 0; k < acCounter; k++) {
4957            //use shapes instead of pixels
4958            if (shape == null) {
4959                shape = new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
4960            }
4961
4962            if (beginLine) {
4963
4964                if (k == 0) {
4965                    shape.set_Style(pLinePoints[k].style);
4966                }
4967
4968                if (k > 0) //doubled points with linestyle=5
4969                {
4970                    if (pLinePoints[k].style == 5 && pLinePoints[k - 1].style == 5 && k < acCounter - 1) {
4971                        continue;
4972                    } else if (pLinePoints[k].style == 5 && pLinePoints[k - 1].style == 10) //CF
4973                    {
4974                        continue;
4975                    }
4976                }
4977
4978                if (k == 0 && pLinePoints.length > 1) {
4979                    if (pLinePoints[k].style == 5 && pLinePoints[k + 1].style == 5) {
4980                        continue;
4981                    }
4982                }
4983
4984                shape.moveTo(pLinePoints[k]);
4985                beginLine = false;
4986            } else {
4987                shape.lineTo(pLinePoints[k]);
4988                if (pLinePoints[k].style == 5 || pLinePoints[k].style == 10) {
4989                    beginLine = true;
4990                    //unless there are doubled points with style=5
4991                }
4992            }
4993            if (k == acCounter - 1) //non-LC should only have one shape
4994            {
4995                if (shape != null && shape.getShape() != null) {
4996                    shapes.add(shape);
4997                }
4998            }
4999        }//end for
5000    }
5001
5002    /**
5003     * Returns which side of the line segment the arrow(s) go on for supply routes
5004     */
5005    public static int SupplyRouteArrowSide(POINT2 pt0, POINT2 pt1) {
5006        ref<double[]> m = new ref();
5007        int bolVertical = lineutility.CalcTrueSlopeDouble(pt0, pt1, m);
5008        if (pt0.x < pt1.x) {
5009            if (m.value[0] < 1) {
5010               return 2;
5011            }
5012            if (m.value[0] >= 1) {
5013                return 1;
5014            }
5015        } else if (pt0.x > pt1.x) {
5016            if (m.value[0] < 1) {
5017                return 3;
5018            }
5019            if (m.value[0] >= 1) {
5020                return 0;
5021            }
5022        } else if (bolVertical == 0) {
5023            if (pt0.y > pt1.y) {
5024             return 0;
5025            } else {
5026                return 1;
5027            }
5028        }
5029        return 0;
5030    }
5031
5032    public static double getScaledSize(double originalSize, double lineWidth, double patternScale) {
5033        if (lineWidth <= 3) { // Default line width
5034            return originalSize;
5035        } else if (lineWidth > 100) {
5036            lineWidth = 100; // Max scale size
5037        }
5038        return originalSize * (1 + ((lineWidth - 3) / 2) * patternScale);
5039    }
5040}