#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#include "vis.h"

typedef Ppoint_t point;
typedef Ppoly_t poly;

#define PS
void print (vconfig_t *cp)
{
    int i, j;
    int *next, *prev;
    point *pts;
    array2 arr;

    next = cp->next;
    prev = cp->prev;
    pts = cp->P;
    arr = cp->vis;

    printf ("this next prev point\n");
    for (i = 0; i < cp->N; i++)
      printf ("%3d  %3d  %3d    (%3g,%3g)\n", i, next[i],prev[i],
        pts[i].x, pts[i].y);

    printf ("\n\n");

    for (i = 0; i < cp->N; i++) {
      for (j = 0; j < cp->N; j++)
        printf ("%4.1f ", arr[i][j]);
      printf ("\n");
    }

}

void printVis (char *lbl, COORD* vis, int n)
{
   int i;

   printf ("%s: ", lbl);
   for (i=0; i < n; i++)
     printf ("%4.1f ", vis[i]);
   printf ("\n");
}

void printDad (int* vis, int n)
{
   int i;

   printf ("     ");
   for (i=0; i < n; i++) {
     printf ("%3d ", i);
   }
   printf ("\n");
   printf ("dad: ");
   for (i=0; i < n; i++) {
     printf ("%3d ", vis[i]);
   }
   printf ("\n");
}

#define NUM_PTS 10000
point points[NUM_PTS];
int   nextpt[NUM_PTS];
poly polys[NUM_PTS];
int polycnt = 0;

vconfig_t* readInput ()
{
    int base = 0;
    int cnt = 0;
    COORD x, y;
    char* tok;
    char buf[1000];
    COORD minx, miny, maxx, maxy;
    
    while (gets (buf)) {
      tok = strtok (buf, " \t\n");
      if (!tok) continue;
      minx = miny = -MAXFLOAT;
      maxx = maxy = MAXFLOAT;
      do {
        x = atof (tok);
        tok = strtok (0, " \t\n");
        y = atof (tok);
        points[cnt].x = x;
        points[cnt].y = y;
        if (x < minx) minx = x;
        else if (x > maxx) maxx = x;
        if (y < miny) miny = y;
        else if (y > maxy) maxy = y;
        nextpt[cnt] = cnt+1;
        cnt++;
        tok = strtok (0, " \t\n");
      } while (tok);
      polys[polycnt].start = base;
      polys[polycnt].n = cnt - base;
      polys[polycnt].UR.x = maxx;
      polys[polycnt].UR.y = maxy;
      polys[polycnt].LL.x = minx;
      polys[polycnt].LL.y = miny;
      polycnt++;
      nextpt[cnt-1] = base;
      base = cnt;
    }

    conf.N = cnt;

    return &conf;
}

char* plog = "%%!PS-Adobe-2.0\n\n\
/Times-Roman findfont 14 scalefont setfont\n\
/lLabel {\n\
\tmoveto\n\
\tgsave\n\
\tshow\n\
\tgrestore\n\
} def\n\
/fillCircle {\n\
\t/r exch def\n\
\t/y exch def\n\
\t/x exch def\n\
\tnewpath\n\
\tx y r 0 360 arc\n\
\tfill\n\
} def\n";

char* elog = "showpage\n";

void initPS ()
{
  fprintf (stderr, plog);
}

void termPS ()
{
  fprintf (stderr, elog);
}

void polyPS (vconfig_t* confp, poly* pp, int polycnt)
{
  int i, j, endj;
  point *pts = confp->P;
  int N = confp->N;
  int *next = confp->next;
  point first;

  fprintf (stderr, "0 setlinewidth\n");
  for (i=0; i < polycnt; i++) {
    /* if (i == 1) */
      /* fprintf (stderr, "2 setlinewidth\n"); */
    /* else */
      /* fprintf (stderr, "0 setlinewidth\n"); */
    j = pp[i].start;
    endj = j + pp[i].n - 1;
    first =  pts[j];
    fprintf (stderr, "%f %f moveto\n", first.x, first.y);
    for (; j < endj; j++) {
      fprintf (stderr, "%f %f lineto\n", pts[next[j]].x, pts[next[j]].y);
    }
    fprintf (stderr, "%f %f lineto stroke\n", first.x, first.y);
    fprintf (stderr, "(%d) %f %f lLabel\n", i, first.x, first.y);

  }

}

void visPS (vconfig_t* confp)
{
  int i, j, endj;
  point *pts = confp->P;
  int N = confp->N;
  double** vis = confp->vis;
  int *next = confp->next;
  point first;

  fprintf (stderr, "1 0 0 setrgbcolor\n");
  for (i = 0; i < N-1; i++)
    for (j = i+1; j < N; j++)
      if (vis[i][j] != 0)
        fprintf (stderr, "%f %f moveto %f %f lineto stroke\n", 
          pts[i].x, pts[i].y, pts[j].x, pts[j].y);

  fprintf (stderr, "0 0 0 setrgbcolor\n");
}

void pathPS (vconfig_t* confp, point p, point q, int* dad)
{
  int i, j, endj;
  point *pts = confp->P;
  int N = confp->N;
  int *next = confp->next;
  point first;

  fprintf (stderr, "%f %f 2 fillCircle\n", p.x, p.y);
  fprintf (stderr, "%f %f 2 fillCircle\n", q.x, q.y);

  /* shortest path */
  fprintf (stderr, "%f %f moveto\n", q.x, q.y);
  for (i = N; ; ) {
    i = dad[i];
    if (i == N+1) break;
    fprintf (stderr, "%f %f lineto\n", pts[i].x, pts[i].y);
  }
  fprintf (stderr, "%f %f lineto stroke\n", p.x, p.y);
  
}

int
findRegion (vconfig_t* confp, poly* polys, int polycnt, point p)
{
   int i;

   for (i = 0; i < polycnt; i++)
     if (in_poly (confp,polys+i,p))
       return i;

   fprintf (stderr, "Point (%f,%f) not in any polygon\n", p.x, p.y);
   exit (1);
}

point p = {267,92};
point q = {299,92};

main ()
{
    int* dad;
    COORD* pvis;
    COORD* qvis;
    vconfig_t* confp;
    int preg, qreg;

    confp = readInput ();
    vis (confp);
    /* preg = findRegion (confp, polys, polycnt, p); */
    /* qreg = findRegion (confp, polys, polycnt, q); */
    pvis = ptVis (confp, 0, p);
    qvis = ptVis (confp, 0, q);
    dad = makePath (p, 0, pvis, q, 0, qvis, confp);

#ifdef PS
    initPS ();
    polyPS (confp, polys, polycnt);
    /* visPS (confp); */
    pathPS (confp, p, q, dad);
    termPS ();
#endif

/*
    print (confp);
    printVis ("p", pvis, confp->N+1);
    printVis ("q", qvis, confp->N+1);
    printDad (dad, confp->N+1);
*/
    exit (0);
}
