//
// toogltest.cpp
// Wes Huang
// January 29, 2001
//
// A simple test program that reads a single polygon from a file and
// displays it in a graphics window.  Uses the CGAL library point
// representation when it reads the polygon and then converts it to
// the TOOGL representation before displaying it.
//

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <list>
#include <string>

using namespace std;

// CGAL setup
#include <CGAL/Cartesian.h>
#include <CGAL/Point_2.h>
#include <CGAL/convex_hull_2.h>

// TOOGL setup
#include <canvas.h>

// some global variables to determine the coordinate transformation to
// the graphics window
//
float graphicsScale = 2.0; // multiply by world distance to get screen distance
int windowHeight=200;
int windowWidth=300;
// coordinates of the lower left hand corner of the window
float windowLLX = -50;
float windowLLY = -25;

typedef CGAL::Cartesian<float> ptRep;
typedef CGAL::Point_2<ptRep> Point_2;
typedef list<Point_2> ptList;


// maximum length for filenames and stuff
const int MAXLEN = 100;

// convert world coordinates to screen coordinates
// (and a CGAL Point_2 to a TOOGL Point)
Point worldToScreen(Point_2& p) 
{
	// first compute world coordinates w/r to the lower left hand
	// corner of the screen
	float x = p.x() - windowLLX;
	float y = p.y() - windowLLY;

	// note that the screen coordinate system has its origin in
	// the upper left hand corner and is left handed (x axis increases to
	// right and y axis increases downward)
	//
	// there could be some error checking here to see whether you
	// go off the screen, but TOOGL doesn't seem to mind...
	//
	return Point((int) (x*graphicsScale),
		     (int) (windowHeight - y*graphicsScale));
}
	

bool readPolygon(ifstream& inpFile, char** polygonName, ptList** p) 
{
  *p = new ptList();
  *polygonName = new char[MAXLEN];

  char lineBuffer[MAXLEN];
  char *tokenA;
  char *tokenB;

  //this works for the sample file... not very robust but it does the trick
  while (true) {
    inpFile.getline(lineBuffer, MAXLEN);
    if (inpFile.eof())
      return false;

    //we break up each line into 1 or 2 pieces
    //we look at the pieces to figure out what the line is doing
    float x=0,y=0;
    tokenA=strtok(lineBuffer," ");
    if(tokenA) {
      tokenB=strtok(NULL," ");
    } 
    if(!tokenA) {

    } else if(tokenA[0]=='#') {
      //comment
    } else if(tokenA[0]=='}') {
      //we are done with this object
      break;
    } else if(tokenB[0]=='{') {
      //get the name from tokenA
      strcpy(*polygonName,tokenA);
    } else {
      //get the x and y coordinates
      x=atoi(tokenA);
      y=atoi(tokenB);
      //push onto pointlist
      (**p).push_back(Point_2(x,y));
    }
  }

  cout << "The polygon "<< *polygonName <<" has the points:\n";
  for (ptList::iterator k = (**p).begin(); k != (**p).end(); k++) {
    cout << "  (" << (*k).x() << ", " << (*k).y() << ")\n";
  }
  return true;
}


void drawPolygon(Canvas& c, ptList& pts)
{
	// first convert the CGAL list of points to a tvector of Points
	tvector<Point> p;

	for (ptList::iterator k = pts.begin(); k != pts.end(); k++) {
		p.push_back( worldToScreen((*k)));
	}

	c.SetFrame();
	c.SetColor(CanvasColor::GREEN);
	c.SetFilled();
	c.DrawPolygon( p, pts.size());
	
	// wait until the user presses escape
	c.runUntilEscape();
}

int main(int argc, char* argv[])
{
  char fName[MAXLEN];

  cout << "Enter the polygon filename\n";
  cin.getline(fName,MAXLEN);
  cout << "Reading the polygon from the file " << fName << "\n";

  // I don't think this error checking works...
  ifstream infile(fName);
  if (infile == NULL) {
    cout << "Error opening the polygon file: " << fName << "\n";
    exit(-1);
  }

  char* polygonName;
  ptList *pts;
  if (!readPolygon( infile, &polygonName, &pts)) {
	cout << "Error reading the polygon from the file: " << fName << "\n";
	exit(-1);
  }

  // Create the window (?)
  Canvas c(300, 200, 100, 100);

  drawPolygon(c, *pts);

  return 0;
	
}








