#ifndef D3FAN_H
#define D3FAN_H

#include <cassert>
#include <set>
#include <map>
#include <vector>
#include <iosfwd>
using namespace std;

#include <d3tess.h>
#include <simplexD2linked.h>
#include <simplexface.h>
#include <typedefs.h>
#include <virtualtriangle.h>


class d3tess;


/*
  \brief  Build a 2D fan from a point outside the convex mesh.

          Assumed tess's virtual triangle's base
          is orientated and viewable to point w_ in eval.
*/
class d3fan
{
  d3tess & tess;
public:

  // Triangle face to triangle.
  map<simplexface,uint> stot; 

  // Boundary or linked faces
  set< simplexface > dead;

  // Constructor
  d3fan( d3tess & tess_ );

  // Build the 3D fan from the point w_ to the 
  //   surface of tess.  Assume tess.cp on surface.
  void eval(uintc w_);

  ostream & print(ostream & os) const;

private:

  /** The central point where all the points
     of the fan converge to. */
  uint w;           

  /** These are associated with partially constructed
     triangles which have been defined but not
     fully linked with their neighbours.
     The map stot connects the simplex with the triangle. */
  vector<simplexface> process;


  /** Build a spike from the current surface to point w.
      Also push the newely formed triangle onto the process stack.
      and partially link it to the old mesh surface. */
  void addspike();

  // When moving from one triangle on the old surface boundary
  //   to another, the associated pointers to the new triangles
  //   need to be connected.
  //
  // from - a newely created triangle which is the current focus
  //   ie is being iterated around
  // fromni - when moving you know the link which you want to set
  //   equal to the newely formed triangle that you are moving in
  //   to.  
  // vslocalpi - refers to the index to get the local point from
  //   the cpsimplex.  The inverse of this point gives the local
  //   index to from when applied to the new triangle.
  //
  //  Note: integer indexes are used and not pointers.  This is
  //    because the vi stack changes and so the pointers can not
  //    be invalidated.
  bool const link
  (
    uintc from, 
    uintc fromni, 
    uintc vslocalpi
  );

  /** The current surface face. */
  simplexface cpf;

  virtualtriangle const & vs;
  vector<simplexD2linked> & vi;
  uint & cp;
};

ostream & operator << (ostream & os, d3fan const & x);

//  About:  
//
//  The class is intended to be constructed once and reused.
//  
//  It may be observed that a hash data structure are more
//    appropriate for stot and dead data structures.  
//    <TODO> replace STL containers with hash tables.




#endif


