
#include <gobj.h>
#include <stringconvert.h>
#include <stringspace.h>
#include <tokenizer.h>



gobjglutSolidCube::gobjglutSolidCube(GLdouble size_)
  : size(size_)
{}

void gobjglutSolidCube::draw()
{
  GOBJDEBUGCODE
  glutSolidCube(size);
}

gobjglutWireCube::gobjglutWireCube(GLdouble size_)
  : size(size_)
{}

void gobjglutWireCube::draw()
{
  GOBJDEBUGCODE
  glutWireCube(size);
}

gobjglutSolidCone::gobjglutSolidCone
(
  GLdouble base_,
  GLdouble height_,
  GLint slices_,
  GLint stacks_
)
  : base(base_), height(height_), slices(slices_),
  stacks(stacks_)
{
}

void gobjglutSolidCone::draw()
{
  GOBJDEBUGCODE
  glutSolidCone(base,height,slices,stacks);
}

gobjglutWireCone::gobjglutWireCone
(
  GLdouble base_,
  GLdouble height_,
  GLint slices_,
  GLint stacks_
)
  : base(base_), height(height_), slices(slices_),
  stacks(stacks_)
{
}

void gobjglutWireCone::draw()
{
  GOBJDEBUGCODE
  glutWireCone(base,height,slices,stacks);
}


gobjglutSolidTeapot::gobjglutSolidTeapot(GLdouble size_)
  : size(size_)
{}

void gobjglutSolidTeapot::draw()
{
  GOBJDEBUGCODE
  glutSolidTeapot(size);
}

gobjglutWireTeapot::gobjglutWireTeapot(GLdouble size_)
  : size(size_)
{}

void gobjglutWireTeapot::draw()
{
  GOBJDEBUGCODE
  glutWireTeapot(size);
}


gobjglutSolidSphere::gobjglutSolidSphere
(
  GLdouble radius_,
  GLint slices_,
  GLint stacks_
)
  : radius(radius_), slices(slices_), stacks(stacks_)
{
}

void gobjglutSolidSphere::draw()
{
  GOBJDEBUGCODE 
  glutSolidSphere(radius,slices,stacks);
}


gobjglutWireSphere::gobjglutWireSphere
(
  GLdouble radius_,
  GLint slices_,
  GLint stacks_
)
  : radius(radius_), slices(slices_), stacks(stacks_)
{
}

void gobjglutWireSphere::draw()
{
  GOBJDEBUGCODE 
  glutWireSphere(radius,slices,stacks);
}

gobjglutSolidTorus::gobjglutSolidTorus
(
  GLdouble innerRadius_, 
  GLdouble outerRadius_, 
  GLint nsides_, 
  GLint rings_
)
  : innerRadius(innerRadius_), outerRadius(outerRadius_),
    nsides(nsides_), rings(rings_) {}

void gobjglutSolidTorus::draw()
{
  GOBJDEBUGCODE
  glutSolidTorus(innerRadius,outerRadius,nsides,rings);
}

gobjglutWireTorus::gobjglutWireTorus
(
  GLdouble innerRadius_, 
  GLdouble outerRadius_, 
  GLint nsides_, 
  GLint rings_
)
  : innerRadius(innerRadius_), outerRadius(outerRadius_),
    nsides(nsides_), rings(rings_) {}

void gobjglutWireTorus::draw()
{
  GOBJDEBUGCODE
  glutWireTorus(innerRadius,outerRadius,nsides,rings);
}




gobjGlobal::gobjGlobal(gobjContainer * const globalnew_)
  : globalnew(globalnew_)
{
  assert(globalnew);
  globalnew->globalpush();
}

gobjGlobal::~gobjGlobal()
{
  globalnew->globalpop();
}

boolc gobjglPushAttrib::serializeInverse(stringc & arg)
{
  string s1(arg);
  spacertrim<>()(s1);
  if (s1=="GL_CURRENT_BIT")
  {
    mask = GL_CURRENT_BIT;
    return true;
  }
  if (s1=="GL_LIGHTING_BIT")
  {
    mask = GL_LIGHTING_BIT;
    return true;
  }

  cout << "error: gobjglPushAttrib(" << arg << ");" << endl; 
  assert(false); 

  return false;
}

gobjglPushAttrib::gobjglPushAttrib(stringc & arg)
{  
  asserteval(serializeInverse(arg));
}

boolc gobjglVertex3f::serializeInverse(stringc & arg) 
{
  tokenizer ss(arg);
  ss.tokenize();
  if (ss.seq.size()!=3)
    return false;

  ss.reset();
  stringfrom(x,ss());
  ++ss;
  stringfrom(y,ss());
  ++ss;
  stringfrom(z,ss());

  return true;
}

gobjglVertex3f::gobjglVertex3f(stringc & arg)
{
  asserteval(serializeInverse(arg));
}




boolc gobjglColor3f::serializeInverse(stringc & arg) 
{
  tokenizer ss(arg);
  ss.tokenize();
  if (ss.seq.size()!=3)
    return false;

  ss.reset();
  stringfrom(x,ss());
  ++ss;
  stringfrom(y,ss());
  ++ss;
  stringfrom(z,ss());

  return true;
}

gobjglColor3f::gobjglColor3f(stringc & arg)
{
  asserteval(serializeInverse(arg));
}



#define gobjglenabledisable(arg)\
{ if (s1=="arg") { capability = arg; return true; } }


boolc gobjglDisable::serializeInverse(stringc & arg)
{
  string s1(arg);
  spacertrim<>()(s1);

  gobjglenabledisable(GL_ALPHA);
  gobjglenabledisable(GL_AUTO_NORMAL);
  gobjglenabledisable(GL_BLEND);
  //gobjglenabledisable(GL_CLIP_PLANEi);
  gobjglenabledisable(GL_COLOR_LOGIC_OP);
  gobjglenabledisable(GL_COLOR_MATERIAL);
  gobjglenabledisable(GL_COLOR_TABLE);
  gobjglenabledisable(GL_CONVOLUTION_1D);
  gobjglenabledisable(GL_CONVOLUTION_2D);
  gobjglenabledisable(GL_CULL_FACE);
  gobjglenabledisable(GL_DEPTH_TEST);
  gobjglenabledisable(GL_DITHER);
  gobjglenabledisable(GL_FOG);
  gobjglenabledisable(GL_HISTOGRAM);
  gobjglenabledisable(GL_INDEX_LOGIC_OP);
  //gobjglenabledisable(GL_LIGHTi);
  gobjglenabledisable(GL_LIGHTING);
  gobjglenabledisable(GL_LINE_SMOOTH);
  gobjglenabledisable(GL_LINE_STIPPLE);
  gobjglenabledisable(GL_MAP1_COLOR_4);
  gobjglenabledisable(GL_MAP1_INDEX);

/*
  if (s1=="GL_LIGHTING")
  {
    capability = GL_LIGHTING;
    return true;
  }
*/

  cout << "error: gobjglDisable(" << arg << ");" << endl; 
  assert(false); 

  return false;
}

gobjglDisable::gobjglDisable(stringc & arg)
{  
  asserteval(serializeInverse(arg));
}

  



boolc gobjglBegin::serializeInverse(stringc & arg)
{
  string s1(arg);
  spacertrim<>()(s1);

  if (s1=="GL_POINTS")
  {
    mode = GL_POINTS;
    return true;
  }

  if (s1=="GL_LINES")
  {
    mode = GL_LINES;
    return true;
  }

  if (s1=="GL_LINE_STRIP")
  {
    mode = GL_LINE_STRIP;
    return true;
  }

  if (s1=="GL_LINE_LOOP")
  {
    mode = GL_LINE_LOOP;
    return true;
  }

  if (s1=="GL_TRIANGLES")
  {
    mode = GL_TRIANGLES;
    return true;
  }

  if (s1=="GL_TRIANGLE_STRIP")
  {
    mode = GL_TRIANGLE_STRIP;
    return true;
  }

  if (s1=="GL_TRIANGLE_FAN")
  {
    mode = GL_TRIANGLE_FAN;
    return true;
  }
  if (s1=="GL_QUADS")
  {
    mode = GL_QUADS;
    return true;
  }

  if (s1=="GL_QUAD_STRIP")
  {
    mode = GL_QUAD_STRIP;
    return true;
  }

  if (s1=="GL_POLYGON")
  {
    mode = GL_POLYGON;
    return true;
  }

  cout << "error: gobjglBegin(" << arg << ");" << endl; 
  assert(false); 

  return false;
}

gobjglBegin::gobjglBegin(stringc & arg)
{  
  asserteval(serializeInverse(arg));
}

  



