#include <gobjbase.h>

gobjContainer * gobj::global = 0;


vector< gobjContainer * > gobjContainer::globalvec;

void gobjContainer::globalpop()
{ 
  assert(globalvec.empty()==false); 
  gobj::global =
    globalvec[globalvec.size()-1]; 
  globalvec.pop_back();
}


gobjglCallList<GLuint> * gobjContainer::displaylistcreatenew
(
  uintc id
)
{
  GLuint listName = glGenLists(id);
  gobjglCallList<GLuint> * gcl = 
    new gobjglCallList<GLuint>(listName);
  glNewList(listName,GL_COMPILE);
  
  draw();

  glEndList();

  return gcl;
}

gobj::~gobj()
{
}

void gobj::globaldisplaylist(uintc id)
{ 
  assert(global!=0); 
  global->displaylist(id); 
}

void gobjContainer::displaylist(uintc id)
{  
  if (vg.empty()) 
    return; 

  gobj * x = displaylistcreatenew(id); 
  nuke(); 
  cleanup=true; 
  push(x); 
}

void gobjContainer::draw()
{
  GOBJDEBUGCODE

  if (vg.empty())
    return;

  for (uint i=0; i<vg.size(); ++i)
    vg[i]->draw();
}

boolc gobjContainer::kill(uintc k)
{ 
  assert(k<vg.size());
  if (k>=vg.size()) 
    return false; 
  vg[k]=0; 

  return true; 
} 

boolc gobjContainer::kill(gobj* const targ)
{ 
  uint imax=vg.size();
  for (uint i=0; i<imax; ++i)
  {
    if (vg[i]==targ)
    {
      vg[i]=0;
      return true;
    }
  }

  return false; 
} 

gobjContainer::gobjContainer()
  : cleanup(true) 
{
};

gobjContainer::gobjContainer(boolc cleanup_)
  : cleanup(cleanup_)
{
}

void gobjContainer::nuke()
{
  if (!cleanup)
  {
    vg.clear();
    return;
  }

  for (uint i=0; i<vg.size(); ++i)
  {
    delete vg[i];
    vg[i] = 0;
  }
  vg.clear();
}

gobjContainer::~gobjContainer()
{
  nuke();
}


void gobjContainerdeque::draw()
{
  GOBJDEBUGCODE
  if (vg.empty())
    return;

  for (uint i=0; i<vg.size(); ++i)
    vg[i]->draw();
}

void gobjContainerdeque::nuke()
{
  if (!cleanup)
  {
    vg.clear();
    return;
  }

  for (uint i=0; i<vg.size(); ++i)
  {
    delete vg[i];
    vg[i] = 0;
  }
  vg.clear();
}

gobjContainerdeque::~gobjContainerdeque()
{
  nuke();
}


gobjContainerSwitch::gobjContainerSwitch(boolc cleanup_)
  : gcontainer(cleanup_)
{
}

gobjSwitch<> * gobjContainerSwitch::push( gobj * g )
{ 
  assert(g!=0); 
  gobjSwitch<> * gs = new gobjSwitch<>(g,true,gcontainer.cleanup);
  assert(gs!=0);
  gswitch.push_back(gs);
  gcontainer.vg.push_back(gs); 

  assert(gcontainer.vg.size()==gswitch.size());

  return gs;
}

//void gobjContainerSwitch::push( gobj * g )
//{
//  push_back(g);
//}

void gobjContainerSwitch::nuke()
{
  uint sz=gswitch.size();
  for (uint i=0; i<sz; ++i)
    delete gswitch[i];
  gswitch.clear();
  gcontainer.vg.clear();
}

gobjContainerSwitch::~gobjContainerSwitch()
{
  nuke();
}

void gobjContainerPrePost::draw()
{
  GOBJDEBUGCODE
  pre.draw();
  gobjContainer::draw();
  post.draw();
}




