namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
TemplateStatsCalculatorCoreVisitor<MData, VData, EData, FData, RW>::TemplateStatsCalculatorCoreVisitor()
{
  // Enter and leave functions.
  define(Recorder<TemplateMesh<MData, VData, EData, FData, RW> >::getEnterFunction(&TemplateStatsCalculatorCoreVisitor::enterMesh));
  define(Recorder<TemplateVertex<MData, VData, EData, FData, RW> >::getEnterFunction(&TemplateStatsCalculatorCoreVisitor::enterVertex));
  define(Recorder<Shape>::getWalkOnFunction(&TemplateStatsCalculatorCoreVisitor::walkOnShape));
}

template<class MData, class VData, class EData, class FData, bool RW>
bool TemplateStatsCalculatorCoreVisitor<MData, VData, EData, FData, RW>::walkOnShape(Shape *, SFNode child)
{
  TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  MFNode selectedNodes = stateVariables->getSelectedNodes();
  return (selectedNodes.empty() || (std::find(selectedNodes.begin(), selectedNodes.end(), child) != selectedNodes.end()));
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateStatsCalculatorCoreVisitor<MData, VData, EData, FData, RW>::enterMesh(TemplateMesh<MData, VData, EData, FData, RW> *M)
{
  TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  if (!stateVariables->getNode(M))
  { 
    stateVariables->setCurrentMesh(M);
  
    stateVariables->addFaces(M->getFaces().size());

    MFNode parents = M->getParentList();
    unsigned int size = 0;
    for (MFNode::const_iterator itParent = parents.begin(); itParent != parents.end(); ++itParent)
    {
      if (dynamic_cast<MESH::Shape *>(*itParent) != 0)
        ++size;
    }
    stateVariables->setInstances(size);
  
    stateVariables->addNode(M);
  }
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateStatsCalculatorCoreVisitor<MData, VData, EData, FData, RW>::enterVertex(TemplateVertex<MData, VData, EData, FData, RW> *V)
{
  TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> *stateVariables = Singleton<TemplateStatsCalculatorStateVariables<MData, VData, EData, FData, RW> >::getInstance();
  if (!stateVariables->getNode(V))
  {
    stateVariables->addVertices(V->getVertices().size());
    stateVariables->addEdges(V->getEdges().size());
        
    stateVariables->addNode(V);
  }
}

}
}  
