namespace X3DTK {
namespace X3D {

template<class MData, class VData, class EData, class FData, bool RW>
TemplateMeshBuilderCoreVisitor<MData, VData, EData, FData, RW>::TemplateMeshBuilderCoreVisitor()
: CoreVisitor()
{
  // Enter functions.
  define(Recorder<Scene>::getEnterFunction(&TemplateMeshBuilderCoreVisitor::enterScene));
  define(Recorder<X3DNode>::getEnterFunction(&TemplateMeshBuilderCoreVisitor::enterX3DNode));
  
  // WalkOn functions.
  define(Recorder<X3DNode>::getWalkOnFunction(&TemplateMeshBuilderCoreVisitor::walkOnX3DNode));
  
  // Leave functions.
  define(Recorder<X3DNode>::getLeaveFunction(&TemplateMeshBuilderCoreVisitor::leaveX3DNode));
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderCoreVisitor<MData, VData, EData, FData, RW>::enterScene(Scene *S) 
{
  TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> >::getInstance();  
  MESH::Scene *MS = dynamic_cast<MESH::Scene *>(stateVariables->getNode(S));
  if (MS == 0)
  {
    MS = new MESH::Scene();
    MS->setName(S->getName());
    MS->getProcessHistory() = S->getProcessHistory();
        
    MS->setFileName(S->getFileName());
    stateVariables->addCoupleNode(S, MS);
  }
  stateVariables->pushNode(MS);
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderCoreVisitor<MData, VData, EData, FData, RW>::enterX3DNode(X3DNode *) 
{
  TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  stateVariables->pushNode(0);
}

template<class MData, class VData, class EData, class FData, bool RW>
bool TemplateMeshBuilderCoreVisitor<MData, VData, EData, FData, RW>::walkOnX3DNode(X3DNode *, SFNode) 
{
  TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  return ((stateVariables->getTop() != 0) && (stateVariables->getChildrenVisit()));
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateMeshBuilderCoreVisitor<MData, VData, EData, FData, RW>::leaveX3DNode(X3DNode *) 
{
  TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateMeshBuilderStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  stateVariables->popNode();
};

}
}
