#include <cassert>
using namespace std;

#include <gobj.h>
#include <mazedisp02.h>
#include <pointsdisplay.h>
#include <typedefs.h>


mazedisp02::mazedisp02
(
  doublec dx_, 
  mazematrixD2<uint> const & mz_
)
  : mz(mz_), dx(dx_), displaycellid(false), 
  pipes(false), pipecolor(point3<double>(1.0,0.0,0.0)),
  walls(true), wallcolor(point3<double>(0.0,0.0,1.0))
{
}

void mazedisp02::draw()
{
  assert(mz.valid());
  assert(mz.vi.size()==(1+mz.dim[2]));

  gobjpush(new gobjglDisable(GL_LIGHTING));
  gobjpush(new gobjglBegin(GL_LINES));

  uint m=mz.dim[0];
  uint n=mz.dim[1];



  uint id;
  point2<uint> pos1;
  point2<double> pos2;
  uint K=m*n-1;

  if (walls)
  {
    gobjpush(new gobjglColor3d(wallcolor));

    for (uint k=0; k<mz.dim[2]; ++k)
    {
      id=k+1;
      pos1.x = k % n;
      pos1.y = K/n-k/n;
      pos2.x = dx*pos1.x;
      pos2.y = dx*pos1.y;
      celldraw(mz.vi[id],pos2);    
    }
  } 

  if (pipes)
  {
    gobjpush(new gobjglColor3d(pipecolor));
    for (uint k=0; k<mz.dim[2]; ++k)
    {
      id=k+1;
      pos1.x = k % n;
      pos1.y = K/n-k/n;
      pos2.x = dx*pos1.x;
      pos2.y = dx*pos1.y;
      celldraw2(mz.vi[id],pos2);
    }
  }
  
  gobjpush(new gobjglEnd()); 

  if (displaycellid)
  {
    vector< point2<double> > pi;
    pi.push_back(point2<double>());

    for (uint k=0; k<mz.dim[2]; ++k)
    {
      id=k+1;
      pos1.x = k % n;
      pos1.y = K/n-k/n;
      pos2.x = dx*pos1.x;
      pos2.y = dx*pos1.y;

      pi.push_back(pos2+point2<double>(dx*0.5,dx*0.5));
    }

    assert(gobjContainer::global);
    gobjpush(new gobjglColor3f(point3<float>(1.0,0.0,0.0)));
    pointsdisplay2D< point2<double> > pd(*gobjContainer::global,pi,false,true,true);
  }

}


void mazedisp02::celldraw
( 
  cellD2<uint> const & x,
  point2<double> const & p00
)
{
  point2<double> p10 = p00;
  p10.x += dx;
  point2<double> p01 = p00;
  p01.y += dx;
  point2<double> p11 = p00;
  p11.x += dx;
  p11.y += dx;

  if (x.ni[1]==0)
  {
    gobjpush(new gobjglVertex2d(p10));
    gobjpush(new gobjglVertex2d(p11));
  }

  if (x.ni[3]==0)
  {
    gobjpush(new gobjglVertex2d(p01));
    gobjpush(new gobjglVertex2d(p00));
  }

  
  if (x.ni[0]==0)
  {
    gobjpush(new gobjglVertex2d(p01));
    gobjpush(new gobjglVertex2d(p11));
  }
  
  if (x.ni[2]==0)
  {
    gobjpush(new gobjglVertex2d(p00));
    gobjpush(new gobjglVertex2d(p10));
  }
}

void mazedisp02::celldraw2
( 
  cellD2<uint> const & x,
  point2<double> const & p00
)
{
  double dx2 = dx*0.5;

  point2<double> p3 = p00;
  p3.y += dx2;
  point2<double> p1 = p00;
  p1.x += dx;
  p1.y += dx2;
  point2<double> p0 = p00;
  p0.x += dx2;
  p0.y += dx;
  point2<double> p2 = p00;
  p2.x += dx2;

  point2<double> pcenter = p00;
  pcenter.x += dx2;
  pcenter.y += dx2;

  if (x.ni[1]!=0)
  {
    gobjpush(new gobjglVertex2d(pcenter));
    gobjpush(new gobjglVertex2d(p1));
  }

  if (x.ni[3]!=0)
  {
    gobjpush(new gobjglVertex2d(pcenter));
    gobjpush(new gobjglVertex2d(p3));
  }
  
  if (x.ni[0]!=0)
  {
    gobjpush(new gobjglVertex2d(pcenter));
    gobjpush(new gobjglVertex2d(p0));
  }
  
  if (x.ni[2]!=0)
  {
    gobjpush(new gobjglVertex2d(pcenter));
    gobjpush(new gobjglVertex2d(p2));
  }
}



