////////////////////////////////////////////////////////////////////////////////
//                            MESH_SFEdge.inl                                 //
////////////////////////////////////////////////////////////////////////////////

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateEdge<MData, VData, EData, FData, RW> *SFTemplateEdge<MData, VData, EData, FData, RW>::getSymetric() 
{
  return _symetric;
}

template<class MData, class VData, class EData, class FData, bool RW>
typename SFTemplateEdge<MData, VData, EData, FData, RW>::MFFace SFTemplateEdge<MData, VData, EData, FData, RW>::getFaces() const 
{
  MFFace faces;
  const MFFace &r1faces = _edgeContent->get1Faces();
  const MFFace &r2faces = _edgeContent->get2Faces();
  
  //faces.reserve(r1faces.size() + r2faces.size() + 1);
  for (typename MFFace::const_iterator it = r1faces.begin(); it != r1faces.end(); ++it)
    faces.push_back(*it);

  for (typename MFFace::const_iterator it = r2faces.begin(); it != r2faces.end(); ++it)
    faces.push_back(*it);

  return faces;
}

template<class MData, class VData, class EData, class FData, bool RW>
bool SFTemplateEdge<MData, VData, EData, FData, RW>::isBoundary() const 
{
  return _edgeContent->isBoundary();
}

template<class MData, class VData, class EData, class FData, bool RW>
bool SFTemplateEdge<MData, VData, EData, FData, RW>::isNonManifold() const 
{
  return _edgeContent->isNonManifold();
}

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

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

#ifdef TEMPLATE_SPECIALIZATION_SUPPORTED
template<class MData, class VData, class EData, class FData, bool RW>
template<class F>  
F &SFTemplateEdge<MData, VData, EData, FData, RW>::getData()
{
  return SFTemplateEdge<MData, VData, EData, FData, RW>::_data.template get<F, false>();
}

template<class MData, class VData, class EData, class FData, bool RW>
template<class F>  
F &SFTemplateEdge<MData, VData, EData, FData, RW>::ogetData()
{
  return SFTemplateEdge<MData, VData, EData, FData, RW>::_data.template get<F, true>();
}
#endif

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateEdge<MData, VData, EData, FData, RW>::SFTemplateEdge(SFTemplateEdgeContent<MData, VData, EData, FData, RW> *const edgeContent)
: BaseSFEdge(), _edgeContent(edgeContent), _symetric(0)
{
}

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

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdge<MData, VData, EData, FData, RW>::setSymetric(SFTemplateEdge *symetric) 
{
  _symetric = symetric;
}

template<class MData, class VData, class EData, class FData, bool RW>
void SFTemplateEdge<MData, VData, EData, FData, RW>::reverse(SFTemplateFace<MData, VData, EData, FData, RW> *face)
{
  _edgeContent->reverse(face);
}

template<class MData, class VData, class EData, class FData, bool RW>
std::ostream& operator<<(std::ostream& o, const SFTemplateEdge<MData, VData, EData, FData, RW> &e)
{
  o << "< " << e.getFromVertex()->getIndex() << ", " << e.getToVertex()->getIndex() << " >";
  return o;
}

}
}
