#include <iostream>
using namespace std;


#include <commandline.h>
#include <gobj.h>
#include <graphmisc.h>
#include <maze004.h>
#include <mazedisp03.h>
#include <mazematrixD2.h>
#include <mazematrixD2createmaze.h>
#include <zpr.h>


string maze004::doc[] = 
{
  "",
  "$ ./main prog=13 m=10 n=20 dx=0.15 backgroundcolor=0,255,0 wallcolor=0,25,255 randozize=0 id=1 origin=-1.4,-.5,0 - Display m by n maze."
};

mazegameD2state01* maze004::mg = 0;
mazedisp03* maze004::md = 0;

// http://www.codeproject.com/KB/openGL/GLUT_WINDOW_TEMPLATE.aspx
void maze004::special01(int key, int x, int y)
{
  assert(mg!=0);
  assert(md!=0);

  switch (key)
  {
    case GLUT_KEY_LEFT : mg->currentmove(3); break;
    case GLUT_KEY_RIGHT : mg->currentmove(1); break;
    case GLUT_KEY_UP : mg->currentmove(0); break;
    case GLUT_KEY_DOWN : mg->currentmove(2); break;
  }

  glutPostRedisplay();
}

void maze004::keyboard01
(
  unsigned char key, 
  int x, 
  int y
)
{
  assert(mg!=0);
  assert(md!=0);

//  bool res;
//  uint k2;

  switch (key)
  {
    case 27: exit(0); break;

//    case 's': mg->currentmove(3); break;
//    case 'd': mg->currentmove(1); break;
//    case 'e': mg->currentmove(0); break;
//    case 'x': mg->currentmove(2); break;
      
  }

  glutPostRedisplay();
}

void maze004::display01()
{ 
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  assert(gobj::global);

  gobj::global->draw();

  glerrordisplay();
  
  glutSwapBuffers();
}


void maze004::reshape01(intc width_,intc height_)
{
  zpr::reshape(width_,height_);
  assert(md);
  assert(md->bp02);
  md->bp02->update();
}

maze004::maze004(int argc, char** argv)
  : xGraphics(true)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(800,600);
  glutCreateWindow("");
  glutDisplayFunc(maze004::display01);
  glutKeyboardFunc(maze004::keyboard01);
  glutSpecialFunc(maze004::special01);


  OpenGLinitialisation();

  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);
  glEnable(GL_NORMALIZE);

  xGraphics.set();


  commandline cmd(argc,argv);


//gobjpush(new myaxes(1.0));

  // Construct the maze.

  mg = new mazegameD2state01();

  cmd.mapvar(mg->m,"m");
  cmd.mapvar(mg->n,"n");
  cmd.mapvar(mg->randomize,"randomize");

  cmd.mapvar(mg->proper,"proper");
  cmd.mapvar(mg->deletewall,"deletewall");

  mg->game01();
  assert(mg->valid());

  md = new mazedisp03(*mg);
  md->game01default();

  cmd.mapvar(md->dx,"dx");

  cmd.mapvar(md->displaycellid,"id");

  cmd.mapvar(md->pipes,"pipes");
  graphmisc::colornormalize(md->pipecolor,cmd,"pipecolor");

  cmd.mapvar(md->walls,"walls");
  graphmisc::colornormalize(md->wallcolor,cmd,"wallcolor");

  string originstr("(0,0)");
  cmd.mapvar(originstr,"origin");
  md->origin.serializeInverseBrackets(originstr);

  graphmisc::colornormalize(md->backgroundcolor,cmd,"backgroundcolor");

  cmd.mapvar(md->endpointratio,"endpointratio");
  graphmisc::colornormalize(md->endpointcolor,cmd,"endpointcolor");

  graphmisc::colornormalize(md->currentposcolor,cmd,"currentposcolor");

cout << mg->settings() << md->settings() << endl;




}


void maze004::eval()
{
  gobjpush(new gobjglTranslated(md->origin.x,md->origin.y,0.0));

  gobjpush(new gobjglClearColor(md->backgroundcolor));
  gobjpush(new gobjglClear(GL_COLOR_BUFFER_BIT));


  zpr zz;
  // Because zpr overides reshape function in constructor.
  glutReshapeFunc(maze004::reshape01);

  assert(md);
  zz.mousecallback = & md->mousecallback;
  md->zm = new zprmouse(zz);

  md->construct();
  gobjpush(md);

  zz.update();
  glutMainLoop();
}


