/*
    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 VERTEX_H
#define VERTEX_H
//---------------------------------------------------------------------------



#include "mesh_const.h"

#ifdef USE_HASH_TABLE
#include <hash_set>
#endif
#include <set>
#include <list>

#include "vertex_base.h"
#include "geometry_vertex.h"
#include "geometry_patch.h"

using namespace std;


/// class vertex to store a node of a mesh
template<int N> class Vertex : public Vertex_Base<N>
{

public :

/// associated type
//  typedef Geometry_Vertex<N> Geometry_Vertex_Type;


/// containers type
  typedef list<Vertex<N> > Container_Type;
///
  typedef typename Container_Type::iterator Iterator;

#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

///
  typedef typename Classification_Type::iterator Classification_Iterator;

protected:
/// locus of this node on the geometry (patch)
  Geometry_Patch<N,Geometry_Vertex<N> >* locus;
/// back-pointer to allow fast erase
  Classification_Iterator I;

public:

/// sets the classification iterator
  void Set_Classification_Iterator ( Classification_Iterator It )
  {
    I=It;
  }

/// gets the classification iterator
  Classification_Iterator Get_Classification_Iterator() const
  {
    return I;
  }

/// gets the geometru patch on witch the node lies
  Geometry_Patch<N,Geometry_Vertex<N> >* Get_Geometry_Patch ( void )
  {
    return locus;
  }

/// gets the geometru patch on witch the node lies
  void Set_Geometry_Patch ( Geometry_Patch<N,Geometry_Vertex<N> >* ELE )
  {
    locus=ELE;
  }

/// init (default constructor)
  Vertex ( void )
  {
    for ( int i=0; i<N; ++i )
    {
      this->coord[i]=0;
    }

    locus=NULL;
  }

/// init (from a user provided array of coordinates)
  Vertex ( double xx[] )
  {
    SetPos ( xx );
    locus=NULL;
  }

/// init (based on an existing geometry vertex)
  Vertex ( const Geometry_Vertex<N> &V )
  {
    for ( int i=0; i<N; ++i )
    {
      this->coord[i]=V[i];
    }

    locus=NULL;
  }

/// init, based on 2 existing vertices and a ratio
  Vertex ( const Vertex<N>& V1,const Vertex<N>& V2,double Ratio )
  {
    SetPos ( V1,V2,Ratio );
    locus=NULL;
  }

/// sets the position of the vertex (array)
  void SetPos ( double x[] )
  {
    for ( int i=0; i<N; ++i )
    {
      this->coord[i]=x[i];
    }
  }

/// sets the position of the vertex (2 other vertices and a ratio)
  void SetPos ( const Vertex_Base<N> &V1,const Vertex_Base<N> &V2,double Ratio )
  {
    Vertex_Base<N>::SetPos ( V1,V2,Ratio );
  }

};


#endif // VERTEX_H



 
