
//CSE 581
//Jason Kim
//Lab 1
//
//
//
//
////////////////////////////////////////////////////////

//Includes
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <math.h>


//some globals
////////////////////////////////
int width=500, height = 500; // display window width and height

int press_x, press_y;
int release_x, release_y;

int forward=0;
int turn = 0;
int scaleu = 0;
int scaled = 0;
int poly = 0;
int star = 0;
int spiral = 0;

double D = 20;
double u = 1;
double v = 0;
double A = 45;
double B = 90;
int   nop = 0; // number of primitives
int   nov = 0; // number of vertices

float startxpos;
float startypos;

int startpos=0;
/////////////////////////////////////////////

void display_all()
{
	float x, y;
 
	
	//Starting Mouse Click Point
	if (startpos==1)
	{
		glBegin(GL_POINTS);
			x = startxpos;
			y = startypos;
			glVertex2f(x,y);
			startpos=0;
		glEnd();
		startpos=0;
		u = 1;
		v = 0;
		glFlush();  // force OpenGL to draw all the objects 
	}

	//Move Forward Point
	if (forward==1)
	{

		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;
		forward=0;
		glFlush();  // force OpenGL to draw all the objects 

	}

	//Turn Point
	if(turn==1)
	{
		u = (u*cos(A)) - (v*sin(A));
		v = (u*sin(A)) + (v*cos(A));
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;
		turn=0;
		glFlush();  // force OpenGL to draw all the objects 
	}
	
	//Scale Up!
	if(scaleu==1)
	{
		u = u*1.5;
		v = v*1.5;
		scaleu=0;

	}

	//Scale Down!
	if(scaled==1)
	{
		u = u*0.5;
		v = v*0.5;
		scaled=0;

	}

	//PolyGon
	if(poly==1)
	{
		//draws a something cool a Polygon!

		//forward
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;

		//turn
		for(int j=0;j<2;j++)
		{
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		}
		
		for(int j=0;j<3;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}
		//turn

			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<6;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}
				//turn

			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<5;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}
			//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<7;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;



		}
			glFlush();  // force OpenGL to draw all the objects
			poly = 0;
	}

	//Star
	if(star==1)
	{
		//Its Totallay A Shooting Star!!!!!!
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;

		//turn
		for(int j=0;j<2;j++)
		{
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		}

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

					//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

							//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

					//forward
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;
		
									//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<10;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;


		}
		u = -1;
		v = 0;
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;

		//turn
		for(int j=0;j<2;j++)
		{
			u = (u*cos(A)) + (v*sin(A));
			v = (u*sin(A)) - (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		}

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

					//turn
			u = (u*cos(A)) + (v*sin(A));
			v = (u*sin(A)) - (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

							//turn
			u = (u*cos(A)) + (v*sin(A));
			v = (u*sin(A)) - (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

					//forward
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;
		
									//turn
			u = (u*cos(A)) + (v*sin(A));
			v = (u*sin(A)) - (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<10;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;


		}
		glFlush();  // force OpenGL to draw all the objects
		star=0;

	}

	//spiral!
	if(spiral==1)
	{
		
		// kind of a spiral
		
		//forward
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;

		//turn
		for(int j=0;j<2;j++)
		{
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		}

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

					//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<2;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;

			glFlush();  // force OpenGL to draw all the objects
			poly = 0;

		}

							//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

					//forward
		glBegin(GL_POINTS);
			x = startxpos + u*D;
			y = startypos + v*D;
			glVertex2f(x,y);
		glEnd();
		
		glBegin(GL_LINES);
			glVertex2f(x,y);
			glVertex2f(startxpos,startypos);
		glEnd();
		startxpos = x;
		startypos = y;
		
									//turn
			u = (u*cos(A)) - (v*sin(A));
			v = (u*sin(A)) + (v*cos(A));
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

		for(int j=0;j<10;j++)
		{
			//forward
			glBegin(GL_POINTS);
				x = startxpos + u*D;
				y = startypos + v*D;
				glVertex2f(x,y);
			glEnd();
		
			glBegin(GL_LINES);
				glVertex2f(x,y);
				glVertex2f(startxpos,startypos);
			glEnd();
			startxpos = x;
			startypos = y;

			startxpos = x;
			startypos = y;


		}
		
			glFlush();  // force OpenGL to draw all the objects
		spiral = 0;

	}
}

/////////////////////////////////////////////

void display()
{
  // clear the screen
  glClearColor(0,0,0,1);  //  background color - black
  //glClear(GL_COLOR_BUFFER_BIT);

  // set the world window
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, 499, 0, 499);  // here I just hard-wire the world window 

  // now call the real drawing function
  display_all();

}

//////////////////////////////////////////////////
//
//  The callback functions
//
//////////////////////////////////////////////////

void mymouse(int button, int state, int x, int y)
{
	//Use the Mouse to Indicate a Start Point
	startxpos = x;
	startypos = height - y;
	startpos = 1;
	glutPostRedisplay();
}

void mymenu(int value){

	//Check Menu for Color and Clear. and all that jazz

	if (value == 2) {
	    glClearColor(0,0,0,1);  //  background color - black
		glClear(GL_COLOR_BUFFER_BIT);
		display_all();
		glFlush();
  }
	if(value==3){
		glColor3f(1,0,0);
	}
	if(value==4){
		glColor3f(0,0,1);
	}
	if(value==5){
		glColor3f(0,1,0);
	}
	if(value==6){
		glColor3f(1,1,1);
	}
	if(value==7){
		glColor3f(1,1,0);
	}
}

void mykey(unsigned char key, int x, int y)
{
	//Check for Key Presses

	if (key =='f') {
	  poly = 0;
	  spiral = 0;
	  star = 0;
	  turn = 0;
	  forward = 1;
	  scaled = 0;
	  scaleu =0;
	}
	
	if (key=='t'){
		poly = 0;
		spiral = 0;
		star = 0;
		turn = 1;
		forward = 0;
		scaled = 0;
		scaleu =0;
	}

	if (key=='S'){
		poly = 0;
		spiral = 0;
		star = 0;
		scaled = 0;
		scaleu = 1;
		turn = 0;
		forward = 0;
	}

	if (key=='s'){
		poly = 0;
		star = 0;
		spiral = 0;
		scaled = 1;
		scaleu = 0;
		turn = 0;
		forward = 0;
	}
	if (key=='p'){
		spiral = 0;
		poly = 1;
		star = 0;
		turn = 0;
		forward = 0;
		scaled = 0;
		scaleu =0;
	}
	if (key=='a'){
		spiral = 0;
		poly = 0;
		star = 1;
		turn = 0;
		forward = 0;
		scaled = 0;
		scaleu =0;
	}
	if (key=='r'){
		spiral = 1;
		poly = 0;
		star = 0;
		turn = 0;
		forward = 0;
		scaled = 0;
		scaleu =0;
	}
	
	glutPostRedisplay();
  if (key =='q')
    exit(0);
}

////////////////////////////////////////////////////

void resize(int w, int h)
{
  glViewport(0,0,w,h); 
  glutPostRedisplay(); 
}

////////////////////////////////////////////////////
void myInit() {

  // set the viewport
  glViewport(0,0,width, height);
}


//////////////////////////////////////////////////////////

int main(int argc, char** argv)
{
  // init glut drawing window
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
  glutInitWindowSize(width,height);
  glutCreateWindow("Jason Kim's Lab1 for CSE581 Simple 2D Drawing");

  myInit();   // my own OpenGL initialization

  // register callbacks
  glutDisplayFunc(display);
  glutReshapeFunc(resize);
  glutMouseFunc(mymouse);
  glutKeyboardFunc(mykey);

  // create menu
  glutCreateMenu(mymenu);
  glutAddMenuEntry("Clear",2);
  glutAddMenuEntry("Red",3);
  glutAddMenuEntry("Blue",4);
  glutAddMenuEntry("Green",5);
  glutAddMenuEntry("White",6);
  glutAddMenuEntry("Yellow",7);
  glutAttachMenu(GLUT_RIGHT_BUTTON);

  // enter the event loop
  glutMainLoop();
}
