/*
    C++ Mesh Generation Library
    Copyright (c) 2000echet <eric at bechet dot ca>

    This file is part of the C++ Mesh Generation Library.

    See the NOTICE & LICENSE files for conditions.
*/
//---------------------------------------------------------------------------
#ifndef TOPOLOGICAL_FACE_H
#define TOPOLOGICAL_FACE_H
//---------------------------------------------------------------------------


#include "mesh_const.h"

#ifdef USE_HASH_TABLE
#include <hash_set>
#endif

#include <list>
#include <set>

#include "entity.h"
#include "topology_entity.h"
#include "comparators.h"


using namespace std;

///class used to formalize relationship between elements in a mesh. It is a similar to a face of an element in 3D
template<class V,class E> class Topological_Face : public Topology_Entity<E,V>

{
public :

///Type of container
  typedef list<Topological_Face<V,E> > Container_Type;
///type of Container iterator
  typedef typename Container_Type::iterator Iterator;


///Type of classification
#ifndef USE_HASH_TABLE
  typedef set<Iterator,Less_Ptr_Type<Iterator> > Classification_Type;
#endif

#ifdef USE_HASH_TABLE
  typedef hash_set<Iterator,Hash_Ptr_Type<Iterator>,Equ_Ptr_Type<Iterator> > Classification_Type;
#endif
///type of Classification iterator
  typedef typename Classification_Type::iterator Classification_Iterator;

///various iterator types used generally
  typedef typename Topology_Entity<E,V>::B_iterator TVertex_iterator;
///
  typedef typename Topology_Entity<E,V>::A_iterator TElement_iterator;
///
  typedef typename Topology_Entity<E,V>::const_B_iterator const_TVertex_iterator;
///
  typedef typename Topology_Entity<E,V>::const_A_iterator const_TElement_iterator;

private :
/// Declare a Classification_Iterator for back-linking to the classification container (fast erase/ access)
  Classification_Iterator I;
public :

///mandatory for hash tables
  size_t hash() const
  {

    size_t hsh=0x0;
    const_TVertex_iterator it=Vertex_begin();
    const_TVertex_iterator itend=Vertex_end();

    while ( it!=itend )
    {
      hsh=hsh^ ( size_t ) & ( * ( *it ) );
      ++it;
    }

    return hsh;
  }

///Set Classification iterator value to It
  void Set_Classification_Iterator ( Classification_Iterator It )
  {
    I=It;
  }

///returns the Classification iterator
  Classification_Iterator Get_Classification_Iterator() const
  {
    return I;
  }

///Topological_Face constructor (default)
  Topological_Face ( void )
  {
  }

///returns an iterator to the beginning  of the container for vertices
  const_TVertex_iterator Vertex_begin ( void ) const
  {
    return this->B_begin();
  }

///returns an iterator to the end  of the container for vertices
  const_TVertex_iterator Vertex_end ( void ) const
  {
    return this->B_end();
  }

///returns an iterator to the beginning  of the container for elements
  const_TElement_iterator Element_begin ( void ) const
  {
    return this->A_begin();
  }

///returns an iterator to the end of the container for elements
  const_TElement_iterator Element_end ( void ) const
  {
    return this->A_end();
  }

///Adds a vertex to the topological face
  void Add_Vertex ( V const Ver )
  {
    this->Add_B ( Ver );
  }

///Adds an element to the topological face
  void Add_Element ( E const Ele )
  {
    this->Add_A ( Ele );
  }

///deletes an element of the topological face
  void Delete_Element ( E const Ele )
  {
    this->Delete_A ( Ele );
  }

///returns the number of vertices
  const int Get_Number_Vertices ( void ) const
  {
    return this->Get_Number_B();
  }

///returns the number of elements
  const int Get_Number_Elements ( void ) const
  {
    return this->Get_Number_A();
  }

///Get vertices and store them in an user allocated array
  void Get_Vertices ( V Ver[] ) const
  {
    this->Get_Bs ( Ver );
  }

///Get elements and store them in an user allocated array
  void Get_Elements ( E Ele[] ) const
  {
    this->Get_As ( Ele );
  }

  /**Overloading == operator to check if two topological Entities are equal
  equality is based on vertices here*/
  bool operator == ( const Topological_Face<V,E>& F ) const
  {
    return this->Equal_B ( F );
  }

  /**Overloading < operator to compare two topological Entities
  based on vertices*/
  bool operator < ( const Topological_Face<V,E>& F ) const
  {
    return this->Less_B ( F );
  }

};
#endif // TOPOLOGICAL_FACE_H

 
