////////////////////////////////////////////////////////////////////////////////
//                            MESH_SFFace.inl                                 //
////////////////////////////////////////////////////////////////////////////////

namespace X3DTK {
namespace MESH {

template<class MData, class VData, class EData, class FData, bool RW>
const typename SFTemplateFace<MData, VData, EData, FData, RW>::MFEdge &SFTemplateFace<MData, VData, EData, FData, RW>::getEdges() const 
{
  return _edges;
}

template<class MData, class VData, class EData, class FData, bool RW>
typename SFTemplateFace<MData, VData, EData, FData, RW>::MFVertex SFTemplateFace<MData, VData, EData, FData, RW>::getVertices() const
{
  MFVertex vertices;
  for (typename MFEdge::const_iterator e = _edges.begin(); e != _edges.end(); ++e)
    vertices.push_back((*e)->getFromVertex());
  
  return vertices;  
}

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

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

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

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

template<class MData, class VData, class EData, class FData, bool RW>
SFTemplateFace<MData, VData, EData, FData, RW>::SFTemplateFace(unsigned int i)
: BaseSFFace(i)
{
}

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

template<class MData, class VData, class EData, class FData, bool RW>  
void SFTemplateFace<MData, VData, EData, FData, RW>::addEdge(SFTemplateEdge<MData, VData, EData, FData, RW> *edge)
{
  _edges.push_back(edge);
}

template<class MData, class VData, class EData, class FData, bool RW>  
void SFTemplateFace<MData, VData, EData, FData, RW>::reverse()
{
  // reversing for each edge of the face.
  for (typename MFEdge::iterator it = _edges.begin(); it != _edges.end(); ++it)
    (*it)->reverse(this);
  
  // reversing the list of edges of the face.
  MFEdge tmp;
  for (typename MFEdge::reverse_iterator it = _edges.rbegin(); it != _edges.rend(); ++it)
  {
    tmp.push_back((*it)->getSymetric());
  }
  _edges.clear();
  _edges = tmp;
}

template<class MData, class VData, class EData, class FData, bool RW>
std::ostream& operator<<(std::ostream& o, const SFTemplateFace<MData, VData, EData, FData, RW> &f)
{
  o << "( ";
  const typename SFTemplateFace<MData, VData, EData, FData, RW>::MFEdge &edges = f.getEdges();
  if (!edges.empty())
  {
    typename SFTemplateFace<MData, VData, EData, FData, RW>::MFEdge::const_iterator itEnd = edges.end();
    --itEnd;
    for (typename SFTemplateFace<MData, VData, EData, FData, RW>::MFEdge::const_iterator it = edges.begin(); it != itEnd; ++it)
      o << (*it)->getFromVertex()->getIndex() << ", ";
  
    o << (*itEnd)->getFromVertex()->getIndex();        
  }
  o << " )";  
  
  return o;
}  

}
}  
