/*
 * ADAPT2D : a software for automatic mesh adaptation in 2D
 *
 * AUTHOR : Manuel J. Castro Diaz(e-mail:castro@gamba.cie.uma.es)
 * ADAPTED FOR FREEFEM : Prud'homme Christophe (e-mail:prudhomm@ann.jussieu.fr) 
 *
 * this code is public domain
 * 
 * You may copy freely these files and use it for    
 * teaching or research. These or part of these may   
 * not be sold or used for a commercial purpose without
 * our consent
 * 
 * Any problems should be reported to the AUTHOR
 * at the following address : castro@gamba.cie.uma.es
 */


#ifndef _aristaCAD_h
#define _aristaCAD_h

#include <header.hxx>
#include <r2.hxx>

class Tangente {
public:
    R2 tang[2]; // Las dos tangentes en los vertices
                // de una arista
    Tangente () {tang[0].set(0,0);tang[1].set(0,0);}
    Tangente (R2 t0, R2 t1) {tang[0]=t0; tang[1]=t1;}
    Tangente (R2 tt[]) {tang[0]=tt[1]; tang[1]=tt[1];}
    void set (R2 t0, R2 t1) {tang[0]=t0; tang[1]=t1;}
    void set (R2 tt[]) {tang[0]=tt[1]; tang[1]=tt[1];}
    Tangente& operator=(const Tangente& tt) {
      tang[0]=tt.tang[0]; tang[1]=tt.tang[1];
      return *this;
    }
};

class Arista_CAD{ 
  friend ostream& operator<<(ostream&,Arista_CAD&);   
public:
  R2       c[2]; // Coordenadas de los vertices de la arista.
  int   refv[2]; // Referencia de los dos vertices.
  int      refa; // referencia de la arista.
  R2      cf[4]; // Puntos de control.
  Boolean front; // Tipo de arista: front=1 frontrera; front=2 interseccion.
  Tangente   tg; // Si la arista esta en la frontera del domino
                 // o la frontera entre subdominios apuntara
                 // a las dos tangentes en cada vertice. En
                 // otro caso apuntara a NIL.
  Arista_CAD (): refa(0),front(0) {
    c[0].set(0,0);
    c[1].set(0,0);
    refv[0]=refv[1]=0;
    cf[0].set(0,0);cf[1].set(0,0);cf[2].set(0,0);cf[3].set(0,0); 
    tg.tang[0].set(0,0); tg.tang[1].set(0,0);
  }
  Arista_CAD (const Arista_CAD& aa) {
    c[0]=aa.c[0]; c[1]=aa.c[1];
    refv[0]=aa.refv[0]; refv[1]=aa.refv[1];
    refa=aa.refa; front=aa.front; tg=aa.tg;
    cf[0]=aa.cf[0];cf[1]=aa.cf[1];cf[2]=aa.cf[2];cf[3]=aa.cf[3];}

  void write(ostream&);
  
  void set (R2 c0,R2 c1,int refv0,int refv1,int ref,Boolean fr) {
    c[0]=c0; c[1]=c1;
    refa=ref; front=fr;
    refv[0]=refv0;refv[1]=refv1;
  }

  void set (const Arista_CAD& aa) {
    c[0]=aa.c[0]; c[1]=aa.c[1];
    refv[0]=aa.refv[0]; refv[1]=aa.refv[1];
    refa=aa.refa; front=aa.front; tg=aa.tg;
    cf[0]=aa.cf[0];cf[1]=aa.cf[1];cf[2]=aa.cf[2];cf[3]=aa.cf[3];}

  Arista_CAD& operator=(const Arista_CAD& aa) {
    c[0]=aa.c[0]; c[1]=aa.c[1];
    refv[0]=aa.refv[0]; refv[1]=aa.refv[1];
    refa=aa.refa; front=aa.front; tg=aa.tg;
    cf[0]=aa.cf[0];cf[1]=aa.cf[1];cf[2]=aa.cf[2];cf[3]=aa.cf[3];
    return *this;}
  int operator==(const Arista_CAD& aa) {
    int v=0;
    if ( (c[0] == aa.c[0]) && (c[1] == aa.c[1])) v=1;
    return v;
  }
  Boolean frontera() { return front;}

  int operator<(Arista_CAD& aa)
  {return (c[1]==aa.c[0]);}
  int vertice(R2);
  R2 eval(Scalar);
  Scalar distancia(const R2&,R2&,Scalar&);
  friend Scalar angle(Arista_CAD*,Arista_CAD*);


};                  


#endif
