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