#include "cs148.h"


#define NPts 10
int saveX, saveY;


void LineTo(GLint x1, GLint y1) {
	glBegin(GL_LINES);
		glVertex2i(saveX, saveY);
		glVertex2i(x1, y1);
	glEnd();
	saveX = x1; saveY = y1;
}

void MoveTo(GLint x1, GLint y1) {
	saveX = x1;
	saveY = y1;
}

void myInit(void)
{
	glClearColor(1.0,1.0,1.0,0.0);
	glLineWidth(2.0);
}

void myDisplay(void)
{
	float x[NPts+1], y[NPts+1], t, xA, xB, xC, xD,
		yA, yB, yC, yD, a0, a1, a2, a3, b0, b1, b2, b3;
	int n, i, j, first, X, Y, marker;

	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0.0f,0.0f,0.0f);

	marker = 2;
	/* our control points */	
	x[0] = 10; y[0] = 150;
	x[1] = 50; y[1] = 100;
	x[2] = 100; y[2] = 100;
	x[3] = 150; y[3] = 200;
	x[4] = 200; y[4] = 50;
	x[5] = 300; y[5] = 100;
	x[6] = 400; y[6] = 270;
	x[7] = 440; y[7] = 430;
	x[8] = 380; y[8] = 340;
	x[9] = 300; y[9] = 400;
	x[10] = 200; y[10] = 420;
	
	/* place X's on the screen where the points are located */
	for (i = 0; i <= NPts; i++)  {
		MoveTo(x[i]-marker, y[i]-marker);  LineTo(x[i]+marker, y[i]+marker);
	    MoveTo(x[i]+marker, y[i]-marker);  LineTo(x[i]-marker, y[i]+marker);
	}   
  	
	/* B-spline calcs */
	first = 1;
	for (i = 1; i < NPts-1; i++)  {
		/* calculate coefficient values */
		xA = x[i-1];	xB = x[i];	xC = x[i+1];	xD = x[i+2];
	  	yA = y[i-1];	yB = y[i];	yC = y[i+1];	yD = y[i+2];
	   	a3 = (-xA+3*(xB-xC)+xD)/6.0;	b3 = (-yA+3*(yB-yC)+yD)/6.0;
	   	a2 = (xA-2*xB+xC)/2.0;  		b2 = (yA-2*yB+yC)/2.0;
		a1 = (xC-xA)/2.0;				b1 = (yC-yA)/2.0;
	   	a0 = (xA+4*xB+xC)/6.0;			b0 = (yA+4*yB+yC)/6.0;
	   	/* vary t and get (X,Y) */
	   	for (j=0; j <= NPts; j++) {
	   		t = (float)j/(float)NPts;
	   		X = ceil(((a3*t+a2)*t+a1)*t+a0);
   	   		Y = ceil(((b3*t+b2)*t+b1)*t+b0);
   	   		if (first) {first = 0; MoveTo(X,Y);} else LineTo(X,Y);
   		}
   	}
	glFlush();
}


void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, 640.0, 0.0, 480.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}


void main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(640,480);
	glutInitWindowPosition(100,50);
	glutCreateWindow("OpenGL");
	glutDisplayFunc(myDisplay);
	glutReshapeFunc(reshape);
	myInit();
	glutMainLoop();
}

