namespace X3DTK {
namespace X3D {

template<class MData, class VData, class EData, class FData, bool RW>
TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::TemplateMeshBuilderStateVariables()
: StateVariables(), _root(0), _childrenVisit(true), _cloner(new Cloner())
{
}

template<class MData, class VData, class EData, class FData, bool RW>
TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::~TemplateMeshBuilderStateVariables()
{
  delete _cloner;
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::init()
{
  _root = 0;
  _nodeStack.push_front(0); 
  _childrenVisit = true;
  _cloner->init();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::finish()
{
  _nodeStack.clear();
  _nodeCoupleMap.clear();
  _cloner->finish();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::enableChildrenVisit()
{
  _childrenVisit = true;
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::disableChildrenVisit()
{
  _childrenVisit = false;
}

template<class MData, class VData, class EData, class FData, bool RW>
X3DNode *TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::clone(X3DNode *N)
{
  return static_cast<X3DNode *>(_cloner->clone(N, false));
}

template<class MData, class VData, class EData, class FData, bool RW>  
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::addCoupleNode(SFNode N, MESH::X3DNode *MN)
{
  _nodeCoupleMap[N] = MN;  
  
  // init root node.
  if (_root == 0)
    _root = MN;
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::pushNode(MESH::X3DNode *N)
{
  MESH::X3DNode *T = getTop();
  if (T != 0)
  {
    T->setChild(N);
  }
  _nodeStack.push_front(N);
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::popNode()
{
  _nodeStack.pop_front();
}

template<class MData, class VData, class EData, class FData, bool RW>
MESH::X3DNode *TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW>::getNode(SFNode N) const
{
  std::map<SFNode, MESH::X3DNode *>::const_iterator it = _nodeCoupleMap.find(N);
  if (it != _nodeCoupleMap.end())
    return (*it).second;
    
  return 0;  
}

}
}
