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

#include "mesh_const.h"

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

#include "discrete_geometry.h"

using namespace std;


/// a specialization for surface geometry
class Discrete_Surface_Geometry : public Discrete_Geometry<2,3>
{
/// useful typedefs
  typedef Vertex_Type::Container_Type Vertex_Container_Type;
public :
///
  typedef Vertex_Type::Iterator Vertex_Iterator;
private :
///
  typedef Vertex_Type::Classification_Type Vertex_Classification_Type;
///
  typedef Vertex_Type::Classification_Iterator Vertex_Classification_Iterator;

/// container
  typedef list<Patch_Type> Patch_Type_Container;


#ifndef USE_HASH_TABLE
/// connectivity container (v1)
  typedef set<Topological_Face_Type/*, Cmp<Topological_Face_Type>*/ > Topological_Face_Type_Container;
#endif

#ifdef USE_HASH_TABLE
/// connectivity container (v2)
  typedef hash_set<Topological_Face_Type, Hash<Topological_Face_Type>, Equ<Topological_Face_Type> > Topological_Face_Type_Container;
#endif


/// the vertices container
  Vertex_Container_Type Vertices;
/// and classification
  Vertex_Classification_Type Classification_Vertices;
/// ... same for patches
  Patch_Type_Container Patches;
/// ... and topological faces
  Topological_Face_Type_Container Topological_Faces;

public:
/// adds a vertex to the mesh. Returns an iterator onto it
  Vertex_Iterator Add_Vertex ( Vertex_Type &Ver );
/// gets a vertex (returns an iterator)
  Vertex_Type* Get_Vertex ( Vertex_Type &Ver );
/// adds a patch (returns an iterator)
  Patch_Type* Add_Patch ( Patch_Type &Ele );
/// adds a topological face (returns an iterator)
  Topological_Face_Type* Add_Topological_Face ( Topological_Face_Type &Fac );

/// creates the topology (neighborhood)
  void Create_Topology();
/// reads an STL file
  void Read_STL_File ( char * filename );
/// constructs a discrete surface from user data
  void Create ( int nbn,double *tabn, int nbelt,int* tabelt );
/// projects a node on a patch
  bool Project_Point_On_Patch ( const Vertex_Type &V,Vertex_Type &VP,Vector &dir,Geometry_Patch<3,Vertex_Type> &ele,double &distance );

  /** projects a node "V" on the geometry
  the projected node is VP, the direction is dir,
  Hint is a list of patches that could possibly contain the node (can be empty),
  dist_max is the maximum distance of the projection. Distance is the actual one.*/
  Geometry_Patch<3,Vertex_Type>* Project_Point_On_Geometry ( const Vertex_Type &V,Vertex_Type &VP,Vector &dir,list<Geometry_Patch<3,Vertex_Type>*> Hint,double dist_max, double& distance );

  /**tesselates the geometry (uses simplexes to cover it "at any price")
   this is used as a starting point for mesh generation */
  void Tessellate ( Simple_Mesh<3,3,Element_Type>& M );

  virtual ~Discrete_Surface_Geometry() {}
};

#endif // DISCRETE_SURFACE_GEOMETRY_H

 
