namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::TemplateEdgesDrawerStateVariables()
: StateVariables(), _selectionMode(false)
{
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::init()
{
  _matrixStack.push_front(SFMatrix34f::identity);
  _matrixVector.clear();
  _vertexVector.clear();
  _coupleList.clear();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::finish()
{
  _matrixStack.pop_front();
  if (_matrixStack.size() != 0)
  {
    cx3d << "TemplateEdgesDrawerStateVariables::finish: Non empty matrix stack at the end of TemplateEdgesDrawer traversal" << std::endl;
    _matrixStack.clear();
  }
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::pushTransform(const SFMatrix34f &matrix)
{
  _matrixStack.push_front(_matrixStack.front()*matrix);
}

template<class MData, class VData, class EData, class FData, bool RW>
SFMatrix34f TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getCurrentTransform()
{
  return _matrixStack.front();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::popTransform()
{
  _matrixStack.pop_front();
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::addCouple(X3DNode *N, const SFMatrix34f &matrix)
{
  _coupleList.push_back(std::pair<X3DNode *, SFMatrix34f>(N, matrix));
}

template<class MData, class VData, class EData, class FData, bool RW>
bool TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getCouple(X3DNode *N, const SFMatrix34f &matrix) const
{
  return (std::find(_coupleList.begin(), _coupleList.end(), std::pair<X3DNode *, SFMatrix34f>(N, matrix)) != _coupleList.end());
}  

template<class MData, class VData, class EData, class FData, bool RW>
int TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getCurrentMeshId()
{
  return _matrixVector.size() - 1;
}
  
template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::storeVertex(TemplateVertex<MData, VData, EData, FData, RW> *vertex)
{
  _matrixVector.push_back(_matrixStack.front());
  _vertexVector.push_back(vertex);
}

template<class MData, class VData, class EData, class FData, bool RW>
TemplateVertex<MData, VData, EData, FData, RW> *TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getVertex(int i) const 
{
  return _vertexVector[i];
}

template<class MData, class VData, class EData, class FData, bool RW>
const SFMatrix34f &TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getMatrix(int i) const 
{
  return _matrixVector[i];
}

template<class MData, class VData, class EData, class FData, bool RW>
void TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::setSelectionMode(bool selectionMode) 
{
  _selectionMode = selectionMode;
}

template<class MData, class VData, class EData, class FData, bool RW>
bool TemplateEdgesDrawerStateVariables<MData, VData, EData, FData, RW>::getSelectionMode() const 
{
  return _selectionMode;
}

}
}
