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