#include <GL/gl.h>
#include <GL/glut.h>

#include <commandline.h>
#include <cubegui.h>
#include <gobj.h>
#include <graphmisc.h>
#include <menusystem.h>
#include <zpr.h>



cubegui * cubegui::member = 0;

cubegui::cubegui()
  : menuhelp(true), display2D(true), display3D(true), cb(), 
    cb2d(cb,1.0), cb3d(cb,1.0), cbperm(cb) 
{
}

void cubegui::keyboard01(unsigned char k, int x, int y)
{
  assert(member!=0);

  switch (k) 
  {
    case 27: exit(0); break;
    case 'S': member->cbperm.save(); break;
    case 'h': member->menuhelp = ! member->menuhelp; break;
    case '2': member->display2D = ! member->display2D; break;
    case '3': member->display3D = ! member->display3D; break;

    case '0': member->cb.reset(); break;

    case 'p':
      cout << member->cb << endl;
      break;

    // Move Cursor
    case 'a': member->cb.cs.left(); break;
    case 's': member->cb.cs.right(); break;
    case 'w': member->cb.cs.up(); break;
    case 'z': member->cb.cs.down(); break;

    // Rotate
    case 'd': member->cb.left(); break;
    case 'f': member->cb.right(); break;
    case 'r': member->cb.up(); break;
    case 'c': member->cb.down(); break;

    // Rotate face
    case 'j': member->cb.faceleft(); break;
    case 'k': member->cb.faceright(); break;
    case 'i': member->cb.faceup(); break;
    case 'm': member->cb.facedown(); break;

    default:
      return;
  }

  glutPostRedisplay();
}

/*
void setOrthographicProjection() 
{
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  gluOrtho2D(-0.5, 639.5, 479.5, -1.0);

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();
}

void resetPerspectiveProjection() 
{
  glPopMatrix();

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
}
*/




void cubegui::display01()
{
  assert(member!=0);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//  if (member->display3D)
//    member->cb3d.draw();

/*

  setOrthographicProjection();

  glRasterPos2i(300,20);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");

  resetPerspectiveProjection();
*/

//  glPushMatrix();
//  glLoadIdentity();

//  if (member->display2D)
//    member->cb2d.draw();

//  glPopMatrix();

  assert(gobj::global!=0);

  gobj::global->draw();

  glerrordisplay();
 
  glutSwapBuffers();
}


void cubegui::prog01(int argc, char** argv)
{
  commandline cmd(argc,argv);

  int width=600;
  int height=800;

  cmd.mapvar(width,"width");
  cmd.mapvar(height,"height");

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(width,height);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  zpr zz;

  OpenGLinitialisation();

  glEnable(GL_DEPTH_TEST);

  glEnable(GL_CULL_FACE);
  glEnable(GL_NORMALIZE);


  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt
  (
    3.0,0.0,6.0,  // Eye
    3.0,0.0,0.0,  // Center
    0.0,1.0,0.0   // Up
  );

  member = this;

  xGraphics.set();

  menusystem * menu = 
    new menusystem(0,0,true,point2<GLint>(60,30),10);
  menu->fontcolor = point4<float>(218.0/255.0,165.0/255.0,32.0/255.0,0.75);

  gobjpush( new gobjSwitch<bool &>(menu,menuhelp) );

  gobjpush( new gobjSwitch<bool &>(&cb3d,display3D,false) );
  gobjpush( new gobjSwitch<bool &>(&cb2d,display2D,false) );

  menu->addfont12("Cube",2);

  menu->addfont10("Cursor",1);
  menu->addfont10("a   left",1);
  menu->addfont10("s   right",1);
  menu->addfont10("w   up",1);
  menu->addfont10("z   down",2);

  menu->addfont10("Move",1);
  menu->addfont10("d   left",1);
  menu->addfont10("f   right",1);
  menu->addfont10("r   up",1);
  menu->addfont10("c   down",2);

  menu->addfont10("Face",1);
  menu->addfont10("j   left",1);
  menu->addfont10("k   right",1);
  menu->addfont10("i   up",1);
  menu->addfont10("m   down",2);

  menu->addfont10("0   Reset",1);
  menu->addfont10("2   Toggle 2D display",1);
  menu->addfont10("3   Toggle 3D display",1);
  menu->addfont10("S   Save",2);

  menu->addfont10("h   toggle this help menu",1);
  menu->addfont10("ESC quit");  

  zz.update();

  // Never return.
  glutMainLoop();
}



