/*
 * 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 <front_t1.hxx>
   
/*    
________________________________________________________________________
                       
                         SUBRRUTINA TESTEO      

    Testea si se puden ir uniendo trozos de frontera para formar una
    curva cerrada. Si los puede unir los unira en un sentido y otro
    segun pueda. El resultado final se una lista (Frontera_T1)
    cuyos elementos seran a su vez una lista de aristas, estas ordenadas
    y de tal manera que forman curvas. El numero de elementos de la
    lista (Frontera_T1) nos da el numero de componentes conexas
    de la frontera.
    
    Entrada: Una lista desordenada de aristas...
    Salida:  Las aristas ordenadas formando curvas. 
*/
void Frontera_T1::testeo() {
  FraristaT1_link* aux,*aux1,*sig;
  aux=begin;
  while(aux) {
    aux1=aux->suc;
    while (aux1) {
      if ((*aux)<(*aux1)) {   
        sig=aux1;
        aux1=aux1->suc;
        enlaza(aux,sig,1);
        delete sig;
      }
      else {
        if ((*aux1)<(*aux)) {
          sig=aux1;
          aux1=aux1->suc;
          enlaza (aux,sig,-1);
          delete sig;     
        }
        else aux1=aux1->suc;
      }
    }
    aux=aux->suc;
  }
}

/*  --------------------------------------------------------------------

                       SUBRRUTINA D_FRONTERA

   Proposito:  Dado un punto y la Frontera de un dominio, busco la
   ---------   arista y por tanto, el elemento mas proximo al punto
               dado. Calcularemos tambien el proyectado sobre la arista.

   Entrada:    pt= Punto dado.
   -------     - Frontera apuntada por this.
               dista=distancia inicial, si no se conoce
                     poner infinito.
   Salida:     proyec= proyectado sobre la frontera.
   ------      aret=  arista mas cercana.
               trian= elemento que contine la arista.

*/
Scalar Frontera_T1::d_frontera(R2 pt, R2& proyec,
                               Arista_T1& arete, Triangulo_T1& triangle,
                               const Scalar& dista,int refwall) {
  
  FraristaT1_link* aux1;
  AristaT1_list* comp_conex;
  AristaT1_link* aux;
  Arista_T1* aret;
  Scalar d0,dist=dista;
  R2 pr_pt(0,0);
  aux1=begin;
  
  while (aux1) {
    comp_conex=aux1->Aretelist;
    aux=comp_conex->principio();
    while(aux) {
      aret=aux->a;
      if (aret->ref==refwall) {
        d0=d_arete(*aret,pt,pr_pt);
        if (d0<dist) {
          dist=d0;
          arete=*aret;
          triangle=*(aret->tr);
          proyec=pr_pt;
        }
      }
      aux=aux->sig();
    }
    aux1=aux1->sig();
  }
  return dist;
}
void Frontera_T1::write (ostream& os) {
  int num=0,i=0;
  FraristaT1_link* aux;
  num=this->num_elem();
  os <<endl<<"Numero de curvas de la frontera:"<<num<<endl;
  aux=begin;
  while (aux) {
    i++;
    os <<aux<<" Curva:"<<i<<" constituida por las Aristas"<<endl;
    os <<(*(aux->Aretelist))<<endl;
    aux=aux->suc;
  }
}

ostream& operator<<(ostream& os, Frontera_T1& fl)
{ fl.write (os); return os;}

