/****************************************************************************/
#ifndef SPLINE_H
#define SPLINE_H
/****************************************************************************/
#include <GL/glut.h>
#include <math.h>
#include "color.h"
/****************************************************************************/
#define BUFSIZE 512
#define CP_NX 4
#define CP_NY 4
#define SPHERE_RADIUS 0.05
#define NUM_POINTS_FOR_SPHERE 10 
#define MAX_SPLINES 100
/****************************************************************************/
typedef struct _theSpline {
	float	cp[CP_NX][CP_NY][3];	 // Control Points
	float	(**data)[3];	 	 // Sampled points for the surface
	float	(**normal)[3];	 	 // Surface normals at each point
	float   r, g, b;
        struct _theSpline *next; // pointer to next spline in LL
} theSpline;
/****************************************************************************/
class Spline
{
   private:
	int splineCount;			// Number of splines
	theSpline *head;
	theSpline *tail;
	theSpline *current;
	struct storageStruct {
		theSpline *s;
		int splineCount, surfaceRender, lineRender, nu, nv;
		} undoBuffer, redoBuffer;		// Undo/redo buffer
	int surfaceRender;
	int lineRender;
	int bumpMappingEnabled;
	int nu, nv;
	int selectedPoint[2];
	int undo_status;
	int xStart, yStart;
	float CPforRotation[CP_NX][CP_NY][3];
	int numTex;
	theSpline *splineList[MAX_SPLINES];	// Storage for selection
	myColor colorDB;		// Color database

	SaveToBuffer(storageStruct *b);
	ReadFromBuffer(storageStruct *b);
	draw();                 // Draws the current spline
	setColorDB();		// Set color database
	drawCP(float p[], int id); 
	setSplineMaterial();
	processHits(GLint hits, GLuint buffer[], int i, int edgeSelectionFlag);
	SaveCurrentBuffer();
	MapCurrentGrid(theSpline *s, int nx, int ny);
	DrawWireframe(theSpline *s);
	DrawSurface(theSpline *s);
	allocData(theSpline *s, int nx, int ny);
	freeData(theSpline *s, int nx, int ny);
	freeMapGrid();
	setlineRender(int flag);
	setsurfaceRender(int flag);
	int Delete(theSpline *ptr); // Delete a spline
	DeleteAll();
	calcTranslation(int x, int y, float dxyz[]);
	calcNormal(float v1[], float v2[], float v3[], float *n);
	CrossProd(float v1[], float v2[], float *n);
	unitCrossProd(float v1[], float v2[], float *n);
	computeBumpMapNormal(float u, float v, float ddu[], float ddv[], 
			float *n);
	clear();	    // Destroys all the spline data

   public:
        Spline();           // Constructor
        Spline(int nU, int nV);           // Constructor
        ~Spline();          // Destructor
	init();             // initializes (same as Constructor)
	init(int nU, int nV); // initializes (same as Constructor)
	int numSplines();   // Return number of splines in the database
	int Add();	    // Add a spline (returns total number of splines)
	int Add(int x, int y);  // Add a spline at mouse location (x,y)
	int DeleteCurrent();		// Delete current spline
	
	int getlineRender();
	togglelineRender();
	int getsurfaceRender();
	togglesurfaceRender();
	changeRenderingQuality(float factor);

	unselectCP();
	int isPointSelected(int i);
	moveCP(int x, int y);
	drawAllCP();		// Draws all the CPs
	drawAndSelectCP(int i, int edgeSelectionFlag); // 'i'th selection of CP
	moveSpline(int x, int y);
	initializeRotate(int x, int y);
	rotateSpline(int x, int y);
	join(int isC1continuity);
	MapGrid();
	drawAll();              // Draws all the spline in the list
	drawEdge(int n);
	clearScreen();		// Delete all data on the screen
	drawString(float x, float y, char *label, ...);

	setTexture();		// Initialized texture environment
	int addTextureFromFile(char *filename); // adds texture from RGB file
	int numTextures();	// Returns number of textures
	toggleBumpMapping();	// Toggle bump mapping flag

	resetUndo();		// reset undo
	undo();			// Undo last modification

	int SaveToFile(char *name, int printflag);	// File I/O routines
	int ReadFromFile(char *name, int printflag);
};
/****************************************************************************/
#endif  /* SPLINE_H */
/****************************************************************************/
