/*
 * 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
 */


#include <t_t1_dl.hxx>

void Triangulo_T0_dlist::write (ostream& os) {
  int num=0;
  num=this->num_elem();
  Triangulo_T0_dlink* aux;
  aux=begin;
  os <<endl<< "Numero de Triangulos"<<num<<endl;
  os << endl
     << "       ***** TRIANGULOS *****"<<endl
     << "             ----------"<<endl;
  
  while (aux) {
    os <<aux<<" "<<(*(aux->t))<<endl;
    aux=aux->suc;
  }
}
ostream& operator<<(ostream& os, Triangulo_T0_dlist& rrl)
{rrl.write(os); return os;}






/*
                     SUBRRUTINA CONTIENE
     
     Determina si un vertice dado por *so esta en la lista de triangulos.
     1=Si su esta en la lista.
     0=Si no esta.
*/
  
Boolean Triangulo_T0_dlist::contiene(Vertice_T0* so) {
  Triangulo_T0_dlink* aux;
  Boolean encontrado=FALSE;
  if (begin) {
    aux=begin;
    while (aux) {
      if((aux->t)->sommet(so)!=-1) {
        encontrado=TRUE;
        break;
      }
      aux=aux->sig();
    }
  }
  return encontrado;
}

/* 
                 SUBRRUTINA T_VECINOS

   Construye la lista de triangulos vecinos al vertice so.

*/

void  t_vecinos(Vertice_T0* so, Triangulo_T0_dlist& lista) {
  Triangulo_T0_dlink* aux;
  Triangulo_T0* tr_ini,*tr,*tr_aux;
  int sent=1;
  Boolean recorrido=FALSE;
  aux=new Triangulo_T0_dlink;
  if (aux==NIL) ERROR();
  tr_ini=so->t;
  aux->set(tr_ini,NIL,NIL);
  lista.append(aux);
  tr_aux=tr_ini;
  do {
    tr=tr_aux->vecino(so,sent);
    if (tr==tr_ini) {
      recorrido=TRUE;
    }
    else {
      if (tr) {
        aux=new Triangulo_T0_dlink;
        if (aux==NIL) ERROR();
        aux->set(tr,NIL,NIL);
        if (sent==1) 
          lista.insert(aux);
        else
          lista.append(aux);
        tr_aux=tr;
      }
      else {
        if (sent==1) {
          sent=-1;
          tr_aux=tr_ini;
        }
        else {
          recorrido=TRUE;      
        }
      }
    }  
  } while (recorrido==FALSE);    
}

/*
                       SUBRRUTINA  AREA
     
         Calcula el area total de los triangulos que constituyen la lista.
 
         La lista es la apuntada por this.
*/

Scalar Triangulo_T0_dlist::area() {
  Triangulo_T0_dlink* aux;
  Scalar area0,areat;;
  if (begin) {
    aux=begin;
    areat=0;
    while (aux) {
      area0=(aux->t)->area();
      if (area0<1e-30) {
        cerr<<"Atencion. Triangulo degenerado"<<endl;
        cerr<<"Error Triangulo_T0_dlist::area."<<endl;
        exit(1);
      }
      areat=areat+area0;
      aux=aux->sig();
    }
  }
  return areat;
}
