#include <math.h>
#include <memory.h>
#include <assert.h>
#include <string.h>
#include "tkogl.h"
#include "tess.h"

/*--------------------------------------------------------------------------
 *
 *  Main Procedure for generating tesselations
 *
 *--------------------------------------------------------------------------*/

int
Tesselate (Tcl_Interp *interp, int argc, char* argv [])
{
   int result = TCL_OK;
   int icoord = 0;
   int edgeflags = 1;
   int iarg;
   GLUtriangulatorObj* obj;
   int dlist = -1;
   GLdouble coord [3];
   GLfloat* vtx;
   GLfloat* vtxptr;

   for (iarg = 2; iarg < argc; iarg++) {	
      int len = strlen (argv [iarg]);
      if (strncmp (argv [iarg], "-displaylist", len) == 0) {
	 iarg++;
	 if (iarg == argc) {
            Tcl_AppendResult (interp, "not enough arguments", (char*)NULL);
            return TCL_ERROR;
         }
         if (strcmp (argv [iarg], "none") == 0) {
            dlist = 0;
         } 
         else if (Tcl_GetInt (interp, argv [iarg], &dlist) != TCL_OK) {
	    Tcl_AppendResult (interp,
	           "\nError parsing display list number", (char*) NULL);
	    return TCL_ERROR;
	 }
      } 
      else if (strncmp (argv [iarg], "-noedgeflags", len) == 0) {
	 edgeflags = 0;
      }
      else break;
   }

   if (argc - iarg < 9) {
      Tcl_AppendResult (interp,
	      "Not enough vertices", (char*) NULL);
      return TCL_ERROR;
   }

   obj = gluNewTess();
   vtx = (GLfloat*) malloc (sizeof (GLfloat) * (argc - iarg));
   vtxptr = vtx;

   assert (vtx != NULL);

   gluTessCallback(obj, GLU_BEGIN, glBegin);
   gluTessCallback(obj, GLU_VERTEX, glVertex3fv); 
   gluTessCallback(obj, GLU_END, glEnd);
   if (edgeflags) gluTessCallback (obj, GLU_EDGE_FLAG, glEdgeFlag);
   if (dlist == -1) dlist = glGenLists (1);   
   if (dlist != 0) glNewList (dlist, GL_COMPILE);
   gluBeginPolygon (obj);

   for (; iarg < argc; iarg++) {	
      int len = strlen (argv [iarg]);
      if (strncmp (argv [iarg], "-contour", len) == 0) {
	 gluNextContour (obj, GLU_UNKNOWN);
      }
      else {
	 if (Tcl_GetDouble (interp, argv [iarg], &coord[icoord]) != TCL_OK) {
	    Tcl_AppendResult (interp,
	      "\nError parsing tesselation vertex coord", (char*) NULL);
	    result = TCL_ERROR;
	    break;
	 }
	 else {
	    icoord = (icoord+1)%3;
	    if (icoord == 0) {
	       *(vtxptr) = coord [0];
	       *(vtxptr+1) = coord [1];
	       *(vtxptr+2) = coord [2];
	       gluTessVertex (obj, coord, vtxptr);
	       vtxptr += 3;
	    }
	 }
      }
   }
   
   gluEndPolygon (obj);
   gluDeleteTess (obj);
   free (vtx);
   if (dlist != 0) glEndList(); else return result;

   if (result == TCL_OK) {
      sprintf (interp->result, "%d", dlist);
   }
   else {
      glDeleteLists (dlist, 1);
   }
   return result;
}




	    
	    


