
#include <graphicsImmediateDeferredTest.h>
#include <graphmisc.h>
#include <menusystem.h>
#include <print.h>

// TODO -get the graphics window dimensions


void graphicsImmediateDeferredTestTri::addshape01
(
  gobjContainer & shp 
)
{
  shp.push(new gobjglColor3ub(shapecolor));

  shp.push(new gobjglBegin(GL_TRIANGLES));
  shp.push(new gobjglVertex2f(-0.5,0));
  shp.push(new gobjglVertex2f(0.5,0));
  shp.push(new gobjglVertex2f(0.0,.7));
  shp.push(new gobjglEnd());
}



void graphicsImmediateDeferredTestTri::addshape02()
{
  gobjContainer* shp = new gobjContainer(true);
  
  shp->push(new gobjglColor3ub(shapecolor));

  shp->push(new gobjglBegin(GL_TRIANGLES));
  shp->push(new gobjglVertex2f(-0.5,0));
  shp->push(new gobjglVertex2f(0.5,0));
  shp->push(new gobjglVertex2f(0.0,.7));
  shp->push(new gobjglEnd());

  gobjpush(shp);
}


void graphicsImmediateDeferredTestTri::graphicscreate01()
{
  assert(graphics==0);
  gobjContainer* g = new gobjContainer(true);

  addshape01(*g);

  graphics=g;
}


void graphicsImmediateDeferredTestg02::draw()
{
/*
  gobjContainer * px = new gobjContainer(true);

  ref.addshape01(*px);

  gobjpush(px);
*/
  ref.addshape02();
}


void graphicsImmediateDeferredTestTri::graphicscreate02()
{
  g02 = new graphicsImmediateDeferred();

  g02->graphicsDeferred.push( new graphicsImmediateDeferredTestg02(*this) );
  g02->update();

  graphics=g02;
}


void graphicsImmediateDeferredTestTri::graphicscreate03()
{
  g02 = new graphicsImmediateDeferred();

cout << SHOW(gobj::global) << endl;
  g02->graphicsDeferred.globalpush();

cout << "graphicscreate03" << endl;
cout << "DEMO to show that this way does not work" << endl;

cout << SHOW(g02->graphicsDeferred.vg.size()) << endl;
  gobjpush(new gobjglColor3ub(shapecolor));
  gobjpush(new gobjglBegin(GL_TRIANGLES));
  gobjpush(new gobjglVertex2f(-0.5,0));
  gobjpush(new gobjglVertex2f(0.5,0));
  gobjpush(new gobjglVertex2f(0.0,.7));
  gobjpush(new gobjglEnd());
cout << SHOW(g02->graphicsDeferred.vg.size()) << endl;

cout << SHOW(gobj::global) << endl;
  g02->graphicsDeferred.globalpop();
cout << SHOW(gobj::global) << endl;
  g02->update();
  graphics=g02;
}


void graphicsImmediateDeferredTestTri::graphicscreate04()
{
  // Build the usual shape graphics.

  g04 = new graphicsImmediateDeferredSwitch();

  g04->pushdeferred(g04switch,new graphicsImmediateDeferredTestg02(*this));

  //g04->push(g04switch,this);  //??? THIS FAILS  - is not a callback for
  //writing geometry.
 
cout << SHOW(g04switch) << endl;
  graphics=g04;
  g04->update();
  //graphics=g04;
}


void graphicsImmediateDeferredTestTri::graphicscreate05()
{
  // Build the usual shape graphics.

  g04 = new graphicsImmediateDeferredSwitch();

  g04->pushdeferred(g04switch,*this,&graphicsImmediateDeferredTestTri::addshape02);

  graphics=g04;
  g04->update();
}


void graphicsImmediateDeferredTestTri::graphicscreate06()
{
  // Build the usual shape graphics.

  g04 = new graphicsImmediateDeferredSwitch();

  g04->pushdeferred(g04switch,*this,&graphicsImmediateDeferredTestTri::addshape01);

  graphics=g04;
  g04->update();
}

void graphicsImmediateDeferredTestTri::graphicscreate07()
{
  g02 = new graphicsImmediateDeferred();

  g02->graphicsDeferred.pushcallback(*this,&graphicsImmediateDeferredTestTri::addshape02 );
  g02->update();

  graphics=g02;
}





void graphicsImmediateDeferredTestTri::draw()
{
  assert(graphics!=0);

  graphics->draw();
}


string graphicsImmediateDeferredTest::doc[] = 
{  
  "",
  "Test opengl rendering",
  "Use ImmediateDefered callback display.",
  "Show code that does not work with ImmediateDeferred.",
  "Add a switch to test02",
  "Functional object with () callback.",
  "Functional object with (gobjContainer&) callback.",
  ""
};

graphicsImmediateDeferredTestTri* graphicsImmediateDeferredTest::model=0;

void graphicsImmediateDeferredTest::keyboard01
(
  unsigned char key, 
  int x, 
  int y
)
{
  switch (key)
  {
    case 27: exit(0); break;

    case 'j': assert(model); model->circledraw.center.x -= model->circledelta; break;
    case 'k': assert(model); model->circledraw.center.x += model->circledelta; break;

    case '1': 
      assert(model); 
      if (model->g02)
      {
        model->shapecolor.x = rand() % 256; 
        model->shapecolor.y = rand() % 256; 
        model->shapecolor.z = rand() % 256; 
        model->g02->update();
      }
      break;

    case '2': 
      assert(model); 
      if (model->g04)
      {

        model->shapecolor.x = rand() % 256; 
        model->shapecolor.y = rand() % 256; 
        model->shapecolor.z = rand() % 256; 
        model->g04->toggle(0);
        model->g04->update();
      }
      break;
  }

  glutPostRedisplay();
}


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

  gobj::global->draw();

  if (graphicsImmediateDeferredTest::model)
  {
    graphicsImmediateDeferredTest::model->circlecolor.draw();
    graphicsImmediateDeferredTest::model->circledraw.draw();
  }

  glerrordisplay();
  
  glutSwapBuffers();
}

void graphicsImmediateDeferredTest::test01(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate01();
  gobjpush(g1);

  glutMainLoop();
}

void graphicsImmediateDeferredTest::test02(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate02();
  gobjpush(g1);

  menu01();

  glutMainLoop();
}

void graphicsImmediateDeferredTest::test03(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate03();
  gobjpush(g1);

  glutMainLoop();
}

void graphicsImmediateDeferredTest::test07(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate07();
  gobjpush(g1);

  glutMainLoop();
}


void graphicsImmediateDeferredTest::test04(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate04();
  gobjpush(g1);

  menu02();

  glutMainLoop();
}

void graphicsImmediateDeferredTest::test05(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate05();
  gobjpush(g1);

  menu02();

  glutMainLoop();
}

void graphicsImmediateDeferredTest::test06(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize(600,600);
  glutCreateWindow("");
  glutDisplayFunc(display01);
  glutKeyboardFunc(keyboard01);

  OpenGLinitialisation();

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

  xGraphics.set();

  gobjpush(new myaxes(1.0));

  graphicsImmediateDeferredTestTri* g1 = new graphicsImmediateDeferredTestTri();
  g1->graphicscreate06();
  gobjpush(g1);

  menu02();

  glutMainLoop();
}

void graphicsImmediateDeferredTest::menu01()
{
  gobjpush(new gobjglDisable(GL_LIGHTING));
  menusystem * menu = 
    new menusystem(point2<GLint>(60,30),10);
  menu->fontcolor = point4<float>(218.0/255.0,165.0/255.0,32.0/255.0,0.75);

  menu->addfont10("[1]   Update shape",1);
  menu->addfont10("[j,k]  Move circle left,right",2);
  menu->addfont10("[ESC]  Quit",1);

  gobjpush(menu);
}

void graphicsImmediateDeferredTest::menu02()
{
  gobjpush(new gobjglDisable(GL_LIGHTING));
  menusystem * menu = 
    new menusystem(point2<GLint>(60,30),10);
  menu->fontcolor = point4<float>(218.0/255.0,165.0/255.0,32.0/255.0,0.75);

  menu->addfont10("[2]   Update and Toggle shape",1);
  menu->addfont10("[j,k]  Move circle left,right",2);
  menu->addfont10("[ESC]  Quit",1);

  gobjpush(menu);
}









