/* $Id: triang2.h,v 1.4 1996/10/31 15:21:06 bzferdma Exp $ */

#ifndef TRIANG2_H
#define TRIANG2_H

#include "triangA.h"
#include "alloc.h"

class PT2; 
class TR2;

//-------------------------------------------------------------------------


class PT2 : public PT
{
  public:

    char  boundP, classA, mark, depth;
    PT2   *next, *prev;
    Real  x,y;

    PT2() { reset(); }
    virtual void reset();

    virtual PATCH* Next() { return next; }
    virtual void setMark() { mark = 1; }
    virtual void unMark()  { mark = 0; }
    virtual Bool marked() const { return mark; }

    virtual int spaceDim() const { return 2; }
    virtual int Class()    const { return classA; }
    virtual int Depth()    const { return depth; }

    virtual Bool isDirichlet() const { return boundP==DIRICHLET; }

    virtual void getNodeCoord(Vector<Real>& v) const; 
    virtual void getCoordinates(Vector<Real>& v) const;

    virtual void print(ostream& os) const;

    void readBC(BufferedParser& parser);
};
//-------------------------------------------------------------------------

class EDG2 : public EDG
{
  private:
    static Vector<PT*>  p;

  public:

    char  mark, type, boundP;
    char  isBlueDiagonal, classA, isoP, depth;
    PT2   *p1, *p2, *pm;
    TR2   *t1, *t2;
    EDG2  *next, *prev, *father, *firstSon;

    EDG2() { reset(); }
    virtual void reset();

    virtual PATCH* Next() { return next; }
    virtual void setMark() { mark = 1; }
    virtual void unMark()  { mark = 0; }
    virtual Bool marked() const { return mark; }

    virtual int spaceDim() const { return 2; }
    virtual int Class() const { return classA; }
    virtual int Depth()    const { return depth; }

    virtual PATCH* getMidPoint() const { return pm; }

    virtual PATCH* Father() const { return father; }

    virtual Bool refined() const { return Bool(firstSon);  }
    virtual Bool isGreen() const { return (type==MESH::T_GREEN); }
    virtual Bool isVolatile() const {return (type==MESH::T_VOLATILE); }

    virtual Bool onBoundary() const  { return (t1==0 || t2==0); }
    virtual Bool isDirichlet() const { return boundP==DIRICHLET; }
    virtual Bool isNeumann() const   { return boundP==NEUMANN; }
    virtual Bool isCauchy() const    { return boundP==CAUCHY; }

    virtual void compNormalVector(Vector<Real>& normal, Real* length) const;

    virtual void realCoordinates(const Vector<Real>& u, Vector<Real>& x) const;

    virtual void getNodeCoord(Vector<Real>& v) const; 
    virtual void getCoordinates(Vector<Real>& p1, Vector<Real>& p2) const;
    virtual const Vector<PT*>& getPoints() const { p[1]=p1; p[2]=p2; return p; }

    virtual Real hMax() const;

    virtual void print(ostream& os) const;

    void readBC(BufferedParser& parser);
};
//-------------------------------------------------------------------------


class TR2 : public TR
{
  private:
    static Vector<PT*>    p;
    static Vector<EDG*>   e;

    static Vector<PATCH*> f;

  public:

    PT2		*p1,*p2,*p3;
    EDG2	*e1,*e2,*e3;
    TR2		*next, *prev, *father, *firstSon;
    float	error;
    char	mark, type, classA, boundP, depth;

    TR2() { reset(); }
    virtual void reset();

    virtual PATCH* Next() { return next; }
    virtual void setMark() { mark = 1; }
    virtual void unMark()  { mark = 0; }
    virtual Bool marked() const { return mark; }

    virtual int spaceDim() const { return 2; }
    virtual int Class() const { return classA; }
    virtual int Depth() const { return depth; }

    virtual PATCH* Father()   const { return father; }
    virtual PATCH* FirstSon() const { return firstSon; }
    virtual int NoOfSons() const;

    virtual Bool refined() const    { return Bool(firstSon); }
    virtual Bool isGreen() const    { return (type==MESH::T_GREEN); }
    virtual Bool isVolatile() const { return (type==MESH::T_VOLATILE); }

    virtual void setBoundary();
    virtual Bool  onBoundary() const { return boundP==BOUNDARY; }

    virtual void realCoordinates(const Vector<Real>& u, Vector<Real>& x) const;
    virtual void unitCoordinates(const Vector<Real>& x, Vector<Real>& u) const;

    virtual void getCoordinates(Vector<Real>& p1, Vector<Real>& p2,
				Vector<Real>& p3) const;
    virtual Real volume() const;

    virtual void compJ(Jacobian& J, Bool checkDetJ=True)  const;
    virtual void compJinv(Jacobian& J) const;

    virtual const Vector<PT*>& getPoints() const
				{ p[1]=p1; p[2]=p2; p[3]=p3; return p; }
    virtual const Vector<EDG*>& getEdges() const
				{ e[1]=e1; e[2]=e2; e[3]=e3; return e; }
    virtual const Vector<PATCH*>& getFaces() const
				{ f[1]=e1; f[2]=e2; f[3]=e3; return f; }
    virtual void getAllFaces(Vector<PATCH*>& faces)  const;  
    virtual void getNeighbours(Vector<PATCH*>& neighbours) const;
    virtual void getEdgeOrientation(Vector<Bool>& orient)  const;

    virtual void getEdges(EDG2* eds[]) const;

    virtual const PATCH* findPatch(const Vector<Real>& x, Vector<Real>& xUnit) 
    									const;
    virtual Bool inPatch(const Vector<Real>& x, Vector<Real>& xUnit) const;
    Real det3P(const Vector<Real>& x, const PT2* p2, const PT2* p3) const;

    virtual void print(ostream& os) const;

    virtual float getError() const { return error; }
    virtual void  setError(float x) { error = x; }
};
//-------------------------------------------------------------------------


class MESH2 : public MESH
{

  public:

    MESH2(const char* inFileName, Bool readMesh=True);
    ~MESH2();

    virtual MESH2* castToMESH2() { return this; }

    void writeTriangulation(const char* outFileText,const Vector<Real>& u) const;
    void writeGrapeFormat (const char* outFileText,const Vector<Real>& u) const;
    void writeZIBFormat (const char* outFileText,const Vector<Real>& u) const;

    virtual void Refine();
    virtual void Flatten();

    virtual FEPlot* newFEPlot(int plotType, char* caption, float size);

    virtual int noOfElements() { return noOfTriangles; }
    virtual int spaceDim() const { return 2; }

    virtual void Resolve(Real hMin, int nSteps=0);

    const Stack<DList<PT2>*>&  points()   const { return ptList; }
    const Stack<DList<TR2>*>&  triangles()const { return trList; }
    const Stack<DList<EDG2>*>& edges ()   const { return edgList; }

    virtual void Info();
    virtual int MemSpace();

		    //  private (at least in principle):
    
    int		noOfPoints, noOfEdges, noOfTriangles;
    enum { ElementsInBlock = 100 };

    Stack<DList<PT2>*>  ptList;   
    Stack<DList<EDG2>*> edgList;
    Stack<DList<TR2>*>  trList;

    Allocator<PT2>   ptAlloc;
    Allocator<TR2>   trAlloc;
    Allocator<EDG2>  edgAlloc;

    Stack<EDG2*> oldGreenEdges;    
    Stack<TR2*>  oldGreenTriangles;    

    virtual TR2* getTR2() 	    { return trAlloc.Get(); }
    virtual void returnTR2(TR2* tr) { trAlloc.Return(tr); }

    virtual const PATCH* findPatch(const Vector<Real>& x, Vector<Real>& xUnit,
				   const PATCH* newPatch)  const;


    // --		element iterator

    virtual void  resetElemIter(Bool lastStep=False);
    virtual PATCH* elemIterAll();
    virtual PATCH* elemIterAllOfHistory();

    virtual PATCH* ptIterAll();

    virtual PATCH* edgIterAll();
    virtual PATCH* edgIterAllOfHistory();


  protected:


    void readTriangulation(const char* inFileName);
    Bool readTriangulationOldFormat(const char* fileName);

    void readPoints  (BufferedParser& parser, Vector<PT2*>& ptAdr);
    void readElements(BufferedParser& parser, Vector<PT2*>& ptAdr);
    void readBoundary(BufferedParser& parser, Vector<PT2*>& ptAdr, 
		      Vector<Stack<EDG2*>*>& edgsOfPts);

    void  CompleteTriangle(TR2* t, Vector<Stack<EDG2*>*>& edsOfPts);
    EDG2* FindEdgByPts(PT2* p1, PT2* p2, Vector<Stack<EDG2*>*>& edsOfPts);
    void  setRightHand(TR2* t);
    Bool  pointOnEdge(PT2* p, EDG2* e);

    int  RefineTriangle(TR2 *t);
    int  MakeGreen();
    void RemoveGreen();
    void refinementInfo(int* noPt, int* noEdg, int* noTr);

    int  MakeTriangleGreen(TR2 *t);
    int  RefineTriangleRed(TR2 *t);
    int  Mark2(TR2 *t);
    EDG2* RefineEdge(EDG2 *ed);
    void InnerEdges (TR2 *t,EDG2 *e1,EDG2 *e2,EDG2 *e3,EDG2 *ie1,
		     EDG2 *ie2,EDG2 *ie3);
    void SetTP(TR2 *t, TR2 *f);
    void SetTE(TR2 *t);
    void DelTE(TR2 *t, int check);
    void consistencyCheck();
    void setXYpm(PT2* pm, const EDG2* e);

    friend ostream& operator<< (ostream& os, MESH2& t);
};
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------


class MESH2BISECT : public MESH2
{
  public:

    MESH2BISECT(const char* inFileName, Bool readMesh=True);

    virtual MESH2* castToMESH2() { return this; }
    virtual void Refine();

		    //  private (at least in principle):
  protected:
   
    Stack<TR2*>  newTriangles;    

    virtual int  RefineTriangle(TR2 *t);
    virtual int  RefineTriangleRed(TR2 *t);
    virtual int  TestBisection(TR2 *t);
    virtual void EdgBisection(TR2 *t);

    friend ostream& operator<< (ostream& os, MESH2BISECT& t);
};
//-------------------------------------------------------------------------


#endif
