package yi.iu.processor.ort;

import java.awt.*;
import java.util.Vector;
public final class DrawUtil
{
    //draw a line on the image without drawing the end points
    //intensity: the color of the line
    //thickness: 1:1-pixel, 2:3-pixel
    public static void ort2image(char[][] image, ORTLine l, int intensity, int thickness)
    {
        int YSize=image.length, XSize=image[0].length;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;

        DrawBezierLine (
            (int)Math.round (l.Start.Col + XCenter),
            (int)Math.round (l.Start.Row + YCenter),
            (int)Math.round (l.End.Col   + XCenter),
            (int)Math.round (l.End.Row   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image);
    }

    //draw all the lines in a vector
    public static void ort2image(char[][] image, Vector lv, int intensity, int thickness, double minLength)
    {
        for (int i=0;i<lv.size();i++) {
            ORTLine l= (ORTLine)lv.elementAt(i);
            if (l.Length<minLength) continue;
            ort2image(image,l,intensity++,thickness);
        }
    }

    //draw all the lines in a vector, using Line ID as the label-index
    public static void ort2image(char[][] image, Vector lv, int thickness, double minLength)
    {
        for (int i=0;i<lv.size();i++) {
            ORTLine l= (ORTLine)lv.elementAt(i);
            //if (l.ID<=0) System.err.println("line ID invalid: "+l.ID);
            if (l.Length<minLength) continue;
            ort2image(image,l,l.ID,thickness);
        }
    }

    //draw all the lines in a line group vector
    public static void linegroup2image(char[][] image, Vector lv, int intensity, int thickness)
    {
        for (int i=0;i<lv.size();i++) {
            ORTLineGroup l= (ORTLineGroup)lv.elementAt(i);
            ort2image(image,l.FirstID, intensity,thickness);
            ort2image(image,l.SecondID, intensity++,thickness);
        }
    }

    //draw all the lines in a line group vector, using the smaller Line ID as the label-index
    public static void linegroup2image(char[][] image, Vector lv, int thickness)
    {
        Dimension d= new Dimension(image[0].length, image.length);
        for (int i=0;i<lv.size();i++) {
            ORTLineGroup lg= (ORTLineGroup)lv.elementAt(i);
            if (lg==null) continue;
            if (lg.groupType==ORTLineGroup.JUNCTION_L||lg.groupType==ORTLineGroup.JUNCTION_T||
                lg.groupType==ORTLineGroup.JUNCTION_V||lg.groupType==ORTLineGroup.JUNCTION_LAMBDA) {
                ORTConjLineGroup clg= (ORTConjLineGroup)lg;
                double cx= clg.JunctionPt.Col, cy= clg.JunctionPt.Row;
                cx+= d.width/2; cy+= d.height/2;
                int index=(int)(Math.round(cy)*d.width+Math.round(cx));
                int color=0xffffffff;
                drawMark(image,d,(int)Math.round(cx),(int)Math.round(cy),8,color);
            }
            int id1=lg.FirstID.ID;
            int id2=lg.SecondID.ID;
            if (id1>id2) id1=id2;
            ort2image(image,lg.FirstID, id1,thickness);
            ort2image(image,lg.SecondID, id1,thickness);
        }
    }

    public static char[][] ort2image(Dimension d, Vector ID_ListORTLine, Vector ID_ListORTCircularArc)
    {
        int OutPutStatus  		= -1;       //-1: output lines&arcs, 0: only lines, 1: only arcs
        int Background 			= 0;        //color/label_index of the background
        int LineIntensity 		= 1;      //color/label_index of lines
        //int LineIntensity 		= 255;
        int LineThickness 		= 1;        //width of the lines
        int LineEndPointIntensity	= 0;    //color/label_index of the end point of lines
                                            //=0 means not draw the end point at all
        //LineEndPointIntensity	= 128;
        int ArcIntensity 		= 1;      //color/label_index of arcs
        //int ArcIntensity 		= 255;      //color/label_index of arcs
        int ArcThickness 		= 1;        //width of the arcs
        //ArcThickness 		= 2;
        int ArcEndPointIntensity	= 0;    //color/label_index of the end point of arcs
        //ArcEndPointIntensity	= 128;
        double MinLength  			= 5.0;  //minimum length of the displayed lines & arcs

        char[][] Image= new char[d.height][d.width];
        //Set image pixels to background value
        for (int i=0;i<d.height;i++) {
            for (int j=0;j<d.width;j++) {
                    Image[i][j] = (char) Background;
                }
        }

        return ort2image(Image, d,ID_ListORTLine,ID_ListORTCircularArc,
            OutPutStatus,Background,LineIntensity,LineThickness,LineEndPointIntensity,
            ArcIntensity,ArcThickness,ArcEndPointIntensity,MinLength);
    }

    public static char[][] ort2image(char[][] image, Dimension d, Vector ID_ListORTLine, Vector ID_ListORTCircularArc)
    {
        int OutPutStatus  		= -1;       //-1: output lines&arcs, 0: only lines, 1: only arcs
        int Background 			= 0;        //color/label_index of the background
        int LineIntensity 		= 1;      //color/label_index of lines
        int LineThickness 		= 1;        //width of the lines
        int LineEndPointIntensity	= 0;    //color/label_index of the end point of lines
                                            //=0 means not draw the end point at all
        int ArcIntensity 		= 1;      //color/label_index of arcs
        int ArcThickness 		= 1;        //width of the arcs
        int ArcEndPointIntensity	= 0;    //color/label_index of the end point of arcs
        double MinLength  			= 5.0;  //minimum length of the displayed lines & arcs
        return ort2image(image, d,ID_ListORTLine,ID_ListORTCircularArc,
            OutPutStatus,Background,LineIntensity,LineThickness,LineEndPointIntensity,
            ArcIntensity,ArcThickness,ArcEndPointIntensity,MinLength);
    }

    public static char[][] ort2image(char[][] image,
        double x0, double y0,
        int r,
        double t0, double t1,
        int ArcIntensity,
        int ArcThickness
        )
    {

        int YSize=image.length, XSize=image[0].length;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;

        int i,j;			/* Loop indecies */

        ORTCircularArc 	ListORTCircularArc;

        int RadiusSquared;

        double x1,x2,x3,x4,y1,y2,y3,y4;

        //shift the center to the image coordinate
        x4 = x0 + XCenter;
        y4 = y0 + YCenter;

        //begin point
        x1 = x4+r*Math.cos(t0);
        y1 = y4+r*Math.sin(t0);
        //end point
        x3 = x4+r*Math.cos(t1);
        y3 = y4+r*Math.sin(t1);

        RadiusSquared = (r*r);
        DrawCircularArc  ( ((int)Math.round(x1)),(int)Math.round(y1),
                                        ((int)Math.round(x3)),((int)Math.round(y3)),
                                        ((int)Math.round(x4)),((int)Math.round(y4)),
                                        1,    /* -1 clockwise 1 counterclockwise */
                                        RadiusSquared,
                                        ArcIntensity, ArcThickness-1, 0,
                                        XSize, YSize, image);

            return image;
    }

    public static char[][] ort2image(char[][] Image, Dimension d, Vector ID_ListORTLine, Vector ID_ListORTCircularArc,
        int OutPutStatus,
        int Background,
        int LineIntensity,
        int LineThickness,
        int LineEndPointIntensity,
        int ArcIntensity,
        int ArcThickness,
        int ArcEndPointIntensity,
        double MinLength
        )
    {

        int YSize=d.height, XSize=d.width;

        int i,j;			/* Loop indecies */

        /*
        Liste data
        */
        int  N_ListORTLine;
        ORTLine        	ListORTLine;

        int N_ListORTCircularArc;
        ORTCircularArc 	ListORTCircularArc;

        /*
        Other parameters
        */

        int CurveCounter;
        int RadiusSquared;

        double r1,r2,r3;

        double junkf,side;
        double x1,x2,x3,x4,y1,y2,y3,y4;
        double XCenter;
        double YCenter;

        char text;



        XCenter = ((double) (XSize))/2.0;
        YCenter = ((double) (YSize))/2.0;
        LineThickness--;
        ArcThickness--;



        if (ID_ListORTLine==null) ID_ListORTLine=new Vector();
        if (OutPutStatus == -1 || OutPutStatus == 0) {
            N_ListORTLine= ID_ListORTLine.size();
            for (i=0 ; i<N_ListORTLine; i++ ) {
                ListORTLine = (ORTLine)( ID_ListORTLine.elementAt(i));
                if (ListORTLine.Length<MinLength) continue;
                DrawBezierLine ( (int)Math.round (ListORTLine.Start.Col + XCenter),
                    (int)Math.round (ListORTLine.Start.Row + YCenter),
                    (int)Math.round (ListORTLine.End.Col   + XCenter),
                    (int)Math.round (ListORTLine.End.Row   + YCenter),
                    LineIntensity++, LineThickness, LineEndPointIntensity,
                                XSize, YSize, Image);
            }

        } /* endif OutPutStatus */

        if (ID_ListORTCircularArc==null) ID_ListORTCircularArc=new Vector();
        if (OutPutStatus == -1 || OutPutStatus == 1) {
            //Read the ORT Curve data and draw the Curve on the image
            N_ListORTCircularArc= ID_ListORTCircularArc.size();
            for (i=0 ; i<N_ListORTCircularArc; i++ ) {
                ListORTCircularArc = (ORTCircularArc)ID_ListORTCircularArc.elementAt(i);
                if ( ListORTCircularArc.Length >= MinLength) {
                    x1 = ( ListORTCircularArc.Start.Col    + XCenter);
                    y1 = ( ListORTCircularArc.Start.Row    + YCenter);
                    x2 = ( ListORTCircularArc.MidPoint.Col + XCenter);
                    y2 = ( ListORTCircularArc.MidPoint.Row + YCenter);
                    x3 = ( ListORTCircularArc.End.Col      + XCenter);
                    y3 = ( ListORTCircularArc.End.Row      + YCenter);
                    x4 = ( ListORTCircularArc.Origin.Col   + XCenter);
                    y4 = ( ListORTCircularArc.Origin.Row   + YCenter);

                    RadiusSquared = (int)Math.round (ListORTCircularArc.Radius *  ListORTCircularArc.Radius);
                    DrawCircularArc  ( ((int)Math.round(x1)),(int)Math.round(y1),
                                        ((int)Math.round(x3)),((int)Math.round(y3)),
                                        ((int)Math.round(x4)),((int)Math.round(y4)),
                                        ListORTCircularArc.Direction,    /* -1 clockwise 1 counterclockwise */
                                        RadiusSquared,
                                        ArcIntensity++, ArcThickness, ArcEndPointIntensity,
                                        XSize, YSize, Image);

                }

            }

        } /* endif OutPutStatus */

            return Image;
    }

    /**
    /* draw the line from (x1,y1)->(x2,y2)
    /* @param LineIntensity: the gray_intensity / color_index of the line
    /* @param LineThickness: thickness (width) of the line
    /*              =0 means only the single line, =1 means 3 pixels width
    /* @param EndPointIntensity: the gray_intensity / color_index of the end point of the line
    /*              =0 means not draw the end points
    */
    static int DrawBezierLine ( int x1, int y1, int x2, int y2,
                        int LineIntensity, int LineThickness,
                        int EndPointIntensity,
                        int xsize, int ysize, char[][] Image)
    {
            int temp, deltax, deltay, xincrement, yincrement, e, a, b, i;
        int k,l;

        //draw a small block for the end points of the line
        if (EndPointIntensity>0) {
            for(k =(x1-1); k<=(x1+1); k++){
                for(l =(y1-1); l<=(y1+1); l++){
                    if (l < ysize && k < xsize && l >= 0 && k >= 0) {
                        //Image[l][k] = (char)(EndPointIntensity & 0377);
                        Image[l][k] = (char)(EndPointIntensity );
                    }
                }
            }

            for(k =(x2-1); k<=(x2+1); k++){
                for(l =(y2-1); l<=(y2+1); l++){
                    if (l < ysize && k < xsize && l >= 0 && k >= 0) {
                        //Image[l][k] = (char)(EndPointIntensity & 0377);
                        Image[l][k] = (char)(EndPointIntensity);
                    }
                }
            }
        }

        if (Math.abs(x2-x1) > Math.abs(y2-y1)) {
            if (x1 > x2) {
                temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }
            deltax = x2 - x1;
            deltay = Math.abs (y2 - y1);
            e = (2 * deltay) - deltax;
            a = (2 * deltay) - (2 * deltax);
            b = (2 * deltay);
            if (y2 > y1) {
                    yincrement = 1;
            } else {
                    yincrement = -1;
            }
            for (i= 0;i<=deltax;i++) {

//                if ((x1>=0) && (x1<xsize) && (y1>=0) && (y1<ysize)) {
                    for(k =(x1-LineThickness); k<=(x1+LineThickness); k++){
                        for(l =(y1-LineThickness); l<=(y1+LineThickness); l++){
                            if (l >= 0 && l < ysize && k >= 0 && k < xsize)
                                //Image[l][k] = (char)(LineIntensity & 0377);
                                Image[l][k] = (char)(LineIntensity);
                        }
                    }
//                }
                if (e > 0) {
                    y1 = y1 + yincrement;
                    e = e + a;
                } else {
                    e = e + b;
                }
                x1 = x1 + 1;
            }
        }
        else {
            if (y1 > y2) {
                temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }
            deltay = y2 - y1;
            deltax = Math.abs(x2 - x1);
            e = (2 * deltax) - deltay;
            a = (2 * deltax) - (2 * deltay);
            b = (2 * deltax);
            if (x2 > x1) {
                    xincrement = 1;
            } else {
                    xincrement = -1;
            }
            for (i= 0;i<=deltay;i++) {
//                if ((x1>0) && (x1<xsize) && (y1>0) && (y1<ysize)) {
                        for(k =(x1-LineThickness); k<=(x1+LineThickness); k++){
                        for(l =(y1-LineThickness); l<=(y1+LineThickness); l++){
                            if (l >= 0 && l < ysize && k >= 0 && k < xsize)
                                        //Image[l][k] = (char)(LineIntensity & 0377);
                                        Image[l][k] = (char)(LineIntensity);
                        }
//                        }
                }
                if (e > 0) {
                    x1 = x1 + xincrement;
                    e = e + a;
                } else {
                    e = e + b;
                }
                    y1 = y1 + 1;
            }
        }
        return(0);
    }

    static void DrawCircularArc (int  x2,int y2, int x1,int y1, int x0,int y0, int dir, int rsq,
                            int ArcIntensity, int ArcThickness,
                            int EndPointIntensity,
                            int xsize, int ysize, char[][] Image)

    /* procedure for drawing arc of a circle
    x0,y0 : circle centre
    x1,y1 : start point of arc
    x2,y2 : end point of arc
    rsq   : radius squared
    source of algorithm is the optimal integer lattice formulation in
    McIllroy paper on circle drawing  ACM Trans on Graphics, Vol 2, No 4,
    October 1983. pp 237-263
    */

    {
        int e,ex,ey,exy,dxe,dye,d2e,dx,dy,xpoint,ypoint;
        int dr;
        boolean done;
        int end_of_arc;
        int k,l;

        //draw the endpoints
        if (EndPointIntensity>0) {
            for(k =(x1-2); k<=(x1+2); k++){
                for(l =(y1-2); l<=(y1+2); l++){
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                        Image[l][k] = (char)(EndPointIntensity & 0377);
                }
            }

            for(k =(x2-2); k<=(x2+2); k++){
                for(l =(y2-2); l<=(y2+2); l++){
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                        Image[l][k] = (char)(EndPointIntensity & 0377);
                }
            }
        }

        x1 = x1 - x0; y1 = y1 - y0;
        e = x1*x1 + y1*y1 - rsq ;
        dr = -sgn(e) ;

        done = false;
        while (done != true) {
            if (Math.abs(y1) > Math.abs(x1)) {
                dx = 0 ;
                dy = sgn(y1)*dr;
            } else {
                if (x1 != 0) {
                    dx = sgn(x1)*dr ;
                    dy = 0 ;
                } else {
                    dx = 1 ;
                    dy = 0 ;
                }
            }

            exy = e + 2*(x1*dx + y1*dy) + 1 ;
            done = (Math.abs(exy) > Math.abs(e)) ;

            if (done == false) {
                x1 = x1 + dx ;
                y1 = y1 + dy ;
                e = exy ;
            }
        }

        x2 = x2 - x0 ; y2 = y2 - y0 ;
        e = x2*x2 + y2*y2 - rsq ;
        dr = -sgn(e) ;
        done = false;
        while (done != true) {
            if (Math.abs(y2) > Math.abs(x2)) {
                dx = 0 ;
                dy = sgn(y2)*dr;
            } else {
                if (x2 != 0) {
                    dx = sgn(x2)*dr ;
                    dy = 0 ;
                } else {
                    dx = 1 ;
                    dy = 0 ;
                }
            }

            exy = e + 2*(x2*dx + y2*dy) + 1 ;
            done = (Math.abs(exy) > Math.abs(e)) ;

            if (done == false) {
                x2 = x2 + dx ;
                y2 = y2 + dy ;
                e = exy ;
            }
        }

        dx = sgn2(-y1*dir,-x1) ;
        dy = sgn2(x1*dir,-y1) ;
        e = x1*x1 + y1*y1 - rsq ;
        dxe = 2*x1*dx ;
        dye = 2*y1*dy ;
        d2e = 2 ;

        if (dx*dy*dir > 0 ) {
            e = -e ;
            dxe = - dxe ;
            dye = - dye ;
            d2e = - d2e ;
        }

        end_of_arc = 0 ;
        while (end_of_arc != 1) {

            xpoint = x0 + x1 ;
            ypoint = y0 + y1 ;
//            if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
                for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                    for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                        if (k >=0 && l >=0 && k < xsize && l < ysize)
                            Image[l][k] = (char)(ArcIntensity & 0377);
                            }
                        }
//            }

            ex = e + dxe ;
            ey = e + dye ;
            exy = e + dxe + dye ;

            if  (-exy < ey) {
                x1 = x1 + dx ;
                e = e + dxe ;
                dxe = dxe + d2e ;
            }

            if (exy < -ex) {
                y1 = y1 + dy ;
                e = e + dye ;
                dye = dye + d2e ;
            }

            if (x1 == 0) {
                dy = -dy ;
                dye = -dye + d2e ;
                e = -e ;
                dxe = - dxe ;
                dye = - dye ;
                d2e = - d2e ;
            }

            if (y1 == 0) {
                dx = -dx ;
                dxe = -dxe + d2e ;
                e = -e ;
                dxe = - dxe ;
                dye = - dye ;
                d2e = - d2e ;
            }
            if ( Math.abs(x1-x2) <= 1 && Math.abs(y1-y2) <= 1)
                end_of_arc = 1;
        }

        //draw the last point next to the end point of the arc
        xpoint = x0 + x1 ;
        ypoint = y0 + y1 ;
//        if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
            for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                    Image[l][k] = (char)(ArcIntensity & 0377);
                }
            }
//        }
        //draw the end point of the arc
        xpoint = x0 + x2 ;
        ypoint = y0 + y2 ;
//        if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
            for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                    Image[l][k] = (char)(ArcIntensity & 0377);
                }
            }
//        }

    }

    static int sgn2( int x,int y )
    {
        if (x != 0) {
            return(sgn(x));
        } else {
            return(sgn(y));
        }

    }

    static int sgn(int x )
    {
        if (x <  0) return(-1) ;
        if (x == 0) return( 0) ;
        if (x >  0) return( 1) ;
        return (0);

    }

    static void drawMark(char[][] img, Dimension d, int cx, int cy, int w, int c)
    {
        int YSize=img.length, XSize=img[0].length;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;
        cx+= XCenter; cy+= YCenter;

        for (int y=cy-w/2;y<=cy-w/2+w;y++) {
            if (y<0||y>=d.height) continue;
            for (int x=cx-w/2;x<=cx-w/2+w;x++) {
                if (x<0||x>=d.width) continue;
                img[y][x]=(char)c;
            }
        }
    }

    //draw a rectangel mark on the image
    //(cx,cy) is the coordinate, w is the width of the mark, c is the color
    public static void drawMark(int[] img, Dimension d, int cx, int cy, int w, int c)
    {
        int YSize=d.height, XSize=d.width;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;
        cx+= XCenter; cy+= YCenter;


        for (int y=cy-w/2;y<=cy-w/2+w;y++) {
            if (y<0||y>=d.height) continue;
            for (int x=cx-w/2;x<=cx-w/2+w;x++) {
                if (x<0||x>=d.width) continue;
                img[y*d.width+x]=c;
            }
        }
    }

    static int DrawBezierLine ( int x1, int y1, int x2, int y2,
                        int LineIntensity, int LineThickness,
                        int EndPointIntensity,
                        int xsize, int ysize, int[] Image, Dimension d)
    {
            int temp, deltax, deltay, xincrement, yincrement, e, a, b, i;
        int k,l;
        int width=d.width, height=d.height;

        //draw a small block for the end points of the line
        if (EndPointIntensity>0) {
            for(k =(x1-1); k<=(x1+1); k++){
                for(l =(y1-1); l<=(y1+1); l++){
                    if (l < ysize && k < xsize && l >= 0 && k >= 0) {
                        //Image[l][k] = (char)(EndPointIntensity & 0377);
                        Image[l*width+k] = (EndPointIntensity );
                    }
                }
            }

            for(k =(x2-1); k<=(x2+1); k++){
                for(l =(y2-1); l<=(y2+1); l++){
                    if (l < ysize && k < xsize && l >= 0 && k >= 0) {
                        //Image[l][k] = (char)(EndPointIntensity & 0377);
                        Image[l*width+k] = (EndPointIntensity);
                    }
                }
            }
        }

        if (Math.abs(x2-x1) > Math.abs(y2-y1)) {
            if (x1 > x2) {
                temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }
            deltax = x2 - x1;
            deltay = Math.abs (y2 - y1);
            e = (2 * deltay) - deltax;
            a = (2 * deltay) - (2 * deltax);
            b = (2 * deltay);
            if (y2 > y1) {
                    yincrement = 1;
            } else {
                    yincrement = -1;
            }
            for (i= 0;i<=deltax;i++) {

//                if ((x1>0) && (x1<xsize) && (y1>0) && (y1<ysize)) {
                    for(k =(x1-LineThickness); k<=(x1+LineThickness); k++){
                        for(l =(y1-LineThickness); l<=(y1+LineThickness); l++){
                            if (l >= 0 && l < ysize && k >= 0 && k < xsize)
                                //Image[l][k] = (char)(LineIntensity & 0377);
                                Image[l*width+k] = (LineIntensity);
                        }
                    }
//                }
                if (e > 0) {
                    y1 = y1 + yincrement;
                    e = e + a;
                } else {
                    e = e + b;
                }
                x1 = x1 + 1;
            }
        }
        else {
            if (y1 > y2) {
                temp = x1; x1 = x2; x2 = temp;
                temp = y1; y1 = y2; y2 = temp;
            }
            deltay = y2 - y1;
            deltax = Math.abs(x2 - x1);
            e = (2 * deltax) - deltay;
            a = (2 * deltax) - (2 * deltay);
            b = (2 * deltax);
            if (x2 > x1) {
                    xincrement = 1;
            } else {
                    xincrement = -1;
            }
            for (i= 0;i<=deltay;i++) {
//                if ((x1>0) && (x1<xsize) && (y1>0) && (y1<ysize)) {
                    for(k =(x1-LineThickness); k<=(x1+LineThickness); k++){
                        for(l =(y1-LineThickness); l<=(y1+LineThickness); l++){
                            if (l>=0&&l<ysize&&k>=0&&k<xsize)
                                        //Image[l][k] = (char)(LineIntensity & 0377);
                                        Image[l*width+k] = (LineIntensity);
                        }
                    }
//                }
                if (e > 0) {
                    x1 = x1 + xincrement;
                    e = e + a;
                } else {
                    e = e + b;
                }
                    y1 = y1 + 1;
            }
        }
        return(0);
    }

    public static void ort2image(int[] image, Dimension d, ORTLine l, int intensity, int thickness)
    {
        int YSize=d.height, XSize=d.width;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;

        DrawBezierLine (
            (int)Math.round (l.Start.Col + XCenter),
            (int)Math.round (l.Start.Row + YCenter),
            (int)Math.round (l.End.Col   + XCenter),
            (int)Math.round (l.End.Row   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image, d);
    }

    public static void ort2image(int[] image, Dimension d, double x1, double y1, double x2, double y2, int intensity, int thickness)
    {
      DrawBezierLine (
          (int)Math.round (x1),
          (int)Math.round (y1),
          (int)Math.round (x2),
          (int)Math.round (y2),
          intensity, thickness-1, 0,
          d.width, d.height, image, d);
    }

    public static void drawRectangle(int[] image, Dimension d, double x1, double y1, double x2, double y2,
            int intensity, int thickness)
    {
        int YSize=d.height, XSize=d.width;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;

        DrawBezierLine (
            (int)Math.round (x1 + XCenter),
            (int)Math.round (y1 + YCenter),
            (int)Math.round (x1   + XCenter),
            (int)Math.round (y2   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image, d);
        DrawBezierLine (
            (int)Math.round (x1 + XCenter),
            (int)Math.round (y2 + YCenter),
            (int)Math.round (x2   + XCenter),
            (int)Math.round (y2   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image, d);
        DrawBezierLine (
            (int)Math.round (x2 + XCenter),
            (int)Math.round (y1 + YCenter),
            (int)Math.round (x2   + XCenter),
            (int)Math.round (y2   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image, d);
        DrawBezierLine (
            (int)Math.round (x1 + XCenter),
            (int)Math.round (y1 + YCenter),
            (int)Math.round (x2   + XCenter),
            (int)Math.round (y1   + YCenter),
            intensity, thickness-1, 0,
            XSize, YSize, image, d);
    }

    static void DrawCircularArc (int  x2,int y2, int x1,int y1, int x0,int y0, int dir, int rsq,
                            int ArcIntensity, int ArcThickness,
                            int EndPointIntensity,
                            int xsize, int ysize, int[] Image, Dimension d)

    /* procedure for drawing arc of a circle
    x0,y0 : circle centre
    x1,y1 : start point of arc
    x2,y2 : end point of arc
    rsq   : radius squared
    source of algorithm is the optimal integer lattice formulation in
    McIllroy paper on circle drawing  ACM Trans on Graphics, Vol 2, No 4,
    October 1983. pp 237-263
    */

    {
        int e,ex,ey,exy,dxe,dye,d2e,dx,dy,xpoint,ypoint;
        int dr;
        boolean done;
        int end_of_arc;
        int k,l;
        int width=d.width, height=d.height;

        //draw the endpoints
        if (EndPointIntensity>0) {
            for(k =(x1-2); k<=(x1+2); k++){
                for(l =(y1-2); l<=(y1+2); l++){
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                        Image[l*width+k] = (EndPointIntensity);
                }
            }

            for(k =(x2-2); k<=(x2+2); k++){
                for(l =(y2-2); l<=(y2+2); l++){
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                        Image[l*width+k] = (EndPointIntensity);
                }
            }
        }

        x1 = x1 - x0; y1 = y1 - y0;
        e = x1*x1 + y1*y1 - rsq ;
        dr = -sgn(e) ;

        done = false;
        while (done != true) {
            if (Math.abs(y1) > Math.abs(x1)) {
                dx = 0 ;
                dy = sgn(y1)*dr;
            } else {
                if (x1 != 0) {
                    dx = sgn(x1)*dr ;
                    dy = 0 ;
                } else {
                    dx = 1 ;
                    dy = 0 ;
                }
            }

            exy = e + 2*(x1*dx + y1*dy) + 1 ;
            done = (Math.abs(exy) > Math.abs(e)) ;

            if (done == false) {
                x1 = x1 + dx ;
                y1 = y1 + dy ;
                e = exy ;
            }
        }

        x2 = x2 - x0 ; y2 = y2 - y0 ;
        e = x2*x2 + y2*y2 - rsq ;
        dr = -sgn(e) ;
        done = false;
        while (done != true) {
            if (Math.abs(y2) > Math.abs(x2)) {
                dx = 0 ;
                dy = sgn(y2)*dr;
            } else {
                if (x2 != 0) {
                    dx = sgn(x2)*dr ;
                    dy = 0 ;
                } else {
                    dx = 1 ;
                    dy = 0 ;
                }
            }

            exy = e + 2*(x2*dx + y2*dy) + 1 ;
            done = (Math.abs(exy) > Math.abs(e)) ;

            if (done == false) {
                x2 = x2 + dx ;
                y2 = y2 + dy ;
                e = exy ;
            }
        }

        dx = sgn2(-y1*dir,-x1) ;
        dy = sgn2(x1*dir,-y1) ;
        e = x1*x1 + y1*y1 - rsq ;
        dxe = 2*x1*dx ;
        dye = 2*y1*dy ;
        d2e = 2 ;

        if (dx*dy*dir > 0 ) {
            e = -e ;
            dxe = - dxe ;
            dye = - dye ;
            d2e = - d2e ;
        }

        end_of_arc = 0 ;
        while (end_of_arc != 1) {

            xpoint = x0 + x1 ;
            ypoint = y0 + y1 ;
//            if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
                for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                    for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                        if (k >=0 && l >=0 && k < xsize && l < ysize)
                            Image[l*width+k] = (ArcIntensity);
                    }
                }
//            }

            ex = e + dxe ;
            ey = e + dye ;
            exy = e + dxe + dye ;

            if  (-exy < ey) {
                x1 = x1 + dx ;
                e = e + dxe ;
                dxe = dxe + d2e ;
            }

            if (exy < -ex) {
                y1 = y1 + dy ;
                e = e + dye ;
                dye = dye + d2e ;
            }

            if (x1 == 0) {
                dy = -dy ;
                dye = -dye + d2e ;
                e = -e ;
                dxe = - dxe ;
                dye = - dye ;
                d2e = - d2e ;
            }

            if (y1 == 0) {
                dx = -dx ;
                dxe = -dxe + d2e ;
                e = -e ;
                dxe = - dxe ;
                dye = - dye ;
                d2e = - d2e ;
            }
            if ( Math.abs(x1-x2) <= 1 && Math.abs(y1-y2) <= 1)
                end_of_arc = 1;
        }

        //draw the last point next to the end point of the arc
        xpoint = x0 + x1 ;
        ypoint = y0 + y1 ;
//        if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
            for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                    Image[l*width+k] = (ArcIntensity);
                }
            }
//        }
        //draw the end point of the arc
        xpoint = x0 + x2 ;
        ypoint = y0 + y2 ;
//        if ( (xpoint>=0) && (xpoint<xsize) && (ypoint>=0) && (ypoint<ysize) ) {
            for (k=(xpoint-ArcThickness);k<=(xpoint+ArcThickness);k++) {
                for (l=(ypoint-ArcThickness);l<=(ypoint+ArcThickness);l++) {
                    if (k >=0 && l >=0 && k < xsize && l < ysize)
                    Image[l*width+k] = (ArcIntensity);
                }
            }
//        }

    }

    public static void ort2image(int[] image, Dimension d,
        double x0, double y0,
        int r,
        double t0, double t1,
        int ArcIntensity,
        int ArcThickness
        )
    {

        int YSize=d.height, XSize=d.width;
        double XCenter = ((double) (XSize))/2.0;
        double YCenter = ((double) (YSize))/2.0;

        int i,j;			/* Loop indecies */

        ORTCircularArc 	ListORTCircularArc;

        int RadiusSquared;

        double x1,x2,x3,x4,y1,y2,y3,y4;

        //shift the center to the image coordinate
        x4 = x0 + XCenter;
        y4 = y0 + YCenter;

        //begin point
        x1 = x4+r*Math.cos(t0);
        y1 = y4+r*Math.sin(t0);
        //end point
        x3 = x4+r*Math.cos(t1);
        y3 = y4+r*Math.sin(t1);

        RadiusSquared = (r*r);
        DrawCircularArc  ( ((int)Math.round(x1)),(int)Math.round(y1),
                                        ((int)Math.round(x3)),((int)Math.round(y3)),
                                        ((int)Math.round(x4)),((int)Math.round(y4)),
                                        1,    /* -1 clockwise 1 counterclockwise */
                                        RadiusSquared,
                                        ArcIntensity, ArcThickness-1, 0,
                                        XSize, YSize, image, d);

    }


}