#ifndef	D3TESSDRAW_H
#define D3TESSDRAW_H

#include <d3marchdisp.h>
#include <d3tess.h>
#include <gobj.h>
#include <graphicsImmediateDeferred.h>


/*!
\brief Draw a simplex mesh including visual options.

For drawing the mesh, mesh surface, current state and 
  the mesh winding can be displayed.  

\par Example
\verbatim
#include <d3tessdraw.h>

mesh = new d3tess(N);
d3tessdraw *meshdraw = new d3tessdraw(*mesh);

meshdraw->graphicsDeffered.vi[d3tessdraw::multicolor]->isdrawn = true;
meshdraw->graphicsDeffered.vi[d3tessdraw::points]->isdrawn = true;
meshdraw->graphicsDeffered.vi[d3tessdraw::simplexes]->isdrawn = true;

meshdraw->meshupdate();
\endverbatim
*/
class d3tessdraw : public gobj
{
public:

  /* Moving over the mesh changes the mesh. */
  d3tess & tess; 
  /* Mesh geometry */
  gobjContainer gdynamic;

  enum 
  { 
    //! Deffered
    points=0,         // Number the points.
    simplexes=1,      // Number the triangles.
    multicolor=2,     // Randomly color the tessellation.
    voronoi=3,        // Voronoi Diagram.
    //! Immediate
    winding=0,        // Draw each simplices winding.
    grid=1,           // Draw the mesh.
    cp=2,             // Draw the cp.
    surface=3,        // Draw the surface.
    circle=4,         // Draw a circle through three point of cp.
    circles=5,        // Draw circles through all simplices.
    voronoip=6        // Draws voronoi polygons at base.
  };

  /** The gobj's write new gobj's when draw() is called.
       ie write to gobjContainer::global */
  gobjContainerSwitch graphicsDeffered;

  /** draw() writes standard OpenGL or immediately evaluated openGL calls. */
  gobjContainerSwitch graphicsImmediate;

  /** The options of configuring what things to display are through the
     gobjSwichContianer's after this class is constructed. */
  d3tessdraw(d3tess & tess_);

  /** Draws and iterates over all the tetrahedrons. */
  void draw();

  /** When the mesh changes the scene graph is recalculated. */
  void meshupdate();

};

class writepointsobj : public gobj
{
  d3tess const & tess;
public:

  gobjglColor3ub col;

  writepointsobj(d3tess const & tess_)
    : tess(tess_), col(255,255,0) {}

  void draw();
};

class writewindingobj : public gobj
{
  d3tess const  & tess;
public:

  writewindingobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};

class writegridobj : public gobj
{
  d3tess const  & tess;
public:

  // Configure the grid or mesh color.
  gobjglColor3ub gridcolor;

  writegridobj(d3tess const & tess_)
    : tess(tess_), gridcolor(gobjglColor3ub(0,0,255)) {}

  void draw();
};

class writesimplicesobj : public gobj
{
  d3tess const  & tess;
public:

  writesimplicesobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};

class writecpobj : public gobj
{
  d3tess const  & tess;
public:

  writecpobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};


class writesurfaceobj : public gobj
{
  d3tess const  & tess;
public:

  // Configure the surface color.
  gobjglColor3ub surfacecolor;

  // Configure the c-value in surface.
  d3marchdisp surface;

  writesurfaceobj(d3tess const & tess_)
    : tess(tess_), surfacecolor(gobjglColor3ub(255,0,0)) {}

  void draw();
};


class writecpcircleobj : public gobj
{
  d3tess const  & tess;
  gobjMyCircle cir;
public:

  writecpcircleobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};

class writecirclesobj : public gobj
{
  d3tess const  & tess;
  gobjMyCircle cir;
public:

  writecirclesobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};

class writecpvoronoiobj : public gobj
{
  d3tess & tess;
  void onevertex() const;
public:

  writecpvoronoiobj(d3tess & tess_)
    : tess(tess_) {}

  void draw();
};

class writemulticolorobj : public gobj
{
  d3tess const  & tess;
public:

  writemulticolorobj(d3tess const & tess_)
    : tess(tess_) {}

  void draw();
};

class writevoronoidiagramobj : public gobj
{
  d3tess & tess;
  // Iterates around tess.vs
  void onevertex() const;
public:

  writevoronoidiagramobj(d3tess & tess_)
    : tess(tess_) {}

  void draw();
};





#endif



