////////////////////////////////////////////////////////////////////////////////
//                            MESH_SFTemplateEdgeContent.inl                          //
////////////////////////////////////////////////////////////////////////////////

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateVertex<MData, VData, EData, FData, RW> *SFTemplateEdgeContent<MData, VData, EData, FData, RW>::getFromVertex() const 
{
  return _from;
}

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateVertex<MData, VData, EData, FData, RW> *SFTemplateEdgeContent<MData, VData, EData, FData, RW>::getToVertex() const 
{
  return _to;
}

template<class MData, class VData, class EData, class FData, bool RW>
const typename SFTemplateEdgeContent<MData, VData, EData, FData, RW>::MFFace &SFTemplateEdgeContent<MData, VData, EData, FData, RW>::get1Faces() const 
{
  return _r1Faces;
}

template<class MData, class VData, class EData, class FData, bool RW>
const typename SFTemplateEdgeContent<MData, VData, EData, FData, RW>::MFFace &SFTemplateEdgeContent<MData, VData, EData, FData, RW>::get2Faces() const 
{
  return _r2Faces;
}

template<class MData, class VData, class EData, class FData, bool RW>
bool SFTemplateEdgeContent<MData, VData, EData, FData, RW>::isBoundary() const 
{
  return (_r2Faces.size() == 0) || (_r1Faces.size() == 0);
}

template<class MData, class VData, class EData, class FData, bool RW>
bool SFTemplateEdgeContent<MData, VData, EData, FData, RW>::isNonManifold() const 
{
  return (_r2Faces.size() > 1) || (_r1Faces.size() > 1);
}

template<class MData, class VData, class EData, class FData, bool RW>
EData &SFTemplateEdgeContent<MData, VData, EData, FData, RW>::data() 
{
  return _data;
}

template<class MData, class VData, class EData, class FData, bool RW>
const EData &SFTemplateEdgeContent<MData, VData, EData, FData, RW>::data() const 
{
  return _data;
}

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateEdgeContent<MData, VData, EData, FData, RW>::SFTemplateEdgeContent(SFTemplateVertex<MData, VData, EData, FData, RW> * from, SFTemplateVertex<MData, VData, EData, FData, RW> *const to) 
: _from(from), _to(to)
{
}

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

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdgeContent<MData, VData, EData, FData, RW>::add1Face(SFTemplateFace<MData, VData, EData, FData, RW> *face) 
{
  _r1Faces.push_back(face);
}

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdgeContent<MData, VData, EData, FData, RW>::add2Face(SFTemplateFace<MData, VData, EData, FData, RW> *face) 
{
  _r2Faces.push_back(face);
}

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdgeContent<MData, VData, EData, FData, RW>::remove1Face(SFTemplateFace<MData, VData, EData, FData, RW> *face) 
{
  typename MFFace::iterator it = std::find(_r1Faces.begin(), _r1Faces.end(), face);
  if (it != _r1Faces.end())
    _r1Faces.erase(it);
}

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdgeContent<MData, VData, EData, FData, RW>::remove2Face(SFTemplateFace<MData, VData, EData, FData, RW> *face) 
{
  typename MFFace::iterator it = std::find(_r2Faces.begin(), _r2Faces.end(), face);
  if (it != _r2Faces.end())
    _r2Faces.erase(it);
}

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdgeContent<MData, VData, EData, FData, RW>::reverse(SFTemplateFace<MData, VData, EData, FData, RW> *face)
{
//  std::cout << "r1 size before = " << _r1Faces.size() << std::endl;
//  std::cout << "r2 size before = " << _r2Faces.size() << std::endl;
  
  typename SFTemplateEdgeContent<MData, VData, EData, FData, RW>::MFFace::iterator it = std::find(_r1Faces.begin(), _r1Faces.end(), face);
  if (it == _r1Faces.end())
  {
    it = std::find(_r2Faces.begin(), _r2Faces.end(), face);
    if (it != _r2Faces.end())
    {
      _r2Faces.erase(it);
      _r1Faces.push_back(face);
    }  
  }
  else
  {
    _r1Faces.erase(it);
    _r2Faces.push_back(face);    
  }  
  
//  std::cout << "r1 size after = " << _r1Faces.size() << std::endl;
//  std::cout << "r2 size after = " << _r2Faces.size() << std::endl;
}


 
}
}
