#include <commandline.h>
#include <desys.h>
#include <desystestspring2.h>
#include <gobj.h>
#include <graphmisc.h>
#include <helixtest.h>
#include <helix.h>
#include <nintegration.h>
#include <singleton.h>
#include <springlineardraw.h>
#include <typedefs.h>
#include <zpr.h>

namespace helixtestscope
{

typedef nintegrationRK< desystestspring2, double > integrator;
typedef  desys< integrator, double > sys;
typedef Singleton< sys > sysptr;

gobjContainer helixtestxGraphics;

framerate<> fr(.1,.05);

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

  gobj::global->draw();

//cout << "displaying framerate." << endl;
//  glColor3f(0.0,0.0,1.0);
  fr.display();

  glerrordisplay();
  
  glutSwapBuffers();
}

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

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

  OpenGLinitialisation();

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

  helixtestxGraphics.set();

  commandline cmd(argc,argv);

  gobjpush(new gobjglPushAttrib(GL_CURRENT_BIT));
  gobjpush(new gobjglDisable(GL_LIGHTING));
  gobjpush(new gobjglColor3f(1.0,0.0,0.0));
  gobjpush(new helix(1.5,100,2.0,0.5));
  gobjpush(new gobjglPopAttrib());

  zpr zz;

  camera::lookatxz(cmd,1.0);

  glutMainLoop();
}

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

  OpenGLinitialisation();

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

  helixtestxGraphics.set();

  springlineardraw & sd = * new springlineardraw(2,0.5,1.5,100);
  sd.springcolor = point3<double>(0.96,.01,0.2);
  sd.lengths[0]=2.0;
  sd.lengths[1]=1.5;
  sd.lengths[2]=0.8;

  sd.quadric.slices=40;
  sd.quadric.loops=10;

  gobjpush((gobj*)&sd);

  commandline cmd(argc,argv);
  cmd.mapvar(sd.lengths[0],"l0");
  cmd.mapvar(sd.lengths[1],"l1");
  cmd.mapvar(sd.lengths[2],"l2");

  cmd.mapvar(sd.xoffsets[0],"x0");
  cmd.mapvar(sd.xoffsets[1],"x1");

  zpr zz;

  camera::lookatxz(cmd,2.0,4.0);

  glutMainLoop();
}

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

    case '-':
      if (sysptr::ptr!=0)
      {
        sysptr::ptr->hstep /= 2.0;
      }
      break;

    case '+':
      if (sysptr::ptr!=0)
      {
        sysptr::ptr->hstep *= 2.0;
      }
      break;
  }
}

void helixtest::idle03()
{
  fr.update();

  sys* pde = sysptr::ptr;
  if (pde==0)
    return;

  pde->eval();

  uintc sample=30;
  static uint counter;
  ++counter;
  if ((counter % sample)==0)
  {
    springlineardraw * sp = Singleton<springlineardraw>::ptr;
    assert(sp!=0);
  
    if (sp!=0)
    {
      sp->xoffsets[0] = pde->yiGet(0,0);
      sp->xoffsets[1] = pde->yiGet(1,0);
    }

    glutPostRedisplay();
  }

//  if (Singleton<helixtestspring2plotter>::ptr!=0)
//    Singleton<helixtestspring2plotter>::ptr->add(); 

}

void helixtest::test03(int argc, char** argv)
{
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  int const wx=500;
  int const wy=500;
  glutInitWindowSize(wx,wy);
  glutCreateWindow("");
  glutDisplayFunc(helixtest::display01);
  glutKeyboardFunc(helixtest::keyboard03);
  glutIdleFunc(helixtest::idle03);

  OpenGLinitialisation();

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

  helixtestxGraphics.set();

  springlineardraw & sd = 
    * new springlineardraw(2,0.5,1.5,100);

  Singleton<springlineardraw>::ptr = &sd;
  sd.springcolor = point3<double>(0.96,.01,0.2);
  sd.lengths[0]=4.0;
  sd.lengths[1]=6.5;
  sd.lengths[2]=3.5;

  sd.quadric.slices=40;
  sd.quadric.loops=10;

  gobjpush((gobj*)&sd);

  commandline cmd(argc,argv);
  cmd.mapvar(sd.lengths[0],"l0");
  cmd.mapvar(sd.lengths[1],"l1");
  cmd.mapvar(sd.lengths[2],"l2");

  cmd.mapvar(sd.xoffsets[0],"x0");
  cmd.mapvar(sd.xoffsets[1],"x1");

  sys de(2,2);
  sysptr::ptr = &de;

  double w0=0.0;
  double w1=0.0;
  double Dw0=1.0;
  double Dw1=1.0;
  double h=0.01;

  cmd.mapvar(w0,"w0");
  cmd.mapvar(Dw0,"Dw0");
  cmd.mapvar(w1,"w1");
  cmd.mapvar(Dw1,"Dw1");
  cmd.mapvar(h,"h");

  de.yiGet(0,0)=w0;
  de.yiGet(0,1)=Dw0;
  de.yiGet(1,0)=w1;
  de.yiGet(1,1)=Dw1;
  de.hstep=h;

  double k0=0.1;
  double k1=0.3;
  double k2=0.2;

  cmd.mapvar(k0,"k0");
  cmd.mapvar(k1,"k1");
  cmd.mapvar(k2,"k2");
  de.integrator.yDorder.ki[0] = k0;
  de.integrator.yDorder.ki[1] = k1;
  de.integrator.yDorder.ki[2] = k2;

/*
  helixtestspring2plotter* plot = 
    new helixtestspring2plotter(&de.yiGet(0,0),&de.yiGet(1,0),500,10.0);

  Singleton<helixtestspring2plotter>::ptr = plot;
  gobjpush(plot);

  sd.masscolor[0] = plot->col0;
  sd.masscolor[1] = plot->col1;
*/

  zpr zz;
  zz.update();

  camera::lookatxz(cmd,4.0,4.0);

  glutMainLoop();
}

}


