// PAINT PROGRAM
// CSIT 462 - Computer Graphics SUNY Fredonia
// designed by: Junichi Edamitsu

#include <GL/glut.h>
#include <iostream.h>
#include <math.h>

//definition
#define Circ 30
#define Rect 30
#define Poly 15
#define PolyMAX 40
#define Pen 30
#define PenMAX 400

//enum
enum drawModeNum {ZERO, PEN, POLYLINE, RECTANGLE, CIRCLE, FILL};
enum colors{BLACK, RED, ORANGE, YELLOW, GREEN, SKYBLUE, BLUE, WHITE};

//window size
int iWindowWidth=500, iWindowHeight=500;
int iCanvasWidth=400, iCanvasHeight=500;

//storage for drawing data
int polyX[Poly][PolyMAX], polyY[Poly][PolyMAX];
int rectX[Rect][2], rectY[Rect][2];
int circX[Circ][2], circY[Circ][2];
int penX[Pen][PenMAX], penY[Pen][PenMAX];

//color info
int circColor[Circ], penColor[Pen], polyColor[Poly], rectColor[Rect];
GLfloat currentColor[3] = {0.0, 0.0, 0.0}, fillColor[3] = {0.0, 0.0, 0.0};

//index (holds which Array currently using)
int indPen = 0, indCirc = 0, indPoly = 0, indRect = 0;

//mouse position
int mPosX, mPosY, mpPosX, mpPosY, iniX, iniY;

//color
int color = 0;
float r = 0.0, g =0.0, b = 0.0;

int drawMode = PEN;

void drawIcons(int x);
void drawPalet(int col, int row, float red, float green, float blue);

void drawPen();
void drawPolyline();
void drawRectangle();
void drawCircle();
void floodFill(int w, int h, float* newcolor, float* oldcolor);
void floodFillE(int w, int h, float* newcolor, float* oldcolor);
void floodFillW(int w, int h, float* newcolor, float* oldcolor);
void floodFillN(int w, int h, float* newcolor, float* oldcolor);
void floodFillS(int w, int h, float* newcolor, float* oldcolor);

void menuClicked(int x, int y);
void canvasClicked(int x, int y);

void setColor(int colorCode);

void init(void) 
{
	int i, j;
	glClearColor (1.0, 1.0, 1.0, 0.0);
	glShadeModel (GL_FLAT);

	// INITIALIZATION of VARIABLES

	for(i=0; i<Poly; i++){
		for(j=0; j<PolyMAX; j++)
			polyX[i][j]=polyY[i][j]=0;
	}
	for(i=0; i<Rect; i++){
		for(j=0; j<2; j++)
			rectX[i][j]=rectY[i][j]=0;
	}
	for(i=0; i<Pen; i++){
		for(j=0; j<PenMAX; j++)
			penX[i][j]=penY[i][j]=0;
	}
	for(i=0; i<Circ; i++){
		for(j=0; j<2; j++)
			circX[i][j] = circY[i][j] = 0;
	}
	
	indPen =  indCirc = indPoly = indRect = 0;
}

void display(void)
{
	glClear (GL_COLOR_BUFFER_BIT);

	//=================================Menu Zone:

	//BackGround
	setColor(BLACK);
	glBegin(GL_POLYGON);
		glVertex2f(0,0);
		glVertex2f(100,0);
		glVertex2f(100,iWindowHeight);
		glVertex2f(0,iWindowHeight);
	glEnd();

//Colors
	drawPalet(0, 0, 0.0, 0.0, 0.0);
	drawPalet(1, 0, 1.0, 0.0, 0.0);
	drawPalet(2, 0, 1.0, 0.7, 0.2);
	drawPalet(3, 0, 1.0, 1.0, 0.0);
	drawPalet(0, 1, 0.0, 1.0, 0.0);
	drawPalet(1, 1, 0.0, 1.0, 1.0);
	drawPalet(2, 1, 0.0, 0.0, 1.0);
	drawPalet(3, 1, 1.0, 1.0, 1.0);

	//Icons
	drawIcons(PEN);
	drawIcons(POLYLINE);
	drawIcons(RECTANGLE);
	drawIcons(CIRCLE);
	drawIcons(FILL);
	drawIcons(drawMode);

	//Drawing
	drawPen();
	drawPolyline();
	drawCircle();
	drawRectangle();
	
	glPushMatrix();
	if(iniX!=0){
		floodFill(iniX,iniY,fillColor,currentColor);
		iniX=0;
	}


	glutSwapBuffers();
}

void drawIcons(int x)
{
	int w = 30;
	int h = x*55;
	float z, y, v, size;
	
	glColor3f(0.7, 0.7, 0.7);

	glBegin(GL_POLYGON); // fill the area for ICON
		glVertex2f(w, h);
		glVertex2f(w+40,h);
		glVertex2f(w+40,h+40);
		glVertex2f(w,h+40);
	glEnd();

	if(drawMode!=x) 
		glColor3f(0.5, 0.5, 0.5); // GREY if not selected
	else
		glColor3f(1.0, 1.0, 1.0); // WHITE if selected

	glBegin(GL_LINE_LOOP); // draw LINE around the icon
		glVertex2f(w, h);
		glVertex2f(w+40,h);
		glVertex2f(w+40,h+40);
		glVertex2f(w,h+40);
	glEnd();

	if(drawMode==x){
		glBegin(GL_LINE_LOOP);
			glVertex2f(w-1, h-1);
			glVertex2f(w+41,h-1);
			glVertex2f(w+41,h+41);
			glVertex2f(w-1,h+41);
		glEnd();
	}

	switch (x){ // draw graphic for ICON
	case PEN:
		setColor(WHITE);
		glBegin(GL_POLYGON);
			glVertex2f(w+5, h+30);
			glVertex2f(w+9, h+34);
			glVertex2f(w+34, h+9);
			glVertex2f(w+34, h+5);
			glVertex2f(w+30, h+5);
		glEnd();
		
		setColor(BLACK);
		glBegin(GL_TRIANGLES);
			glVertex2f(w+34, h+9);
			glVertex2f(w+34, h+5);
			glVertex2f(w+30, h+5);
		glEnd();

		break;
	case POLYLINE:
		setColor(WHITE);
		glBegin(GL_LINE_STRIP);
			glVertex2f(w+5, h+5);
			glVertex2f(w+5, h+6);
			glVertex2f(w+37, h+28);
			glVertex2f(w+18, h+24);
			glVertex2f(w+18, h+35);
		glEnd();

		break;
	case RECTANGLE:
		w = w + 5;
		h = h + 5;
		setColor(WHITE);
		glBegin(GL_LINE_LOOP);
			glVertex2f(w, h);
			glVertex2f(w+30,h);
			glVertex2f(w+30,h+30);
			glVertex2f(w,h+30);
		glEnd();
		glColor3f(0.5,0.5,0.5);
		glBegin(GL_LINE_LOOP);
			glVertex2f(w+10, h+10);
			glVertex2f(w+30,h+10);
			glVertex2f(w+30,h+30);
			glVertex2f(w+10,h+30);
		glEnd();
		setColor(BLACK);
		glBegin(GL_LINE_LOOP);
			glVertex2f(w+20, h+20);
			glVertex2f(w+30,h+20);
			glVertex2f(w+30,h+30);
			glVertex2f(w+20,h+30);
		glEnd();

		break;
	case FILL:
		size = 26;
		w  = w + (40 - size) / 2;
		h  = h + (40 - size) / 2;
		z = size / ( 1 + sqrt(3) );
		y = z * sqrt(3);
		v = 2 / sqrt(3) * 2 * z;

		glColor3f(0.3,0.3,0.3);
		glBegin(GL_LINE_STRIP);
			glVertex2f(w, h+z);
			glVertex2f(w+z, h+size);
			glVertex2f(w+size, h+y);
			glVertex2f(w+y, h);
		glEnd();

		setColor(WHITE);
		glBegin(GL_POLYGON);
			glVertex2f(w, h+z);
			glVertex2f(w+z, h+size);
			glVertex2f(w+size, h+y);
			glVertex2f(w+y, h);
		glEnd();
		glColor3f(0.5,0.5,0.5);
		glBegin(GL_POLYGON);
			glVertex2f(w, h+z);
			glVertex2f(w+z, h+size);
			glVertex2f(w+size, h+y);
			glVertex2f(w+v, h+z);
		glEnd();

		break;
	case CIRCLE:
		float x[3] = {w+15, w+23, w+29};
		float y[3] = {h+20, h+20, h+20};
		float r[3] = {12, 8, 6};
		float c[3] = {WHITE, BLACK, WHITE};
		float vectorX;
		float vectorY;
		float vectorY1;
		float vectorX1;
		
		for(int i=0; i<3; i++){
			vectorY1 = y[i] + r[i];
			vectorX1 = x[i];
			setColor(c[i]);
			glBegin(GL_LINE_STRIP); 
				float angle; 
				for(angle=0.0f;angle<=(2.0f*3.14159);angle+=0.01f) 
				{ 
					vectorX=x[i]+(r[i]*(float)sin((double)angle));
					vectorY=y[i]+(r[i]*(float)cos((double)angle)); 
					glVertex2f(vectorX1,vectorY1);
					vectorY1=vectorY;
					vectorX1=vectorX; 
				}
			glEnd();
		}
		
		break;
	}

}

void drawPalet(int col, int row, float red, float green, float blue)
{
	int h=iWindowHeight-75, c, r;

	glColor3f(red, green, blue);
	glBegin(GL_POLYGON);
		glVertex2f(25*col,h+25*row);
		glVertex2f(25*(col+1),h+25*row);
		glVertex2f(25*(col+1),h+25*(row+1));
		glVertex2f(25*col,h+25*(row+1));
	glEnd();

	
	
	if(color==0)
		c=r=0;
	else{
		r =	color / 4;
		c = color % 4;
	}
	
	if (col == c && row == r)
		glColor3f(0.7, 0.7, 0.7);
	else
		glColor3f(0.2, 0.2, 0.2);
	
	glBegin(GL_LINE_LOOP);
		glVertex2f(25*col,h+25*row);
		glVertex2f(25*(col+1),h+25*row);
		glVertex2f(25*(col+1),h+25*(row+1));
		glVertex2f(25*col,h+25*(row+1));
	glEnd();
}


void drawPen()
{
	for (int j=0; j<Pen; j++){
		setColor(penColor[j]);
		glBegin(GL_LINE_STRIP);
		for (int i=0; i<PenMAX; i++){
			if(penX[j][i]!=0){
					glVertex2i(penX[j][i], penY[j][i]);
			}else
				break;
		}
		glEnd();		
	}

}

void drawPolyline()
{
	int i,j;

	//====================draw an outline

	if(drawMode == POLYLINE){		
	
		i = indPoly;
		for(j=0; j<PolyMAX; j++){
			if(polyX[i][j]!=0){
				if(polyX[i][j+1]==0){
					glColor3f(0.8,0.8,0.8);
					glBegin(GL_LINE_STRIP);
						glVertex2i(polyX[i][j],polyY[i][j]);
						glVertex2i(mPosX,mPosY);
					glEnd();

					glColor3f(1.0,0.0,0.0);
					glBegin(GL_POLYGON);
						glVertex2i(polyX[i][j]-2, polyY[i][j]-2);
						glVertex2i(polyX[i][j]+2, polyY[i][j]-2);
						glVertex2i(polyX[i][j]+2, polyY[i][j]+2);
						glVertex2i(polyX[i][j]-2, polyY[i][j]+2);
					glEnd();

				break;
				}
			}
		}
	}
	//=====================draw a real line

	
	for ( i=0; i<Poly; i++){
		if(polyX[i][0]==0)
			break;
		else
		{
			setColor(polyColor[i]);
			glColor3f(r,g,b);
			glBegin(GL_LINE_STRIP);	
			for(j=0; j<PolyMAX; j++){
				if(polyX[i][j]!=0)
					glVertex2i(polyX[i][j],polyY[i][j]);
				else
					break;
			}
			glEnd();
		}				
	}
}

void drawRectangle()
{
	int i;
	//check for NEXT
	for(i=0; i<Rect; i++){
		if(rectX[i][0]==0)
			break;
		else
		{ 
			if (rectX[i][1] == 0){	//1st click => blue print OR draw a Rect.
				if (drawMode==RECTANGLE){
				if (rectX[i][0] != 0){ //draw -> blue print
					if (drawMode==RECTANGLE){
						glColor3f(0.9, 0.9, 0.9);
						glBegin(GL_LINE_LOOP);
							glVertex2i(rectX[i][0], rectY[i][0]);
							glVertex2i(rectX[i][0], mPosY);
							glVertex2i(mPosX, mPosY);
							glVertex2i(mPosX, rectY[i][0]);
						glEnd();
					}
				}
			}

			}else{  // draw -> real Rect
				setColor(rectColor[i]);
				glBegin(GL_LINE_LOOP);
					glVertex2i(rectX[i][0], rectY[i][0]);
					glVertex2i(rectX[i][0], rectY[i][1]);
					glVertex2i(rectX[i][1], rectY[i][1]);
					glVertex2i(rectX[i][1], rectY[i][0]);
				glEnd();

			}
		}
	}
}

void drawCircle()
{
	for(int i=0; i<Circ; i++){
	if(circX[i][0]==0)			//check for NEXT
		break;
	else
	{ 
	if (circX[i][1] == 0){		//1st click => blue print OR draw a circle.
		if (circX[i][0] != 0){
			if (drawMode==CIRCLE){
		
		float x = circX[i][0], y = circY[i][0];
		float r = sqrt( pow((mPosX - circX[i][0]),2) + pow((mPosY - circY[i][0]),2) );
		float vectorX;
		float vectorY;
		float vectorY1 = y + r;
		float vectorX1 = x;
		bool brk = false;

		glColor3f(0.8,0.8,0.8);
		
		glBegin(GL_LINE_STRIP); 
			float angle; 
			for(angle=0.0f;angle<=(2.0f*3.14159);angle+=0.01f) 
			{ 
				vectorX=x+(r*(float)sin((double)angle));
				vectorY=y+(r*(float)cos((double)angle)); 
				if(vectorX1>=100)
					glVertex2f(vectorX1,vectorY1);
				else{
					brk = true;
					break;}
				vectorY1=vectorY;
				vectorX1=vectorX; 
			}
		glEnd();
		if(brk){
			vectorY1 = y + r;
			vectorX1 = x;

			glBegin(GL_LINE_STRIP);
			for(angle=(2.0f*3.14159);angle>=0.0f;angle-=0.01f)
			{	 
				vectorX=x+(r*(float)sin((double)angle));
				vectorY=y+(r*(float)cos((double)angle)); 
				if(vectorX1>=100)
					glVertex2f(vectorX1,vectorY1);
				else
					break;
				vectorY1=vectorY;
				vectorX1=vectorX; 
			}
			glEnd();
		}
			}
		}

	}
	else
	{
		float x = circX[i][0], y = circY[i][0];
		float r = sqrt( pow((circX[i][1] - circX[i][0]),2) + pow((circY[i][1] - circY[i][0]),2) );
		float vectorX;
		float vectorY;
		float vectorY1 = y + r;
		float vectorX1 = x;
		bool brk = false;

		//glColor3f(r,g,b);
		setColor(circColor[i]);
		
		glBegin(GL_LINE_STRIP); 
			float angle; 
			for(angle=0.0f;angle<=(2.0f*3.14159);angle+=0.01f) 
			{ 
				vectorX=x+(r*(float)sin((double)angle));
				vectorY=y+(r*(float)cos((double)angle)); 
				if(vectorX1>=100)
					glVertex2f(vectorX1,vectorY1);
				else{
					brk = true;
					break;}
				vectorY1=vectorY;
				vectorX1=vectorX; 
			}
		glEnd();
		if(brk){
			vectorY1 = y + r;
			vectorX1 = x;

			glBegin(GL_LINE_STRIP);
			for(angle=(2.0f*3.14159);angle>=0.0f;angle-=0.01f)
			{	 
				vectorX=x+(r*(float)sin((double)angle));
				vectorY=y+(r*(float)cos((double)angle)); 
				if(vectorX1>=100)
					glVertex2f(vectorX1,vectorY1);
				else
					break;
				vectorY1=vectorY;
				vectorX1=vectorX; 
			}
			glEnd();
		}
	}
	}
	}
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// FLOOD FILL starts
//
//  Problems occur Randomly, acutally... 
//

void floodFill(int w, int h, float* newcolor, float* oldcolor)
{
	float thisColor[3];
	if ((w < 100) || (w > iWindowWidth)) return;
	if ((h < 0) || (h > iWindowHeight)) return;
	glReadPixels(w, iWindowHeight-h, 1, 1, GL_RGB, GL_FLOAT, thisColor);
	if(thisColor[0] == newcolor[0] && thisColor[1] == newcolor[1]
		&& thisColor[2] == newcolor[2] ) return;
	if(thisColor[0] == oldcolor[0] && thisColor[1] == oldcolor[1]
		&& thisColor[2] == oldcolor[2] )
	{
		glColor3fv(newcolor);
		glBegin(GL_POINTS);
			glVertex2i(w, h);
		glEnd();
		floodFillN(w, h-1, newcolor, oldcolor);//d) WORKS alone & with a)
		floodFillE(w+1, h, newcolor, oldcolor);//a) WORKS alone & with c)
		floodFillS(w, h+1, newcolor, oldcolor);//b) WORKS alone, but weird...
		floodFillW(w-1, h, newcolor, oldcolor);//c) WORKS alone 
		
	}
}


// FLOOD FILL ends
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// FAST FLOOD FILL -- Future use...

void floodFillE(int w, int h, float* newcolor, float* oldcolor)
{
	float thisColor[3];
	if  (w > iWindowWidth) return;
	glReadPixels(w, iWindowHeight-h, 1, 1, GL_RGB, GL_FLOAT, thisColor);
	if(thisColor[0] == newcolor[0] && thisColor[1] == newcolor[1]
		&& thisColor[2] == newcolor[2] ) return;
	if(thisColor[0] == oldcolor[0] && thisColor[1] == oldcolor[1]
		&& thisColor[2] == oldcolor[2] )
	{
		glColor3fv(newcolor);
		glBegin(GL_POINTS);
		glVertex2i(w, h);
		glEnd();
		floodFillE(w+1, h, newcolor, oldcolor);
		floodFillN(w, h-1, newcolor, oldcolor);
		floodFillS(w, h+1, newcolor, oldcolor);
	}
}
void floodFillN(int w, int h, float* newcolor, float* oldcolor)
{
	float thisColor[3];
	if (h < 0) return;
	glReadPixels(w, iWindowHeight-h, 1, 1, GL_RGB, GL_FLOAT, thisColor);
	if(thisColor[0] == newcolor[0] && thisColor[1] == newcolor[1]
		&& thisColor[2] == newcolor[2] ) return;
	if(thisColor[0] == oldcolor[0] && thisColor[1] == oldcolor[1]
		&& thisColor[2] == oldcolor[2] )
	{
		glColor3fv(newcolor);
		glBegin(GL_POINTS);
		glVertex2i(w, h);
		glEnd();
		floodFillE(w+1, h, newcolor, oldcolor);
		floodFillN(w, h-1, newcolor, oldcolor);
		floodFillW(w-1, h, newcolor, oldcolor);
	}
}
void floodFillW(int w, int h, float* newcolor, float* oldcolor)
{
	float thisColor[3];
	if (w < 100) return;
	glReadPixels(w, iWindowHeight-h, 1, 1, GL_RGB, GL_FLOAT, thisColor);
	if(thisColor[0] == newcolor[0] && thisColor[1] == newcolor[1]
		&& thisColor[2] == newcolor[2] ) return;
	if(thisColor[0] == oldcolor[0] && thisColor[1] == oldcolor[1]
		&& thisColor[2] == oldcolor[2] )
	{
		glColor3fv(newcolor);
		glBegin(GL_POINTS);
		glVertex2i(w, h);
		glEnd();
		floodFillN(w, h-1, newcolor, oldcolor);
		floodFillW(w-1, h, newcolor, oldcolor);
		floodFillS(w, h+1, newcolor, oldcolor);
	}
}
void floodFillS(int w, int h, float* newcolor, float* oldcolor)
{
	float thisColor[3];
	if (h > iWindowHeight) return;
	glReadPixels(w, iWindowHeight-h, 1, 1, GL_RGB, GL_FLOAT, thisColor);
	if(thisColor[0] == newcolor[0] && thisColor[1] == newcolor[1]
		&& thisColor[2] == newcolor[2] ) return;
	if(thisColor[0] == oldcolor[0] && thisColor[1] == oldcolor[1]
		&& thisColor[2] == oldcolor[2] )
	{
		glColor3fv(newcolor);
		glBegin(GL_POINTS);
		glVertex2i(w, h);
		glEnd();
		floodFillE(w+1, h, newcolor, oldcolor);
		floodFillW(w-1, h, newcolor, oldcolor);
		floodFillS(w, h+1, newcolor, oldcolor);
	}
}

void setColor(int colorCode){
	switch (colorCode){
	case 0:
		r=0.0; g=0.0; b=0.0;
		break;
	case 1:
		r=1.0; g=0.0; b=0.0;
		break;
	case 2:
		r=1.0; g=0.7; b=0.2;
		break;
	case 3:
		r=1.0; g=1.0; b=0.0;
		break;
	case 4:
		r=0.0; g=1.0; b=0.0;
		break;
	case 5:
		r=0.0; g=1.0; b=1.0;
		break;
	case 6:
		r=0.0; g=0.0; b=1.0;
		break;
	case 7:
		r=1.0; g=1.0; b=1.0;
		break;
	}
	glColor3f(r,g,b);
}


void MouseClick (int button, int state, int x, int y)
{
	int i, j, h;
	h=iWindowHeight-75;
	switch (state) {
		case GLUT_DOWN:{
			switch( button ){
				case GLUT_LEFT_BUTTON:	//LEFT BUTTON CLICKED
					{
						//============================	Menu Clicked

						if (x < 100){
							if(y < h){
								if (x >= 30 && x <= 70){
									if (y >= 40 && y <= 315){
										for(i=0; i<10; i++){
											if(y >= i*55 && y <= i*55 + 40){
													drawMode = i;
											}
										}
									}
								}
							}else{
								if(y < h+50){
									for(i=0; i<4; i++){
										for(j=0; j<2; j++){
											if(x >= i*25 && x < (1+i)*25){
												if(y >= h+j*25 && y < h+(j+1)*25){
													if((i + 4*j)==7)
														init();
													else
														color = i+4*j;
													break;
												}
											}
										}
									}
									setColor(color);
									fillColor[0]=r;
									fillColor[1]=g; 
									fillColor[2]=b;
								}
							}

						}else{ //=====================	Canvas Clicked
							switch (drawMode){
							case PEN:
								if(drawMode==PEN){
									if(penX[indPen][0] != 0 && indPen < Pen-1){										
										indPen++;
										
									}
									penColor[indPen]=color;
									for(i=0; i<PenMAX; i++){
										if(penX[indPen][i]==0){
										penX[indPen][i]=x;
										penY[indPen][i]=y;
										break;
										}
									}
								}
										break;
							case POLYLINE:
								if( indPoly < Poly-1){										
										polyColor[indPoly]=color;
								}
								for(i=0; i<PolyMAX; i++){
									if(polyX[indPoly][i]==0){
										polyX[indPoly][i]=x;
										polyY[indPoly][i]=y;
										break;
									}
								}
								break;
							case RECTANGLE:
								if(rectX[indRect][0]==0){
									//First Click
									rectX[indRect][0] = x;
									rectY[indRect][0] = y;
								}else{
									//Second Click
									rectX[indRect][1] = x;
									rectY[indRect][1] = y;
									
									if(indRect < Rect-1){									
										rectColor[indRect]=color;
										indRect++;
									}	
								}

								break;
							case CIRCLE:
								for(i=0; i<Circ; i++){
									if(circX[i][1]==0){	//look for NEXT								
										if(circX[i][0]==0){
											//First Click
											circX[i][0] = x;
											circY[i][0] = y;
										}else{
											if(circX[indCirc][0] != 0 && indCirc < Circ-1){
												circColor[indCirc]=color;
												indCirc++;
											}
											//Second Click
											circX[i][1] = x;
											circY[i][1] = y;
										}
										break;
									}
								}
								break;
							case FILL:
								glReadPixels(x, iWindowHeight-y, 1, 1, GL_RGB, GL_FLOAT, currentColor);
								setColor(color);
								fillColor[0]=r;
								fillColor[1]=g;
								fillColor[2]=b;
								iniX=x;
								iniY=y;
								break;
							default:
								break;
							}
						}

					break;
					}
				case GLUT_RIGHT_BUTTON:{
					switch(drawMode){
					case POLYLINE:
						if(polyX[indPoly][0] != 0 && indPoly < Poly-1){										
							indPoly++;
							polyColor[indPoly]=color;
						}
						break;
					case RECTANGLE:
						break;
					}
						

					break;}
			}
			glutPostRedisplay();
	   }
	}
}

void MouseMoveActive (int x, int y)
{
	mpPosX = x;
	mpPosY = y;

	if(x >= 100){
		if(drawMode==PEN){
			for(int i=0; i<PenMAX; i++){
				if(penX[indPen][i]==0){
				penX[indPen][i]=x;
				penY[indPen][i]=y;
				break;
				}
			}
			glutPostRedisplay();
		}
	}
}

void MouseMovePassive (int x, int y)
{
	if(x >=100){
		mPosX = x;
		mPosY = y;

		switch (drawMode){
		case POLYLINE:
		case RECTANGLE:
		case CIRCLE:
			glutPostRedisplay();		
			break;
		}
	}
}

void keyboard (unsigned char key, int x, int y)
{
	switch (key) {
	case '1':
	case 'a':
	case 'A':
		drawMode = PEN;
		break;
	case '2':
	case 's':
	case 'S':
		drawMode = POLYLINE;
		break;
	case '3':
	case 'd':
	case 'D':
		drawMode = RECTANGLE;
		break;
	case '4':
	case 'f':
	case 'F':
		drawMode = CIRCLE;
		break;
	case '5':
	case 'g':
	case 'G':
		drawMode = FILL;
		break;
	case 'c':
	case 'C':
		if(color!=7)
			color = color++;
		else
			color = 0;
		break;
	}
	glutPostRedisplay();
}

void reshape (int w, int h)
{
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   glOrtho(0.0, iWindowWidth,  iWindowHeight, 0.0, -1.0, 1.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   iWindowWidth = w;
   iWindowHeight = h;
}

int main(int argc, char** argv)
{
	// INSTRUCTION
	cout<<"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"<<endl
		<<"          P A I N T   P R O G R A M   with  O p e n G L         "<<endl
		<<"        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        "<<endl
		<<"   INSTRUCTION:   (1) Pen tool        (2) Polyline tool         "<<endl
		<<"                  (3) Rectangle tool  (4) Circle tool           "<<endl
		<<"                  (3) Fill Rectangle tool                       "<<endl
		<<"   ----------------------------------------------------------   "<<endl
		<<"   (1) Pen      -->  LEFT CLICK & DRAG for drawing              "<<endl
		<<"   (2) Polyline -->  LEFT CLICK for drawing                     "<<endl
		<<"                     RIGHT CLICK to start new polyline          "<<endl
		<<"   (3) Rectangle-->  1st LEFT CLICK to set the point            "<<endl
		<<"                     2nd LEFT CLICK to draw the rectangle       "<<endl
		<<"   (4) Circle   -->  1st LEFT CLICK to set the center point     "<<endl
		<<"                     2nd LEFT CLICK to draw the circle          "<<endl
		<<"   (5) Fill     -->  LEFT CLICK to select area to fill with new "<<endl
		<<"                     color (NOTE: MAY CRASH DEPENDING ON SYSTEM)"<<endl
		<<"   ----------------------------------------------------------   "<<endl
		<<"   *  Click color panel to CHANGE color                         "<<endl
		<<"   *  Click white panel to CLEAR the canvas                     "<<endl
		<<"   ** (( SHORTCUT KEY ))                                        "<<endl
		<<"     1, 2, 3, 4, 5  -->  for corresponding tool                 "<<endl
		<<"    (a, s, d, f, g)                                             "<<endl
		<<"        c, C        -->  for changing the color                 "<<endl
		<<"=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"<<endl;

	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize (iWindowWidth, iWindowHeight);
	glutInitWindowPosition (0, 0);
	glutCreateWindow ("My Paint Program");
	glutMouseFunc(MouseClick);
	glutMotionFunc(MouseMoveActive);
	glutPassiveMotionFunc(MouseMovePassive);
	glutKeyboardFunc(keyboard);

	init();
	glutDisplayFunc(display); 
	glutReshapeFunc(reshape);
	glutMainLoop();
	return 0;
}

