namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::TemplateX3DBuilderStateVariables()
: StateVariables(), _root(0), _cloner(Singleton<Cloner>::getInstance())
{
}

template<class MData, class VData, class EData, class FData, bool RW>
TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::~TemplateX3DBuilderStateVariables()
{
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::init()
{
  _root = 0;
  _nodeStack.push_front(0);
  _cloner->init();
}
template<class MData, class VData, class EData, class FData, bool RW>
void TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::finish()
{
  _nodeStack.clear();
  _nodeCoupleMap.clear();
  _cloner->finish();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::addCoupleNode(SFNode N, X3D::X3DNode *NN)
{
  _nodeCoupleMap[N] = NN;  

  // init root node.
  if (_root == 0)
    _root = NN;
}

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

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::popNode()
{
  _nodeStack.pop_front();
}
  
template<class MData, class VData, class EData, class FData, bool RW>
X3D::X3DNode *TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::getRoot() const 
{
  return _root;
}

template<class MData, class VData, class EData, class FData, bool RW>
X3D::X3DNode *TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::getTop() const 
{
  return (!_nodeStack.empty() ? _nodeStack.front() : 0);
}

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

template<class MData, class VData, class EData, class FData, bool RW>
SFNode TemplateX3DBuilderStateVariables<MData, VData, EData, FData, RW>::clone(SFNode N)
{
  return _cloner->clone(N, false);
}
  
}
}

