/* $Id: triang1.h,v 1.2 1996/10/11 15:15:38 bzferdma Exp $ */

#ifndef TRIANG1_H
#define TRIANG1_H

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

class PT1;
class EDG1;

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


class PT1 : public PT
{
  public:

    char  boundP, classA, mark, depth;
    EDG1  *e1, *e2;
    PT1   *next, *prev;
    Real  x;

    PT1() { 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 1; }
    virtual int Class() const { return classA; }
    virtual int Depth()    const { return depth; }

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

    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 EDG1 : public EDG
{
  private:
    static Vector<PT*>     p;
    static Vector<EDG*>    e;
    static Vector<PATCH*>  f;

  public:

    char  mark, classA, type, depth, boundP;
    PT1   *p1, *p2, *pm;
    EDG1  *next, *prev, *father, *firstSon;
    float error;

    EDG1() { 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 1; }
    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 { return 2; }

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

    virtual Bool refined() const { return Bool(firstSon); }
    virtual Bool isDirichlet() const { return False; }
    virtual Bool isGreen() const { return False; }

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

    virtual const Vector<PT*>& getPoints() const
				{ p[1]=p1; p[2]=p2; return p; }
    virtual const Vector<EDG*>& getEdges() const
                             {    void* pE = (void*) this;
				  e[1] = (EDG*) pE; return e;  }

    virtual const Vector<PATCH*>& getFaces() const
				{ f[1]=p1; f[2]=p2; return f; }
    virtual void getNeighbours(Vector<PATCH*>& neighbours)  const;

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

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

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

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


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

    virtual void print(ostream& os) const;

    virtual Real hMax() const;

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


class MESH1 : public MESH
{

  public:

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

    virtual MESH1* castToMESH1() { return this; }

    virtual void writeTriangulation(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 noOfEdges; }
    virtual int spaceDim() const { return 1; }

    const Stack<DList<PT1>*>&  points()  const { return ptList; }
    const Stack<DList<EDG1>*>& edges ()  const { return edgList; }

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

  protected:

    int	  noOfPoints, noOfEdges;

    enum { ElementsInBlock = 50 };

    Stack<DList<PT1>*>  ptList;   
    Stack<DList<EDG1>*> edgList;

    Allocator<PT1>  ptAlloc;
    Allocator<EDG1> edgAlloc;

    virtual EDG1* getEDG1() 	       { return edgAlloc.Get(); }
    virtual void  returnEDG1(EDG1* ed) { edgAlloc.Return(ed); }

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

    // --		general list iterators

    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* fileName);

    void readElements(BufferedParser& parser, Vector<PT1*>& ptAdr);
    void readPoints(BufferedParser& parser, Vector<PT1*>& ptAdr);
    void readBoundary(BufferedParser& parser, Vector<PT1*>& ptAdr);

    void setRightHand(EDG1* e);
    Bool RefineEdge(EDG1* e);
    void SetEP(EDG1 *e);
    void DelEP(EDG1 *e);
    
    void refinementInfo(int* noPt, int* noEdg);

    friend ostream& operator<< (ostream& os, const MESH1& t);
};

#endif
