001/*
002 * To change this template, choose Tools | Templates
003 * and open the template in the editor.
004 */
005
006package armyc2.c5isr.JavaLineArray;
007//import java.awt.Color;
008import armyc2.c5isr.JavaTacticalRenderer.TGLight;
009import armyc2.c5isr.renderer.utilities.Color;
010import java.util.ArrayList;
011import armyc2.c5isr.renderer.utilities.ErrorLogger;
012import armyc2.c5isr.renderer.utilities.RendererException;
013import armyc2.c5isr.renderer.utilities.RendererSettings;
014
015/**
016 * CELineArray Channels class calculates the channel points
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.TRIPLE:
530                case TacticalLines.DOUBLEC:
531                case TacticalLines.SINGLEC:
532                case TacticalLines.HWFENCE:
533                case TacticalLines.LWFENCE:
534                case TacticalLines.UNSP:
535                case TacticalLines.DOUBLEA:
536                case TacticalLines.SFENCE:
537                case TacticalLines.DFENCE:
538                    bolResult = 1;
539                    break;
540                default:
541                    bolResult = 0;
542                    break;
543            }
544        } catch (Exception exc) {
545            ErrorLogger.LogException(_className ,"FenceType",
546                    new RendererException("Failed inside FenceType " + Integer.toString(linetype), exc));
547        }
548        return bolResult;
549    }
550    /**
551    * Calculates the point count for the concertina wire and fence channels.
552    *
553    * @param pLinePoints client points
554    * @param vblCounter the client point count
555    * @param linetype the line type
556    *
557    * @return the number of points required to render the symbol
558    */
559    protected static int GetTripleCountDouble(POINT2[] pLinePoints,
560            int vblCounter,
561            int linetype) {
562        int lTotal = 0;
563        try {
564            //declarations
565            int j = 0;
566            int lHowManyThisSegment = 0;
567            double d = 0;
568            //end declarations
569
570            for (j = 0; j < vblCounter - 1; j++) {
571                d = lineutility.CalcDistanceDouble(pLinePoints[j], pLinePoints[j + 1]);
572                if (d <= 10) {
573                    lHowManyThisSegment = 0;
574                } else {
575                    lHowManyThisSegment = (int) ((d - 10) / 10);
576                }
577
578                lTotal += lHowManyThisSegment;
579            }
580
581            switch (linetype) {
582                case TacticalLines.SINGLEC:
583                case TacticalLines.DOUBLEC:
584                case TacticalLines.TRIPLE:
585                    lTotal = 6 * vblCounter + 37 * lTotal;  //was 2*vblCounter+37*lTotal
586                    break;
587                case TacticalLines.HWFENCE:
588                case TacticalLines.LWFENCE:
589                case TacticalLines.UNSP:
590                case TacticalLines.DOUBLEA:
591                case TacticalLines.SFENCE:
592                case TacticalLines.DFENCE:
593                    lTotal = 4 * vblCounter + 4 * lTotal;
594                    break;
595                default:
596                    lTotal = 2 * vblCounter;
597                    break;
598            }
599        } catch (Exception exc) {
600            ErrorLogger.LogException(_className ,"GetTripleCountDouble",
601                    new RendererException("Failed inside GetTripleCountDouble " + Integer.toString(linetype), exc));
602        }
603        return lTotal;
604    }
605
606    protected static POINT2[] CoordIL2Double(int nPrinter,
607            POINT2[] pLinePoints,
608            int nUpperLower,
609            int vblCounter,
610            int linetype,
611            int vblChannelWidth) {
612            POINT2[]pLinePoints2=new POINT2[vblCounter];
613        try {
614            //declarations
615            int j, channelWidth = 20;
616            POINT2[] pNewLinePoints = new POINT2[vblCounter];
617            CChannelPoints2[] pChannelPoints = new CChannelPoints2[vblCounter];
618            //end declarations
619
620            lineutility.InitializePOINT2Array(pLinePoints2);
621            for (j = 0; j < vblCounter; j++) {
622                pNewLinePoints[j] = new POINT2(pLinePoints[j]);
623            }
624
625            channelWidth = vblChannelWidth;
626
627            if (linetype != (long) TacticalLines.LC &&
628                    linetype != TacticalLines.LC_HOSTILE) {
629                channelWidth /= 2;
630            }
631
632            pChannelPoints = GetChannel2Double(channelWidth * nPrinter,
633                    vblCounter,
634                    pNewLinePoints,
635                    pChannelPoints);
636
637            if (nUpperLower == 1) {
638                pNewLinePoints = GetUpperChannelLineDouble(pChannelPoints,
639                        vblCounter,
640                        pNewLinePoints);
641
642                for (j = 0; j < vblCounter; j++) {
643                    pLinePoints2[j] = new POINT2(pNewLinePoints[j]);
644                }
645            }
646
647            if (nUpperLower == 0) {
648                pNewLinePoints = GetLowerChannelLineDouble(pChannelPoints,
649                        vblCounter,
650                        pNewLinePoints);
651
652                for (j = 0; j < vblCounter; j++) {
653                    pLinePoints2[j] = new POINT2(pNewLinePoints[j]);
654                }
655            }
656
657            //clean up
658            pNewLinePoints = null;
659            pChannelPoints = null;
660        } catch (Exception exc) {
661            ErrorLogger.LogException(_className ,"CoordIL2Double",
662                    new RendererException("Failed inside CoordIL2Double", exc));
663        }
664        return pLinePoints2;
665    }
666
667    /**
668     * gets the axis of advance arrowhead
669     * @param dPrinter
670     * @param pLowerLinePoints
671     * @param lLowerCounter
672     * @param pUpperLinePoints
673     * @param lUpperCounter
674     * @param ArrowLinePoint
675     * @param pLinePoints
676     * @param vbiDrawThis
677     * @param dOffsetFactor
678     */
679    private static void GetAXADDouble(double dPrinter,
680            POINT2[] pLowerLinePoints,
681            int lLowerCounter,
682            POINT2[] pUpperLinePoints,
683            int lUpperCounter,
684            POINT2 ArrowLinePoint,
685            POINT2[] pLinePoints,
686            int vbiDrawThis,
687            double dOffsetFactor) {
688        try {            
689            int j = 0,
690                    lCounter = lLowerCounter + lUpperCounter + 8;
691            double x = 0, y = 0;
692            POINT2 OuterTipLinePoint = new POINT2(pUpperLinePoints[0]),
693                    InnerTipLinePoint = new POINT2(pUpperLinePoints[0]),
694                    EndLinePoint = new POINT2(pUpperLinePoints[0]),
695                    TempLinePoint = new POINT2(pUpperLinePoints[0]);
696            POINT2 pt0 = new POINT2(), pt1 = new POINT2();
697            //double dOffsetFactor = 10;
698            //end declarations
699            
700            //10-19-12
701            //we must do this for catkbyfire because the rotary arrow tip now has to match the
702            //anchor point, i.e. the rotary feature can no longer stick out past the anchor point
703            //45 pixels shift here matches the 45 pixels shift for catkbyfire found in 
704            //lineutility.adjustCATKBYFIREControlPoint as called by clsChannelUtility.DrawChannel
705            POINT2 origArrowPt=new POINT2(ArrowLinePoint);
706            POINT2 ptUpper0=new POINT2(pUpperLinePoints[lUpperCounter-1]);
707            POINT2 ptLower0=new POINT2(pLowerLinePoints[lLowerCounter-1]);
708            double dist=lineutility.CalcDistanceDouble(pLowerLinePoints[lLowerCounter-1], pLowerLinePoints[lLowerCounter-2]);
709            if(vbiDrawThis==TacticalLines.CATKBYFIRE)
710            {
711                if(dist>45)
712                {
713                    POINT2 midPt=lineutility.MidPointDouble(pLowerLinePoints[lLowerCounter-2], pUpperLinePoints[lUpperCounter-2], 0);
714                    ArrowLinePoint=lineutility.ExtendAlongLineDouble(ArrowLinePoint, midPt, 45);
715                    pLowerLinePoints[lLowerCounter-1]=lineutility.ExtendAlongLineDouble(pLowerLinePoints[lLowerCounter-1], pLowerLinePoints[lLowerCounter-2], 45);//will be 45 if Oculus adjusts control point
716                    pUpperLinePoints[lUpperCounter-1]=lineutility.ExtendAlongLineDouble(pUpperLinePoints[lUpperCounter-1], pUpperLinePoints[lUpperCounter-2], 45);//will be 45 if Oculus adjusts control point
717                }
718            }
719            //end section
720
721            for (j = 0; j < lLowerCounter; j++) {
722                pLinePoints[j] = new POINT2(pLowerLinePoints[j]);
723            }
724
725            pLinePoints[lLowerCounter - 1].style = 5;
726
727            for (j = 0; j < lUpperCounter; j++) {
728                pLinePoints[lLowerCounter + j] = new POINT2(pUpperLinePoints[j]);
729            }
730
731            for (j = lCounter - 8; j < lCounter; j++) //initializations
732            {
733                pLinePoints[j] = new POINT2(pUpperLinePoints[0]);
734            }
735
736            EndLinePoint.x = (int) ((double) (pLowerLinePoints[lLowerCounter - 1].x +
737                    pUpperLinePoints[lUpperCounter - 1].x) / 2);
738
739            EndLinePoint.y = (int) ((double) (pLowerLinePoints[lLowerCounter - 1].y +
740                    pUpperLinePoints[lUpperCounter - 1].y) / 2);
741
742
743            x = (double) (pLowerLinePoints[lLowerCounter - 1].x - pUpperLinePoints[lUpperCounter - 1].x);
744            y = (double) (pLowerLinePoints[lLowerCounter - 1].y - pUpperLinePoints[lUpperCounter - 1].y);
745            x = x * x;
746            y = y * y;
747            //nBase = (int) Math.sqrt(x + y);
748
749            //nBase *= (int) dPrinter;
750
751            OuterTipLinePoint = new POINT2(ArrowLinePoint);
752            InnerTipLinePoint = lineutility.GetOffsetPointDouble(EndLinePoint, OuterTipLinePoint, -(int) (dOffsetFactor * dPrinter));
753            pLinePoints[lCounter - 9].style = 5;
754            pLinePoints[lCounter - 8] = new POINT2(OuterTipLinePoint);
755
756            pt0.x = pUpperLinePoints[lUpperCounter - 1].x;
757            pt0.y = pUpperLinePoints[lUpperCounter - 1].y;
758            pt1.x = pLowerLinePoints[lLowerCounter - 1].x;
759            pt1.y = pLowerLinePoints[lLowerCounter - 1].y;
760            TempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
761
762            pLinePoints[lCounter - 7] = new POINT2(TempLinePoint);
763            pLinePoints[lCounter - 6] = new POINT2( pLowerLinePoints[lLowerCounter - 1]);
764            pLinePoints[lCounter - 5] =  new POINT2(InnerTipLinePoint);
765            pLinePoints[lCounter - 4] =  new POINT2(pUpperLinePoints[lUpperCounter - 1]);
766
767            pt0.x = pLowerLinePoints[lLowerCounter - 1].x;
768            pt0.y = pLowerLinePoints[lLowerCounter - 1].y;
769            pt1.x = pUpperLinePoints[lUpperCounter - 1].x;
770            pt1.y = pUpperLinePoints[lUpperCounter - 1].y;
771            TempLinePoint = lineutility.GetOffsetPointDouble(pt0, pt1, (int) (dOffsetFactor * dPrinter));
772
773            pLinePoints[lCounter - 3] =  new POINT2(TempLinePoint);
774            pLinePoints[lCounter - 2] =  new POINT2(OuterTipLinePoint);
775            pLinePoints[lCounter - 1] =  new POINT2(OuterTipLinePoint);
776            pLinePoints[lCounter - 1].style = 5;
777
778            switch (vbiDrawThis) {
779                case TacticalLines.SPT_STRAIGHT:
780                case TacticalLines.SPT:
781                case TacticalLines.AAAAA:
782                case TacticalLines.AIRAOA:
783                case TacticalLines.CATK:
784                case TacticalLines.CATKBYFIRE:
785                    pLinePoints[lCounter - 6].style = 5;
786                    pLinePoints[lCounter - 5].style = 5;
787                    break;
788                default:
789                    break;
790            }
791            
792            //10-19-12
793            //reset the original points after the hack for catkbyfire
794            if(vbiDrawThis==TacticalLines.CATKBYFIRE && dist>45)
795            {
796                pUpperLinePoints[lUpperCounter-1].x=ptUpper0.x;
797                pUpperLinePoints[lUpperCounter-1].y=ptUpper0.y;
798                pLowerLinePoints[lLowerCounter-1].x=ptLower0.x;
799                pLowerLinePoints[lLowerCounter-1].y=ptLower0.y;
800                ArrowLinePoint.x=origArrowPt.x;
801                ArrowLinePoint.y=origArrowPt.y;
802            }
803            //end section
804        } catch (Exception exc) {
805            ErrorLogger.LogException(_className ,"GetAXADDouble",
806                    new RendererException("Failed inside GetAXADDouble " + Integer.toString(vbiDrawThis), exc));
807        }
808    }
809    /**
810     * Calculates a channel line and is called once each time for lower and upper channel lines.
811     *
812     * @param nPrinter always 1
813     * @param pLinePoints client points
814     * @param nUpperLower 0 for lower channel line, 1 for upper channel line
815     * @param vblCounter the client point count
816     * @param vbiDrawThis the line type
817     * @param vblChannelWidth the channel width
818     *
819     * @return the channel line array as POINT2
820     */
821    protected static POINT2[] GetChannelArray2Double(int nPrinter,
822            POINT2[] pLinePoints,
823            int nUpperLower,
824            int vblCounter,
825            int vbiDrawThis,
826            int vblChannelWidth) {
827        try {
828            //get the upper or lower channel array for the specified channel type
829            switch (vbiDrawThis) {
830                case TacticalLines.LC:
831                case TacticalLines.LC_HOSTILE:
832                case TacticalLines.AIRAOA:
833                case TacticalLines.AAAAA:
834                case TacticalLines.CATK:
835                case TacticalLines.CATKBYFIRE:
836                case TacticalLines.MAIN:
837                case TacticalLines.MAIN_STRAIGHT:
838                case TacticalLines.SPT:
839                case TacticalLines.SPT_STRAIGHT:
840                case TacticalLines.TRIPLE:
841                case TacticalLines.DOUBLEC:
842                case TacticalLines.SINGLEC:
843                case TacticalLines.HWFENCE:
844                case TacticalLines.LWFENCE:
845                case TacticalLines.DOUBLEA:
846                case TacticalLines.UNSP:
847                case TacticalLines.SFENCE:
848                case TacticalLines.DFENCE:
849                case TacticalLines.CHANNEL:
850                case TacticalLines.CHANNEL_FLARED:
851                case TacticalLines.CHANNEL_DASHED:
852                    pLinePoints = CoordIL2Double(nPrinter, pLinePoints, nUpperLower, vblCounter, vbiDrawThis, vblChannelWidth);
853                    break;
854                default:
855                    //do nothing if it's not a channel type
856                    break;
857            }   //end switch
858
859        } catch (Exception exc) {
860            ErrorLogger.LogException(_className ,"GetChannelArray2Double",
861                    new RendererException("Failed inside GetChannelArray2Double " + Integer.toString(vbiDrawThis), exc));
862        }
863        return pLinePoints;
864    }
865
866    private static CChannelPoints2 GetTrueEndPointDouble(int nWidth,
867                                        POINT2 EndLinePoint,
868                                        POINT2 NextLinePoint,
869                                        int lLast)
870    {
871        CChannelPoints2 cAnswers=new CChannelPoints2();
872        try
873        {
874            //declarations
875            POINT2 LinePoint1=new POINT2(),LinePoint2=new POINT2();
876            double m = 0,
877                    b = 0,
878                    bPerpendicular = 0,
879                    Upperb = 0,
880                    Lowerb = 0,
881                    dWidth=(double)nWidth;
882            int bolVertical=0;
883            ref<double[]> pdResult=new ref();// double[6];
884            //end declarations
885
886            bolVertical=lineutility.CalcTrueLinesDouble(nWidth,EndLinePoint,NextLinePoint,pdResult);
887            m = pdResult.value[0];
888            b = pdResult.value[1];
889            Upperb = pdResult.value[3];
890            Lowerb = pdResult.value[5];
891
892            if(bolVertical==0)  //lines are vertical
893            {
894                switch(lLast)
895                {
896                    case 4:
897                    case 6:
898                        cAnswers.m_Line1.x=EndLinePoint.x-dWidth;
899                        cAnswers.m_Line1.y=EndLinePoint.y;
900                        cAnswers.m_Line2.x=EndLinePoint.x+dWidth;
901                        cAnswers.m_Line2.y=EndLinePoint.y;
902                        break;
903                    case 5:
904                    case 7:
905                        cAnswers.m_Line1.x=EndLinePoint.x+dWidth;
906                        cAnswers.m_Line1.y=EndLinePoint.y;
907                        cAnswers.m_Line2.x=EndLinePoint.x-dWidth;
908                        cAnswers.m_Line2.y=EndLinePoint.y;
909                        break;
910                    default:    //cases 0-3 should not occur if line is vertical
911                        break;
912                }
913            }
914
915            if(m==0)
916            {
917                switch(lLast)
918                {
919                    case 0:     //line1 is above segment2
920                    case 2:
921                        cAnswers.m_Line1.x=EndLinePoint.x;
922                        cAnswers.m_Line1.y=EndLinePoint.y-dWidth;
923                        cAnswers.m_Line2.x=EndLinePoint.x;
924                        cAnswers.m_Line2.y=EndLinePoint.y+dWidth;
925                        break;
926                    case 1:     //line1 is above segment2
927                    case 3:
928                        cAnswers.m_Line1.x=EndLinePoint.x;
929                        cAnswers.m_Line1.y=EndLinePoint.y+dWidth;
930                        cAnswers.m_Line2.x=EndLinePoint.x;
931                        cAnswers.m_Line2.y=EndLinePoint.y-dWidth;
932                        break;
933                    default:    //cases 4-7 should not be passed since line not vertical
934                        break;
935                }
936            }
937
938            //remaining cases, line is neither vertical nor horizontal
939            if(bolVertical!=0 && m!=0)  //lines are neither vertical nor horizontal
940            {
941                bPerpendicular = EndLinePoint.y + EndLinePoint.x / m;
942                LinePoint1=lineutility.CalcTrueIntersectDouble2(m,Upperb,-1/m,bPerpendicular,1,1,0,0);
943                LinePoint2=lineutility.CalcTrueIntersectDouble2(m,Lowerb,-1/m,bPerpendicular,1,1,0,0);
944
945                switch(lLast)
946                {
947                    case 0:     //line1 is above segment2
948                    case 2:
949                        if(LinePoint1.y<LinePoint2.y)
950                        {
951                            cAnswers.m_Line1=LinePoint1;
952                            cAnswers.m_Line2=LinePoint2;
953                        }
954                        else
955                        {
956                            cAnswers.m_Line1=LinePoint2;
957                            cAnswers.m_Line2=LinePoint1;
958                        }
959                        break;
960                    case 1:     //line1 is below segment2
961                    case 3:
962                        if(LinePoint1.y>LinePoint2.y)
963                        {
964                            cAnswers.m_Line1=LinePoint1;
965                            cAnswers.m_Line2=LinePoint2;
966                        }
967                        else
968                        {
969                            cAnswers.m_Line1=LinePoint2;
970                            cAnswers.m_Line2=LinePoint1;
971                        }
972                        break;
973                    default:    //cases1-4 should not occur since line is not vertical
974                        break;
975                }
976            }
977            pdResult=null;
978        }
979        catch(Exception exc)
980        {
981            ErrorLogger.LogException(_className ,"GetTrueEndPointDouble",
982                    new RendererException("Failed inside GetTrueEndPointDouble", exc));
983        }
984        return cAnswers;
985    }
986    private static CChannelPoints2 ConnectTrueDouble2(int nWidth,
987            POINT2  LinePoint1,
988            POINT2  LinePoint2,
989            POINT2  LinePoint3,
990            int  lOrient)
991    {
992        CChannelPoints2 pAnswerLinePoints=new CChannelPoints2();
993        try
994        {
995            //declarations
996            double  m1 = 0,
997                    b1 = 0,
998                    m2 = 0,
999                    b2 = 0,
1000                    Lowerb1 = 0,
1001                    Upperb1 = 0,
1002                    Lowerb2 = 0,
1003                    Upperb2 = 0,
1004                    dWidth=(double)nWidth;
1005
1006            ref<double[]> pdResult=new ref();//double[6];
1007            //pdResult.value=new double[6];
1008            //POINT2 AnswerLinePoint=new POINT2();
1009            int bolVerticalSlope1=0,bolVerticalSlope2=0;
1010            ref<double[]> x=new ref(),y=new ref();
1011            //end declarations
1012
1013            //Call CalcLines function for first two points (LinePoint1, LinePoint2)
1014            //and put parameters into the proper variables
1015            bolVerticalSlope1 = lineutility.CalcTrueLinesDouble(nWidth, LinePoint1, LinePoint2, pdResult);
1016            if(bolVerticalSlope1!=0)    //line is not vertical
1017            {
1018                m1 = pdResult.value[0];
1019                b1 = pdResult.value[1];
1020                Upperb1 = pdResult.value[5];
1021                Lowerb1 = pdResult.value[3];
1022            }
1023
1024            //Call CalcLines function for next two points (LinePoint2, LinePoint3)
1025            bolVerticalSlope2 = lineutility.CalcTrueLinesDouble(nWidth, LinePoint2, LinePoint3, pdResult);
1026            if(bolVerticalSlope2!=0)    //line is not vertical
1027            {
1028                m2 = pdResult.value[0];
1029                b2 = pdResult.value[1];
1030                Upperb2 = pdResult.value[5];
1031                Lowerb2 = pdResult.value[3];
1032            }
1033
1034            //must alter dWidth from the standard if bolVerticalSlope is 0.
1035            switch(lOrient)
1036            {
1037                case 0:
1038                    //line1 is above segment1 and above segment2
1039                    //use 0 for the orientation for Line 1
1040                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);
1041                    pAnswerLinePoints.m_Line1.x=x.value[0];
1042                    pAnswerLinePoints.m_Line1.y=y.value[0];
1043                    //line 2 point:     line2 is below segment1 and below segment2
1044                    //use 3 for the orientation for Line 2
1045                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);
1046                    pAnswerLinePoints.m_Line2.x=x.value[0];
1047                    pAnswerLinePoints.m_Line2.y=y.value[0];
1048                    break;
1049                case 1:
1050                    //line1 is above segment1 and below segment2
1051                    //use 1 for the orientation for Line 1
1052                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);
1053                    pAnswerLinePoints.m_Line1.x=x.value[0];
1054                    pAnswerLinePoints.m_Line1.y=y.value[0];
1055                    //line2 is below segment1 and above segment2
1056                    //use 2 for the orientation for Line 2
1057                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);
1058                    pAnswerLinePoints.m_Line2.x=x.value[0];
1059                    pAnswerLinePoints.m_Line2.y=y.value[0];
1060                    break;
1061                case 2:
1062                    //line1 is below segment1 and above segment2
1063                    //use 2 for the orientation for Line 1
1064                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,2,x,y);
1065                    pAnswerLinePoints.m_Line1.x=x.value[0];
1066                    pAnswerLinePoints.m_Line1.y=y.value[0];
1067                    //line2 is above segment1 and below segment2
1068                    //use 1 for the orientation for Line 1
1069                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,1,x,y);
1070                    pAnswerLinePoints.m_Line2.x=x.value[0];
1071                    pAnswerLinePoints.m_Line2.y=y.value[0];
1072                    break;
1073                case 3:
1074                    //line1 is below segment1 and below segment2
1075                    //use 3 for the orientation for Line 1
1076                    lineutility.CalcTrueIntersectDouble(m1,Lowerb1,m2,Lowerb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,3,x,y);
1077                    pAnswerLinePoints.m_Line1.x=x.value[0];
1078                    pAnswerLinePoints.m_Line1.y=y.value[0];
1079                    //line2 is above segment1 and above segment2
1080                    //use 0 for the orientation for Line 2
1081                    lineutility.CalcTrueIntersectDouble(m1,Upperb1,m2,Upperb2,LinePoint2,bolVerticalSlope1,bolVerticalSlope2,dWidth,0,x,y);
1082                    pAnswerLinePoints.m_Line2.x=x.value[0];
1083                    pAnswerLinePoints.m_Line2.y=y.value[0];
1084                    break;
1085                default:
1086                    break;
1087            }
1088            pdResult=null;
1089        }
1090        catch(Exception exc)
1091        {
1092            ErrorLogger.LogException(_className ,"ConnectTrueDouble2",
1093                    new RendererException("Failed inside ConnectTrueDouble2", exc));
1094        }
1095        return pAnswerLinePoints;
1096    }
1097    /*
1098     * Shift CounterAttack By Fire to not extend past the first point
1099     * @param vbiDrawThis
1100     * @param lpsaUpperVBPoints
1101     * @param vblLowerCounter
1102     * @param lpsaLowerVBPoints
1103     * @param vblUpperCounter 
1104     */
1105//    private static void shiftCATKBYFIREPoints(int vbiDrawThis,
1106//            double[] lpsaUpperVBPoints,
1107//            int vblLowerCounter,
1108//            double[] lpsaLowerVBPoints,
1109//            int vblUpperCounter)
1110//    {
1111//        try
1112//        {
1113//            if(vbiDrawThis != TacticalLines.CATKBYFIRE)
1114//                return;
1115//
1116//            POINT2 nextToLastPoint=new POINT2(lpsaUpperVBPoints[vblUpperCounter-4],lpsaUpperVBPoints[vblUpperCounter-3]);
1117//            POINT2 lastPoint=new POINT2(lpsaUpperVBPoints[vblUpperCounter-2],lpsaUpperVBPoints[vblUpperCounter-1]);
1118//            double dist=lineutility.CalcDistanceDouble(lastPoint, nextToLastPoint);
1119//            
1120//            if(dist<45)
1121//            {
1122//                nextToLastPoint=lineutility.ExtendAlongLineDouble(lastPoint,nextToLastPoint,45+2*dist);
1123//                lastPoint=lineutility.ExtendLineDouble(nextToLastPoint,lastPoint, -45);
1124//                lpsaUpperVBPoints[vblUpperCounter-4]=nextToLastPoint.x;
1125//                lpsaUpperVBPoints[vblUpperCounter-3]=nextToLastPoint.y;
1126//                lpsaLowerVBPoints[vblLowerCounter-4]=nextToLastPoint.x;
1127//                lpsaLowerVBPoints[vblLowerCounter-3]=nextToLastPoint.y;                                    
1128//            }
1129//            //lastPoint=lineutility.ExtendAlongLineDouble(lastPoint, nextToLastPoint, 45);
1130//            else
1131//                lastPoint=lineutility.ExtendLineDouble(nextToLastPoint,lastPoint, -45);
1132//            
1133//            lpsaUpperVBPoints[vblUpperCounter-2]=lastPoint.x;
1134//            lpsaUpperVBPoints[vblUpperCounter-1]=lastPoint.y;
1135//            lpsaLowerVBPoints[vblLowerCounter-2]=lastPoint.x;
1136//            lpsaLowerVBPoints[vblLowerCounter-1]=lastPoint.y;                                    
1137//        }
1138//        catch(Exception exc)
1139//        {
1140//            ErrorLogger.LogException(_className ,"ShiftCATKBYFIREPoints",
1141//                    new RendererException("Failed inside ShiftCATKBYFIREPoints", exc));
1142//        }
1143//    }
1144    /*
1145     * tester function to shift counterattack by fire point back to account for
1146     * aligning the rotary arrow tip with the anchor point. the feature used to extend past 
1147     * the anchor so the control point was shove forward. Intended to be called by the tester.
1148     * note: this function is not used by the CPOF client, it is for tester use only
1149     * @param linetype line type
1150     * @param pLinePoints
1151     * @param shift amount to shift back the existing control point
1152     */
1153//    public static void shiftCATKBYFIREControlPoint(
1154//            int linetype,
1155//            ArrayList<POINT2>pLinePoints,
1156//            double shift)
1157//    {
1158//        try
1159//        {
1160//            if(linetype != TacticalLines.CATKBYFIRE)
1161//                return;
1162//            int controlPtIndex=pLinePoints.size()-1;
1163//            POINT2 pt0=pLinePoints.get(0);
1164//            POINT2 pt1=pLinePoints.get(1);
1165//            double dist=lineutility.CalcDistanceDouble(pLinePoints.get(0), pLinePoints.get(1));
1166//            if(dist<=45)
1167//                return;
1168//            POINT2 controlPt=pLinePoints.get(controlPtIndex);
1169//            //pt3 is the point on parallel line which contains the control point and corresponds to,
1170//            //i.e. is perpendicular to, pt0.
1171//            POINT2 pt3=lineutility.PointRelativeToLine(pt0, pt1, pt0, controlPt);
1172//            //pt4 will be the shifted control point
1173//            POINT2 pt4=lineutility.ExtendLineDouble(pt3, controlPt, shift);
1174//            //set the control point as the new shifted control point
1175//            pLinePoints.set(controlPtIndex, pt4);
1176//        }
1177//        catch(Exception exc)
1178//        {
1179//            ErrorLogger.LogException(_className ,"shiftCATKBYFIREControlPoint",
1180//                    new RendererException("Failed inside shiftCATKBYFIREControlPoint", exc));
1181//        }
1182//    }
1183    /**
1184     * Calculates the channel points
1185     * @param lpsaUpperVBPoints the client points as 2-tuples
1186     * @param lpsaLowerVBPoints the client points as 2 tuples
1187     * @param resultVBPoints the result points as 3-tuples x,y,linestyle
1188     * @param vblUpperCounter the number of client 2-tuples
1189     * @param vblLowerCounter the number of client 2-tuples
1190     * @param vblChannelWidth the channel width in pixels
1191     * @param useptr the distance in pixels from the arrow tip to the back of the arrowhead
1192     * @param shapes the ShapeInfo array, each object contains the GeneralPath
1193     * @return
1194     */
1195    public static int GetChannel1Double(TGLight tg,
1196            double[] lpsaUpperVBPoints,
1197            double[] lpsaLowerVBPoints,
1198            double[] resultVBPoints,
1199            int vblUpperCounter,
1200            int vblLowerCounter,
1201            int vblChannelWidth,
1202            int useptr,
1203            ArrayList<Shape2>shapes) {
1204        int lResult = -1;
1205        try {
1206            int vbiDrawThis = tg.get_LineType();
1207            int k = 0, vblCounter = 0;
1208            int nPrinter = 1,
1209                    nArrowSize = 40 * nPrinter,
1210                    max = 0;
1211            double dist = 0,remainder=0;
1212            int vblUpperCounter2 = vblUpperCounter, vblLowerCounter2 = vblLowerCounter;
1213            int nReverseUpper = 0;
1214            int lUpperFlotCount = 0, lLowerFlotCount = 0;
1215            int nLowerCounter = 0, lUpperCounter = 0, lResultCounter = 0;
1216            int XCounter = 0;
1217            int j = 0, lHowManyThisSegment = 0, l = 0, t = 0;
1218            double pi = Math.PI, dAngle = 0, d = 0;
1219            double a = 13;//13;
1220            double b = 6;  //6;
1221            double dFactor = 0;
1222            int lEllipseCounter = 0;
1223            //double arrowOffsetFactor = 10;
1224            double arrowOffsetFactor = vblChannelWidth/4;  //diagnostic was 10
1225            POINT2[] pLowerLinePoints = new POINT2[vblLowerCounter],
1226                    pUpperLinePoints = new POINT2[vblUpperCounter],
1227                    pArrowLinePoints = new POINT2[1],
1228                    pLinePoints = null,
1229                    pUpperFlotPoints = null, pLowerFlotPoints = null, pOriginalLinePoints = null, pOriginalLinePoints2 = null;
1230            lineutility.InitializePOINT2Array(pLowerLinePoints);
1231            lineutility.InitializePOINT2Array(pUpperLinePoints);
1232            lineutility.InitializePOINT2Array(pArrowLinePoints);
1233
1234            POINT2 pt1 = new POINT2(), pt2 = new POINT2(), pt3 = new POINT2(), pt4 = new POINT2(), midPt1 = new POINT2(), midPt2 = new POINT2(), pt0 = new POINT2();
1235            POINT2[] arrowPts = new POINT2[3];
1236            //POINT2 startLinePoint = new POINT2();
1237            POINT2[] XPoints = new POINT2[4], pEllipsePoints2 = new POINT2[37];
1238            lineutility.InitializePOINT2Array(XPoints);
1239            lineutility.InitializePOINT2Array(pEllipsePoints2);
1240
1241            //POINT2 endLinePoint = new POINT2();
1242            POINT2 temp1LinePoint = new POINT2(), ptCenter = new POINT2(pLowerLinePoints[0]),
1243                    temp2LinePoint = new POINT2();
1244            POINT2 lastPoint = new POINT2(), nextToLastPoint = new POINT2();    //used by CATKBYFIRE
1245            //end declarations
1246
1247            //initializations
1248            if (vblChannelWidth < 5) {
1249                vblChannelWidth = 5;
1250            }
1251
1252            if (vblLowerCounter < 2 || vblUpperCounter < 2) {
1253                return -1;
1254            }
1255
1256            //shiftCATKBYFIREPoints(vbiDrawThis,lpsaUpperVBPoints,lpsaUpperVBPoints.length,lpsaLowerVBPoints,lpsaLowerVBPoints.length);
1257            //load client points
1258            for (k = 0; k < (long) vblLowerCounter; k++) {
1259                pLowerLinePoints[k].x = lpsaLowerVBPoints[nLowerCounter];
1260                nLowerCounter++;
1261                pLowerLinePoints[k].y = lpsaLowerVBPoints[nLowerCounter];
1262                nLowerCounter++;
1263                if (k == vblLowerCounter - 2) {
1264                    nextToLastPoint.x = pLowerLinePoints[k].x;
1265                    nextToLastPoint.y = pLowerLinePoints[k].y;
1266                }
1267                if (k == vblLowerCounter - 1) {
1268                    lastPoint.x = pLowerLinePoints[k].x;
1269                    lastPoint.y = pLowerLinePoints[k].y;
1270                }
1271                pLowerLinePoints[k].style = 0;
1272            }
1273            nLowerCounter = 0;
1274
1275            double lastSegmentLength = lineutility.CalcDistanceDouble(lastPoint, nextToLastPoint);
1276
1277            for (k = 0; k < (long) vblUpperCounter; k++) {
1278                pUpperLinePoints[k].x = lpsaUpperVBPoints[lUpperCounter];
1279                lUpperCounter++;
1280                pUpperLinePoints[k].y = lpsaUpperVBPoints[lUpperCounter];
1281                lUpperCounter++;
1282                pUpperLinePoints[k].style = 0;
1283            }
1284            lUpperCounter = 0;
1285            pArrowLinePoints[0] = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
1286            //end load client points
1287
1288            pt0 = new POINT2(pLowerLinePoints[0]);
1289            //diagnostic 1-7-13            
1290            boolean shiftLines=_shiftLines;
1291            switch(vbiDrawThis)
1292            {
1293                case TacticalLines.LC:
1294                case TacticalLines.LC_HOSTILE:
1295                case TacticalLines.UNSP:
1296                case TacticalLines.LWFENCE:
1297                case TacticalLines.HWFENCE:
1298                case TacticalLines.SINGLEC:
1299                case TacticalLines.DOUBLEC:
1300                case TacticalLines.TRIPLE:
1301                    break;
1302                default:
1303                    shiftLines=false;
1304                    break;
1305            }
1306            //end section
1307            
1308            switch (vbiDrawThis) {
1309                case TacticalLines.CATK:
1310                case TacticalLines.AIRAOA:
1311                case TacticalLines.AAAAA:
1312                case TacticalLines.SPT:
1313                case TacticalLines.SPT_STRAIGHT:
1314                case TacticalLines.MAIN:
1315                case TacticalLines.MAIN_STRAIGHT:
1316                case TacticalLines.CATKBYFIRE:  //80
1317                    dist = (double) useptr;
1318
1319                    nArrowSize = (int) Math.sqrt(dist * dist + vblChannelWidth / 2 * vblChannelWidth / 2);
1320                    //nArrowSize = (int) Math.sqrt(dist * dist + vblChannelWidth * vblChannelWidth);
1321                    //lineutility.WriteFile(Integer.toString(nArrowSize));
1322                    
1323                    pUpperLinePoints[vblUpperCounter - 1] = lineutility.ExtendAlongLineDouble(pUpperLinePoints[vblUpperCounter - 1], pUpperLinePoints[vblUpperCounter - 2], dist);
1324                    pLowerLinePoints[vblLowerCounter - 1] = lineutility.ExtendAlongLineDouble(pLowerLinePoints[vblLowerCounter - 1], pLowerLinePoints[vblLowerCounter - 2], dist);
1325                    break;
1326                default:
1327                    break;
1328            }
1329            //end section
1330
1331            temp1LinePoint = new POINT2(pLowerLinePoints[0]);
1332            temp2LinePoint = new POINT2(pUpperLinePoints[0]);
1333
1334            //get the channel array
1335            switch (vbiDrawThis) {
1336                case TacticalLines.MAIN:
1337                case TacticalLines.MAIN_STRAIGHT:
1338                case TacticalLines.SPT:
1339                case TacticalLines.SPT_STRAIGHT:
1340                case TacticalLines.CATK:
1341                case TacticalLines.CATKBYFIRE:
1342                case TacticalLines.TRIPLE:
1343                case TacticalLines.DOUBLEC:
1344                case TacticalLines.SINGLEC:
1345                case TacticalLines.HWFENCE:
1346                case TacticalLines.LWFENCE:
1347                case TacticalLines.UNSP:
1348                case TacticalLines.DOUBLEA:
1349                case TacticalLines.DFENCE:
1350                case TacticalLines.SFENCE:
1351                case TacticalLines.CHANNEL:
1352                case TacticalLines.CHANNEL_FLARED:
1353                case TacticalLines.CHANNEL_DASHED:
1354                    vblCounter = GetTripleCountDouble(pUpperLinePoints, vblUpperCounter, vbiDrawThis);
1355                    //save the original line points for later
1356                    pOriginalLinePoints = new POINT2[vblUpperCounter];
1357                    for (k = 0; k < vblUpperCounter; k++) {
1358                        pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1359                    }
1360                    pOriginalLinePoints2 = new POINT2[vblUpperCounter];
1361                    for (k = 0; k < vblUpperCounter; k++) {
1362                        pOriginalLinePoints2[k] = new POINT2(pUpperLinePoints[k]);
1363                    }
1364                    //bound the points
1365                    switch (vbiDrawThis) {
1366                        case TacticalLines.TRIPLE:
1367                        case TacticalLines.DOUBLEC:
1368                        case TacticalLines.SINGLEC:
1369                        case TacticalLines.HWFENCE:
1370                        case TacticalLines.LWFENCE:
1371                        case TacticalLines.UNSP:
1372                        case TacticalLines.DOUBLEA:
1373                        case TacticalLines.DFENCE:
1374                        case TacticalLines.SFENCE:
1375                            pLowerLinePoints = new POINT2[vblLowerCounter];
1376                            for (k = 0; k < vblLowerCounter2; k++) {
1377                                pLowerLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1378                            }
1379
1380                            pUpperLinePoints = new POINT2[vblUpperCounter];
1381                            for (k = 0; k < vblUpperCounter2; k++) {
1382                                pUpperLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1383                            }
1384                            pOriginalLinePoints = new POINT2[vblUpperCounter];
1385                            for (k = 0; k < vblUpperCounter2; k++) {
1386                                pOriginalLinePoints[k] = new POINT2(pOriginalLinePoints2[k]);
1387                            }                            
1388                            break;
1389                        default:
1390                            //do not bound the points
1391                            break;
1392                    }
1393                    lineutility.moveSingleCPixels(vbiDrawThis, pUpperLinePoints);
1394                    lineutility.moveSingleCPixels(vbiDrawThis, pLowerLinePoints);
1395                    lineutility.MoveChannelPixels(pUpperLinePoints);
1396                    lineutility.MoveChannelPixels(pLowerLinePoints);
1397                    
1398                    //diagnostic 1-7-13
1399                    //if(_shiftLines && vbiDrawThis != TacticalLines.DOUBLEC)
1400                    if(shiftLines)
1401                        vblChannelWidth *=2;
1402                    //end section
1403                    
1404                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1405                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1406                    
1407                    //diagnostic 1-7-13
1408                    if(shiftLines)
1409                    {
1410                        //if(vbiDrawThis != TacticalLines.SINGLEC && vbiDrawThis != TacticalLines.DOUBLEC)
1411                          //  pUpperLinePoints=pOriginalLinePoints;
1412                        if(vbiDrawThis == TacticalLines.SINGLEC)                        
1413                            pLowerLinePoints=pOriginalLinePoints;                        
1414                        else if(vbiDrawThis == TacticalLines.DOUBLEC)                        
1415                        {
1416                            for(j=0;j<pUpperLinePoints.length;j++)
1417                            {
1418                                pUpperLinePoints[j]=lineutility.MidPointDouble(pLowerLinePoints[j], pOriginalLinePoints[j], 0);
1419                            }
1420                            //pOriginalLinePoints=pLowerLinePoints.clone();
1421                        }
1422                        else if(vbiDrawThis == TacticalLines.TRIPLE)                        
1423                            pUpperLinePoints=pOriginalLinePoints;                        
1424                        else
1425                            pUpperLinePoints=pOriginalLinePoints;                        
1426                    }
1427                    break;
1428                case TacticalLines.LC:
1429                case TacticalLines.LC_HOSTILE:
1430                    if(shiftLines) {
1431                        pOriginalLinePoints = new POINT2[vblUpperCounter];
1432                        for (k = 0; k < vblUpperCounter; k++) {
1433                            pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1434                        }
1435                        vblChannelWidth *= 2;
1436                    }
1437                    
1438                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1439                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1440                    
1441                    if(shiftLines)   
1442                    {                        
1443                        //if(_affiliation != null && _affiliation.equalsIgnoreCase("H"))
1444                        if(vbiDrawThis==TacticalLines.LC_HOSTILE)
1445                            pLowerLinePoints=pOriginalLinePoints;
1446                        else
1447                            pUpperLinePoints=pOriginalLinePoints;
1448                    }
1449                    
1450                    if ((pUpperLinePoints[0].x > pUpperLinePoints[1].x) && (pUpperLinePoints[0].y != pUpperLinePoints[1].y)) {
1451                        nReverseUpper = 1;
1452                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1453                    } else if ((pUpperLinePoints[0].x > pUpperLinePoints[1].x) && (pUpperLinePoints[0].y == pUpperLinePoints[1].y)) {
1454                        nReverseUpper = 0;
1455                        lineutility.ReversePointsDouble2(pUpperLinePoints, vblUpperCounter);
1456                    } else if (pUpperLinePoints[0].x < pUpperLinePoints[1].x) {
1457                        nReverseUpper = 1;
1458                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1459                    } else if ((pUpperLinePoints[0].y > pUpperLinePoints[1].y) && (pUpperLinePoints[0].x == pUpperLinePoints[1].x)) {
1460                        nReverseUpper = 1;
1461                        lineutility.ReversePointsDouble2(pLowerLinePoints, vblLowerCounter);
1462                    } else if ((pUpperLinePoints[0].y < pUpperLinePoints[1].y) && (pUpperLinePoints[0].x == pUpperLinePoints[1].x)) {
1463                        nReverseUpper = 0;
1464                        lineutility.ReversePointsDouble2(pUpperLinePoints, vblUpperCounter);
1465                    }
1466                    break;
1467                case TacticalLines.AAAAA:
1468                case TacticalLines.AIRAOA:
1469                    pOriginalLinePoints = new POINT2[vblUpperCounter];
1470                    for (k = 0; k < vblUpperCounter; k++) {
1471                        pOriginalLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1472                    }
1473                    pUpperLinePoints = GetChannelArray2Double(nPrinter, pUpperLinePoints, 1, vblUpperCounter, vbiDrawThis, vblChannelWidth);
1474                    pLowerLinePoints = GetChannelArray2Double(nPrinter, pLowerLinePoints, 0, vblLowerCounter, vbiDrawThis, vblChannelWidth);
1475
1476
1477            //end section
1478                    //only allow the lines to cross if there is enough room
1479                    //if (lastSegmentLength > vblChannelWidth / 2)
1480                    //{
1481                        temp1LinePoint = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
1482                        temp2LinePoint = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
1483                        pLowerLinePoints[vblLowerCounter - 1] = new POINT2(temp2LinePoint);
1484                        pUpperLinePoints[vblUpperCounter - 1] = new POINT2(temp1LinePoint);
1485                    //}
1486                    break;
1487                default:
1488                    break;
1489            }   //end get channel array
1490            //load channel array into pLinePoints
1491            switch (vbiDrawThis) {
1492                case TacticalLines.LC:
1493                case TacticalLines.LC_HOSTILE:
1494                    lUpperFlotCount = flot.GetFlotCountDouble(pUpperLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness()), vblUpperCounter);
1495                    lLowerFlotCount = flot.GetFlotCountDouble(pLowerLinePoints, arraysupport.getScaledSize(20, tg.get_LineThickness()), vblLowerCounter);
1496                    if (lUpperFlotCount <= 0 || lLowerFlotCount <= 0) {
1497                        return 0;
1498                    }
1499                    //vblCounter = lUpperFlotCount + lLowerFlotCount;
1500
1501                    max = vblUpperCounter;
1502                    if (max < lUpperFlotCount) {
1503                        max = lUpperFlotCount;
1504                    }
1505                    pUpperFlotPoints = new POINT2[max];
1506                    lineutility.InitializePOINT2Array(pUpperFlotPoints);
1507                    max = vblLowerCounter;
1508                    if (max < lLowerFlotCount) {
1509                        max = lLowerFlotCount;
1510                    }
1511                    pLowerFlotPoints = new POINT2[max];
1512                    lineutility.InitializePOINT2Array(pLowerFlotPoints);
1513                    for (k = 0; k < vblUpperCounter; k++) {
1514                        pUpperFlotPoints[k] = new POINT2(pUpperLinePoints[k]);
1515                    }
1516                    for (k = 0; k < vblLowerCounter; k++) {
1517                        pLowerFlotPoints[k] = new POINT2(pLowerLinePoints[k]);
1518                    }
1519
1520                    lUpperFlotCount = flot.GetFlotDouble(pUpperFlotPoints, arraysupport.getScaledSize(20, tg.get_LineThickness()), vblUpperCounter);    //6/24/04
1521                    lLowerFlotCount = flot.GetFlotDouble(pLowerFlotPoints, arraysupport.getScaledSize(20, tg.get_LineThickness()), vblLowerCounter);    //6/24/04
1522                    pLinePoints = new POINT2[lUpperFlotCount + lLowerFlotCount];
1523                    lineutility.InitializePOINT2Array(pLinePoints);
1524
1525                    vblCounter = lLowerFlotCount + lUpperFlotCount;
1526
1527                    if (nReverseUpper == 1) {
1528                        for (k = 0; k < lUpperFlotCount; k++) {
1529                            pLinePoints[k] = new POINT2(pUpperFlotPoints[k]);
1530                            pLinePoints[k].style = 25;  //was 26
1531                        }
1532                        //added one line M. Deutch 4-22-02
1533                        if (lUpperFlotCount > 0) {
1534                            pLinePoints[lUpperFlotCount - 1].style = 5;
1535                        }
1536                        for (k = 0; k < lLowerFlotCount; k++) {
1537                            pLinePoints[k + lUpperFlotCount] = new POINT2(pLowerFlotPoints[k]);
1538                            pLinePoints[k + lUpperFlotCount].style = 26;    //was 0
1539                        }
1540                        if (lUpperFlotCount+lLowerFlotCount > 0) {
1541                            pLinePoints[lUpperFlotCount+lLowerFlotCount - 1].style = 5;}
1542                    }
1543                    if (nReverseUpper == 0) {
1544                        for (k = 0; k < lUpperFlotCount; k++) {
1545                            pLinePoints[k] = new POINT2(pUpperFlotPoints[k]);
1546                            pLinePoints[k].style = 26;  //was 0
1547                        }
1548                        if(lUpperFlotCount>0)
1549                            pLinePoints[lUpperFlotCount - 1].style = 5;
1550
1551                        for (k = 0; k < lLowerFlotCount; k++) {
1552                            pLinePoints[k + lUpperFlotCount] = new POINT2(pLowerFlotPoints[k]);
1553                            pLinePoints[k + lUpperFlotCount].style = 25;    //was 26
1554                        }
1555                        if(lUpperFlotCount+lLowerFlotCount>0)
1556                            pLinePoints[lUpperFlotCount+lLowerFlotCount - 1].style = 5;
1557                    }
1558                    break;
1559                case TacticalLines.TRIPLE:
1560                case TacticalLines.DOUBLEC:
1561                case TacticalLines.SINGLEC:
1562                case TacticalLines.HWFENCE:
1563                case TacticalLines.LWFENCE:
1564                case TacticalLines.UNSP:
1565                case TacticalLines.DOUBLEA:
1566                case TacticalLines.SFENCE:
1567                case TacticalLines.DFENCE:
1568                case TacticalLines.CHANNEL:
1569                case TacticalLines.CHANNEL_FLARED:
1570                case TacticalLines.CHANNEL_DASHED:
1571                    //load the channel points
1572                    pLinePoints = new POINT2[vblCounter];
1573                    lineutility.InitializePOINT2Array(pLinePoints);
1574                    //initialize points
1575                    for (j = 0; j < pLinePoints.length; j++) {
1576                        pLinePoints[j].x = lpsaUpperVBPoints[0];
1577                        pLinePoints[j].y = lpsaUpperVBPoints[1];
1578                    }
1579                    switch (vbiDrawThis) {
1580                        case TacticalLines.TRIPLE:
1581                        case TacticalLines.HWFENCE:
1582                        case TacticalLines.CHANNEL:
1583                        case TacticalLines.CHANNEL_FLARED:
1584                        case TacticalLines.CHANNEL_DASHED:
1585                        case TacticalLines.SINGLEC:   //added 7-10-07
1586                            for (k = 0; k < vblLowerCounter; k++) 
1587                            {
1588                                pLinePoints[k] = new POINT2(pLowerLinePoints[k]);   //don't shift here
1589                            }
1590                            break;
1591                        case TacticalLines.DOUBLEC:
1592                            if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) 
1593                            {
1594                                for (k = 0; k < vblLowerCounter; k++) 
1595                                {
1596                                    pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1597                                }
1598                            } 
1599                            else 
1600                            {
1601                                for (k = 0; k < vblLowerCounter; k++) 
1602                                {
1603                                    pLinePoints[k] = new POINT2(pUpperLinePoints[k]);
1604                                }
1605                            }
1606                            break;
1607
1608                        case TacticalLines.LWFENCE:
1609                            for (k = 0; k < vblLowerCounter; k++) {
1610                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1611                                pLinePoints[k].style = 5;
1612                                }
1613                            break;
1614                        case TacticalLines.UNSP:
1615                            for (k = 0; k < vblLowerCounter; k++) {
1616                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1617                                pLinePoints[k].style = 5;
1618                            }
1619                            break;
1620                        case TacticalLines.DOUBLEA:
1621                            for (k = 0; k < vblLowerCounter; k++) {
1622                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1623                            }
1624                            break;
1625                        default:
1626                            for (k = 0; k < vblLowerCounter; k++) {
1627                                pLinePoints[k] = new POINT2(pOriginalLinePoints[k]);
1628                            }
1629                            break;
1630                    }
1631                    pLinePoints[vblLowerCounter - 1].style = 5;
1632
1633                    switch (vbiDrawThis) {
1634                        case TacticalLines.TRIPLE:
1635                        case TacticalLines.HWFENCE:
1636                        case TacticalLines.CHANNEL:
1637                        case TacticalLines.CHANNEL_FLARED:
1638                        case TacticalLines.CHANNEL_DASHED:
1639                            for (k = 0; k < vblUpperCounter; k++) {
1640                                pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1641                            }
1642                            break;
1643                        case TacticalLines.DOUBLEC:
1644                            if (pOriginalLinePoints[0].x < pOriginalLinePoints[1].x) 
1645                            {
1646                                for (k = 0; k < vblUpperCounter; k++) 
1647                                {
1648                                    pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1649                                }
1650                            } 
1651                            else 
1652                            {
1653                                for (k = 0; k < vblUpperCounter; k++) 
1654                                {
1655                                    pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1656                                }
1657                            }
1658                            break;
1659                        case TacticalLines.SINGLEC:
1660                            for (k = 0; k < vblUpperCounter; k++) {
1661                                //pLinePoints[vblLowerCounter + k] = pOriginalLinePoints[k];    //revised 7-10-07
1662                                pLinePoints[vblLowerCounter + k] = new POINT2(pLowerLinePoints[k]);
1663                            }
1664                            break;
1665                        case TacticalLines.LWFENCE:
1666                            //remove block to make channel line aoways below the X
1667                                for (k = 0; k < vblUpperCounter; k++) 
1668                                {
1669                                    pLinePoints[vblLowerCounter + k] = new POINT2(pUpperLinePoints[k]);
1670                                }
1671                            break;
1672                        case TacticalLines.UNSP:
1673                            for (k = 0; k < vblUpperCounter; k++) 
1674                            {
1675                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1676                                pLinePoints[vblLowerCounter + k].style = 5;
1677                            }
1678                            break;
1679                        case TacticalLines.DOUBLEA:
1680                            for (k = 0; k < vblUpperCounter; k++) {
1681                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1682                            }
1683                            break;
1684                        default:
1685                            for (k = 0; k < vblUpperCounter; k++) {
1686                                pLinePoints[vblLowerCounter + k] = new POINT2(pOriginalLinePoints[k]);
1687                            }
1688                            break;
1689                    }
1690
1691                    pLinePoints[vblLowerCounter + vblUpperCounter - 1].style = 5;
1692
1693                    lEllipseCounter = vblLowerCounter + vblUpperCounter;
1694                    //following section only for lines with repeating features, e.g. DOUBLEA
1695                    //if(segments!=null &&
1696                    if (vbiDrawThis != TacticalLines.CHANNEL &&
1697                            vbiDrawThis != TacticalLines.CHANNEL_DASHED &&
1698                            vbiDrawThis != TacticalLines.CHANNEL_FLARED &&
1699                            vbiDrawThis != TacticalLines.SPT_STRAIGHT &&
1700                            vbiDrawThis != TacticalLines.MAIN_STRAIGHT)
1701                    {
1702                        int xSize;
1703                        if (shiftLines)
1704                            xSize = vblChannelWidth / 8;
1705                        else
1706                            xSize = vblChannelWidth / 4;
1707                        for (j = 0; j < vblUpperCounter - 1; j++) {
1708                            double dIncrement = xSize + arraysupport.getScaledSize(2, tg.get_LineThickness() / 2d);
1709                            d = lineutility.CalcDistanceDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1710                            lHowManyThisSegment = (int) (d/dIncrement);
1711                            remainder=d-dIncrement*lHowManyThisSegment;
1712                            dAngle = lineutility.CalcSegmentAngleDouble(pOriginalLinePoints[j], pOriginalLinePoints[j + 1]);
1713                            dAngle = dAngle + pi / 2;
1714                            for (k = 0; k < lHowManyThisSegment; k++) {
1715                                
1716                                if(vbiDrawThis==TacticalLines.SFENCE)
1717                                {
1718                                    if(k%4==0)
1719                                        continue;
1720                                }
1721                                else
1722                                {
1723                                    if(k%2==0)
1724                                        continue;
1725                                }
1726
1727                                double f=k;
1728                                f*=(1d+remainder/d);
1729                                                                
1730                                //diagnostic 1-7-13                                
1731                                //note: for shiftLines upper line points were set to original line points ealier
1732                                //ptCenter.x = pOriginalLinePoints[j].x + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].x - (double) pOriginalLinePoints[j].x) / (double) lHowManyThisSegment);
1733                                //ptCenter.y = pOriginalLinePoints[j].y + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].y - (double) pOriginalLinePoints[j].y) / (double) lHowManyThisSegment);                                
1734                                if(shiftLines==true && vbiDrawThis==TacticalLines.DOUBLEC)
1735                                {
1736                                    ptCenter.x = pUpperLinePoints[j].x + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].x - (double) pUpperLinePoints[j].x) / (double) lHowManyThisSegment);
1737                                    ptCenter.y = pUpperLinePoints[j].y + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].y - (double) pUpperLinePoints[j].y) / (double) lHowManyThisSegment);
1738                                }
1739                                else if(shiftLines==false)
1740                                {
1741                                    ptCenter.x = pOriginalLinePoints[j].x + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].x - (double) pOriginalLinePoints[j].x) / (double) lHowManyThisSegment);
1742                                    ptCenter.y = pOriginalLinePoints[j].y + (int) ((double) (f) * ((double) pOriginalLinePoints[j + 1].y - (double) pOriginalLinePoints[j].y) / (double) lHowManyThisSegment);
1743                                }
1744                                else
1745                                {
1746                                    ptCenter.x = pUpperLinePoints[j].x + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].x - (double) pUpperLinePoints[j].x) / (double) lHowManyThisSegment);
1747                                    ptCenter.y = pUpperLinePoints[j].y + (int) ((double) (f) * ((double) pUpperLinePoints[j + 1].y - (double) pUpperLinePoints[j].y) / (double) lHowManyThisSegment);
1748                                    POINT2 ptCenter2=new POINT2();
1749                                    ptCenter2.x = pLowerLinePoints[j].x + (int) ((double) (f) * ((double) pLowerLinePoints[j + 1].x - (double) pLowerLinePoints[j].x) / (double) lHowManyThisSegment);
1750                                    ptCenter2.y = pLowerLinePoints[j].y + (int) ((double) (f) * ((double) pLowerLinePoints[j + 1].y - (double) pLowerLinePoints[j].y) / (double) lHowManyThisSegment);
1751                                    ptCenter=lineutility.MidPointDouble(ptCenter, ptCenter2, 0);
1752                                }
1753                                //end section
1754                                
1755                                switch (vbiDrawThis) {
1756                                    case TacticalLines.SINGLEC:
1757                                    case TacticalLines.DOUBLEC:
1758                                    case TacticalLines.TRIPLE:
1759                                        for (l = 1; l < 37; l++) {
1760                                            dFactor = (10d * (double)l) * pi / 180d;
1761                                            pEllipsePoints2[l - 1].x = ptCenter.x + xSize * Math.cos(dFactor);
1762                                            pEllipsePoints2[l - 1].y = ptCenter.y + xSize / 2 * Math.sin(dFactor);
1763                                            pEllipsePoints2[l - 1].style = 0;
1764                                        }
1765                                        lineutility.RotateGeometryDouble(pEllipsePoints2, 36, dAngle * 180d / pi);
1766                                        pEllipsePoints2[36] = new POINT2(pEllipsePoints2[35]);
1767                                        pEllipsePoints2[36].style = 5;
1768                                        for (l = 0; l < 37; l++) {
1769                                            pLinePoints[lEllipseCounter] = new POINT2(pEllipsePoints2[l]);
1770                                            lEllipseCounter++;
1771                                        }
1772                                        break;
1773                                    case TacticalLines.HWFENCE:
1774                                    case TacticalLines.LWFENCE:
1775                                    case TacticalLines.DOUBLEA:
1776                                    case TacticalLines.UNSP:
1777                                    case TacticalLines.SFENCE:
1778                                    case TacticalLines.DFENCE:
1779                                        XPoints[0].x = ptCenter.x - xSize;//was 4
1780                                        XPoints[0].y = ptCenter.y - xSize;
1781                                        XPoints[0].style = 0;
1782                                        XPoints[1].x = ptCenter.x + xSize;
1783                                        XPoints[1].y = ptCenter.y + xSize;
1784                                        XPoints[1].style = 5;
1785                                        XPoints[2].x = ptCenter.x - xSize;
1786                                        XPoints[2].y = ptCenter.y + xSize;
1787                                        XPoints[2].style = 0;
1788                                        XPoints[3].x = ptCenter.x + xSize;
1789                                        XPoints[3].y = ptCenter.y - xSize;
1790                                        XPoints[3].style = 5;
1791                                        XCounter++;
1792                                        lineutility.RotateGeometryDouble(XPoints, 4, (int) (dAngle * 180 / pi));
1793                                        for (l = 0; l < 4; l++) {
1794                                            pLinePoints[lEllipseCounter] = new POINT2(XPoints[l]);
1795                                            switch (vbiDrawThis) {
1796                                                case TacticalLines.SFENCE:
1797                                                    if (XCounter == 2 || XCounter == 3 || XCounter == 4 || XCounter == 5) {
1798                                                        pLinePoints[lEllipseCounter].style = 5;
1799                                                    }
1800                                                    break;
1801                                                case TacticalLines.DFENCE:
1802                                                    if (XCounter == 3 || XCounter == 4 || XCounter == 5) {  //was 2,3 OR 4
1803                                                        pLinePoints[lEllipseCounter].style = 5;
1804                                                    }
1805                                                    break;
1806                                                default:
1807                                                    break;
1808                                            }
1809                                            lEllipseCounter++;
1810                                        }
1811                                        if (XCounter == 5) {
1812                                            XCounter = 0;
1813                                        }
1814                                        break;
1815                                    default:
1816                                        break;
1817                                }
1818                            }//end how many this segment loop
1819                            if (lHowManyThisSegment == 0) {
1820                                if(pLinePoints.length>lEllipseCounter)
1821                                {
1822                                    pLinePoints[lEllipseCounter] = new POINT2(pOriginalLinePoints[j]);
1823                                    lEllipseCounter++;
1824                                    pLinePoints[lEllipseCounter] = new POINT2(pOriginalLinePoints[j + 1]);
1825                                    pLinePoints[lEllipseCounter].style=5;
1826                                    lEllipseCounter++;
1827                                }
1828                            }
1829                        }
1830                        pLinePoints=lineutility.ResizeArray(pLinePoints, lEllipseCounter);
1831                        vblCounter=pLinePoints.length;  //added 11-2-09 M. Deutch
1832                    }
1833
1834                    //if none of the segments were long enough to have features
1835                    //then make the style solid
1836                    if (FenceType(vbiDrawThis) == 1) {
1837                        if (lEllipseCounter <= vblLowerCounter + vblUpperCounter) {
1838                            for (k = 0; k < vblLowerCounter + vblUpperCounter; k++) 
1839                            {
1840                                if(pLinePoints[k].style != 5)   //added 2-8-13
1841                                    pLinePoints[k].style = 0;
1842                            }
1843                        } 
1844                        else 
1845                        {
1846                            for (k = lEllipseCounter - 1; k < pLinePoints.length; k++) {
1847                                pLinePoints[k].style = 5;
1848                            }
1849                        }
1850                    }
1851                    break;
1852                case TacticalLines.SPT:
1853                case TacticalLines.SPT_STRAIGHT:
1854                case TacticalLines.CATK:
1855                case TacticalLines.CATKBYFIRE:
1856                case TacticalLines.AIRAOA:
1857                case TacticalLines.AAAAA:
1858                case TacticalLines.MAIN:
1859                case TacticalLines.MAIN_STRAIGHT:
1860                    if (vbiDrawThis != (long) TacticalLines.CATKBYFIRE) {
1861                        vblCounter = vblLowerCounter + vblUpperCounter + 8;
1862                    } else {
1863                        vblCounter = vblLowerCounter + vblUpperCounter + 17;
1864                    }
1865                    //diagnostic
1866                    if (vbiDrawThis == (long) TacticalLines.AAAAA) {
1867                        vblCounter = vblLowerCounter + vblUpperCounter + 19;
1868                    }
1869
1870                    pLinePoints = new POINT2[vblCounter];
1871                    lineutility.InitializePOINT2Array(pLinePoints);
1872                    //initialize points
1873                    for (j = 0; j < pLinePoints.length; j++) {
1874                        pLinePoints[j].x = lpsaUpperVBPoints[0];
1875                        pLinePoints[j].y = lpsaUpperVBPoints[1];
1876                    }
1877
1878                    if (vbiDrawThis != (long) TacticalLines.CATK &&
1879                            vbiDrawThis != (long) TacticalLines.CATKBYFIRE) 
1880                    {
1881                        for (k = 0; k < vblCounter; k++) 
1882                        {
1883                            pLinePoints[k].style = 0;
1884                        }
1885                    }
1886                    GetAXADDouble(nPrinter, pLowerLinePoints,
1887                            vblLowerCounter, pUpperLinePoints,
1888                            vblUpperCounter, pArrowLinePoints[0],
1889                            pLinePoints, vbiDrawThis, arrowOffsetFactor);
1890
1891                    if (vbiDrawThis == (long) TacticalLines.CATK ||
1892                            vbiDrawThis == (long) TacticalLines.CATKBYFIRE) {
1893                        for (k = 0; k < vblCounter; k++) {
1894                            if (pLinePoints[k].style != 5) {
1895                                pLinePoints[k].style = 1;
1896                            }
1897                        }
1898                    }
1899
1900                    //get the rotary symbol for AAAAA
1901                    if (vbiDrawThis == (long) TacticalLines.AAAAA)
1902                    {
1903                        Boolean rotaryTooShort=false;
1904                        ref<double[]> mUpper = new ref(), mLower = new ref();
1905                        int bolVerticalUpper = 0, bolVerticalLower = 0;
1906                        double bUpper = 0, bLower = 0;
1907
1908                        pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
1909                        pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
1910                        double dist1 = lineutility.CalcDistanceDouble(pt0, pt1);
1911
1912                        bolVerticalLower = lineutility.CalcTrueSlopeDouble(pt0, pt1, mLower);
1913                        bLower = pt0.y - mLower.value[0] * pt0.x;
1914
1915                        pt0 = new POINT2(pUpperLinePoints[vblUpperCounter - 2]);
1916                        pt1 = new POINT2(pUpperLinePoints[vblUpperCounter - 1]);
1917                        bolVerticalUpper = lineutility.CalcTrueSlopeDouble(pt0, pt1, mUpper);
1918                        bUpper = pt0.y - mUpper.value[0] * pt0.x;
1919                        double dist2 = lineutility.CalcDistanceDouble(pt0, pt1);
1920
1921                        //if (dist1 > vblChannelWidth && dist2 > vblChannelWidth)
1922                        //{
1923                        midPt1 = lineutility.CalcTrueIntersectDouble2(mLower.value[0], bLower, mUpper.value[0], bUpper, bolVerticalLower, bolVerticalUpper, pt0.x, pt0.y);
1924
1925                        //both sides of the channel need to be long enough
1926                        //or the rotary sides will not work, but we still
1927                        //include the arrow by using a simpler midpoint
1928                        if (dist1 <= vblChannelWidth || dist2 <= vblChannelWidth)
1929                        {
1930                            rotaryTooShort=true;
1931                            midPt1=lineutility.MidPointDouble(pt0, pt1, 0);
1932                        }
1933
1934                            a = lineutility.CalcDistanceDouble(pt0, pt1);
1935                            b = 30;
1936                            if (a < 90) {
1937                                b = a / 3;
1938                            }
1939
1940                            pt3 = new POINT2(pOriginalLinePoints[vblUpperCounter - 2]);
1941                            pt4 = new POINT2(pOriginalLinePoints[vblUpperCounter - 1]);
1942                            d = vblChannelWidth / 4;
1943                            double DPIScaleFactor = RendererSettings.getInstance().getDeviceDPI() / 96.0;
1944                            if (d > maxLength * DPIScaleFactor) {
1945                                d = maxLength * DPIScaleFactor;
1946                            }
1947                            if (d < minLength * DPIScaleFactor) {
1948                                d = minLength * DPIScaleFactor;
1949                            }
1950
1951                            //for non-vertical lines extend above or below the line
1952                            if (pt3.x != pt4.x) {
1953                                //extend below the line
1954                                pt0 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 3, 2 * d);
1955                                pLinePoints[vblLowerCounter + vblUpperCounter + 8] = pt0;
1956                                pLinePoints[vblLowerCounter + vblUpperCounter + 8].style = 0;
1957                                //extend above the line
1958                                pt1 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 2, 2 * d);
1959                                pLinePoints[vblLowerCounter + vblUpperCounter + 9] = pt1;
1960                                pLinePoints[vblLowerCounter + vblUpperCounter + 9].style = 5;
1961                            }
1962                            else //for vertical lines arrow points to the left
1963                            {
1964                                //extend right of the line
1965                                pt0 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 1, 2 * d);
1966                                pLinePoints[vblLowerCounter + vblUpperCounter + 8] = pt0;
1967                                pLinePoints[vblLowerCounter + vblUpperCounter + 8].style = 0;
1968                                //extend left of the line
1969                                pt1 = lineutility.ExtendDirectedLine(pt3, pt4, midPt1, 0, 2 * d);
1970                                pLinePoints[vblLowerCounter + vblUpperCounter + 9] = pt1;
1971                                pLinePoints[vblLowerCounter + vblUpperCounter + 9].style = 5;
1972                                midPt1 = lineutility.MidPointDouble(pt0, pt1, 0);
1973                            }
1974                            //get the rotary symbol arrow
1975                            lineutility.GetArrowHead4Double(pt0, pt1, (int) d, (int) d, arrowPts, 0);
1976
1977                            for (k = 0; k < 3; k++) {
1978                                pLinePoints[vblLowerCounter + vblUpperCounter + 10 + k] = arrowPts[k];
1979                            }
1980
1981                            pLinePoints[vblLowerCounter + vblUpperCounter + 12].style = 5;
1982
1983                            //get the base points
1984                            pt3 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt0, d / 2, 0);
1985                            pt4 = lineutility.ExtendTrueLinePerpDouble(pt0, pt1, pt0, -d / 2, 0);
1986
1987                            pLinePoints[vblLowerCounter + vblUpperCounter + 13] = pt3;
1988                            pLinePoints[vblLowerCounter + vblUpperCounter + 14] = pt4;
1989
1990                            //the side lines
1991                            //first point
1992                            pLinePoints[vblLowerCounter + vblUpperCounter + 14].style = 5;
1993                            pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
1994                            pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
1995                            pt3 = lineutility.ExtendLine2Double(pt0, midPt1, b, 0);     //line distance from midpt, a was 30
1996                            pLinePoints[vblLowerCounter + vblUpperCounter + 15] = new POINT2(pt3);
1997
1998                            //second point
1999                            pt0 = new POINT2(pUpperLinePoints[vblLowerCounter - 2]);
2000                            pt1 = new POINT2(pUpperLinePoints[vblLowerCounter - 1]);
2001                            pt3 = lineutility.ExtendLine2Double(pt0, midPt1, b, 5);     //line distance from midpt, a was 30
2002                            pLinePoints[vblLowerCounter + vblUpperCounter + 16] = new POINT2(pt3);
2003
2004                            //third point
2005                            pt0 = new POINT2(pLowerLinePoints[vblLowerCounter - 2]);
2006                            pt1 = new POINT2(pLowerLinePoints[vblLowerCounter - 1]);
2007                            pt3 = lineutility.ExtendLine2Double(pt1, midPt1, b, 0);     //line distance from midpt, a was 30
2008                            pLinePoints[vblLowerCounter + vblUpperCounter + 17] = new POINT2(pt3);
2009
2010                            //fourth point
2011                            pt0 = new POINT2(pUpperLinePoints[vblLowerCounter - 2]);
2012                            pt1 = new POINT2(pUpperLinePoints[vblLowerCounter - 1]);
2013                            pt3 = lineutility.ExtendLine2Double(pt1, midPt1, b, 5);     //line distance from midpt, a was 30
2014                            pLinePoints[vblLowerCounter + vblUpperCounter + 18] = new POINT2(pt3);
2015                        //}
2016                        //else
2017                        //{   //if last segment too short then don't draw the rotary features
2018                            //if last segment too short then no side points
2019                            if(rotaryTooShort)
2020                            {
2021                                for (l = vblLowerCounter + vblUpperCounter + 14; l < vblLowerCounter + vblLowerCounter + 19; l++)
2022                                {
2023                                    pLinePoints[l].style = 5;
2024                                }
2025                            }
2026                        //}
2027                    }//end if (vbiDrawThis == (long) TacticalLines.AAAAA)
2028                    
2029                    double dFeature=0;
2030                    double dist2=0;
2031                    if (vbiDrawThis == TacticalLines.CATKBYFIRE) 
2032                    {       //dist is the distance to the back of the arrowhead                        
2033                        //10-19-12
2034                        //this line is part of the new requirement that the rotary feature must align 
2035                        //with the anchor point, it can  no longer stick out beond the anchor point
2036                        //so the points have to be shifted by 45 pixels.
2037                        
2038                        //dist-=45;
2039                        //end section
2040                        dist2 = lineutility.CalcDistanceDouble(nextToLastPoint, lastPoint);
2041                        if(dist2>45)
2042                            dist-=45;
2043                        if (dist2 > 20) 
2044                        {                                                                                       //was 20+dist
2045                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], 5+dist);//distance from tip to back of rotary
2046                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], 5+dist);//distance from tip to back of rotary
2047                        } 
2048                        else 
2049                        {
2050                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], -50);//was -40
2051                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], -50);//was -40
2052                        }
2053                        //was dist
2054                        pt3 = lineutility.ExtendLine2Double(pt2, pt1, 10 + Math.abs(dist/2), 18); //vert height of rotary from horiz segment was dist/2.5
2055                        pt4 = lineutility.ExtendLine2Double(pt1, pt2, 10 + Math.abs(dist/2), 5); //vert height of rotary from horiz segment was dist/2.5
2056                        midPt1 = lineutility.MidPointDouble(pt1, pt2, 17);
2057                        pLinePoints[vblCounter - 9] = new POINT2(pt3);
2058                        pLinePoints[vblCounter - 6] = new POINT2(pt4);
2059
2060                        if (dist2 > 20) {                                                                                               //was 30+dist
2061                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], 15 + dist);//distance from tip to back of rotary
2062                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], 15 + dist);//distance from tip to back of rotary
2063                        } else {
2064                            pt1 = lineutility.ExtendLineDouble(pUpperLinePoints[vblUpperCounter - 2], pUpperLinePoints[vblUpperCounter - 1], -50);//was -50
2065                            pt2 = lineutility.ExtendLineDouble(pLowerLinePoints[vblLowerCounter - 2], pLowerLinePoints[vblLowerCounter - 1], -50);//was -50
2066                        }
2067
2068                        pt3 = lineutility.ExtendLine2Double(pt2, pt1, Math.abs(dist/2), 18);//vert height of rotary from horiz segment was dist/2.5
2069                        pt4 = lineutility.ExtendLine2Double(pt1, pt2, Math.abs(dist/2), 18);//vert height of rotary from horiz segment was dist/2.5
2070                                                
2071                        midPt2 = lineutility.MidPointDouble(pt1, pt2, 18);
2072                        pLinePoints[vblCounter - 8] = new POINT2(pt3);
2073                        pLinePoints[vblCounter - 7] = new POINT2(pt4);
2074                        pLinePoints[vblCounter - 5] = new POINT2(midPt2);
2075                        if (midPt1.x == midPt2.x && midPt1.y == midPt2.y) //last segment too short
2076                        {
2077                            //diagnostic 2-27-13
2078                            if(_client.startsWith("cpof"))
2079                                dFeature=30;
2080                            else                            
2081                                dFeature=15;
2082                            
2083                            
2084                            midPt1 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 10, 17);
2085                            //pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, 30, 18);
2086                            //pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, -30, 5);                            
2087                            pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, dFeature, 18);
2088                            pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt1, midPt1, -dFeature, 5);
2089                            //end section
2090                            pLinePoints[vblCounter - 9] = new POINT2(pt1);
2091                            pLinePoints[vblCounter - 6] = new POINT2(pt2);
2092                            
2093                            if(_client.startsWith("cpof"))
2094                                midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 20, 17);
2095                            else
2096                            {
2097                                if(dist2>30)
2098                                    midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], 20, 17);
2099                                else
2100                                    midPt2 = lineutility.ExtendLine2Double(nextToLastPoint, pArrowLinePoints[0], dFeature, 17);
2101                            }
2102                            //end section
2103                            
2104                            //diagnostic 2-27-13                            
2105                            //pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, 20, 18);
2106                            //pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, -20, 18);
2107                            dFeature -=10;
2108                            pt1 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, dFeature, 18);
2109                            pt2 = lineutility.ExtendTrueLinePerpDouble(lastPoint, midPt2, midPt2, -dFeature, 18);
2110                            pLinePoints[vblCounter - 8] = new POINT2(pt1);
2111                            pLinePoints[vblCounter - 7] = new POINT2(pt2);
2112                            pLinePoints[vblCounter - 5] = new POINT2(midPt2);
2113                        }
2114                        if(_client.startsWith("cpof"))
2115                            dFeature=30;
2116                        else
2117                        {
2118                            if(dist2>30)
2119                                dFeature=30;
2120                            else if(dist2>20)
2121                                dFeature=10;
2122                            else
2123                                dFeature=10;
2124                        }
2125
2126                        pt1 = lineutility.ExtendLine2Double(midPt1, midPt2, dFeature, (int)dFeature); //30, then 5
2127                        pLinePoints[vblCounter - 4] = new POINT2(pt1);
2128                        lineutility.GetArrowHead4Double(midPt2, pt1, (int)dFeature/2, (int)dFeature/2, arrowPts, 18);//15,15
2129                        //end section
2130                        for (k = 0; k < 3; k++) {
2131                            pLinePoints[vblCounter - k - 1] = new POINT2(arrowPts[k]);
2132                            pLinePoints[vblCounter - k - 1].style = 18;
2133                        }
2134                    }
2135                    break;
2136                default:
2137                    break;
2138            }   //end load channel array ino pLinePoints
2139            if (vbiDrawThis == (long) TacticalLines.CHANNEL_DASHED) {
2140                for (k = 0; k < vblCounter; k++) {
2141                    if (pLinePoints[k].style != 5) {
2142                        pLinePoints[k].style = 18;
2143                    }
2144                }
2145            }
2146
2147            //if shapes is null it is not a CPOF client
2148            if(shapes==null)
2149            {
2150                //load result points because client is using points, not shapes
2151                for(j=0;j<pLinePoints.length;j++)
2152                {
2153                    resultVBPoints[3*j]=pLinePoints[j].x;
2154                    resultVBPoints[3*j+1]=pLinePoints[j].y;
2155                    resultVBPoints[3*j+2]=(double)pLinePoints[j].style;
2156                }
2157                return pLinePoints.length;
2158            }
2159
2160            //the shapes
2161            Shape2 shape=null;
2162            //Shape2 outline=null;
2163            boolean beginLine=true;
2164            boolean beginPath=true;
2165
2166            for (k = 0; k < vblCounter; k++)
2167            {
2168                //use shapes instead of pixels
2169
2170                if(shape==null)
2171                {
2172                    shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2173                }
2174
2175                switch(vbiDrawThis)
2176                {
2177                    case TacticalLines.CATK:
2178                    case TacticalLines.CATKBYFIRE:
2179                        shape.set_Style(1);
2180                        break;
2181                }
2182
2183                switch(vbiDrawThis)
2184                {
2185                    case TacticalLines.LC:
2186                    case TacticalLines.LC_HOSTILE:
2187                        if(beginPath==false)
2188                        {
2189                            if(k>0)
2190                            {   //if the linestyle is changes on the next point then this point is end of the current path
2191                                //because it's changing between friendly and enemy ellipses
2192                                if(  pLinePoints[k].style == 5)
2193                                {
2194                                    //add the last point to the current path
2195                                    shape.lineTo(pLinePoints[k]);
2196                                    //add the shape
2197                                    if(shape !=null && shape.getShape() != null)
2198                                    {
2199                                        shapes.add(shape);
2200                                    }
2201
2202                                    beginPath=true;
2203                                }
2204                                else    //continue the current path
2205                                {
2206                                    shape.lineTo(pLinePoints[k]);
2207                                }
2208                            }
2209                            else    //k=0
2210                            {
2211                                shape.moveTo(pLinePoints[k]);
2212                            }
2213                        }
2214                        else    //start a new path
2215                        {
2216                            shape=new Shape2(Shape2.SHAPE_TYPE_POLYLINE);
2217                            shape.moveTo(pLinePoints[k]);
2218                            shape.set_Style(pLinePoints[k].style);
2219                            //assume friendly
2220                            if(pLinePoints[k].style==25)
2221                               shape.setLineColor(Color.RED);
2222                            
2223                            beginPath=false;
2224                        }
2225                        //if(k==vblCounter-1) //LC should have 2 shapes
2226                          //  if(shape !=null && shape.get_Shape() != null)
2227                            //    shapes.add(shape);
2228                        break;
2229                    case TacticalLines.CATK:    //same as default except these have doubled 5's
2230                    case TacticalLines.CATKBYFIRE:
2231                    case TacticalLines.AAAAA:
2232                    case TacticalLines.SPT:
2233                    case TacticalLines.SPT_STRAIGHT:
2234                    case TacticalLines.AIRAOA:
2235                        if(beginLine)
2236                        {
2237                            if(k>0) //doubled points with linestyle=5
2238                            {
2239                                if(pLinePoints[k].style==5 && pLinePoints[k-1].style==5 && k != vblCounter-1)
2240                                    continue;
2241                            }
2242
2243                            shape.moveTo(pLinePoints[k]);
2244                            beginLine=false;
2245                        }
2246                        else
2247                        {
2248                            shape.lineTo(pLinePoints[k]);
2249                            if(pLinePoints[k].style==5)
2250                            {
2251                                beginLine=true;
2252                                //unless there are doubled points with style=5
2253                            }
2254                        }
2255                        if(k==vblCounter-1) //non-LC should only have one shape
2256                        {
2257                            if(shape !=null && shape.getShape() != null)
2258                            {
2259                                shapes.add(shape);
2260                            }
2261                        }
2262                        break;
2263                    case TacticalLines.UNSP:
2264                    case TacticalLines.SFENCE:
2265                    case TacticalLines.DFENCE:
2266                    case TacticalLines.LWFENCE:
2267                    case TacticalLines.HWFENCE:
2268                        if(k==0)
2269                        {
2270                            shape.moveTo(pLinePoints[k]);
2271                            if(pLinePoints[k].style==5)
2272                            {
2273                                continue;
2274                            }
2275                        }
2276                        if(k>0 && k < vblCounter-1)
2277                        {
2278                            if(pLinePoints[k-1].style==5)
2279                                shape.moveTo(pLinePoints[k]);
2280                            else if(pLinePoints[k-1].style==0)
2281                                shape.lineTo(pLinePoints[k]);
2282
2283                            if(pLinePoints[k].style==5)
2284                              shape.moveTo(pLinePoints[k]);
2285
2286                            if(k==vblCounter-2 && pLinePoints[k].style==0)
2287                            {
2288                                shape.moveTo(pLinePoints[k]);
2289                                shape.lineTo(pLinePoints[k+1]);
2290                            }
2291                        }
2292
2293                        if(k==vblCounter-1) //non-LC should only have one shape
2294                        {
2295                            if(shape !=null && shape.getShape() != null)
2296                                shapes.add(shape);
2297                        }
2298                        break;
2299                    default:                        
2300                        if(beginLine)
2301                        {
2302                            if(k==0)
2303                                shape.set_Style(pLinePoints[k].style);
2304
2305                            shape.moveTo(pLinePoints[k]);
2306                            beginLine=false;
2307                        }
2308                        else
2309                        {
2310                            shape.lineTo(pLinePoints[k]);
2311                            if(pLinePoints[k].style==5)
2312                            {
2313                                beginLine=true;
2314                                //unless there are doubled points with style=5
2315                            }
2316                        }
2317                        if(k==vblCounter-1) //non-LC should only have one shape
2318                        {
2319                            if(shape !=null && shape.getShape() != null)
2320                                shapes.add(shape);
2321                        }
2322                        break;
2323                }//end switch
2324            }   //end for
2325            //a requirement was added to enable fill for the axis of advance line types
2326            ArrayList<Shape2>fillShapes=getAXADFillShapes(vbiDrawThis, pLinePoints);
2327            if(fillShapes != null && fillShapes.size()>0)
2328                shapes.addAll(0,fillShapes);
2329            
2330            lResult=lResultCounter;
2331            //FillPoints(pLinePoints,pLinePoints.length);
2332            //clean up
2333            pLinePoints = null;
2334            pLowerLinePoints = null;
2335            pUpperLinePoints = null;
2336            pArrowLinePoints = null;
2337            pUpperFlotPoints = null;
2338            arrowPts = null;
2339            XPoints = null;
2340            pEllipsePoints2 = null;
2341            pOriginalLinePoints = null;
2342            pOriginalLinePoints2 = null;
2343        }
2344        catch (Exception exc) {
2345            ErrorLogger.LogException(_className ,"GetChannel1Double",
2346                    new RendererException("Failed inside GetChannel1Double " + Integer.toString(tg.get_LineType()), exc));
2347        }
2348        return lResult;
2349    }
2350    /**
2351     * They decided that axis of advance must enable fill
2352     * @param lineType
2353     * @param pLinePoints
2354     * @return
2355     */
2356    private static ArrayList<Shape2> getAXADFillShapes(int lineType, POINT2[]pLinePoints)
2357    {
2358        ArrayList<Shape2>shapes=null;
2359        try
2360        {
2361            ArrayList<POINT2>newPts=new ArrayList();
2362            int j=0;
2363            Shape2 shape=null;
2364            int n=pLinePoints.length;
2365            switch(lineType)
2366            {
2367                case TacticalLines.CHANNEL:
2368                case TacticalLines.CHANNEL_FLARED:
2369                case TacticalLines.CHANNEL_DASHED:
2370                    for(j=0;j<n/2;j++)
2371                    {
2372                        newPts.add(pLinePoints[j]);
2373                    }
2374                    for(j=n-1;j>=n/2;j--)
2375                    {
2376                        newPts.add(pLinePoints[j]);
2377                    }
2378                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2379                    shape.moveTo(newPts.get(0));
2380                    int t=newPts.size();
2381                    //for(j=1;j<newPts.size();j++)
2382                    for(j=1;j<t;j++)
2383                    {
2384                        shape.lineTo(newPts.get(j));
2385                    }
2386                    break;
2387                case TacticalLines.AIRAOA:
2388                case TacticalLines.SPT:
2389                case TacticalLines.CATK:
2390                case TacticalLines.SPT_STRAIGHT:
2391                    //add the upper (lower) channel points
2392                    //for(j=0;j<(pLinePoints.length-8)/2;j++)
2393                    for(j=0;j<(n-8)/2;j++)
2394                    {
2395                        newPts.add(pLinePoints[j]);
2396                    }
2397                    //add the arrow outline
2398                    newPts.add(pLinePoints[n-6]);
2399                    newPts.add(pLinePoints[n-7]);
2400                    newPts.add(pLinePoints[n-8]);
2401                    newPts.add(pLinePoints[n-3]);
2402                    newPts.add(pLinePoints[n-4]);
2403                    //add the upper (lower) channel points
2404                    for(j=n-9;j>=(n-8)/2;j--)
2405                    {
2406                        newPts.add(pLinePoints[j]);
2407                    }
2408                    //newPts.add(pLinePoints[0]);
2409                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2410                    //shape.moveTo(newPts.get(0).x,newPts.get(0).y);
2411                    shape.moveTo(newPts.get(0));
2412                    t=newPts.size();
2413                    //for(j=1;j<newPts.size();j++)
2414                    for(j=1;j<t;j++)
2415                    {
2416                        shape.lineTo(newPts.get(j));
2417                    }
2418                    break;
2419                case TacticalLines.MAIN_STRAIGHT:
2420                case TacticalLines.MAIN:
2421                    //for(j=0;j<(pLinePoints.length-8)/2;j++)
2422                    for(j=0;j<(n-8)/2;j++)
2423                    {
2424                        newPts.add(pLinePoints[j]);
2425                    }
2426                    //add the arrow outline
2427                    newPts.add(pLinePoints[n-6]);
2428                    newPts.add(pLinePoints[n-5]);
2429                    for(j=n-9;j>=(n-8)/2;j--)
2430                    {
2431                        newPts.add(pLinePoints[j]);
2432                    }
2433                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2434                    shape.moveTo(newPts.get(0));
2435                    t=newPts.size();
2436                    //for(j=1;j<newPts.size();j++)
2437                    for(j=1;j<t;j++)
2438                    {
2439                        shape.lineTo(newPts.get(j));
2440                    }
2441                    break;
2442                case TacticalLines.AAAAA:
2443                    //for(j=0;j<(pLinePoints.length-19)/2;j++)
2444                    for(j=0;j<(n-19)/2;j++)
2445                    {
2446                        newPts.add(pLinePoints[j]);
2447                    }
2448                    //add the arrow outline
2449                    newPts.add(pLinePoints[n-17]);
2450                    newPts.add(pLinePoints[n-18]);
2451                    newPts.add(pLinePoints[n-19]);
2452                    newPts.add(pLinePoints[n-14]);
2453                    newPts.add(pLinePoints[n-15]);
2454
2455                    for(j=n-20;j>=(n-19)/2;j--)
2456                    {
2457                        newPts.add(pLinePoints[j]);
2458                    }
2459                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2460                    shape.moveTo(newPts.get(0));
2461                    t=newPts.size();
2462                    //for(j=1;j<newPts.size();j++)
2463                    for(j=1;j<t;j++)
2464                    {
2465                        shape.lineTo(newPts.get(j));
2466                    }
2467                    break;
2468                case TacticalLines.CATKBYFIRE:
2469                    //for(j=0;j<(pLinePoints.length-17)/2;j++)
2470                    for(j=0;j<(n-17)/2;j++)
2471                    {
2472                        newPts.add(pLinePoints[j]);
2473                    }
2474                    //add the arrow outline
2475                    newPts.add(pLinePoints[n-15]);
2476                    newPts.add(pLinePoints[n-16]);
2477                    newPts.add(pLinePoints[n-17]);
2478                    newPts.add(pLinePoints[n-12]);
2479                    newPts.add(pLinePoints[n-13]);
2480                    for(j=n-18;j>=(n-17)/2;j--)
2481                    {
2482                        newPts.add(pLinePoints[j]);
2483                    }
2484                    shape=new Shape2(Shape2.SHAPE_TYPE_FILL);
2485                    shape.moveTo(newPts.get(0));
2486                    t=newPts.size();
2487                    //for(j=1;j<newPts.size();j++)
2488                    for(j=1;j<t;j++)
2489                    {
2490                        shape.lineTo(newPts.get(j));
2491                    }
2492                    break;
2493                default:
2494                    break;
2495            }
2496            if(shape!=null)
2497            {
2498                shapes=new ArrayList();
2499                shape.setLineColor(null);
2500                shapes.add(shape);
2501            }
2502        }
2503        catch (Exception exc) {
2504            ErrorLogger.LogException(_className ,"getAXADfillShapes",
2505                    new RendererException("Failed inside getAXADFillShapes", exc));
2506        }
2507        return shapes;
2508    }
2509    /*
2510     * sets shape2 properties to those of shape1
2511     * @param shape1
2512     * @param shape2
2513     */
2514//    private static void SetShapeProperties(Shape2 shape1, Shape2 shape2)
2515//    {
2516//        try
2517//        {
2518//            shape2.setLineColor(shape1.getLineColor());
2519//            shape2.setStroke(shape1.getStroke());
2520//            shape2.setFillColor(shape1.getFillColor());
2521//        }
2522//        catch (Exception exc) {
2523//            ErrorLogger.LogException(_className ,"GetChannel1Double",
2524//                    new RendererException("Failed inside SetShapeProperties", exc));
2525//        }
2526//    }
2527}