001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006package armyc2.c2sd.JavaLineArray;
007//import java.awt.Color;
008import armyc2.c2sd.renderer.utilities.Color;
009import java.util.ArrayList;
010import armyc2.c2sd.renderer.utilities.ErrorLogger;
011import armyc2.c2sd.renderer.utilities.RendererException;
012import armyc2.c2sd.renderer.utilities.RendererSettings;
013
014/**
015 * CELineArray Channels class calculates the channel points
016 * @author Michael Deutch
017 */
018public final class Channels {
019    private static final double maxLength=100;//max arrow size
020    private static final double minLength=5;    //max arrow size
021    private static final String _className="Channels";
022    private static String _client="";
023    public static void setClient(String value)
024    {
025        _client=value;
026    }
027//    private static String _affiliation="";
028//    public static void setAffiliation(String value)
029//    {
030//        _affiliation=value;
031//    }
032    private static boolean _shiftLines=true;
033//    public static void setShiftLines(boolean value)
034//    {
035//        _shiftLines=value;
036//    }
037    public static boolean getShiftLines()
038    {
039        return _shiftLines;
040    }
041    private static CChannelPoints2[] ConnectArrayTrueDouble(int  nWidth,
042                                                    int  nCounter,
043                                                    POINT2[] pLinePoints,
044                                                    CChannelPoints2[] pResultChannelPoints)
045
046    {
047        try
048        {
049            //declarations
050            int  nPointCounter = 0;
051            double      nDiff1X = 0,
052                    nDiff2X = 0,
053                    nDiff1Y = 0,
054                    nDiff2Y = 0;
055            int nLast = 0;
056            int lOrient=0;
057            POINT2  LinePoint1 = new POINT2(pLinePoints[0]),
058                    LinePoint2 = new POINT2(pLinePoints[0]),
059                    LinePoint3 = new POINT2(pLinePoints[0]);
060
061            //POINT2 EndPoint1=new POINT2(pLinePoints[0]);
062            //POINT2 EndPoint2=new POINT2(pLinePoints[0]);
063            CChannelPoints2  ResultChannelPoint=new CChannelPoints2();
064            //end declarations
065
066            //must establish nLast before we get the first channel end point
067            //put first GetEndPoint into the pResultChannelPoints array
068            LinePoint1 = new POINT2(pLinePoints[0]);
069            LinePoint2 = new POINT2(pLinePoints[1]);
070            nDiff1X = LinePoint2.x - LinePoint1.x;
071            nDiff1Y = LinePoint2.y - LinePoint1.y;
072            if(nDiff1X==0)
073            {
074                if(nDiff1Y>0)
075                    nLast=6;
076                if(nDiff1Y<0)
077                    nLast=4;
078            }
079            if(nDiff1Y==0)
080            {
081                if(nDiff1X>0)
082                    nLast=0;
083                if(nDiff1X<0)
084                    nLast=2;
085            }
086            if(nDiff1X<0 && nDiff1Y>0)
087                nLast=3;
088            if(nDiff1X>0 && nDiff1Y>0)
089                nLast=0;
090            if(nDiff1X<0 && nDiff1Y<0)
091                nLast=3;
092            if(nDiff1X>0 && nDiff1Y<0)
093                nLast=0;
094
095            ResultChannelPoint = GetTrueEndPointDouble(nWidth,pLinePoints[0],pLinePoints[1],nLast);
096            pResultChannelPoints[0] = new CChannelPoints2(ResultChannelPoint);
097            //initialize nLast depending on the first 1 or 2 segments
098
099            //stuff the array
100            //nLast needs to indicate if the last segment2 had line1 above or below it
101            for(nPointCounter=1;nPointCounter < nCounter;nPointCounter++)
102            {
103                LinePoint1 = new POINT2(pLinePoints[nPointCounter-1]);
104                LinePoint2 = new POINT2(pLinePoints[nPointCounter]);
105                LinePoint3 = new POINT2(pLinePoints[nPointCounter+1]);
106                nDiff1X = LinePoint2.x - LinePoint1.x;
107                nDiff2X = LinePoint3.x - LinePoint2.x;
108                nDiff1Y = LinePoint2.y - LinePoint1.y;
109                nDiff2Y = LinePoint3.y - LinePoint2.y;
110
111                //determine nLast to use in the next iteration
112                //nLast=0: last segment2 was left to right and line1 above it
113                //nLast=1: last segment2 was left to right and line1 below it
114                //nLast=2: last segment2 was right to left and line1 above it
115                //nLast=3: last segment2 was right to left and line1 below it
116                //nLast=4: last segment2 was vertical upward and line1 above (to the left of it)
117                //nLast=5: last segment2 was vertical upward and line1 below (to the right of it)
118                //nLast=6: last segment2 was vertical downward and line1 above (to the left of it)
119                //nLast=7: last segment2 was vertical downward and line1 below (to the right of it)
120                if(nDiff1X>0 && nDiff2X>0)      //pt1------pt2------pt3
121                {
122                    switch(nLast)
123                    {
124                        case 0:
125                        case 3:
126                        case 4:
127                        case 7:
128                            lOrient=0;  //above & above
129                            break;
130                        case 1:
131                        case 2:
132                        case 5:
133                        case 6:
134                            lOrient=3;  //below & below
135                            break;
136                        default:
137                            break;
138                    }
139                }
140
141                //                                                              pt1-----pt2    or                  pt3
142                //                                                                              |                                       |
143                //                                                                              |                                       |
144                //                                                                              |                                       |
145                //                                                                              pt3                pt1-----pt2
146                if(nDiff1X>0 && nDiff2X==0)
147                {
148                    switch(nLast)
149                    {
150                        case 0:
151                        case 3:
152                        case 4:
153                        case 7:
154                            if(nDiff2Y>0)
155                                lOrient=1;      //above & below
156                            if(nDiff2Y<0)
157                                lOrient=0;      //above & above
158                            break;
159                        case 1:
160                        case 2:
161                        case 5:
162                        case 6:
163                            if(nDiff2Y>0)
164                                lOrient=2;
165                            if(nDiff2Y<0)
166                                lOrient=3;
167                            break;
168                        default:
169                            break;
170                    }
171                }
172
173                //                                                              pt2-----pt1    or   pt3
174                //                                                              |                                       |
175                //                                                              |                                       |
176                //                                                              |                                       |
177                //                                                              pt3                                     pt2-----pt1
178                if(nDiff1X<0 && nDiff2X==0)
179                {
180                    switch(nLast)
181                    {
182                        case 0:
183                        case 3:
184                        case 4:
185                        case 7:
186                            if(nDiff2Y>0)
187                                lOrient=3;
188                            if(nDiff2Y<0)
189                                lOrient=2;
190                            break;
191                        case 1:
192                        case 2:
193                        case 5:
194                        case 6:
195                            if(nDiff2Y>0)
196                                lOrient=0;
197                            if(nDiff2Y<0)
198                                lOrient=1;
199                            break;
200                        default:
201                            break;
202                    }
203                }
204
205                //                                                              pt2-----pt3    or   pt1
206                //                                                              |                                       |
207                //                                                              |                                       |
208                //                                                              |                                       |
209                //                                                              pt1                                     pt2-----pt3
210                if(nDiff1X==0 && nDiff2X>0)
211                {
212                    switch(nLast)
213                    {
214                        case 0:
215                        case 3:
216                        case 4:
217                        case 7:
218                            if(nDiff1Y>0)
219                                lOrient=2;
220                            if(nDiff1Y<0)
221                                lOrient=0;
222                            break;
223                        case 1:
224                        case 2:
225                        case 5:
226                        case 6:
227                            if(nDiff1Y>0)
228                                lOrient=1;
229                            if(nDiff1Y<0)
230                                lOrient=3;
231                            break;
232                        default:
233                            break;
234                    }
235                }
236
237                //                                              pt3-----pt2    or                       pt1
238                //                                                              |                                       |
239                //                                                              |                                       |
240                //                                                              |                                       |
241                //                                                              pt1                     pt3-----pt2
242                if(nDiff1X==0 && nDiff2X<0)
243                {
244                    switch(nLast)
245                    {
246                        case 0:
247                        case 3:
248                        case 4:
249                        case 7:
250                            if(nDiff1Y>0)
251                                lOrient=3;
252                            if(nDiff1Y<0)
253                                lOrient=1;
254                            break;
255                        case 1:
256                        case 2:
257                        case 5:
258                        case 6:
259                            if(nDiff1Y>0)
260                                lOrient=0;
261                            if(nDiff1Y<0)
262                                lOrient=2;
263                            break;
264                        default:
265                            break;
266                    }
267                }
268
269
270                if(nDiff1X<0 && nDiff2X<0)      //pt3-----pt2------pt1
271                {
272                    switch(nLast)
273                    {
274                        case 0:
275                        case 3:
276                        case 4:
277                        case 7:
278                            lOrient=3;  //below & below
279                            break;
280                        case 1:
281                        case 2:
282                        case 5:
283                        case 6:
284                            lOrient=0;  //above & above
285                            break;
286                        default:
287                            break;
288                    }
289                }
290
291                //      pt1\
292                //               \
293                //                 \pt2
294                //                 /
295                //           /
296                //  pt3/
297                if(nDiff1X>0 & nDiff2X<0)
298                {
299                    switch(nLast)
300                    {
301                        case 0:
302                        case 3:
303                        case 4:
304                        case 7:
305                            lOrient=1;  //above & below
306                            break;
307                        case 1:
308                        case 2:
309                        case 5:
310                        case 6:
311                            lOrient=2;  //below & above
312                            break;
313                        default:
314                            break;
315                    }
316                }
317
318                //                       pt1
319                //                 /
320                //               /
321                //      pt2/
322                //              \
323                //            \
324                //                  \pt3
325                if(nDiff1X<0 & nDiff2X>0)
326                {
327                    switch(nLast)
328                    {
329                        case 0:
330                        case 3:
331                        case 4:
332                        case 7:
333                            lOrient=2;  //below & above
334                            break;
335                        case 1:
336                        case 2:
337                        case 5:
338                        case 6:
339                            lOrient=1;  //above & below
340                            break;
341                        default:
342                            break;
343                    }   //end switch(nLast)
344                }       //end if
345
346
347                //                       pt1    or   pt3
348                //                    |                   |
349                //                        |               |
350                //                       pt2             pt2
351                //                    |                   |
352                //                |                       |
353                //                   pt3                 pt1
354                if(nDiff1X==0 && nDiff2X==0)
355                {
356                    switch(nLast)
357                    {
358                        case 4:
359                            if(nDiff2Y<0)
360                                lOrient=0;
361                            break;
362                        case 6:
363                            if(nDiff2Y>0)
364                                lOrient=0;
365                            break;
366                        case 5:
367                            if(nDiff2Y<0)
368                                lOrient=3;
369                            break;
370                        case 7:
371                            if(nDiff2Y>0)
372                                lOrient=3;
373                            break;
374                        default:
375                                break;
376                    }
377                }
378
379                //get the channel points based on the desired orientation
380                pResultChannelPoints[nPointCounter] = ConnectTrueDouble2(nWidth,LinePoint1,
381                        LinePoint2,LinePoint3,lOrient);
382
383                //2nd segment vertical
384                if(nDiff2X==0)
385                {
386                    switch (lOrient) {
387                        case 0:
388                            if (nDiff2Y > 0) {
389                                nLast = 6;
390                            }
391                            if (nDiff2Y < 0) {
392                                nLast = 4;
393                            }
394                            break;
395                        case 1:
396                            if (nDiff2Y > 0) {
397                                nLast = 7;
398                            }
399                            if (nDiff2Y < 0) {
400                                nLast = 5;
401                            }
402                            break;
403                        case 2:
404                            if (nDiff2Y > 0) {
405                                nLast = 6;
406                            }
407                            if (nDiff2Y < 0) {
408                                nLast = 4;
409                            }
410                            break;
411                        case 3:
412                            if (nDiff2Y > 0) {
413                                nLast = 7;
414                            }
415                            if (nDiff2Y < 0) {
416                                nLast = 5;
417                            }
418                            break;
419                        default:
420                            break;
421                    }
422                }
423                //pt2--------pt3
424                if (nDiff2X > 0) {
425                    switch (lOrient) {
426                        case 0: //above & above
427                            nLast = 0;
428                            break;
429                        case 1: //above & below
430                            nLast = 1;
431                            break;
432                        case 2: //below & above
433                            nLast = 0;
434                            break;
435                        case 3: //below & below
436                            nLast = 1;
437                            break;
438                        default:
439                            break;
440                    }
441                    //break;
442                }
443                //pt3--------pt2
444                if (nDiff2X < 0) {
445                    switch (lOrient) {
446                        case 0: //above & above
447                            nLast = 2;
448                            break;
449                        case 1: //above & below
450                            nLast = 3;
451                            break;
452                        case 2: //below & above
453                            nLast = 2;
454                            break;
455                        case 3: //below & below
456                            nLast = 3;
457                            break;
458                        default:
459                            break;
460                    }
461                }
462            }   //end for
463
464            ResultChannelPoint = GetTrueEndPointDouble(nWidth, pLinePoints[nCounter],
465                pLinePoints[nCounter - 1],nLast);
466
467            pResultChannelPoints[nCounter] = new CChannelPoints2(ResultChannelPoint);
468        }
469        catch(Exception exc)
470        {
471            //System.out.println(e.getMessage());
472            ErrorLogger.LogException(_className ,"ConnectArrayTrueDouble",
473                    new RendererException("Failed inside ConnectArrayTrueDouble", exc));
474        }
475        return pResultChannelPoints;
476    }
477    private static CChannelPoints2[] GetChannel2Double(long nChannelWidth,
478            long vblCounter,
479            POINT2[] pLinePoints,
480            CChannelPoints2[] pResultChannelPoints) {
481        try {
482            pResultChannelPoints = ConnectArrayTrueDouble((int) nChannelWidth / 2, (int) vblCounter - 1,
483                    pLinePoints, pResultChannelPoints);
484
485        }
486        catch (Exception exc) {
487            ErrorLogger.LogException(_className ,"GetChannel2Double",
488                    new RendererException("Failed inside GetChannel2Double", exc));
489        }
490        return pResultChannelPoints;
491    }
492    
493    private static POINT2[] GetLowerChannelLineDouble(CChannelPoints2[] pChannelPoints,
494            int vblCounter,
495            POINT2[] pResultLinePoints) throws Exception
496    {
497        try {
498            int j = 0;
499
500            for (j = 0; j < vblCounter; j++) {
501                pResultLinePoints[j] = new POINT2(pChannelPoints[j].m_Line1);
502            }
503
504        } catch (Exception exc) {
505            ErrorLogger.LogException(_className ,"GetLowerChannelLineDouble",
506                    new RendererException("GetLowerChannelLineDouble", exc));
507        }
508        return pResultLinePoints;
509    }
510    private static POINT2[] GetUpperChannelLineDouble(CChannelPoints2[] pChannelPoints,
511            int vblCounter,
512            POINT2[] pResultLinePoints) {
513        try {
514            int j;
515            for (j = 0; j < vblCounter; j++) {
516                pResultLinePoints[j] = new POINT2(pChannelPoints[j].m_Line2);
517            }
518
519        } catch (Exception exc) {
520            ErrorLogger.LogException(_className ,"GetUpperChannelLineDouble",
521                    new RendererException("Failed inside GetUpperChannelLineDouble", exc));
522        }
523        return pResultLinePoints;
524    }
525    private static int FenceType(int linetype) {
526        int bolResult = 0;
527        try {
528            switch (linetype) {
529                case TacticalLines.TRIPLE2:
530                case TacticalLines.DOUBLEC2:
531                case TacticalLines.SINGLEC2:
532                case TacticalLines.TRIPLE:
533                case TacticalLines.DOUBLEC:
534                case TacticalLines.SINGLEC:
535                case TacticalLines.HWFENCE:
536                case TacticalLines.LWFENCE:
537                case TacticalLines.UNSP:
538                case TacticalLines.DOUBLEA:
539                case TacticalLines.SFENCE:
540                case TacticalLines.DFENCE:
541                    bolResult = 1;
542                    break;
543                default:
544                    bolResult = 0;
545                    break;
546            }
547        } catch (Exception exc) {
548            ErrorLogger.LogException(_className ,"FenceType",
549                    new RendererException("Failed inside FenceType " + Integer.toString(linetype), exc));
550        }
551        return bolResult;
552    }
553    /**
554    * Calculates the point count for the concertina wire and fence channels.
555    *
556    * @param pLinePoints client points
557    * @param vblCounter the client point count
558    * @param linetype the line type
559    *
560    * @return the number of points required to render the symbol
561    */
562    protected static int GetTripleCountDouble(POINT2[] pLinePoints,
563            int vblCounter,
564            int linetype) {
565        int lTotal = 0;
566        try {
567            //declarations
568            int j = 0;
569            int lHowManyThisSegment = 0;
570            double d = 0;
571            //end declarations
572
573            for (j = 0; j < vblCounter - 1; j++) {
574                d = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
575                if (d <= 10) {
576                    lHowManyThisSegment = 0;
577                } else {
578                    lHowManyThisSegment = (int) ((d - 10) / 10);
579                }
580
581                lTotal += lHowManyThisSegment;
582            }
583
584            switch (linetype) {
585                case TacticalLines.SINGLEC2:
586                case TacticalLines.DOUBLEC2:
587                case TacticalLines.TRIPLE2:
588                    lTotal = 3 * vblCounter;
589                    break;
590                case TacticalLines.SINGLEC:
591                case TacticalLines.DOUBLEC:
592                case TacticalLines.TRIPLE:
593                    lTotal = 6 * vblCounter + 37 * lTotal;  //was 2*vblCounter+37*lTotal
594                    break;
595                case TacticalLines.HWFENCE:
596                case TacticalLines.LWFENCE:
597                case TacticalLines.UNSP:
598                case TacticalLines.DOUBLEA:
599                case TacticalLines.SFENCE:
600                case TacticalLines.DFENCE:
601                    lTotal = 4 * vblCounter + 4 * lTotal;
602                    break;
603                case TacticalLines.BBS_LINE:
604                    lTotal = 2 * vblCounter + 1;
605                    break;
606                default:
607                    lTotal = 2 * vblCounter;
608                    break;
609            }
610        } catch (Exception exc) {
611            ErrorLogger.LogException(_className ,"GetTripleCountDouble",
612                    new RendererException("Failed inside GetTripleCountDouble " + Integer.toString(linetype), exc));
613        }
614        return lTotal;
615    }
616
617    protected static POINT2[] CoordIL2Double(int nPrinter,
618            POINT2[] pLinePoints,
619            int nUpperLower,
620            int vblCounter,
621            int linetype,
622            int vblChannelWidth) {
623            POINT2[]pLinePoints2=new POINT2[vblCounter];
624        try {
625            //declarations
626            int j, channelWidth = 20;
627            POINT2[] pNewLinePoints = new POINT2[vblCounter];
628            CChannelPoints2[] pChannelPoints = new CChannelPoints2[vblCounter];
629            //end declarations
630
631            lineutility.InitializePOINT2Array(pLinePoints2);
632            for (j = 0; j < vblCounter; j++) {
633                pNewLinePoints[j] = new POINT2(pLinePoints[j]);
634            }
635
636            switch (linetype) {
637                case TacticalLines.TRIPLE2:
638                case TacticalLines.DOUBLEC2:
639                case TacticalLines.SINGLEC2:
640                case TacticalLines.TRIPLE:
641                case TacticalLines.DOUBLEC:
642                case TacticalLines.SINGLEC:
643                case TacticalLines.HWFENCE:
644                case TacticalLines.LWFENCE:
645                case TacticalLines.DOUBLEA:
646                case TacticalLines.UNSP:
647                case TacticalLines.DFENCE:
648                case TacticalLines.SFENCE:
649                case TacticalLines.BELT:
650                case TacticalLines.BELT1:
651                case TacticalLines.BBS_LINE:
652                    channelWidth = vblChannelWidth;
653                    break;
654                default:
655                    channelWidth = vblChannelWidth;
656                    break;
657            }
658            if (linetype != (long) TacticalLines.LC &&
659                    linetype != (long) TacticalLines.LC2 &&
660                    linetype != TacticalLines.LC_HOSTILE) {
661                channelWidth /= 2;
662            }
663
664            pChannelPoints = GetChannel2Double(channelWidth * nPrinter,
665                    vblCounter,
666                    pNewLinePoints,
667                    pChannelPoints);
668
669            if (nUpperLower == 1) {
670                pNewLinePoints = GetUpperChannelLineDouble(pChannelPoints,
671                        vblCounter,
672                        pNewLinePoints);
673
674                for (j = 0; j < vblCounter; j++) {
675                    pLinePoints2[j] = new POINT2(pNewLinePoints[j]);
676                }
677            }
678
679            if (nUpperLower == 0) {
680                pNewLinePoints = GetLowerChannelLineDouble(pChannelPoints,
681                        vblCounter,
682                        pNewLinePoints);
683
684                for (j = 0; j < vblCounter; j++) {
685                    pLinePoints2[j] = new POINT2(pNewLinePoints[j]);
686                }
687            }
688
689            //clean up
690            pNewLinePoints = null;
691            pChannelPoints = null;
692        } catch (Exception exc) {
693            ErrorLogger.LogException(_className ,"CoordIL2Double",
694                    new RendererException("Failed inside CoordIL2Double", exc));
695        }
696        return pLinePoints2;
697    }
698    private static void GetAAFNTDouble(double dPrinter,
699            POINT2[] pLowerLinePoints,
700            int lLowerCounter,
701            POINT2[] pUpperLinePoints,
702            int lUpperCounter,
703            POINT2 ArrowLinePoint,
704            POINT2[] pLinePoints,
705            double dOffsetFactor) {
706        try {
707            //declarations
708            int j = 0;
709                    //nBase = 0;
710            int lCounter;
711            double x = 0, y = 0;
712            POINT2 outerTipLinePoint = new POINT2(pUpperLinePoints[0]),
713                    dottedTipLinePoint = new POINT2(pUpperLinePoints[0]),
714                    endLinePoint = new POINT2(pUpperLinePoints[0]),
715                    tempLinePoint = new POINT2(pUpperLinePoints[0]);
716            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
717            //double dOffsetFactor = 10;
718            //end declarations
719
720            lCounter = lLowerCounter + lUpperCounter + 8;
721
722            for (j = 0; j < lLowerCounter; j++) {
723                pLinePoints[j] = new POINT2(pLowerLinePoints[j]);
724            }
725
726            pLinePoints[lLowerCounter - 1].style = 5;
727
728            for (j = 0; j < lUpperCounter; j++) {
729                pLinePoints[lLowerCounter + j] = new POINT2(pUpperLinePoints[j]);
730            }
731
732            for (j = lCounter - 8; j < lCounter; j++) //initializations
733            {
734                pLinePoints[j] = new POINT2(pUpperLinePoints[0]);
735            }
736
737            endLinePoint.x =
738                    (int) ((double) (pLowerLinePoints[lLowerCounter - 1].x +
739                    pUpperLinePoints[lUpperCounter - 1].x) / 2);
740
741            endLinePoint.y =
742                    (int) ((double) (pLowerLinePoints[lLowerCounter - 1].y +
743                    pUpperLinePoints[lUpperCounter - 1].y) / 2);
744
745            x = (double) (pLowerLinePoints[lLowerCounter - 1].x - pUpperLinePoints[lUpperCounter - 1].x);
746            y = (double) (pLowerLinePoints[lLowerCounter - 1].y - pUpperLinePoints[lUpperCounter - 1].y);
747            x = x * x;
748            y = y * y;
749            //nBase = (int) Math.sqrt(x + y);
750
751            //nBase *= (int) (dPrinter);
752            outerTipLinePoint = new POINT2(ArrowLinePoint);
753            //dottedTipLinePoint = lineutility.GetOffsetPointDouble
754            //    (endLinePoint, outerTipLinePoint, (int)(dOffsetFactor * dPrinter));
755            
756            //dottedTipLinePoint = lineutility.GetOffsetPointDouble(endLinePoint, outerTipLinePoint, (int) (10 * dPrinter));
757            dottedTipLinePoint = lineutility.GetOffsetPointDouble(endLinePoint, outerTipLinePoint, (int)(dOffsetFactor*dPrinter) );
758
759            pLinePoints[lCounter - 9].style = 5;
760
761            pLinePoints[lCounter - 8] = new POINT2(pLowerLinePoints[lLowerCounter - 1]);
762
763            pt0.x = pUpperLinePoints[lUpperCounter - 1].x;
764            pt0.y = pUpperLinePoints[lUpperCounter - 1].y;
765            pt1.x = pLowerLinePoints[lLowerCounter - 1].x;
766            pt1.y = pLowerLinePoints[lLowerCounter - 1].y;
767            tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
768
769            pLinePoints[lCounter - 7] = new POINT2(tempLinePoint);
770            pLinePoints[lCounter - 6] = new POINT2(outerTipLinePoint);
771
772            pt0.x = pLowerLinePoints[lLowerCounter - 1].x;
773            pt0.y = pLowerLinePoints[lLowerCounter - 1].y;
774            pt1.x = pUpperLinePoints[lUpperCounter - 1].x;
775            pt1.y = pUpperLinePoints[lUpperCounter - 1].y;
776            tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
777
778            pLinePoints[lCounter - 5] = new POINT2(tempLinePoint);
779            pLinePoints[lCounter - 4] = new POINT2(pUpperLinePoints[lUpperCounter - 1]);
780            pLinePoints[lCounter - 4].style = 5;
781
782            pt0.x = pUpperLinePoints[lUpperCounter - 1].x;
783            pt0.y = pUpperLinePoints[lUpperCounter - 1].y;
784            pt1.x = pLowerLinePoints[lLowerCounter - 1].x;
785            pt1.y = pLowerLinePoints[lLowerCounter - 1].y;
786            //tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int)(2 * dOffsetFactor * dPrinter));
787            //tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) ((dOffsetFactor + 10) * dPrinter));
788            tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (2*dOffsetFactor * dPrinter));
789
790            pLinePoints[lCounter - 3] = new POINT2(tempLinePoint);
791            //pLinePoints[lCounter-3].weight=0;
792            pLinePoints[lCounter - 3].style = 2;//PS_DOT;
793            pLinePoints[lCounter - 2] = new POINT2(dottedTipLinePoint);
794            //pLinePoints[lCounter-2].weight=0;
795            pLinePoints[lCounter - 2].style = 2;//PS_DOT;
796
797            pt0.x = pLowerLinePoints[lLowerCounter - 1].x;
798            pt0.y = pLowerLinePoints[lLowerCounter - 1].y;
799            pt1.x = pUpperLinePoints[lUpperCounter - 1].x;
800            pt1.y = pUpperLinePoints[lUpperCounter - 1].y;
801            //tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int)(2 * dOffsetFactor * dPrinter));
802            //tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) ((dOffsetFactor + 10) * dPrinter));
803            tempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (2*dOffsetFactor * dPrinter));
804
805            pLinePoints[lCounter - 1] = new POINT2(tempLinePoint);
806            pLinePoints[lCounter - 1].style = 5;
807
808        } catch (Exception exc) {
809            ErrorLogger.LogException(_className ,"GetAAFNTDouble",
810                    new RendererException("Failed inside GetAAFNTDouble", exc));
811        }
812    }
813    /**
814     * gets the AXAD arrowhead
815     * @param dPrinter
816     * @param pLowerLinePoints
817     * @param lLowerCounter
818     * @param pUpperLinePoints
819     * @param lUpperCounter
820     * @param ArrowLinePoint
821     * @param pLinePoints
822     * @param vbiDrawThis
823     * @param dOffsetFactor
824     */
825    private static void GetAXADDouble(double dPrinter,
826            POINT2[] pLowerLinePoints,
827            int lLowerCounter,
828            POINT2[] pUpperLinePoints,
829            int lUpperCounter,
830            POINT2 ArrowLinePoint,
831            POINT2[] pLinePoints,
832            int vbiDrawThis,
833            double dOffsetFactor) {
834        try {            
835            int j = 0,
836                    lCounter = lLowerCounter + lUpperCounter + 8;
837            double x = 0, y = 0;
838            POINT2 OuterTipLinePoint = new POINT2(pUpperLinePoints[0]),
839                    InnerTipLinePoint = new POINT2(pUpperLinePoints[0]),
840                    EndLinePoint = new POINT2(pUpperLinePoints[0]),
841                    TempLinePoint = new POINT2(pUpperLinePoints[0]);
842            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
843            //double dOffsetFactor = 10;
844            //end declarations
845            
846            //10-19-12
847            //we must do this for catkbyfire because the rotary arrow tip now has to match the
848            //anchor point, i.e. the rotary feature can no longer stick out past the anchor point
849            //45 pixels shift here matches the 45 pixels shift for catkbyfire found in 
850            //lineutility.adjustCATKBYFIREControlPoint as called by clsChannelUtility.DrawChannel
851            POINT2 origArrowPt=new POINT2(ArrowLinePoint);
852            POINT2 ptUpper0=new POINT2(pUpperLinePoints[lUpperCounter-1]);
853            POINT2 ptLower0=new POINT2(pLowerLinePoints[lLowerCounter-1]);
854            double dist=lineutility.CalcDistanceDouble(pLowerLinePoints[lLowerCounter-1], pLowerLinePoints[lLowerCounter-2]);
855            if(vbiDrawThis==TacticalLines.CATKBYFIRE)
856            {
857                if(dist>45)
858                {
859                    POINT2 midPt=lineutility.MidPointDouble(pLowerLinePoints[lLowerCounter-2], pUpperLinePoints[lUpperCounter-2], 0);
860                    ArrowLinePoint=lineutility.ExtendAlongLineDouble(ArrowLinePoint, midPt, 45);
861                    pLowerLinePoints[lLowerCounter-1]=lineutility.ExtendAlongLineDouble(pLowerLinePoints[lLowerCounter-1], pLowerLinePoints[lLowerCounter-2], 45);//will be 45 if Oculus adjusts control point
862                    pUpperLinePoints[lUpperCounter-1]=lineutility.ExtendAlongLineDouble(pUpperLinePoints[lUpperCounter-1], pUpperLinePoints[lUpperCounter-2], 45);//will be 45 if Oculus adjusts control point
863                }
864            }
865            //end section
866
867            for (j = 0; j < lLowerCounter; j++) {
868                pLinePoints[j] = new POINT2(pLowerLinePoints[j]);
869            }
870
871            pLinePoints[lLowerCounter - 1].style = 5;
872
873            for (j = 0; j < lUpperCounter; j++) {
874                pLinePoints[lLowerCounter + j] = new POINT2(pUpperLinePoints[j]);
875            }
876
877            for (j = lCounter - 8; j < lCounter; j++) //initializations
878            {
879                pLinePoints[j] = new POINT2(pUpperLinePoints[0]);
880            }
881
882            EndLinePoint.x = (int) ((double) (pLowerLinePoints[lLowerCounter - 1].x +
883                    pUpperLinePoints[lUpperCounter - 1].x) / 2);
884
885            EndLinePoint.y = (int) ((double) (pLowerLinePoints[lLowerCounter - 1].y +
886                    pUpperLinePoints[lUpperCounter - 1].y) / 2);
887
888
889            x = (double) (pLowerLinePoints[lLowerCounter - 1].x - pUpperLinePoints[lUpperCounter - 1].x);
890            y = (double) (pLowerLinePoints[lLowerCounter - 1].y - pUpperLinePoints[lUpperCounter - 1].y);
891            x = x * x;
892            y = y * y;
893            //nBase = (int) Math.sqrt(x + y);
894
895            //nBase *= (int) dPrinter;
896
897            OuterTipLinePoint = new POINT2(ArrowLinePoint);
898            InnerTipLinePoint = lineutility.GetOffsetPointDouble(EndLinePoint, OuterTipLinePoint, -(int) (dOffsetFactor * dPrinter));
899            pLinePoints[lCounter - 9].style = 5;
900            pLinePoints[lCounter - 8] = new POINT2(OuterTipLinePoint);
901
902            pt0.x = pUpperLinePoints[lUpperCounter - 1].x;
903            pt0.y = pUpperLinePoints[lUpperCounter - 1].y;
904            pt1.x = pLowerLinePoints[lLowerCounter - 1].x;
905            pt1.y = pLowerLinePoints[lLowerCounter - 1].y;
906            TempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
907
908            pLinePoints[lCounter - 7] = new POINT2(TempLinePoint);
909            pLinePoints[lCounter - 6] = new POINT2( pLowerLinePoints[lLowerCounter - 1]);
910            pLinePoints[lCounter - 5] =  new POINT2(InnerTipLinePoint);
911            pLinePoints[lCounter - 4] =  new POINT2(pUpperLinePoints[lUpperCounter - 1]);
912
913            pt0.x = pLowerLinePoints[lLowerCounter - 1].x;
914            pt0.y = pLowerLinePoints[lLowerCounter - 1].y;
915            pt1.x = pUpperLinePoints[lUpperCounter - 1].x;
916            pt1.y = pUpperLinePoints[lUpperCounter - 1].y;
917            TempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
918
919            pLinePoints[lCounter - 3] =  new POINT2(TempLinePoint);
920            pLinePoints[lCounter - 2] =  new POINT2(OuterTipLinePoint);
921            pLinePoints[lCounter - 1] =  new POINT2(OuterTipLinePoint);
922            pLinePoints[lCounter - 1].style = 5;
923
924            switch (vbiDrawThis) {
925                case TacticalLines.SPT_STRAIGHT:
926                case TacticalLines.SPT:
927                case TacticalLines.AAAAA:
928                case TacticalLines.AIRAOA:
929                case TacticalLines.AXAD:
930                case TacticalLines.CATK:
931                case TacticalLines.CATKBYFIRE:
932                    pLinePoints[lCounter - 6].style = 5;
933                    pLinePoints[lCounter - 5].style = 5;
934                    break;
935                default:
936                    break;
937            }
938            
939            //10-19-12
940            //reset the original points after the hack for catkbyfire
941            if(vbiDrawThis==TacticalLines.CATKBYFIRE && dist>45)
942            {
943                pUpperLinePoints[lUpperCounter-1].x=ptUpper0.x;
944                pUpperLinePoints[lUpperCounter-1].y=ptUpper0.y;
945                pLowerLinePoints[lLowerCounter-1].x=ptLower0.x;
946                pLowerLinePoints[lLowerCounter-1].y=ptLower0.y;
947                ArrowLinePoint.x=origArrowPt.x;
948                ArrowLinePoint.y=origArrowPt.y;
949            }
950            //end section
951        } catch (Exception exc) {
952            ErrorLogger.LogException(_className ,"GetAXADDouble",
953                    new RendererException("Failed inside GetAXADDouble " + Integer.toString(vbiDrawThis), exc));
954        }
955    }
956    /**
957     * Calculates a channel line and is called once each time for lower and upper channel lines.
958     *
959     * @param nPrinter always 1
960     * @param pLinePoints client points
961     * @param nUpperLower 0 for lower channel line, 1 for upper channel line
962     * @param vblCounter the client point count
963     * @param vbiDrawThis the line type
964     * @param vblChannelWidth the channel width
965     *
966     * @return the channel line array as POINT2
967     */
968    protected static POINT2[] GetChannelArray2Double(int nPrinter,
969            POINT2[] pLinePoints,
970            int nUpperLower,
971            int vblCounter,
972            int vbiDrawThis,
973            int vblChannelWidth) {
974        try {
975            //get the upper or lower channel array for the specified channel type
976            switch (vbiDrawThis) {
977                case TacticalLines.TRIPLE2:
978                case TacticalLines.DOUBLEC2:
979                case TacticalLines.SINGLEC2:
980                case TacticalLines.LC2:
981                case TacticalLines.LC:
982                case TacticalLines.LC_HOSTILE:
983                case TacticalLines.AIRAOA:
984                case TacticalLines.AAAAA:
985                case TacticalLines.AXAD:
986                case TacticalLines.CATK:
987                case TacticalLines.CATKBYFIRE:
988                case TacticalLines.MAIN:
989                case TacticalLines.MAIN_STRAIGHT:
990                case TacticalLines.AAFNT:
991                case TacticalLines.AAFNT_STRAIGHT:
992                case TacticalLines.SPT:
993                case TacticalLines.SPT_STRAIGHT:
994                case TacticalLines.BELT:
995                case TacticalLines.TRIPLE:
996                case TacticalLines.DOUBLEC:
997                case TacticalLines.SINGLEC:
998                case TacticalLines.HWFENCE:
999                case TacticalLines.BBS_LINE:
1000                case TacticalLines.LWFENCE:
1001                case TacticalLines.DOUBLEA:
1002                case TacticalLines.UNSP:
1003                case TacticalLines.SFENCE:
1004                case TacticalLines.DFENCE:
1005                case TacticalLines.CHANNEL:
1006                case TacticalLines.CHANNEL_FLARED:
1007                case TacticalLines.CHANNEL_DASHED:
1008                    pLinePoints = CoordIL2Double(nPrinter, pLinePoints, nUpperLower, vblCounter, vbiDrawThis, vblChannelWidth);
1009                    break;
1010                default:
1011                    //do nothing if it's not a channel type
1012                    break;
1013            }   //end switch
1014
1015        } catch (Exception exc) {
1016            ErrorLogger.LogException(_className ,"GetChannelArray2Double",
1017                    new RendererException("Failed inside GetChannelArray2Double " + Integer.toString(vbiDrawThis), exc));
1018        }
1019        return pLinePoints;
1020    }
1021
1022    private static CChannelPoints2 GetTrueEndPointDouble(int nWidth,
1023                                        POINT2 EndLinePoint,
1024                                        POINT2 NextLinePoint,
1025                                        int lLast)
1026    {
1027        CChannelPoints2 cAnswers=new CChannelPoints2();
1028        try
1029        {
1030            //declarations
1031            POINT2 LinePoint1=new POINT2(),LinePoint2=new POINT2();
1032            double m = 0,
1033                    b = 0,
1034                    bPerpendicular = 0,
1035                    Upperb = 0,
1036                    Lowerb = 0,
1037                    dWidth=(double)nWidth;
1038            int bolVertical=0;
1039            ref<double[]> pdResult=new ref();// double[6];
1040            //end declarations
1041
1042            bolVertical=lineutility.CalcTrueLinesDouble(nWidth,EndLinePoint,NextLinePoint,pdResult);
1043            m = pdResult.value[0];
1044            b = pdResult.value[1];
1045            Upperb = pdResult.value[3];
1046            Lowerb = pdResult.value[5];
1047
1048            if(bolVertical==0)  //lines are vertical
1049            {
1050                switch(lLast)
1051                {
1052                    case 4:
1053                    case 6:
1054                        cAnswers.m_Line1.x=EndLinePoint.x-dWidth;
1055                        cAnswers.m_Line1.y=EndLinePoint.y;
1056                        cAnswers.m_Line2.x=EndLinePoint.x+dWidth;
1057                        cAnswers.m_Line2.y=EndLinePoint.y;
1058                        break;
1059                    case 5:
1060                    case 7:
1061                        cAnswers.m_Line1.x=EndLinePoint.x+dWidth;
1062                        cAnswers.m_Line1.y=EndLinePoint.y;
1063                        cAnswers.m_Line2.x=EndLinePoint.x-dWidth;
1064                        cAnswers.m_Line2.y=EndLinePoint.y;
1065                        break;
1066                    default:    //cases 0-3 should not occur if line is vertical
1067                        break;
1068                }
1069            }
1070
1071            if(m==0)
1072            {
1073                switch(lLast)
1074                {
1075                    case 0:     //line1 is above segment2
1076                    case 2:
1077                        cAnswers.m_Line1.x=EndLinePoint.x;
1078                        cAnswers.m_Line1.y=EndLinePoint.y-dWidth;
1079                        cAnswers.m_Line2.x=EndLinePoint.x;
1080                        cAnswers.m_Line2.y=EndLinePoint.y+dWidth;
1081                        break;
1082                    case 1:     //line1 is above segment2
1083                    case 3:
1084                        cAnswers.m_Line1.x=EndLinePoint.x;
1085                        cAnswers.m_Line1.y=EndLinePoint.y+dWidth;
1086                        cAnswers.m_Line2.x=EndLinePoint.x;
1087                        cAnswers.m_Line2.y=EndLinePoint.y-dWidth;
1088                        break;
1089                    default:    //cases 4-7 should not be passed since line not vertical
1090                        break;
1091                }
1092            }
1093
1094            //remaining cases, line is neither vertical nor horizontal
1095            if(bolVertical!=0 && m!=0)  //lines are neither vertical nor horizontal
1096            {
1097                bPerpendicular = EndLinePoint.y + EndLinePoint.x / m;
1098                LinePoint1=lineutility.CalcTrueIntersectDouble2(m,Upperb,-1/m,bPerpendicular,1,1,0,0);
1099                LinePoint2=lineutility.CalcTrueIntersectDouble2(m,Lowerb,-1/m,bPerpendicular,1,1,0,0);
1100
1101                switch(lLast)
1102                {
1103                    case 0:     //line1 is above segment2
1104                    case 2:
1105                        if(LinePoint1.y<LinePoint2.y)
1106                        {
1107                            cAnswers.m_Line1=LinePoint1;
1108                            cAnswers.m_Line2=LinePoint2;
1109                        }
1110                        else
1111                        {
1112                            cAnswers.m_Line1=LinePoint2;
1113                            cAnswers.m_Line2=LinePoint1;
1114                        }
1115                        break;
1116                    case 1:     //line1 is below segment2
1117                    case 3:
1118                        if(LinePoint1.y>LinePoint2.y)
1119                        {
1120                            cAnswers.m_Line1=LinePoint1;
1121                            cAnswers.m_Line2=LinePoint2;
1122                        }
1123                        else
1124                        {
1125                            cAnswers.m_Line1=LinePoint2;
1126                            cAnswers.m_Line2=LinePoint1;
1127                        }
1128                        break;
1129                    default:    //cases1-4 should not occur since line is not vertical
1130                        break;
1131                }
1132            }
1133            pdResult=null;
1134        }
1135        catch(Exception exc)
1136        {
1137            ErrorLogger.LogException(_className ,"GetTrueEndPointDouble",
1138                    new RendererException("Failed inside GetTrueEndPointDouble", exc));
1139        }
1140        return cAnswers;
1141    }
1142    private static CChannelPoints2 ConnectTrueDouble2(int nWidth,
1143            POINT2  LinePoint1,
1144            POINT2  LinePoint2,
1145            POINT2  LinePoint3,
1146            int  lOrient)
1147    {
1148        CChannelPoints2 pAnswerLinePoints=new CChannelPoints2();
1149        try
1150        {
1151            //declarations
1152            double  m1 = 0,
1153                    b1 = 0,
1154                    m2 = 0,
1155                    b2 = 0,
1156                    Lowerb1 = 0,
1157                    Upperb1 = 0,
1158                    Lowerb2 = 0,
1159                    Upperb2 = 0,
1160                    dWidth=(double)nWidth;
1161
1162            ref<double[]> pdResult=new ref();//double[6];
1163            //pdResult.value=new double[6];
1164            //POINT2 AnswerLinePoint=new POINT2();
1165            int bolVerticalSlope1=0,bolVerticalSlope2=0;
1166            ref<double[]> x=new ref(),y=new ref();
1167            //end declarations
1168
1169            //Call CalcLines function for first two points (LinePoint1, LinePoint2)
1170            //and put parameters into the proper variables
1171            bolVerticalSlope1 = lineutility.CalcTrueLinesDouble(nWidth, LinePoint1, LinePoint2, pdResult);
1172            if(bolVerticalSlope1!=0)    //line is not vertical
1173            {
1174                m1 = pdResult.value[0];
1175                b1 = pdResult.value[1];
1176                Upperb1 = pdResult.value[5];
1177                Lowerb1 = pdResult.value[3];
1178            }
1179
1180            //Call CalcLines function for next two points (LinePoint2, LinePoint3)
1181            bolVerticalSlope2 = lineutility.CalcTrueLinesDouble(nWidth, LinePoint2, LinePoint3, pdResult);
1182            if(bolVerticalSlope2!=0)    //line is not vertical
1183            {
1184                m2 = pdResult.value[0];
1185                b2 = pdResult.value[1];
1186                Upperb2 = pdResult.value[5];
1187                Lowerb2 = pdResult.value[3];
1188            }
1189
1190            //must alter dWidth from the standard if bolVerticalSlope is 0.
1191            switch(lOrient)
1192            {
1193                case 0:
1194                    //line1 is above segment1 and above segment2
1195                    //use 0 for the orientation for Line 1
1196                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);
1197                    pAnswerLinePoints.m_Line1.x=x.value[0];
1198                    pAnswerLinePoints.m_Line1.y=y.value[0];
1199                    //line 2 point:     line2 is below segment1 and below segment2
1200                    //use 3 for the orientation for Line 2
1201                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);
1202                    pAnswerLinePoints.m_Line2.x=x.value[0];
1203                    pAnswerLinePoints.m_Line2.y=y.value[0];
1204                    break;
1205                case 1:
1206                    //line1 is above segment1 and below segment2
1207                    //use 1 for the orientation for Line 1
1208                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);
1209                    pAnswerLinePoints.m_Line1.x=x.value[0];
1210                    pAnswerLinePoints.m_Line1.y=y.value[0];
1211                    //line2 is below segment1 and above segment2
1212                    //use 2 for the orientation for Line 2
1213                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);
1214                    pAnswerLinePoints.m_Line2.x=x.value[0];
1215                    pAnswerLinePoints.m_Line2.y=y.value[0];
1216                    break;
1217                case 2:
1218                    //line1 is below segment1 and above segment2
1219                    //use 2 for the orientation for Line 1
1220                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);
1221                    pAnswerLinePoints.m_Line1.x=x.value[0];
1222                    pAnswerLinePoints.m_Line1.y=y.value[0];
1223                    //line2 is above segment1 and below segment2
1224                    //use 1 for the orientation for Line 1
1225                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);
1226                    pAnswerLinePoints.m_Line2.x=x.value[0];
1227                    pAnswerLinePoints.m_Line2.y=y.value[0];
1228                    break;
1229                case 3:
1230                    //line1 is below segment1 and below segment2
1231                    //use 3 for the orientation for Line 1
1232                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);
1233                    pAnswerLinePoints.m_Line1.x=x.value[0];
1234                    pAnswerLinePoints.m_Line1.y=y.value[0];
1235                    //line2 is above segment1 and above segment2
1236                    //use 0 for the orientation for Line 2
1237                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);
1238                    pAnswerLinePoints.m_Line2.x=x.value[0];
1239                    pAnswerLinePoints.m_Line2.y=y.value[0];
1240                    break;
1241                default:
1242                    break;
1243            }
1244            pdResult=null;
1245        }
1246        catch(Exception exc)
1247        {
1248            ErrorLogger.LogException(_className ,"ConnectTrueDouble2",
1249                    new RendererException("Failed inside ConnectTrueDouble2", exc));
1250        }
1251        return pAnswerLinePoints;
1252    }
1253    /**
1254     * Shift CounterAttack By Fire to not extend past the first point
1255     * @param vbiDrawThis
1256     * @param lpsaUpperVBPoints
1257     * @param vblLowerCounter
1258     * @param lpsaLowerVBPoints
1259     * @param vblUpperCounter 
1260     */
1261//    private static void shiftCATKBYFIREPoints(int vbiDrawThis,
1262//            double[] lpsaUpperVBPoints,
1263//            int vblLowerCounter,
1264//            double[] lpsaLowerVBPoints,
1265//            int vblUpperCounter)
1266//    {
1267//        try
1268//        {
1269//            if(vbiDrawThis != TacticalLines.CATKBYFIRE)
1270//                return;
1271//
1272//            POINT2 nextToLastPoint=new POINT2(lpsaUpperVBPoints[vblUpperCounter-4],lpsaUpperVBPoints[vblUpperCounter-3]);
1273//            POINT2 lastPoint=new POINT2(lpsaUpperVBPoints[vblUpperCounter-2],lpsaUpperVBPoints[vblUpperCounter-1]);
1274//            double dist=lineutility.CalcDistanceDouble(lastPoint, nextToLastPoint);
1275//            
1276//            if(dist<45)
1277//            {
1278//                nextToLastPoint=lineutility.ExtendAlongLineDouble(lastPoint,nextToLastPoint,45+2*dist);
1279//                lastPoint=lineutility.ExtendLineDouble(nextToLastPoint,lastPoint, -45);
1280//                lpsaUpperVBPoints[vblUpperCounter-4]=nextToLastPoint.x;
1281//                lpsaUpperVBPoints[vblUpperCounter-3]=nextToLastPoint.y;
1282//                lpsaLowerVBPoints[vblLowerCounter-4]=nextToLastPoint.x;
1283//                lpsaLowerVBPoints[vblLowerCounter-3]=nextToLastPoint.y;                                    
1284//            }
1285//            //lastPoint=lineutility.ExtendAlongLineDouble(lastPoint, nextToLastPoint, 45);
1286//            else
1287//                lastPoint=lineutility.ExtendLineDouble(nextToLastPoint,lastPoint, -45);
1288//            
1289//            lpsaUpperVBPoints[vblUpperCounter-2]=lastPoint.x;
1290//            lpsaUpperVBPoints[vblUpperCounter-1]=lastPoint.y;
1291//            lpsaLowerVBPoints[vblLowerCounter-2]=lastPoint.x;
1292//            lpsaLowerVBPoints[vblLowerCounter-1]=lastPoint.y;                                    
1293//        }
1294//        catch(Exception exc)
1295//        {
1296//            ErrorLogger.LogException(_className ,"ShiftCATKBYFIREPoints",
1297//                    new RendererException("Failed inside ShiftCATKBYFIREPoints", exc));
1298//        }
1299//    }
1300    /**
1301     * tester function to shift counterattack by fire point back to account for
1302     * aligning the rotary arrow tip with the anchor point. the feature used to extend past 
1303     * the anchor so the control point was shove forward. Intended to be called by the tester.
1304     * note: this function is not used by the CPOF client, it is for tester use only
1305     * @param linetype line type
1306     * @param pLinePoints
1307     * @param shift amount to shift back the existing control point
1308     */
1309//    public static void shiftCATKBYFIREControlPoint(
1310//            int linetype,
1311//            ArrayList<POINT2>pLinePoints,
1312//            double shift)
1313//    {
1314//        try
1315//        {
1316//            if(linetype != TacticalLines.CATKBYFIRE)
1317//                return;
1318//            int controlPtIndex=pLinePoints.size()-1;
1319//            POINT2 pt0=pLinePoints.get(0);
1320//            POINT2 pt1=pLinePoints.get(1);
1321//            double dist=lineutility.CalcDistanceDouble(pLinePoints.get(0), pLinePoints.get(1));
1322//            if(dist<=45)
1323//                return;
1324//            POINT2 controlPt=pLinePoints.get(controlPtIndex);
1325//            //pt3 is the point on parallel line which contains the control point and corresponds to,
1326//            //i.e. is perpendicular to, pt0.
1327//            POINT2 pt3=lineutility.PointRelativeToLine(pt0, pt1, pt0, controlPt);
1328//            //pt4 will be the shifted control point
1329//            POINT2 pt4=lineutility.ExtendLineDouble(pt3, controlPt, shift);
1330//            //set the control point as the new shifted control point
1331//            pLinePoints.set(controlPtIndex, pt4);
1332//        }
1333//        catch(Exception exc)
1334//        {
1335//            ErrorLogger.LogException(_className ,"shiftCATKBYFIREControlPoint",
1336//                    new RendererException("Failed inside shiftCATKBYFIREControlPoint", exc));
1337//        }
1338//    }
1339    /**
1340     * Calculates the channel points
1341     * @param lpsaUpperVBPoints the client points as 2-tuples
1342     * @param lpsaLowerVBPoints the client points as 2 tuples
1343     * @param resultVBPoints the result points as 3-tuples x,y,linestyle
1344     * @param vblUpperCounter the number of client 2-tuples
1345     * @param vblLowerCounter the number of client 2-tuples
1346     * @param vbiDrawThis the line type as a hierarchy
1347     * @param vblChannelWidth the channel width in pixels
1348     * @param useptr the distance in pixels from the arrow tip to the back of the arrowhead
1349     * @param shapes the ShapeInfo array, each object contains the GeneralPath
1350     * @param rev the Mil-Standard 2525 revision
1351     * @return
1352     */
1353    protected static int GetChannel1Double(double[] lpsaUpperVBPoints,
1354            double[] lpsaLowerVBPoints,
1355            double[] resultVBPoints,
1356            int vblUpperCounter,
1357            int vblLowerCounter,
1358            int vbiDrawThis,
1359            int vblChannelWidth,
1360            int useptr,
1361            ArrayList<Shape2>shapes,
1362            int rev) {
1363        int lResult = -1;
1364        try {
1365            int k = 0, vblCounter = 0;
1366            int nPrinter = 1,
1367                    nArrowSize = 40 * nPrinter,
1368                    max = 0;
1369            double dist = 0,remainder=0;
1370            int vblUpperCounter2 = vblUpperCounter, vblLowerCounter2 = vblLowerCounter;
1371            int nReverseUpper = 0;
1372            int lUpperFlotCount = 0, lLowerFlotCount = 0;
1373            int nLowerCounter = 0, lUpperCounter = 0, lResultCounter = 0;
1374            int XCounter = 0;
1375            int j = 0, lHowManyThisSegment = 0, l = 0, t = 0;
1376            double pi = Math.PI, dAngle = 0, d = 0;
1377            double a = 13;//13;
1378            double b = 6;  //6;
1379            double dFactor = 0;
1380            int lEllipseCounter = 0;
1381            //double arrowOffsetFactor = 10;
1382            double arrowOffsetFactor = vblChannelWidth/4;  //diagnostic was 10
1383            POINT2[] pLowerLinePoints = new POINT2[vblLowerCounter],
1384                    pUpperLinePoints = new POINT2[vblUpperCounter],
1385                    pArrowLinePoints = new POINT2[1],
1386                    pLinePoints = null,
1387                    pUpperFlotPoints = null, pLowerFlotPoints = null, pOriginalLinePoints = null, pOriginalLinePoints2 = null;
1388            lineutility.InitializePOINT2Array(pLowerLinePoints);
1389            lineutility.InitializePOINT2Array(pUpperLinePoints);
1390            lineutility.InitializePOINT2Array(pArrowLinePoints);
1391
1392            POINT2 pt1 = new POINT2(), pt2 = new POINT2(), pt3 = new POINT2(), pt4 = new POINT2(), midPt1 = new POINT2(), midPt2 = new POINT2(), pt0 = new POINT2();
1393            POINT2[] arrowPts = new POINT2[3];
1394            //POINT2 startLinePoint = new POINT2();
1395            POINT2[] XPoints = new POINT2[4], pEllipsePoints2 = new POINT2[37];
1396            lineutility.InitializePOINT2Array(XPoints);
1397            lineutility.InitializePOINT2Array(pEllipsePoints2);
1398
1399            //POINT2 endLinePoint = new POINT2();
1400            POINT2 temp1LinePoint = new POINT2(), ptCenter = new POINT2(pLowerLinePoints[0]),
1401                    temp2LinePoint = new POINT2();
1402            POINT2 lastPoint = new POINT2(), nextToLastPoint = new POINT2();    //used by CATKBYFIRE
1403            //end declarations
1404
1405            //initializations
1406            if (vblChannelWidth < 5 && vbiDrawThis != TacticalLines.BBS_LINE) {
1407                vblChannelWidth = 5;
1408            }
1409
1410            if (vblLowerCounter < 2 || vblUpperCounter < 2) {
1411                return -1;
1412            }
1413
1414            //shiftCATKBYFIREPoints(vbiDrawThis,lpsaUpperVBPoints,lpsaUpperVBPoints.length,lpsaLowerVBPoints,lpsaLowerVBPoints.length);
1415            //load client points
1416            for (k = 0; k < (long) vblLowerCounter; k++) {
1417                pLowerLinePoints[k].x = lpsaLowerVBPoints[nLowerCounter];
1418                nLowerCounter++;
1419                pLowerLinePoints[k].y = lpsaLowerVBPoints[nLowerCounter];
1420                nLowerCounter++;
1421                if (k == vblLowerCounter - 2) {
1422                    nextToLastPoint.x = pLowerLinePoints[k].x;
1423                    nextToLastPoint.y = pLowerLinePoints[k].y;
1424                }
1425                if (k == vblLowerCounter - 1) {
1426                    lastPoint.x = pLowerLinePoints[k].x;
1427                    lastPoint.y = pLowerLinePoints[k].y;
1428                }
1429                pLowerLinePoints[k].style = 0;
1430            }
1431            nLowerCounter = 0;
1432
1433            double lastSegmentLength = lineutility.CalcDistanceDouble(lastPoint, nextToLastPoint);
1434
1435            for (k = 0; k < (long) vblUpperCounter; k++) {
1436                pUpperLinePoints[k].x = lpsaUpperVBPoints[lUpperCounter];
1437                lUpperCounter++;
1438                pUpperLinePoints[k].y = lpsaUpperVBPoints[lUpperCounter];
1439                lUpperCounter++;
1440                pUpperLinePoints[k].style = 0;
1441            }
1442            lUpperCounter = 0;
1443            pArrowLinePoints[0] = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
1444            //end load client points
1445
1446            pt0 = new POINT2(pLowerLinePoints[0]);
1447            //diagnostic 1-7-13            
1448            boolean shiftLines=_shiftLines;
1449            switch(vbiDrawThis)
1450            {
1451                case TacticalLines.LC:
1452                case TacticalLines.LC_HOSTILE:
1453                case TacticalLines.UNSP:
1454                case TacticalLines.LWFENCE:
1455                case TacticalLines.HWFENCE:
1456                //case TacticalLines.BBS_LINE:
1457                case TacticalLines.SINGLEC:
1458                case TacticalLines.DOUBLEC:
1459                case TacticalLines.TRIPLE:
1460                    break;
1461                default:
1462                    shiftLines=false;
1463                    break;
1464            }
1465            //end section
1466            
1467            switch (vbiDrawThis) {
1468                case TacticalLines.CATK:
1469                case TacticalLines.AXAD:
1470                case TacticalLines.AIRAOA:
1471                case TacticalLines.AAAAA:
1472                case TacticalLines.SPT:
1473                case TacticalLines.SPT_STRAIGHT:
1474                case TacticalLines.AAFNT:               //40
1475                case TacticalLines.AAFNT_STRAIGHT:
1476                case TacticalLines.MAIN:
1477                case TacticalLines.MAIN_STRAIGHT:
1478                case TacticalLines.CATKBYFIRE:  //80
1479                    dist = (double) useptr;
1480
1481                    nArrowSize = (int) Math.sqrt(dist * dist + vblChannelWidth / 2 * vblChannelWidth / 2);
1482                    //nArrowSize = (int) Math.sqrt(dist * dist + vblChannelWidth * vblChannelWidth);
1483                    //lineutility.WriteFile(Integer.toString(nArrowSize));
1484                    
1485                    pUpperLinePoints[vblUpperCounter - 1] = lineutility.ExtendAlongLineDouble(pUpperLinePoints[vblUpperCounter - 1], pUpperLinePoints[vblUpperCounter - 2], dist);
1486                    pLowerLinePoints[vblLowerCounter - 1] = lineutility.ExtendAlongLineDouble(pLowerLinePoints[vblLowerCounter - 1], pLowerLinePoints[vblLowerCounter - 2], dist);
1487                    break;
1488                default:
1489                    break;
1490            }
1491            //end section
1492
1493            temp1LinePoint = new POINT2(pLowerLinePoints[0]);
1494            temp2LinePoint = new POINT2(pUpperLinePoints[0]);
1495
1496            //get the channel array
1497            switch (vbiDrawThis) {
1498                case TacticalLines.TRIPLE2:
1499                case TacticalLines.DOUBLEC2:
1500                case TacticalLines.SINGLEC2:
1501                case TacticalLines.AAFNT:
1502                case TacticalLines.AAFNT_STRAIGHT:
1503                case TacticalLines.MAIN:
1504                case TacticalLines.MAIN_STRAIGHT:
1505                case TacticalLines.SPT:
1506                case TacticalLines.SPT_STRAIGHT:
1507                case TacticalLines.CATK:
1508                case TacticalLines.CATKBYFIRE:
1509                case TacticalLines.TRIPLE:
1510                case TacticalLines.DOUBLEC:
1511                case TacticalLines.SINGLEC:
1512                case TacticalLines.HWFENCE:
1513                case TacticalLines.BBS_LINE:
1514                case TacticalLines.LWFENCE:
1515                case TacticalLines.UNSP:
1516                case TacticalLines.DOUBLEA:
1517                case TacticalLines.DFENCE:
1518                case TacticalLines.SFENCE:
1519                case TacticalLines.CHANNEL:
1520                case TacticalLines.CHANNEL_FLARED:
1521                case TacticalLines.CHANNEL_DASHED:
1522                    vblCounter = GetTripleCountDouble(pUpperLinePoints, vblUpperCounter, vbiDrawThis);
1523                    //save the original line points for later
1524                    pOriginalLinePoints = new POINT2[vblUpperCounter];
1525                    for (k = 0; k < vblUpperCounter; k++) {
1526                        pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1527                    }
1528                    pOriginalLinePoints2 = new POINT2[vblUpperCounter];
1529                    for (k = 0; k < vblUpperCounter; k++) {
1530                        pOriginalLinePoints2[k] = new POINT2(pUpperLinePoints[k]);
1531                    }
1532                    //bound the points
1533                    switch (vbiDrawThis) {
1534                        case TacticalLines.TRIPLE2:
1535                        case TacticalLines.DOUBLEC2:
1536                        case TacticalLines.SINGLEC2:
1537                        case TacticalLines.TRIPLE:
1538                        case TacticalLines.DOUBLEC:
1539                        case TacticalLines.SINGLEC:
1540                        case TacticalLines.HWFENCE:
1541                        case TacticalLines.BBS_LINE:
1542                        case TacticalLines.LWFENCE:
1543                        case TacticalLines.UNSP:
1544                        case TacticalLines.DOUBLEA:
1545                        case TacticalLines.DFENCE:
1546                        case TacticalLines.SFENCE:
1547                            pLowerLinePoints = new POINT2[vblLowerCounter];
1548                            for (k = 0; k < vblLowerCounter2; k++) {
1549                                pLowerLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1550                            }
1551
1552                            pUpperLinePoints = new POINT2[vblUpperCounter];
1553                            for (k = 0; k < vblUpperCounter2; k++) {
1554                                pUpperLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1555                            }
1556                            pOriginalLinePoints = new POINT2[vblUpperCounter];
1557                            for (k = 0; k < vblUpperCounter2; k++) {
1558                                pOriginalLinePoints[k] = new POINT2(pOriginalLinePoints2[k]);
1559                            }                            
1560                            break;
1561                        default:
1562                            //do not bound the points
1563                            break;
1564                    }
1565                    lineutility.moveSingleCPixels(vbiDrawThis, pUpperLinePoints);
1566                    lineutility.moveSingleCPixels(vbiDrawThis, pLowerLinePoints);
1567                    lineutility.MoveChannelPixels(pUpperLinePoints);
1568                    lineutility.MoveChannelPixels(pLowerLinePoints);
1569                    
1570                    //diagnostic 1-7-13
1571                    //if(_shiftLines && vbiDrawThis != TacticalLines.DOUBLEC)
1572                    if(shiftLines)
1573                        vblChannelWidth *=2;
1574                    //end section
1575                    
1576                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1577                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1578                    
1579                    //diagnostic 1-7-13
1580                    if(shiftLines)
1581                    {
1582                        //if(vbiDrawThis != TacticalLines.SINGLEC && vbiDrawThis != TacticalLines.DOUBLEC)
1583                          //  pUpperLinePoints=pOriginalLinePoints;
1584                        if(vbiDrawThis == TacticalLines.SINGLEC)                        
1585                            pLowerLinePoints=pOriginalLinePoints;                        
1586                        else if(vbiDrawThis == TacticalLines.DOUBLEC)                        
1587                        {
1588                            for(j=0;j<pUpperLinePoints.length;j++)
1589                            {
1590                                pUpperLinePoints[j]=lineutility.MidPointDouble(pLowerLinePoints[j], pOriginalLinePoints[j], 0);
1591                            }
1592                            //pOriginalLinePoints=pLowerLinePoints.clone();
1593                        }
1594                        else if(vbiDrawThis == TacticalLines.TRIPLE)                        
1595                            pUpperLinePoints=pOriginalLinePoints;                        
1596                        else
1597                            pUpperLinePoints=pOriginalLinePoints;                        
1598                    }
1599                    //end section
1600                    
1601                    //AAFNT, MAIN, SPT, and CHANNEL_FLARED have flared first segment
1602                    //AAFNT_STRAIGHT, MAIN_STRAIGHT, SPT_STRAIGHT, and CHANNEL
1603                    //do not have flared first segment (except 2525 rev C has straight 1st segment)
1604                    if(rev != RendererSettings.Symbology_2525C)
1605                    {
1606                        if (vbiDrawThis == TacticalLines.AAFNT ||
1607                                vbiDrawThis == TacticalLines.MAIN ||
1608                                vbiDrawThis ==  TacticalLines.SPT ||
1609                                vbiDrawThis ==  TacticalLines.CHANNEL_FLARED) {
1610                            pUpperLinePoints[0] = lineutility.ExtendLineDouble(temp2LinePoint, pUpperLinePoints[0], 10);
1611                            pLowerLinePoints[0] = lineutility.ExtendLineDouble(temp1LinePoint, pLowerLinePoints[0], 10);
1612                        }
1613                    }
1614                    break;
1615                case TacticalLines.LC:
1616                case TacticalLines.LC_HOSTILE:
1617                case TacticalLines.LC2:
1618                    if(shiftLines==true || vbiDrawThis == TacticalLines.LC2)
1619                    {
1620                        pOriginalLinePoints = new POINT2[vblUpperCounter];
1621                        for (k = 0; k < vblUpperCounter; k++) {
1622                            pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1623                        }
1624                    }
1625                    if (vbiDrawThis == TacticalLines.LC2) //bound the points
1626                    {
1627                        pLowerLinePoints = new POINT2[vblLowerCounter];
1628                        for (k = 0; k < vblLowerCounter2; k++) {
1629                            pLowerLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1630                        }
1631
1632                        pUpperLinePoints = null;
1633                        pUpperLinePoints = new POINT2[vblUpperCounter];
1634                        for (k = 0; k < vblUpperCounter2; k++) {
1635                            pUpperLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1636                        }
1637                    }                    
1638                    if(shiftLines)
1639                        vblChannelWidth *= 2;
1640                    
1641                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1642                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1643                    
1644                    if(shiftLines)   
1645                    {                        
1646                        //if(_affiliation != null && _affiliation.equalsIgnoreCase("H"))
1647                        if(vbiDrawThis==TacticalLines.LC_HOSTILE)
1648                            pLowerLinePoints=pOriginalLinePoints;
1649                        else
1650                            pUpperLinePoints=pOriginalLinePoints;
1651                    }
1652                    
1653                    if ((pUpperLinePoints[0].x > pUpperLinePoints[1].x) && (pUpperLinePoints[0].y != pUpperLinePoints[1].y)) {
1654                        nReverseUpper = 1;
1655                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1656                    } else if ((pUpperLinePoints[0].x > pUpperLinePoints[1].x) && (pUpperLinePoints[0].y == pUpperLinePoints[1].y)) {
1657                        nReverseUpper = 0;
1658                        lineutility.ReversePointsDouble2(pUpperLinePoints, vblUpperCounter);
1659                    } else if (pUpperLinePoints[0].x < pUpperLinePoints[1].x) {
1660                        nReverseUpper = 1;
1661                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1662                    } else if ((pUpperLinePoints[0].y > pUpperLinePoints[1].y) && (pUpperLinePoints[0].x == pUpperLinePoints[1].x)) {
1663                        nReverseUpper = 1;
1664                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1665                    } else if ((pUpperLinePoints[0].y < pUpperLinePoints[1].y) && (pUpperLinePoints[0].x == pUpperLinePoints[1].x)) {
1666                        nReverseUpper = 0;
1667                        lineutility.ReversePointsDouble2(pUpperLinePoints, vblUpperCounter);
1668                    }
1669                    break;
1670                case TacticalLines.AAAAA:
1671                case TacticalLines.AIRAOA:
1672                case TacticalLines.AXAD:
1673                    pOriginalLinePoints = new POINT2[vblUpperCounter];
1674                    for (k = 0; k < vblUpperCounter; k++) {
1675                        pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1676                    }
1677                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1678                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1679
1680
1681            //end section
1682                    //only allow the lines to cross if there is enough room
1683                    //if (lastSegmentLength > vblChannelWidth / 2)
1684                    //{
1685                        temp1LinePoint = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
1686                        temp2LinePoint = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
1687                        pLowerLinePoints[vblLowerCounter - 1] = new POINT2(temp2LinePoint);
1688                        pUpperLinePoints[vblUpperCounter - 1] = new POINT2(temp1LinePoint);
1689                    //}
1690                    break;
1691                default:
1692                    break;
1693            }   //end get channel array
1694            //load channel array into pLinePoints
1695            switch (vbiDrawThis) {
1696                case TacticalLines.LC2:
1697                    pLinePoints = new POINT2[vblUpperCounter + vblLowerCounter];
1698                    //initialize points
1699                    for (j = 0; j < pLinePoints.length; j++) {
1700                        pLinePoints[j].x = lpsaUpperVBPoints[0];
1701                        pLinePoints[j].y = lpsaUpperVBPoints[1];
1702                    }
1703                    vblCounter = vblLowerCounter + vblUpperCounter;
1704                    for (k = 0; k < vblUpperCounter; k++) {
1705                        pLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1706
1707                        if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) {
1708                            pLinePoints[k].style = 26;
1709                        }
1710                        if (pOriginalLinePoints[0].x > pOriginalLinePoints[1].x) {
1711                            pLinePoints[k].style = 26;
1712                        }
1713                        if (pOriginalLinePoints[0].x > pOriginalLinePoints[1].x) {
1714                            if (pOriginalLinePoints[0].y == pOriginalLinePoints[1].y) {
1715                                pLinePoints[k].style = 25;
1716                            }
1717                        }
1718                        if (pOriginalLinePoints[0].x == pOriginalLinePoints[1].x) {
1719                            if (pOriginalLinePoints[0].y < pOriginalLinePoints[1].y) {
1720                                pLinePoints[k].style = 25;
1721                            } else {
1722                                pLinePoints[k].style = 26;
1723                            }
1724                        }
1725                    }
1726                    for (k = 0; k < vblLowerCounter - 1; k++) {
1727                        pLinePoints[vblUpperCounter + k] = new POINT2(pLowerLinePoints[k]);
1728
1729
1730                        if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) {
1731                            pLinePoints[vblUpperCounter + k].style = 25;
1732                        }
1733                        if (pOriginalLinePoints[0].x > pOriginalLinePoints[1].x) {
1734                            pLinePoints[vblUpperCounter + k].style = 25;
1735                        }
1736                        if (pOriginalLinePoints[0].x > pOriginalLinePoints[1].x) {
1737                            if (pOriginalLinePoints[0].y == pOriginalLinePoints[1].y) {
1738                                pLinePoints[vblUpperCounter + k].style = 26;
1739                            }
1740                        }
1741                        if (pOriginalLinePoints[0].x == pOriginalLinePoints[1].x) {
1742                            if (pOriginalLinePoints[0].y < pOriginalLinePoints[1].y) {
1743                                pLinePoints[vblUpperCounter + k].style = 26;
1744                            } else {
1745                                pLinePoints[vblUpperCounter + k].style = 25;
1746                            }
1747                        }
1748                    }
1749                    pLinePoints[k + vblUpperCounter] = new POINT2(pLowerLinePoints[k]);
1750                    pLinePoints[k].style = 5;
1751                    break;
1752                case TacticalLines.LC:
1753                case TacticalLines.LC_HOSTILE:
1754                    lUpperFlotCount = flot.GetFlotCountDouble(pUpperLinePoints, vblUpperCounter);
1755                    lLowerFlotCount = flot.GetFlotCountDouble(pLowerLinePoints, vblLowerCounter);
1756                    if (lUpperFlotCount <= 0 || lLowerFlotCount <= 0) {
1757                        return 0;
1758                    }
1759                    //vblCounter = lUpperFlotCount + lLowerFlotCount;
1760
1761                    max = vblUpperCounter;
1762                    if (max < lUpperFlotCount) {
1763                        max = lUpperFlotCount;
1764                    }
1765                    pUpperFlotPoints = new POINT2[max];
1766                    lineutility.InitializePOINT2Array(pUpperFlotPoints);
1767                    max = vblLowerCounter;
1768                    if (max < lLowerFlotCount) {
1769                        max = lLowerFlotCount;
1770                    }
1771                    pLowerFlotPoints = new POINT2[max];
1772                    lineutility.InitializePOINT2Array(pLowerFlotPoints);
1773                    for (k = 0; k < vblUpperCounter; k++) {
1774                        pUpperFlotPoints[k] = new POINT2(pUpperLinePoints[k]);
1775                    }
1776                    for (k = 0; k < vblLowerCounter; k++) {
1777                        pLowerFlotPoints[k] = new POINT2(pLowerLinePoints[k]);
1778                    }
1779
1780                    lUpperFlotCount = flot.GetFlotDouble(pUpperFlotPoints, vblUpperCounter);    //6/24/04
1781                    lLowerFlotCount = flot.GetFlotDouble(pLowerFlotPoints, vblLowerCounter);    //6/24/04
1782                    pLinePoints = new POINT2[lUpperFlotCount + lLowerFlotCount];
1783                    lineutility.InitializePOINT2Array(pLinePoints);
1784
1785                    vblCounter = lLowerFlotCount + lUpperFlotCount;
1786
1787                    if (nReverseUpper == 1) {
1788                        for (k = 0; k < lUpperFlotCount; k++) {
1789                            pLinePoints[k] = new POINT2(pUpperFlotPoints[k]);
1790                            pLinePoints[k].style = 25;  //was 26
1791                        }
1792                        //added one line M. Deutch 4-22-02
1793                        if (lUpperFlotCount > 0) {
1794                            pLinePoints[lUpperFlotCount - 1].style = 5;
1795                        }
1796                        for (k = 0; k < lLowerFlotCount; k++) {
1797                            pLinePoints[k + lUpperFlotCount] = new POINT2(pLowerFlotPoints[k]);
1798                            pLinePoints[k + lUpperFlotCount].style = 26;    //was 0
1799                        }
1800                        if (lUpperFlotCount+lLowerFlotCount > 0) {
1801                            pLinePoints[lUpperFlotCount+lLowerFlotCount - 1].style = 5;}
1802                    }
1803                    if (nReverseUpper == 0) {
1804                        for (k = 0; k < lUpperFlotCount; k++) {
1805                            pLinePoints[k] = new POINT2(pUpperFlotPoints[k]);
1806                            pLinePoints[k].style = 26;  //was 0
1807                        }
1808                        if(lUpperFlotCount>0)
1809                            pLinePoints[lUpperFlotCount - 1].style = 5;
1810
1811                        for (k = 0; k < lLowerFlotCount; k++) {
1812                            pLinePoints[k + lUpperFlotCount] = new POINT2(pLowerFlotPoints[k]);
1813                            pLinePoints[k + lUpperFlotCount].style = 25;    //was 26
1814                        }
1815                        if(lUpperFlotCount+lLowerFlotCount>0)
1816                            pLinePoints[lUpperFlotCount+lLowerFlotCount - 1].style = 5;
1817                    }
1818                    break;
1819                case TacticalLines.TRIPLE2:
1820                case TacticalLines.DOUBLEC2:
1821                case TacticalLines.SINGLEC2:
1822                case TacticalLines.TRIPLE:
1823                case TacticalLines.DOUBLEC:
1824                case TacticalLines.SINGLEC:
1825                case TacticalLines.HWFENCE:
1826                case TacticalLines.LWFENCE:
1827                case TacticalLines.UNSP:
1828                case TacticalLines.DOUBLEA:
1829                case TacticalLines.SFENCE:
1830                case TacticalLines.DFENCE:
1831                case TacticalLines.CHANNEL:
1832                case TacticalLines.CHANNEL_FLARED:
1833                case TacticalLines.CHANNEL_DASHED:
1834                    //load the channel points
1835                    pLinePoints = new POINT2[vblCounter];
1836                    lineutility.InitializePOINT2Array(pLinePoints);
1837                    //initialize points
1838                    for (j = 0; j < pLinePoints.length; j++) {
1839                        pLinePoints[j].x = lpsaUpperVBPoints[0];
1840                        pLinePoints[j].y = lpsaUpperVBPoints[1];
1841                    }
1842                    switch (vbiDrawThis) {
1843                        case TacticalLines.TRIPLE2:
1844                        case TacticalLines.TRIPLE:
1845                        case TacticalLines.HWFENCE:
1846                        case TacticalLines.CHANNEL:
1847                        case TacticalLines.CHANNEL_FLARED:
1848                        case TacticalLines.CHANNEL_DASHED:
1849                        case TacticalLines.SINGLEC2:  //added 7-10-07
1850                        case TacticalLines.SINGLEC:   //added 7-10-07
1851                            for (k = 0; k < vblLowerCounter; k++) 
1852                            {
1853                                pLinePoints[k] = new POINT2(pLowerLinePoints[k]);   //don't shift here
1854                            }
1855                            break;
1856                        case TacticalLines.DOUBLEC2:
1857                        case TacticalLines.DOUBLEC:
1858                            if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) 
1859                            {
1860                                for (k = 0; k < vblLowerCounter; k++) 
1861                                {
1862                                    pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1863                                }
1864                            } 
1865                            else 
1866                            {
1867                                for (k = 0; k < vblLowerCounter; k++) 
1868                                {
1869                                    pLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1870                                }
1871                            }
1872                            break;
1873
1874                        case TacticalLines.LWFENCE:
1875                            for (k = 0; k < vblLowerCounter; k++) {
1876                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1877                                pLinePoints[k].style = 5;
1878                                }
1879                            break;
1880                        case TacticalLines.UNSP:
1881                            for (k = 0; k < vblLowerCounter; k++) {
1882                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1883                                pLinePoints[k].style = 5;
1884                            }
1885                            break;
1886                        case TacticalLines.DOUBLEA:
1887                            for (k = 0; k < vblLowerCounter; k++) {
1888                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1889                            }
1890                            break;
1891                        default:
1892                            for (k = 0; k < vblLowerCounter; k++) {
1893                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1894                            }
1895                            break;
1896                    }
1897                    pLinePoints[vblLowerCounter - 1].style = 5;
1898
1899                    switch (vbiDrawThis) {
1900                        case TacticalLines.TRIPLE2:
1901                        case TacticalLines.TRIPLE:
1902                        case TacticalLines.HWFENCE:
1903                        case TacticalLines.CHANNEL:
1904                        case TacticalLines.CHANNEL_FLARED:
1905                        case TacticalLines.CHANNEL_DASHED:
1906                            for (k = 0; k < vblUpperCounter; k++) {
1907                                pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1908                            }
1909                            break;
1910                        case TacticalLines.DOUBLEC2:
1911                        case TacticalLines.DOUBLEC:
1912                            if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) 
1913                            {
1914                                for (k = 0; k < vblUpperCounter; k++) 
1915                                {
1916                                    pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1917                                }
1918                            } 
1919                            else 
1920                            {
1921                                for (k = 0; k < vblUpperCounter; k++) 
1922                                {
1923                                    pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1924                                }
1925                            }
1926                            break;
1927                        case TacticalLines.SINGLEC2:
1928                        case TacticalLines.SINGLEC:
1929                            for (k = 0; k < vblUpperCounter; k++) {
1930                                //pLinePoints[vblLowerCounter + k] = pOriginalLinePoints[k];    //revised 7-10-07
1931                                pLinePoints[vblLowerCounter + k] = new POINT2(pLowerLinePoints[k]);
1932                            }
1933                            break;
1934                        case TacticalLines.LWFENCE:
1935                            //remove block to make channel line aoways below the X
1936                                for (k = 0; k < vblUpperCounter; k++) 
1937                                {
1938                                    pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1939                                }
1940                            break;
1941                        case TacticalLines.UNSP:
1942                            for (k = 0; k < vblUpperCounter; k++) 
1943                            {
1944                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1945                                pLinePoints[vblLowerCounter + k].style = 5;
1946                            }
1947                            break;
1948                        case TacticalLines.DOUBLEA:
1949                            for (k = 0; k < vblUpperCounter; k++) {
1950                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1951                            }
1952                            break;
1953                        default:
1954                            for (k = 0; k < vblUpperCounter; k++) {
1955                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1956                            }
1957                            break;
1958                    }
1959
1960                    pLinePoints[vblLowerCounter + vblUpperCounter - 1].style = 5;
1961
1962                    lEllipseCounter = vblLowerCounter + vblUpperCounter;
1963                    //following section only for lines with repeating features, e.g. DOUBLEA
1964                    //if(segments!=null &&
1965                    if (vbiDrawThis != TacticalLines.SINGLEC2 &&
1966                            vbiDrawThis != TacticalLines.DOUBLEC2 &&
1967                            vbiDrawThis != TacticalLines.TRIPLE2 &&
1968                            vbiDrawThis != TacticalLines.BBS_LINE &&
1969                            vbiDrawThis != TacticalLines.CHANNEL &&
1970                            vbiDrawThis != TacticalLines.CHANNEL_DASHED &&
1971                            vbiDrawThis != TacticalLines.CHANNEL_FLARED &&
1972                            vbiDrawThis != TacticalLines.SPT_STRAIGHT &&
1973                            vbiDrawThis != TacticalLines.MAIN_STRAIGHT &&
1974                            vbiDrawThis != TacticalLines.AAFNT_STRAIGHT)
1975                    {
1976                        for (j = 0; j < vblUpperCounter - 1; j++) {
1977                            d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1978                            lHowManyThisSegment = (int)d/10;
1979                            remainder=d-10*lHowManyThisSegment;
1980                            dAngle = lineutility.CalcSegmentAngleDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1981                            dAngle = dAngle + pi / 2;
1982                            for (k = 0; k < lHowManyThisSegment; k++) {
1983                                
1984                                if(vbiDrawThis==TacticalLines.SFENCE)
1985                                {
1986                                    if(k%4==0)
1987                                        continue;
1988                                }
1989                                else
1990                                {
1991                                    if(k%2==0)
1992                                        continue;
1993                                }
1994
1995                                double f=k;
1996                                f*=(1d+remainder/d);
1997                                                                
1998                                //diagnostic 1-7-13                                
1999                                //note: for shiftLines upper line points were set to original line points ealier
2000                                //ptCenter.x = pOriginalLinePoints[j].x + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].x - (double) pOriginalLinePoints[j].x) / (double) lHowManyThisSegment);
2001                                //ptCenter.y = pOriginalLinePoints[j].y + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].y - (double) pOriginalLinePoints[j].y) / (double) lHowManyThisSegment);                                
2002                                if(shiftLines==true && vbiDrawThis==TacticalLines.DOUBLEC)
2003                                {
2004                                    ptCenter.x = pUpperLinePoints[j].x + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].x - (double) pUpperLinePoints[j].x) / (double) lHowManyThisSegment);
2005                                    ptCenter.y = pUpperLinePoints[j].y + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].y - (double) pUpperLinePoints[j].y) / (double) lHowManyThisSegment);
2006                                }
2007                                else if(shiftLines==false)
2008                                {
2009                                    ptCenter.x = pOriginalLinePoints[j].x + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].x - (double) pOriginalLinePoints[j].x) / (double) lHowManyThisSegment);
2010                                    ptCenter.y = pOriginalLinePoints[j].y + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].y - (double) pOriginalLinePoints[j].y) / (double) lHowManyThisSegment);
2011                                }
2012                                else
2013                                {
2014                                    ptCenter.x = pUpperLinePoints[j].x + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].x - (double) pUpperLinePoints[j].x) / (double) lHowManyThisSegment);
2015                                    ptCenter.y = pUpperLinePoints[j].y + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].y - (double) pUpperLinePoints[j].y) / (double) lHowManyThisSegment);
2016                                    POINT2 ptCenter2=new POINT2();
2017                                    ptCenter2.x = pLowerLinePoints[j].x + (int) ((double) (f) * ((double) pLowerLinePoints[j + 1].x - (double) pLowerLinePoints[j].x) / (double) lHowManyThisSegment);
2018                                    ptCenter2.y = pLowerLinePoints[j].y + (int) ((double) (f) * ((double) pLowerLinePoints[j + 1].y - (double) pLowerLinePoints[j].y) / (double) lHowManyThisSegment);
2019                                    ptCenter=lineutility.MidPointDouble(ptCenter, ptCenter2, 0);
2020                                }
2021                                //end section
2022                                
2023                                switch (vbiDrawThis) {
2024                                    case TacticalLines.SINGLEC:
2025                                    case TacticalLines.DOUBLEC:
2026                                    case TacticalLines.TRIPLE:
2027                                        for (l = 1; l < 37; l++) {
2028                                            dFactor = (10d * (double)l) * pi / 180d;
2029                                            pEllipsePoints2[l - 1].x = ptCenter.x + a * Math.cos(dFactor);
2030                                            pEllipsePoints2[l - 1].y = ptCenter.y + b * Math.sin(dFactor);
2031                                            pEllipsePoints2[l - 1].style = 0;
2032                                        }
2033                                        lineutility.RotateGeometryDouble(pEllipsePoints2, 36, dAngle * 180d / pi);
2034                                        pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
2035                                        pEllipsePoints2[36].style = 5;
2036                                        for (l = 0; l < 37; l++) {
2037                                            pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
2038                                            lEllipseCounter++;
2039                                        }
2040                                        break;
2041                                    case TacticalLines.HWFENCE:
2042                                    case TacticalLines.LWFENCE:
2043                                    case TacticalLines.DOUBLEA:
2044                                    case TacticalLines.UNSP:
2045                                    case TacticalLines.SFENCE:
2046                                    case TacticalLines.DFENCE:
2047                                        XPoints[0].x = ptCenter.x - 8;//was 4
2048                                        XPoints[0].y = ptCenter.y - 8;
2049                                        XPoints[0].style = 0;
2050                                        XPoints[1].x = ptCenter.x + 8;
2051                                        XPoints[1].y = ptCenter.y + 8;
2052                                        XPoints[1].style = 5;
2053                                        XPoints[2].x = ptCenter.x - 8;
2054                                        XPoints[2].y = ptCenter.y + 8;
2055                                        XPoints[2].style = 0;
2056                                        XPoints[3].x = ptCenter.x + 8;
2057                                        XPoints[3].y = ptCenter.y - 8;
2058                                        XPoints[3].style = 5;
2059                                        XCounter++;
2060                                        lineutility.RotateGeometryDouble(XPoints, 4, (int) (dAngle * 180 / pi));
2061                                        for (l = 0; l < 4; l++) {
2062                                            pLinePoints[lEllipseCounter] = new POINT2(XPoints[l]);
2063                                            switch (vbiDrawThis) {
2064                                                case TacticalLines.SFENCE:
2065                                                    if (XCounter == 2 || XCounter == 3 || XCounter == 4 || XCounter == 5) {
2066                                                        pLinePoints[lEllipseCounter].style = 5;
2067                                                    }
2068                                                    break;
2069                                                case TacticalLines.DFENCE:
2070                                                    if (XCounter == 3 || XCounter == 4 || XCounter == 5) {  //was 2,3 OR 4
2071                                                        pLinePoints[lEllipseCounter].style = 5;
2072                                                    }
2073                                                    break;
2074                                                default:
2075                                                    break;
2076                                            }
2077                                            lEllipseCounter++;
2078                                        }
2079                                        if (XCounter == 5) {
2080                                            XCounter = 0;
2081                                        }
2082                                        break;
2083                                    default:
2084                                        break;
2085                                }
2086                            }//end how many this segment loop
2087                            if (lHowManyThisSegment == 0) {
2088                                if(pLinePoints.length>lEllipseCounter)
2089                                {
2090                                    pLinePoints[lEllipseCounter] = new POINT2(pOriginalLinePoints[j]);
2091                                    lEllipseCounter++;
2092                                    pLinePoints[lEllipseCounter] = new POINT2(pOriginalLinePoints[j + 1]);
2093                                    pLinePoints[lEllipseCounter].style=5;
2094                                    lEllipseCounter++;
2095                                }
2096                            }
2097                        }
2098                        pLinePoints=lineutility.ResizeArray(pLinePoints, lEllipseCounter);
2099                        vblCounter=pLinePoints.length;  //added 11-2-09 M. Deutch
2100                    }
2101
2102                    //if none of the segments were long enough to have features
2103                    //then make the style solid
2104                    if (FenceType(vbiDrawThis) == 1) {
2105                        if (lEllipseCounter <= vblLowerCounter + vblUpperCounter) {
2106                            for (k = 0; k < vblLowerCounter + vblUpperCounter; k++) 
2107                            {
2108                                if(pLinePoints[k].style != 5)   //added 2-8-13
2109                                    pLinePoints[k].style = 0;
2110                            }
2111                        } 
2112                        else 
2113                        {
2114                            for (k = lEllipseCounter - 1; k < pLinePoints.length; k++) {
2115                                pLinePoints[k].style = 5;
2116                            }
2117                        }
2118                    }
2119                    break;
2120                case TacticalLines.BBS_LINE:
2121                    pLinePoints=new POINT2[vblLowerCounter+vblUpperCounter+1];
2122                    for(j=0;j<vblLowerCounter;j++)
2123                        pLinePoints[j]=pLowerLinePoints[j];
2124                    for(j=0;j<vblUpperCounter;j++)
2125                        pLinePoints[j+vblLowerCounter]=pUpperLinePoints[vblUpperCounter-1-j];
2126                    pLinePoints[pLinePoints.length-1]=pLinePoints[0];
2127                    break;
2128                case TacticalLines.SPT:
2129                case TacticalLines.SPT_STRAIGHT:
2130                case TacticalLines.AXAD:
2131                case TacticalLines.CATK:
2132                case TacticalLines.CATKBYFIRE:
2133                case TacticalLines.AIRAOA:
2134                case TacticalLines.AAAAA:
2135                case TacticalLines.MAIN:
2136                case TacticalLines.MAIN_STRAIGHT:
2137                    if (vbiDrawThis != (long) TacticalLines.CATKBYFIRE) {
2138                        vblCounter = vblLowerCounter + vblUpperCounter + 8;
2139                    } else {
2140                        vblCounter = vblLowerCounter + vblUpperCounter + 17;
2141                    }
2142                    //diagnostic
2143                    if (vbiDrawThis == (long) TacticalLines.AAAAA) {
2144                        vblCounter = vblLowerCounter + vblUpperCounter + 19;
2145                    }
2146
2147                    pLinePoints = new POINT2[vblCounter];
2148                    lineutility.InitializePOINT2Array(pLinePoints);
2149                    //initialize points
2150                    for (j = 0; j < pLinePoints.length; j++) {
2151                        pLinePoints[j].x = lpsaUpperVBPoints[0];
2152                        pLinePoints[j].y = lpsaUpperVBPoints[1];
2153                    }
2154
2155                    if (vbiDrawThis != (long) TacticalLines.CATK &&
2156                            vbiDrawThis != (long) TacticalLines.CATKBYFIRE) 
2157                    {
2158                        for (k = 0; k < vblCounter; k++) 
2159                        {
2160                            pLinePoints[k].style = 0;
2161                        }
2162                    }
2163                    GetAXADDouble(nPrinter, pLowerLinePoints,
2164                            vblLowerCounter, pUpperLinePoints,
2165                            vblUpperCounter, pArrowLinePoints[0],
2166                            pLinePoints, vbiDrawThis, arrowOffsetFactor);
2167
2168                    if (vbiDrawThis == (long) TacticalLines.CATK ||
2169                            vbiDrawThis == (long) TacticalLines.CATKBYFIRE) {
2170                        for (k = 0; k < vblCounter; k++) {
2171                            if (pLinePoints[k].style != 5) {
2172                                pLinePoints[k].style = 1;
2173                            }
2174                        }
2175                    }
2176
2177                    //get the rotary symbol for AAAAA
2178                    if (vbiDrawThis == (long) TacticalLines.AAAAA)
2179                    {
2180                        Boolean rotaryTooShort=false;
2181                        ref<double[]> mUpper = new ref(), mLower = new ref();
2182                        int bolVerticalUpper = 0, bolVerticalLower = 0;
2183                        double bUpper = 0, bLower = 0;
2184
2185                        pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
2186                        pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
2187                        double dist1 = lineutility.CalcDistanceDouble(pt0, pt1);
2188
2189                        bolVerticalLower = lineutility.CalcTrueSlopeDouble(pt0, pt1, mLower);
2190                        bLower = pt0.y - mLower.value[0] * pt0.x;
2191
2192                        pt0 = new POINT2(pUpperLinePoints[vblUpperCounter - 2]);
2193                        pt1 = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
2194                        bolVerticalUpper = lineutility.CalcTrueSlopeDouble(pt0, pt1, mUpper);
2195                        bUpper = pt0.y - mUpper.value[0] * pt0.x;
2196                        double dist2 = lineutility.CalcDistanceDouble(pt0, pt1);
2197
2198                        //if (dist1 > vblChannelWidth && dist2 > vblChannelWidth)
2199                        //{
2200                        midPt1 = lineutility.CalcTrueIntersectDouble2(mLower.value[0], bLower, mUpper.value[0], bUpper, bolVerticalLower, bolVerticalUpper, pt0.x, pt0.y);
2201
2202                        //both sides of the channel need to be long enough
2203                        //or the rotary sides will not work, but we still
2204                        //include the arrow by using a simpler midpoint
2205                        if (dist1 <= vblChannelWidth || dist2 <= vblChannelWidth)
2206                        {
2207                            rotaryTooShort=true;
2208                            midPt1=lineutility.MidPointDouble(pt0, pt1, 0);
2209                        }
2210
2211                            a = lineutility.CalcDistanceDouble(pt0, pt1);
2212                            b = 30;
2213                            if (a < 90) {
2214                                b = a / 3;
2215                            }
2216
2217                            pt3 = new POINT2(pOriginalLinePoints[vblUpperCounter - 2]);
2218                            pt4 = new POINT2(pOriginalLinePoints[vblUpperCounter - 1]);
2219                            d = vblChannelWidth / 4;
2220                            if (d > maxLength) {
2221                                d = maxLength;
2222                            }
2223                            if (d < minLength) {
2224                                d = minLength;
2225                            }
2226
2227                            //for non-vertical lines extend above or below the line
2228                            if (pt3.x != pt4.x) {
2229                                //extend below the line
2230                                pt0 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 3, 2 * d);
2231                                pLinePoints[vblLowerCounter + vblUpperCounter + 8] = pt0;
2232                                pLinePoints[vblLowerCounter + vblUpperCounter + 8].style = 0;
2233                                //extend above the line
2234                                pt1 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 2, 2 * d);
2235                                pLinePoints[vblLowerCounter + vblUpperCounter + 9] = pt1;
2236                                pLinePoints[vblLowerCounter + vblUpperCounter + 9].style = 5;
2237                            }
2238                            else //for vertical lines arrow points to the left
2239                            {
2240                                //extend right of the line
2241                                pt0 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 1, 2 * d);
2242                                pLinePoints[vblLowerCounter + vblUpperCounter + 8] = pt0;
2243                                pLinePoints[vblLowerCounter + vblUpperCounter + 8].style = 0;
2244                                //extend left of the line
2245                                pt1 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 0, 2 * d);
2246                                pLinePoints[vblLowerCounter + vblUpperCounter + 9] = pt1;
2247                                pLinePoints[vblLowerCounter + vblUpperCounter + 9].style = 5;
2248                                midPt1 = lineutility.MidPointDouble(pt0, pt1, 0);
2249                            }
2250                            //get the rotary symbol arrow
2251                            lineutility.GetArrowHead4Double(pt0, pt1, (int) d, (int) d, arrowPts, 0);
2252
2253                            for (k = 0; k < 3; k++) {
2254                                pLinePoints[vblLowerCounter + vblUpperCounter + 10 + k] = arrowPts[k];
2255                            }
2256
2257                            pLinePoints[vblLowerCounter + vblUpperCounter + 12].style = 5;
2258
2259                            //get the base points
2260                            pt3 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt0, d / 2, 0);
2261                            pt4 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt0, -d / 2, 0);
2262
2263                            pLinePoints[vblLowerCounter + vblUpperCounter + 13] = pt3;
2264                            pLinePoints[vblLowerCounter + vblUpperCounter + 14] = pt4;
2265
2266                            //the side lines
2267                            //first point
2268                            pLinePoints[vblLowerCounter + vblUpperCounter + 14].style = 5;
2269                            pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
2270                            pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
2271                            pt3 = lineutility.ExtendLine2Double(pt0, midPt1, b, 0);     //line distance from midpt, a was 30
2272                            pLinePoints[vblLowerCounter + vblUpperCounter + 15] = new POINT2(pt3);
2273
2274                            //second point
2275                            pt0 = new POINT2(pUpperLinePoints[vblLowerCounter - 2]);
2276                            pt1 = new POINT2(pUpperLinePoints[vblLowerCounter - 1]);
2277                            pt3 = lineutility.ExtendLine2Double(pt0, midPt1, b, 5);     //line distance from midpt, a was 30
2278                            pLinePoints[vblLowerCounter + vblUpperCounter + 16] = new POINT2(pt3);
2279
2280                            //third point
2281                            pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
2282                            pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
2283                            pt3 = lineutility.ExtendLine2Double(pt1, midPt1, b, 0);     //line distance from midpt, a was 30
2284                            pLinePoints[vblLowerCounter + vblUpperCounter + 17] = new POINT2(pt3);
2285
2286                            //fourth point
2287                            pt0 = new POINT2(pUpperLinePoints[vblLowerCounter - 2]);
2288                            pt1 = new POINT2(pUpperLinePoints[vblLowerCounter - 1]);
2289                            pt3 = lineutility.ExtendLine2Double(pt1, midPt1, b, 5);     //line distance from midpt, a was 30
2290                            pLinePoints[vblLowerCounter + vblUpperCounter + 18] = new POINT2(pt3);
2291                        //}
2292                        //else
2293                        //{   //if last segment too short then don't draw the rotary features
2294                            //if last segment too short then no side points
2295                            if(rotaryTooShort)
2296                            {
2297                                for (l = vblLowerCounter + vblUpperCounter + 14; l < vblLowerCounter + vblLowerCounter + 19; l++)
2298                                {
2299                                    pLinePoints[l].style = 5;
2300                                }
2301                            }
2302                        //}
2303                    }//end if (vbiDrawThis == (long) TacticalLines.AAAAA)
2304                    
2305                    double dFeature=0;
2306                    double dist2=0;
2307                    if (vbiDrawThis == TacticalLines.CATKBYFIRE) 
2308                    {       //dist is the distance to the back of the arrowhead                        
2309                        //10-19-12
2310                        //this line is part of the new requirement that the rotary feature must align 
2311                        //with the anchor point, it can  no longer stick out beond the anchor point
2312                        //so the points have to be shifted by 45 pixels.
2313                        
2314                        //dist-=45;
2315                        //end section
2316                        dist2 = lineutility.CalcDistanceDouble(nextToLastPoint, lastPoint);
2317                        if(dist2>45)
2318                            dist-=45;
2319                        if (dist2 > 20) 
2320                        {                                                                                       //was 20+dist
2321                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], 5+dist);//distance from tip to back of rotary
2322                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], 5+dist);//distance from tip to back of rotary
2323                        } 
2324                        else 
2325                        {
2326                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], -50);//was -40
2327                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], -50);//was -40
2328                        }
2329                        //was dist
2330                        pt3 = lineutility.ExtendLine2Double(pt2, pt1, 10 + Math.abs(dist/2), 18); //vert height of rotary from horiz segment was dist/2.5
2331                        pt4 = lineutility.ExtendLine2Double(pt1, pt2, 10 + Math.abs(dist/2), 5); //vert height of rotary from horiz segment was dist/2.5
2332                        midPt1 = lineutility.MidPointDouble(pt1, pt2, 17);
2333                        pLinePoints[vblCounter - 9] = new POINT2(pt3);
2334                        pLinePoints[vblCounter - 6] = new POINT2(pt4);
2335
2336                        if (dist2 > 20) {                                                                                               //was 30+dist
2337                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], 15 + dist);//distance from tip to back of rotary
2338                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], 15 + dist);//distance from tip to back of rotary
2339                        } else {
2340                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], -50);//was -50
2341                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], -50);//was -50
2342                        }
2343
2344                        pt3 = lineutility.ExtendLine2Double(pt2, pt1, Math.abs(dist/2), 18);//vert height of rotary from horiz segment was dist/2.5
2345                        pt4 = lineutility.ExtendLine2Double(pt1, pt2, Math.abs(dist/2), 18);//vert height of rotary from horiz segment was dist/2.5
2346                                                
2347                        midPt2 = lineutility.MidPointDouble(pt1, pt2, 18);
2348                        pLinePoints[vblCounter - 8] = new POINT2(pt3);
2349                        pLinePoints[vblCounter - 7] = new POINT2(pt4);
2350                        pLinePoints[vblCounter - 5] = new POINT2(midPt2);
2351                        if (midPt1.x == midPt2.x && midPt1.y == midPt2.y) //last segment too short
2352                        {
2353                            //diagnostic 2-27-13
2354                            if(_client.startsWith("cpof"))
2355                                dFeature=30;
2356                            else                            
2357                                dFeature=15;
2358                            
2359                            
2360                            midPt1 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 10, 17);
2361                            //pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, 30, 18);
2362                            //pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, -30, 5);                            
2363                            pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, dFeature, 18);
2364                            pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, -dFeature, 5);
2365                            //end section
2366                            pLinePoints[vblCounter - 9] = new POINT2(pt1);
2367                            pLinePoints[vblCounter - 6] = new POINT2(pt2);
2368                            
2369                            if(_client.startsWith("cpof"))
2370                                midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 20, 17);
2371                            else
2372                            {
2373                                if(dist2>30)
2374                                    midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 20, 17);
2375                                else
2376                                    midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], dFeature, 17);
2377                            }
2378                            //end section
2379                            
2380                            //diagnostic 2-27-13                            
2381                            //pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, 20, 18);
2382                            //pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, -20, 18);
2383                            dFeature -=10;
2384                            pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, dFeature, 18);
2385                            pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, -dFeature, 18);
2386                            pLinePoints[vblCounter - 8] = new POINT2(pt1);
2387                            pLinePoints[vblCounter - 7] = new POINT2(pt2);
2388                            pLinePoints[vblCounter - 5] = new POINT2(midPt2);
2389                        }
2390                        if(_client.startsWith("cpof"))
2391                            dFeature=30;
2392                        else
2393                        {
2394                            if(dist2>30)
2395                                dFeature=30;
2396                            else if(dist2>20)
2397                                dFeature=10;
2398                            else
2399                                dFeature=10;
2400                        }
2401
2402                        pt1 = lineutility.ExtendLine2Double(midPt1, midPt2, dFeature, (int)dFeature); //30, then 5
2403                        pLinePoints[vblCounter - 4] = new POINT2(pt1);
2404                        lineutility.GetArrowHead4Double(midPt2, pt1, (int)dFeature/2, (int)dFeature/2, arrowPts, 18);//15,15
2405                        //end section
2406                        for (k = 0; k < 3; k++) {
2407                            pLinePoints[vblCounter - k - 1] = new POINT2(arrowPts[k]);
2408                            pLinePoints[vblCounter - k - 1].style = 18;
2409                        }
2410                    }
2411                    break;
2412                case TacticalLines.AAFNT:
2413                case TacticalLines.AAFNT_STRAIGHT:
2414                    vblCounter = vblLowerCounter + vblUpperCounter + 8;
2415                    pLinePoints = new POINT2[vblCounter];
2416                    lineutility.InitializePOINT2Array(pLinePoints);
2417                    //initialize points
2418                    for (j = 0; j < pLinePoints.length; j++) {
2419                        pLinePoints[j].x = lpsaUpperVBPoints[0];
2420                        pLinePoints[j].y = lpsaUpperVBPoints[1];
2421                    }
2422                    for (k = 0; k < vblCounter; k++) {
2423                        pLinePoints[k].style = 0;
2424                    }
2425                    GetAAFNTDouble(nPrinter, pLowerLinePoints,
2426                            vblLowerCounter, pUpperLinePoints,
2427                            vblUpperCounter, pArrowLinePoints[0],
2428                            pLinePoints, arrowOffsetFactor);
2429                    break;
2430                default:
2431                    break;
2432            }   //end load channel array ino pLinePoints
2433
2434            //these three need the original bounded points
2435            //because the linestyle assigned will cause the
2436            //client (tactical renderer) to draw ellipses
2437            if (vbiDrawThis == (long) TacticalLines.SINGLEC2 ||
2438                    vbiDrawThis == (long) TacticalLines.DOUBLEC2 ||
2439                    vbiDrawThis == (long) TacticalLines.TRIPLE2) {
2440                vblCounter = 3 * vblUpperCounter;
2441                for (k = vblLowerCounter + vblUpperCounter; k < vblCounter; k++) {
2442                    pLinePoints[k] = new POINT2(pOriginalLinePoints[k - vblLowerCounter - vblUpperCounter]);
2443                    //if(segments[k-vblLowerCounter-vblUpperCounter]!=0)
2444                    pLinePoints[k].style = 25;  //client to draw ellipses along segment
2445                    //else
2446                    //  pLinePoints[k].style=5;
2447                }
2448                pLinePoints[vblLowerCounter - 1].style = 5;
2449                pLinePoints[vblLowerCounter + vblUpperCounter - 1].style = 5;
2450            }
2451
2452            if (vbiDrawThis == (long) TacticalLines.CHANNEL_DASHED) {
2453                for (k = 0; k < vblCounter; k++) {
2454                    if (pLinePoints[k].style != 5) {
2455                        pLinePoints[k].style = 18;
2456                    }
2457                }
2458            }
2459
2460            //if shapes is null it is not a CPOF client
2461            if(shapes==null)
2462            {
2463                //load result points because client is using points, not shapes
2464                for(j=0;j<pLinePoints.length;j++)
2465                {
2466                    resultVBPoints[3*j]=pLinePoints[j].x;
2467                    resultVBPoints[3*j+1]=pLinePoints[j].y;
2468                    resultVBPoints[3*j+2]=(double)pLinePoints[j].style;
2469                }
2470                return pLinePoints.length;
2471            }
2472
2473            //the shapes
2474            Shape2 shape=null;
2475            //Shape2 outline=null;
2476            boolean beginLine=true;
2477            boolean beginPath=true;
2478            if(vbiDrawThis==TacticalLines.AAFNT || vbiDrawThis==TacticalLines.AAFNT_STRAIGHT)
2479            {
2480                //the solid lines
2481                for (k = 0; k < vblCounter; k++)
2482                {
2483                    if(pLinePoints[k].style==2)
2484                        continue;
2485
2486                    if(shape==null)
2487                        shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2488
2489                    if(beginLine)
2490                    {
2491                        if(k>0) //doubled points with linestyle=5
2492                            if(pLinePoints[k].style==5 && pLinePoints[k-1].style==5)
2493                                shape.lineTo(pLinePoints[k]);
2494
2495                        if(k==0)
2496                            shape.set_Style(pLinePoints[k].style);
2497
2498                        shape.moveTo(pLinePoints[k]);
2499                        beginLine=false;
2500                    }
2501                    else
2502                    {
2503                        shape.lineTo(pLinePoints[k]);
2504                        if(pLinePoints[k].style==5)
2505                        {
2506                            beginLine=true;
2507                            //unless there are doubled points with style=5
2508                        }
2509                    }
2510                    if(k==vblCounter-1) //non-LC should only have one shape
2511                    {
2512                        shapes.add(shape);
2513                    }
2514                }
2515                //the dotted lines
2516                for (k = 0; k < vblCounter; k++)
2517                {
2518                    if(pLinePoints[k].style==2 && pLinePoints[k-1].style==5)
2519                    {
2520                        shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2521                        //shape.set_Style(pLinePoints[k].style);
2522                        shape.set_Style(2); //GraphicProperties uses 2 for dotted
2523                        shape.moveTo(pLinePoints[k]);
2524                    }
2525                    else if(pLinePoints[k].style==2 && pLinePoints[k-1].style==2)
2526                    {
2527                        shape.lineTo(pLinePoints[k]);
2528                    }
2529                    else if(pLinePoints[k].style==5 && pLinePoints[k-1].style==2)
2530                    {
2531                        shape.lineTo(pLinePoints[k]);
2532                        shapes.add(shape);
2533                        break;
2534                    }
2535                    else
2536                        continue;
2537                }
2538            }
2539
2540
2541            for (k = 0; k < vblCounter; k++)
2542            {
2543                //use shapes instead of pixels
2544
2545                if(shape==null)
2546                {
2547                    shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2548                }
2549
2550                switch(vbiDrawThis)
2551                {
2552                    case TacticalLines.CATK:
2553                    case TacticalLines.CATKBYFIRE:
2554                        shape.set_Style(1);
2555                        break;
2556                }
2557
2558                switch(vbiDrawThis)
2559                {
2560                    case TacticalLines.AAFNT:
2561                    case TacticalLines.AAFNT_STRAIGHT:
2562                        break;
2563                    case TacticalLines.LC:
2564                    case TacticalLines.LC_HOSTILE:
2565                        if(beginPath==false)
2566                        {
2567                            if(k>0)
2568                            {   //if the linestyle is changes on the next point then this point is end of the current path
2569                                //because it's changing between friendly and enemy ellipses
2570                                if(  pLinePoints[k].style == 5)
2571                                {
2572                                    //add the last point to the current path
2573                                    shape.lineTo(pLinePoints[k]);
2574                                    //add the shape
2575                                    if(shape !=null && shape.getShape() != null)
2576                                    {
2577                                        shapes.add(shape);
2578                                    }
2579
2580                                    beginPath=true;
2581                                }
2582                                else    //continue the current path
2583                                {
2584                                    shape.lineTo(pLinePoints[k]);
2585                                }
2586                            }
2587                            else    //k=0
2588                            {
2589                                shape.moveTo(pLinePoints[k]);
2590                            }
2591                        }
2592                        else    //start a new path
2593                        {
2594                            shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2595                            shape.moveTo(pLinePoints[k]);
2596                            shape.set_Style(pLinePoints[k].style);
2597                            //assume friendly
2598                            if(pLinePoints[k].style==25)
2599                               shape.setLineColor(Color.RED);
2600                            
2601                            beginPath=false;
2602                        }
2603                        //if(k==vblCounter-1) //LC should have 2 shapes
2604                          //  if(shape !=null && shape.get_Shape() != null)
2605                            //    shapes.add(shape);
2606                        break;
2607                    case TacticalLines.CATK:    //same as default except these have doubled 5's
2608                    case TacticalLines.CATKBYFIRE:
2609                    case TacticalLines.AAAAA:
2610                    case TacticalLines.SPT:
2611                    case TacticalLines.SPT_STRAIGHT:
2612                    case TacticalLines.AIRAOA:
2613                    case TacticalLines.AXAD:
2614                        if(beginLine)
2615                        {
2616                            if(k>0) //doubled points with linestyle=5
2617                            {
2618                                if(pLinePoints[k].style==5 && pLinePoints[k-1].style==5 && k != vblCounter-1)
2619                                    continue;
2620                            }
2621
2622                            shape.moveTo(pLinePoints[k]);
2623                            beginLine=false;
2624                        }
2625                        else
2626                        {
2627                            shape.lineTo(pLinePoints[k]);
2628                            if(pLinePoints[k].style==5)
2629                            {
2630                                beginLine=true;
2631                                //unless there are doubled points with style=5
2632                            }
2633                        }
2634                        if(k==vblCounter-1) //non-LC should only have one shape
2635                        {
2636                            if(shape !=null && shape.getShape() != null)
2637                            {
2638                                shapes.add(shape);
2639                            }
2640                        }
2641                        break;
2642                    case TacticalLines.UNSP:
2643                    case TacticalLines.SFENCE:
2644                    case TacticalLines.DFENCE:
2645                    case TacticalLines.LWFENCE:
2646                    case TacticalLines.HWFENCE:
2647                        if(k==0)
2648                        {
2649                            shape.moveTo(pLinePoints[k]);
2650                            if(pLinePoints[k].style==5)
2651                            {
2652                                continue;
2653                            }
2654                        }
2655                        if(k>0 && k < vblCounter-1)
2656                        {
2657                            if(pLinePoints[k-1].style==5)
2658                                shape.moveTo(pLinePoints[k]);
2659                            else if(pLinePoints[k-1].style==0)
2660                                shape.lineTo(pLinePoints[k]);
2661
2662                            if(pLinePoints[k].style==5)
2663                              shape.moveTo(pLinePoints[k]);
2664
2665                            if(k==vblCounter-2 && pLinePoints[k].style==0)
2666                            {
2667                                shape.moveTo(pLinePoints[k]);
2668                                shape.lineTo(pLinePoints[k+1]);
2669                            }
2670                        }
2671
2672                        if(k==vblCounter-1) //non-LC should only have one shape
2673                        {
2674                            if(shape !=null && shape.getShape() != null)
2675                                shapes.add(shape);
2676                        }
2677                        break;
2678                    default:                        
2679                        if(beginLine)
2680                        {
2681                            if(k==0)
2682                                shape.set_Style(pLinePoints[k].style);
2683
2684                            shape.moveTo(pLinePoints[k]);
2685                            beginLine=false;
2686                        }
2687                        else
2688                        {
2689                            shape.lineTo(pLinePoints[k]);
2690                            if(pLinePoints[k].style==5)
2691                            {
2692                                beginLine=true;
2693                                //unless there are doubled points with style=5
2694                            }
2695                        }
2696                        if(k==vblCounter-1) //non-LC should only have one shape
2697                        {
2698                            if(shape !=null && shape.getShape() != null)
2699                                shapes.add(shape);
2700                        }
2701                        break;
2702                }//end switch
2703            }   //end for
2704            //a requirement was added to enable fill for the axis of advance line types
2705            ArrayList<Shape2>fillShapes=getAXADFillShapes(vbiDrawThis, pLinePoints);
2706            if(fillShapes != null && fillShapes.size()>0)
2707                shapes.addAll(0,fillShapes);
2708            
2709            //diagnostic
2710            if(vbiDrawThis==TacticalLines.BBS_LINE)
2711            {
2712                //shapes.remove(1);
2713                shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2714                shape.moveTo(pOriginalLinePoints[0]);
2715                for(j=1;j<pOriginalLinePoints.length;j++)
2716                    shape.lineTo(pOriginalLinePoints[j]);
2717                shapes.add(shape);
2718            }
2719            //end section
2720            
2721            lResult=lResultCounter;
2722            //FillPoints(pLinePoints,pLinePoints.length);
2723            //clean up
2724            pLinePoints = null;
2725            pLowerLinePoints = null;
2726            pUpperLinePoints = null;
2727            pArrowLinePoints = null;
2728            pUpperFlotPoints = null;
2729            arrowPts = null;
2730            XPoints = null;
2731            pEllipsePoints2 = null;
2732            pOriginalLinePoints = null;
2733            pOriginalLinePoints2 = null;
2734        }
2735        catch (Exception exc) {
2736            ErrorLogger.LogException(_className ,"GetChannel1Double",
2737                    new RendererException("Failed inside GetChannel1Double " + Integer.toString(vbiDrawThis), exc));
2738        }
2739        return lResult;
2740    }
2741    /**
2742     * They decided that axis of advance must enable fill
2743     * @param lineType
2744     * @param pLinePoints
2745     * @return
2746     */
2747    private static ArrayList<Shape2> getAXADFillShapes(int lineType, POINT2[]pLinePoints)
2748    {
2749        ArrayList<Shape2>shapes=null;
2750        try
2751        {
2752            ArrayList<POINT2>newPts=new ArrayList();
2753            int j=0;
2754            Shape2 shape=null;
2755            int n=pLinePoints.length;
2756            switch(lineType)
2757            {
2758                case TacticalLines.BBS_LINE:
2759                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2760                    shape.moveTo(pLinePoints[0]);
2761                    //for(j=1;j<pLinePoints.length;j++)
2762                    for(j=1;j<n;j++)
2763                    {
2764                        shape.lineTo(pLinePoints[j]);
2765                    }
2766                    break;
2767                case TacticalLines.CHANNEL:
2768                case TacticalLines.CHANNEL_FLARED:
2769                case TacticalLines.CHANNEL_DASHED:
2770                    for(j=0;j<n/2;j++)
2771                    {
2772                        newPts.add(pLinePoints[j]);
2773                    }
2774                    for(j=n-1;j>=n/2;j--)
2775                    {
2776                        newPts.add(pLinePoints[j]);
2777                    }
2778                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2779                    shape.moveTo(newPts.get(0));
2780                    int t=newPts.size();
2781                    //for(j=1;j<newPts.size();j++)
2782                    for(j=1;j<t;j++)
2783                    {
2784                        shape.lineTo(newPts.get(j));
2785                    }
2786                    break;
2787                case TacticalLines.AXAD:
2788                case TacticalLines.AIRAOA:
2789                case TacticalLines.SPT:
2790                case TacticalLines.CATK:
2791                case TacticalLines.SPT_STRAIGHT:
2792                    //add the upper (lower) channel points
2793                    //for(j=0;j<(pLinePoints.length-8)/2;j++)
2794                    for(j=0;j<(n-8)/2;j++)
2795                    {
2796                        newPts.add(pLinePoints[j]);
2797                    }
2798                    //add the arrow outline
2799                    newPts.add(pLinePoints[n-6]);
2800                    newPts.add(pLinePoints[n-7]);
2801                    newPts.add(pLinePoints[n-8]);
2802                    newPts.add(pLinePoints[n-3]);
2803                    newPts.add(pLinePoints[n-4]);
2804                    //add the upper (lower) channel points
2805                    for(j=n-9;j>=(n-8)/2;j--)
2806                    {
2807                        newPts.add(pLinePoints[j]);
2808                    }
2809                    //newPts.add(pLinePoints[0]);
2810                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2811                    //shape.moveTo(newPts.get(0).x,newPts.get(0).y);
2812                    shape.moveTo(newPts.get(0));
2813                    t=newPts.size();
2814                    //for(j=1;j<newPts.size();j++)
2815                    for(j=1;j<t;j++)
2816                    {
2817                        shape.lineTo(newPts.get(j));
2818                    }
2819                    break;
2820                case TacticalLines.AAFNT:
2821                case TacticalLines.AAFNT_STRAIGHT:
2822                    //for(j=0;j<(pLinePoints.length-8)/2;j++)
2823                    for(j=0;j<(n-8)/2;j++)
2824                    {
2825                        newPts.add(pLinePoints[j]);
2826                    }
2827                    //add the arrow outline
2828                    newPts.add(pLinePoints[n-8]);
2829                    newPts.add(pLinePoints[n-7]);
2830                    newPts.add(pLinePoints[n-6]);
2831                    newPts.add(pLinePoints[n-5]);
2832                    newPts.add(pLinePoints[n-4]);
2833                    for(j=n-9;j>=(n-8)/2;j--)
2834                    {
2835                        newPts.add(pLinePoints[j]);
2836                    }
2837                    //newPts.add(pLinePoints[0]);
2838                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2839                    //shape.moveTo(newPts.get(0).x,newPts.get(0).y);
2840                    shape.moveTo(newPts.get(0));
2841                    t=newPts.size();
2842                    //for(j=1;j<newPts.size();j++)
2843                    for(j=1;j<t;j++)
2844                    {
2845                        shape.lineTo(newPts.get(j));
2846                    }
2847                    break;
2848                case TacticalLines.MAIN_STRAIGHT:
2849                case TacticalLines.MAIN:
2850                    //for(j=0;j<(pLinePoints.length-8)/2;j++)
2851                    for(j=0;j<(n-8)/2;j++)
2852                    {
2853                        newPts.add(pLinePoints[j]);
2854                    }
2855                    //add the arrow outline
2856                    newPts.add(pLinePoints[n-6]);
2857                    newPts.add(pLinePoints[n-5]);
2858                    for(j=n-9;j>=(n-8)/2;j--)
2859                    {
2860                        newPts.add(pLinePoints[j]);
2861                    }
2862                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2863                    shape.moveTo(newPts.get(0));
2864                    t=newPts.size();
2865                    //for(j=1;j<newPts.size();j++)
2866                    for(j=1;j<t;j++)
2867                    {
2868                        shape.lineTo(newPts.get(j));
2869                    }
2870                    break;
2871                case TacticalLines.AAAAA:
2872                    //for(j=0;j<(pLinePoints.length-19)/2;j++)
2873                    for(j=0;j<(n-19)/2;j++)
2874                    {
2875                        newPts.add(pLinePoints[j]);
2876                    }
2877                    //add the arrow outline
2878                    newPts.add(pLinePoints[n-17]);
2879                    newPts.add(pLinePoints[n-18]);
2880                    newPts.add(pLinePoints[n-19]);
2881                    newPts.add(pLinePoints[n-14]);
2882                    newPts.add(pLinePoints[n-15]);
2883
2884                    for(j=n-20;j>=(n-19)/2;j--)
2885                    {
2886                        newPts.add(pLinePoints[j]);
2887                    }
2888                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2889                    shape.moveTo(newPts.get(0));
2890                    t=newPts.size();
2891                    //for(j=1;j<newPts.size();j++)
2892                    for(j=1;j<t;j++)
2893                    {
2894                        shape.lineTo(newPts.get(j));
2895                    }
2896                    break;
2897                case TacticalLines.CATKBYFIRE:
2898                    //for(j=0;j<(pLinePoints.length-17)/2;j++)
2899                    for(j=0;j<(n-17)/2;j++)
2900                    {
2901                        newPts.add(pLinePoints[j]);
2902                    }
2903                    //add the arrow outline
2904                    newPts.add(pLinePoints[n-15]);
2905                    newPts.add(pLinePoints[n-16]);
2906                    newPts.add(pLinePoints[n-17]);
2907                    newPts.add(pLinePoints[n-12]);
2908                    newPts.add(pLinePoints[n-13]);
2909                    for(j=n-18;j>=(n-17)/2;j--)
2910                    {
2911                        newPts.add(pLinePoints[j]);
2912                    }
2913                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2914                    shape.moveTo(newPts.get(0));
2915                    t=newPts.size();
2916                    //for(j=1;j<newPts.size();j++)
2917                    for(j=1;j<t;j++)
2918                    {
2919                        shape.lineTo(newPts.get(j));
2920                    }
2921                    break;
2922                default:
2923                    break;
2924            }
2925            if(shape!=null)
2926            {
2927                shapes=new ArrayList();
2928                shape.setLineColor(null);
2929                shapes.add(shape);
2930            }
2931        }
2932        catch (Exception exc) {
2933            ErrorLogger.LogException(_className ,"getAXADfillShapes",
2934                    new RendererException("Failed inside getAXADFillShapes", exc));
2935        }
2936        return shapes;
2937    }
2938    /**
2939     * sets shape2 properties to those of shape1
2940     * @param shape1
2941     * @param shape2
2942     */
2943//    private static void SetShapeProperties(Shape2 shape1, Shape2 shape2)
2944//    {
2945//        try
2946//        {
2947//            shape2.setLineColor(shape1.getLineColor());
2948//            shape2.setStroke(shape1.getStroke());
2949//            shape2.setFillColor(shape1.getFillColor());
2950//        }
2951//        catch (Exception exc) {
2952//            ErrorLogger.LogException(_className ,"GetChannel1Double",
2953//                    new RendererException("Failed inside SetShapeProperties", exc));
2954//        }
2955//    }
2956}