/*
 *    Ygl: Run 2d-GL programs with standard X11 routines.
 *    (C) Fred Hucht 1993-95
 *    EMail: fred@thp.Uni-Duisburg.DE
 */

#include "header.h"

#define DWGC D,W->draw,W->gc
#define Coo Coord
#define Ico Icoord
#define Sco Scoord

/* Drawing */
void clear(void) { I("clear"); XFillRectangle(DWGC, 0, 0, W->xm, W->ym); F;}

/* Points */
void pnt2  (Coo x, Coo y) { I("pnt2" ); if(W->pm) XFillRectangle(DWGC, XS(x), YS(y), 1, 1);else XDrawPoint(DWGC, XS(x), YS(y)); F;}
void pnt2i (Ico x, Ico y) { I("pnt2i"); if(W->pm) XFillRectangle(DWGC, XS(x), YS(y), 1, 1);else XDrawPoint(DWGC, XS(x), YS(y)); F;}
void pnt2s (Sco x, Sco y) { I("pnt2s"); if(W->pm) XFillRectangle(DWGC, XS(x), YS(y), 1, 1);else XDrawPoint(DWGC, XS(x), YS(y)); F;}

/* Lines */
void move2 (Coo x, Coo y) { SCP( =x, =y);}
void move2i(Ico x, Ico y) { SCP( =x, =y);}
void move2s(Sco x, Sco y) { SCP( =x, =y);}

void rmv2  (Coo x, Coo y) { SCP(+=x,+=y);}
void rmv2i (Ico x, Ico y) { SCP(+=x,+=y);}
void rmv2s (Sco x, Sco y) { SCP(+=x,+=y);}

void draw2 (Coo x, Coo y) { I("draw2" ); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(x), Y(y)); SCP( =x, =y); F;}
void draw2i(Ico x, Ico y) { I("draw2i"); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(x), Y(y)); SCP( =x, =y); F;}
void draw2s(Sco x, Sco y) { I("draw2s"); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(x), Y(y)); SCP( =x, =y); F;}

void rdr2  (Coo x, Coo y) { I("rdr2" ); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(W->xp+x), Y(W->yp+y)); SCP(+=x,+=y); F;}
void rdr2i (Ico x, Ico y) { I("rdr2i"); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(W->xp+x), Y(W->yp+y)); SCP(+=x,+=y); F;}
void rdr2s (Sco x, Sco y) { I("rdr2s"); XDrawLine(DWGC, X(W->xp), Y(W->yp), X(W->xp+x), Y(W->yp+y)); SCP(+=x,+=y); F;}

/* Arcs & Circles */
void arc   (Coo x, Coo y, Coo r, Angle s, Angle e) { I("arc" ); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}
void arci  (Ico x, Ico y, Ico r, Angle s, Angle e) { I("arci"); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}
void arcs  (Sco x, Sco y, Sco r, Angle s, Angle e) { I("arcs"); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}

void arcf  (Coo x, Coo y, Coo r, Angle s, Angle e) { I("arcf" ); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}
void arcfi (Ico x, Ico y, Ico r, Angle s, Angle e) { I("arcfi"); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}
void arcfs (Sco x, Sco y, Sco r, Angle s, Angle e) { I("arcfs"); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), (64*s)/10, (64*(e-s))/10); F;}

void circ  (Coo x, Coo y, Coo r)                   { I("circ" ); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}
void circi (Ico x, Ico y, Ico r)                   { I("circi"); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}
void circs (Sco x, Sco y, Sco r)                   { I("circs"); r=MAX(0,r); XDrawArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}

void circf (Coo x, Coo y, Coo r)                   { I("circf" ); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}
void circfi(Ico x, Ico y, Ico r)                   { I("circfi"); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}
void circfs(Sco x, Sco y, Sco r)                   { I("circfs"); r=MAX(0,r); XFillArc(DWGC, X(x-r), Y(y+r), XR(2*r), YR(2*r), 0, 64*360); F;}

/* Rects & Boxes */
void rect  (Coo x1, Coo y1, Coo x2, Coo y2) { I("rect" ); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}
void sbox  (Coo x1, Coo y1, Coo x2, Coo y2) { I("sbox" ); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}
void recti (Ico x1, Ico y1, Ico x2, Ico y2) { I("recti"); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}
void sboxi (Ico x1, Ico y1, Ico x2, Ico y2) { I("sboxi"); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}
void rects (Sco x1, Sco y1, Sco x2, Sco y2) { I("rects"); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}
void sboxs (Sco x1, Sco y1, Sco x2, Sco y2) { I("sboxs"); XDrawRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), XR(ABS(x2-x1)), YR(ABS(y2-y1))); F;}

void rectf (Coo x1, Coo y1, Coo x2, Coo y2) { I("rectf" ); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}
void sboxf (Coo x1, Coo y1, Coo x2, Coo y2) { I("sboxf" ); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}
void rectfi(Ico x1, Ico y1, Ico x2, Ico y2) { I("rectfi"); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}
void sboxfi(Ico x1, Ico y1, Ico x2, Ico y2) { I("sboxfi"); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}
void rectfs(Sco x1, Sco y1, Sco x2, Sco y2) { I("rectfs"); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}
void sboxfs(Sco x1, Sco y1, Sco x2, Sco y2) { I("sboxfs"); XFillRectangle(DWGC, X(MIN(x1,x2)), Y(MAX(y1,y2)), 1+XR(ABS(x2-x1)), 1+YR(ABS(y2-y1))); F;}

/* Filled Polygons */
static XPoint P[256];
static int    L;
static Int32  PMode = Convex;

void concave(Int32 bool) { PMode = bool ? Complex : Convex;}

void  pmv2 (Coo x, Coo y) { L=0; P[0].x = XS(x); P[0].y = YS(y);}
void  pmv2i(Ico x, Ico y) { L=0; P[0].x = XS(x); P[0].y = YS(y);}
void  pmv2s(Sco x, Sco y) { L=0; P[0].x = XS(x); P[0].y = YS(y);}

void  pdr2 (Coo x, Coo y) { L++; P[L].x = X(x);  P[L].y = Y(y);}
void  pdr2i(Ico x, Ico y) { L++; P[L].x = X(x);  P[L].y = Y(y);}
void  pdr2s(Sco x, Sco y) { L++; P[L].x = X(x);  P[L].y = Y(y);}

void rpdr2 (Coo x, Coo y) { L++; P[L].x = P[L-1].x + XR(x); P[L].y = P[L-1].y - YR(y);}
void rpdr2i(Ico x, Ico y) { L++; P[L].x = P[L-1].x + XR(x); P[L].y = P[L-1].y - YR(y);}
void rpdr2s(Sco x, Sco y) { L++; P[L].x = P[L-1].x + XR(x); P[L].y = P[L-1].y - YR(y);}

void pclos(void) { L++; I("pclos"); XFillPolygon(DWGC, P, L, PMode, CoordModeOrigin); F;}

#define MKP(n, p) { Int32 i;for(i = 0; i < n; i++) {P[i].x = X(p[i][0]);P[i].y = Y(p[i][1]);}}

void poly2 (Int32 n, Coo p[][2]) { I("poly2" ); MKP(n, p); P[n].x = XS(p[0][0]); P[n].y = YS(p[0][1]); XDrawLines(DWGC, P, n+1, CoordModeOrigin); F;}
void poly2i(Int32 n, Ico p[][2]) { I("poly2i"); MKP(n, p); P[n].x = XS(p[0][0]); P[n].y = YS(p[0][1]); XDrawLines(DWGC, P, n+1, CoordModeOrigin); F;}
void poly2s(Int32 n, Sco p[][2]) { I("poly2s"); MKP(n, p); P[n].x = XS(p[0][0]); P[n].y = YS(p[0][1]); XDrawLines(DWGC, P, n+1, CoordModeOrigin); F;}

void polf2 (Int32 n, Coo p[][2]) { I("polf2" ); MKP(n, p); SCP(=p[0][0],=p[0][1]); XFillPolygon(DWGC, P, n, PMode, CoordModeOrigin); F;}
void polf2i(Int32 n, Ico p[][2]) { I("polf2i"); MKP(n, p); SCP(=p[0][0],=p[0][1]); XFillPolygon(DWGC, P, n, PMode, CoordModeOrigin); F;}
void polf2s(Int32 n, Sco p[][2]) { I("polf2s"); MKP(n, p); SCP(=p[0][0],=p[0][1]); XFillPolygon(DWGC, P, n, PMode, CoordModeOrigin); F;}

/* Text */
void cmov2 (Coo x, Coo y) { W->xc = x; W->yc = y;}
void cmov2s(Sco x, Sco y) { W->xc = x; W->yc = y;}
void cmov2i(Ico x, Ico y) { W->xc = x; W->yc = y;}

void getcpos(Screencoord *x, Screencoord *y) {
  Int32 xo, yo;
  I("getcpos");
  getorigin(&xo, &yo);  
  *x = xo + X(W->xc);
  *y = yo + W->ym - Y(W->yc);
#ifdef DEBUG
  fprintf(stderr, "getcpos: *x = %d, *y = %d\n", *x, *y);
#endif
}

/* Extensions: Routines from X not in gl. Contributed by MiSt (michael@hal6000.thp.Uni-Duisburg.DE) */

void arcx  (Coo x,Coo y,Coo rx,Coo ry,Angle s,Angle e) { I("arcx" ); XDrawArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}
void arcxi (Ico x,Ico y,Ico rx,Ico ry,Angle s,Angle e) { I("arcxi"); XDrawArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}
void arcxs (Sco x,Sco y,Sco rx,Sco ry,Angle s,Angle e) { I("arcxs"); XDrawArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}

void arcxf (Coo x,Coo y,Coo rx,Coo ry,Angle s,Angle e) { I("arcxf" ); XFillArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}
void arcxfi(Ico x,Ico y,Ico rx,Ico ry,Angle s,Angle e) { I("arcxfi"); XFillArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}
void arcxfs(Sco x,Sco y,Sco rx,Sco ry,Angle s,Angle e) { I("arcxfs"); XFillArc(DWGC, X(x-rx), Y(y+ry), XR(2*MAX(0,rx)), YR(2*MAX(0,ry)), (64*s)/10, (64*(e-s))/10); F;}
