#include<GL/glut.h>
#include<GL/glu.h>
#include<GL/gl.h>
#define PAWN 1
#define TOWER 2
#define HORSE 3
#define BISHOP 4
#define QUEEN 5
#define KING 6

GLfloat square_dim = 5.0f;
GLint pieceselected = -1;

typedef struct {
bool selected;
int type;
int position[2];
} PIECE;

PIECE whitepieces[16];
PIECE blackpieces[16];

GLfloat fLightPos[4]   = { 50.0f, 10.0f, 50.0f, 1.0f };
GLfloat fLowLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat fBrightLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };

void Setup()
{
  for(int i=0;i<16;i++)
  {
	whitepieces[i].selected = false;
	if(i > 7)
		whitepieces[i].type = PAWN;
	else
	  switch(i)
	 {
	  case 0 : case 7 :
	    whitepieces[i].type = TOWER; break;
	  case 1 : case 6 :
		whitepieces[i].type = HORSE; break;
	  case 2 : case 5 :
		whitepieces[i].type = BISHOP; break;
	  case 3 :
		whitepieces[i].type = QUEEN; break;
	  case 4 :
		whitepieces[i].type = KING; break;
	 }
    whitepieces[i].position[1] = i%8;
	if(i < 8)
	  whitepieces[i].position[0] = 0;
	else
	  whitepieces[i].position[0] = 1;
  }

  for( i=0;i<16;i++)
  {
	blackpieces[i].selected = false;
	if(i > 7)
		blackpieces[i].type = PAWN;
	else
	  switch(i)
	 {
	  case 0 : case 7 :
	    blackpieces[i].type = TOWER; break;
	  case 1 : case 6 :
		blackpieces[i].type = HORSE; break;
	  case 2 : case 5 :
		blackpieces[i].type = BISHOP; break;
	  case 3 :
		blackpieces[i].type = QUEEN; break;
	  case 4 :
		blackpieces[i].type = KING; break;
	 }
    blackpieces[i].position[1] = i%8;
	if(i < 8)
	  blackpieces[i].position[0] = 7;
	else
	  blackpieces[i].position[0] = 6;
  }


    
    glClearColor(0.5,0.5, 0, 0);
	glEnable(GL_DEPTH_TEST);
    
    // Setup light parameters
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, fLowLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, fBrightLight);
    glLightfv(GL_LIGHT0, GL_SPECULAR, fBrightLight);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
   
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMateriali(GL_FRONT, GL_SHININESS, 128);
    }

	
void DrawGround(void)
    {
    GLfloat fExtent = 20.0f;
    GLfloat fStep = 5.0f;
    GLfloat y = 0.0f;
    GLfloat fColor;
    GLfloat iStrip, iRun;
    GLint iBounce = 0;
    
    glShadeModel(GL_FLAT);
    for(iStrip = -fExtent; iStrip < fExtent; iStrip += fStep)
        {
        glBegin(GL_TRIANGLE_STRIP);
            for(iRun = fExtent; iRun >= -fExtent; iRun -= fStep)
                {
                if((iBounce %2) == 0)
                    fColor = 1.0f;
                else
                    fColor = 0.0f;
                    
                glColor4f(fColor, fColor, fColor, 0.5f);
                glVertex3f(iStrip, y, iRun);
                glVertex3f(iStrip + fStep, y, iRun);
                
                iBounce++;
                }
        glEnd();
        }
    glShadeModel(GL_SMOOTH);
    }


void DrawWorld(void)
{
 

  for(int i = 0; i < 16; i++)
  {
    PIECE p = whitepieces[i];
	
	
	  glPushMatrix();
	  glTranslatef(-20 +p.position[1]*square_dim + square_dim/2,1,
	               -20+p.position[0]*square_dim + square_dim/2);
	  if(p.selected == true){
	    glColor3f(1.0f,0.0f,0.0f);
		glutWireCube(5);
	  }
	  glColor3f(0.8f,0.8f,0.8f);
	  glLoadName(i+1);
	 switch(p.type)
	  {
	    case PAWN :
		  glutSolidCube(1); break;
	  	case TOWER :
	  	  glutSolidTetrahedron(); break;
	  	case HORSE :
          glutSolidSphere(1,10,10); break;
	  	case BISHOP :
		  glPushMatrix();
	  	  glRotatef(-90.0f,1,0,0);
		  glutSolidCone(1,2,10,10); 
		  glPopMatrix();
		  break;
	  	case KING :
		  glutSolidTorus(0.3,0.7,60,40);
		  break;
	  	case QUEEN :
		  glutSolidTeapot(1);
		  glPopMatrix();
		  break;
	  }
	  glPopMatrix();
	}


   for(i = 0; i < 16; i++)
  {
    PIECE p = blackpieces[i];
	  glPushMatrix();
	  glTranslatef(-20 +p.position[1]*square_dim + square_dim/2,1,
	               -20+p.position[0]*square_dim + square_dim/2);
	  if(p.selected == true){
	    glColor3f(1.0f,0.0f,0.0f);
		glutWireCube(5);
	  }
	  glColor3f(0.3f,0.3f,0.3f);
	  glLoadName(i+16);
	  switch(p.type)
	  {
	    case PAWN :
	  	  glutSolidCube(1); break;
	  	case TOWER :
	  	  glutSolidTetrahedron(); break;
	  	case HORSE :
          glutSolidSphere(1,20,20); break;
	  	case BISHOP :
		  glPushMatrix();
		  glTranslatef(0,-1,0);
	  	  glRotatef(-90.0f,1,0,0);
		  glutSolidCone(1,2,10,10); 
		  glPopMatrix();
		  break;
	  	case KING :
		  glutSolidTorus(0.3,0.7,60,40);
		  break;
	  	case QUEEN :
          glFrontFace(GL_CW);
	  	  glutSolidTeapot(1);
		  glFrontFace(GL_CCW);
		  break;
	  }
	  glPopMatrix();
  }
}

void RenderScene(void)
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDisable(GL_LIGHT0);
    DrawGround();
	glEnable(GL_LIGHT0);
    DrawWorld();
    glutSwapBuffers();
    }


void ChangeSize(int w, int h)
{
    GLfloat fAspect;
    if(h == 0)
        h = 1;
    glViewport(0, 0, w, h);   
    fAspect = (GLfloat)w / (GLfloat)h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, fAspect, 1.0f, 600.0f);   
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();    
    glTranslatef(0.0f, -10.0f, -50.0f);
	glLightfv(GL_LIGHT0, GL_POSITION, fLightPos);
}

void keyboard(unsigned char key, int x, int y)
{
	if(pieceselected != -1)
	{
        whitepieces[pieceselected].selected = false;
		pieceselected=-1;
	}
	if(key>=97 && key<=112)
	{
	  whitepieces[key-97].selected = true;
      pieceselected = key-97;
	}
    glutPostRedisplay();
	
}
void key(int key, int x, int y)
{
  if(pieceselected==-1)
	return;
  switch(key)
  {
  case GLUT_KEY_LEFT:
	whitepieces[pieceselected].position[1]-=1;
	break;
  case GLUT_KEY_RIGHT:
	whitepieces[pieceselected].position[1]+=1;
	break;
   case GLUT_KEY_UP:
	whitepieces[pieceselected].position[0]+=1;
	break;
    case GLUT_KEY_DOWN:
	whitepieces[pieceselected].position[0]-=1;
	break;
  }
  if(whitepieces[pieceselected].position[1]<0)
	whitepieces[pieceselected].position[1]=0;
  if(whitepieces[pieceselected].position[1]>7)
	whitepieces[pieceselected].position[1]=7;
  if(whitepieces[pieceselected].position[0]<0)
	whitepieces[pieceselected].position[0]=0;
  if(whitepieces[pieceselected].position[0]>7)
	whitepieces[pieceselected].position[0]=7;
  glutPostRedisplay();
}  

int main(int argc, char* argv[])
{
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800,600);
  glutCreateWindow("Chess");
  glutReshapeFunc(ChangeSize);
  glutSpecialFunc(key);
  glutKeyboardFunc(keyboard);
  glutDisplayFunc(RenderScene);
  Setup();
  glutMainLoop();
}

