/*
 * 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 <header.hxx>
#include <r2.hxx>
#include <cad.hxx>
#include <a_t1.hxx>

Arista_CAD_dlink*  proyeccion_cao (CAD* cad,R2 pt, R2& pr_pt,Arista_CAD_dlink* a_ini,int tipo,int prof) {

  FraristaCAD_link* cad_lk;
  Arista_CAD_dlist* dlist;
  Arista_CAD_dlink* lk;
  Arista_CAD_dlink* a_fin=NIL;
  Arista_CAD* a0,*a0_fin;
  R2 p0;
  Scalar dist=1e+30;
  Scalar d0;
  Scalar temp,t0;
  int cont;
  Boolean calculado=FALSE;

  if (cad==NIL) ERROR();
  if (a_ini==NIL || prof==0) {
    cad_lk=cad->principio();
    while (cad_lk) {
      dlist=cad_lk->Aretelist;
      lk=dlist->principio();
      if (lk->a->front!=tipo) lk=NIL;
      while (lk) {
        a0=lk->a;
        d0=a0->distancia(pt,p0,temp);
        if (d0<dist) {
          calculado=TRUE;
          dist=d0;
          pr_pt=p0;
          a_fin=lk;
          a0_fin=a0;
          t0=temp;
        }
        lk=lk->sig();
      }
      cad_lk=cad_lk->sig();
    }
  }
  else {
    lk=a_ini;
    dlist=lk->dlist;
    cont=0;
    while (cont<prof) {
      a0=lk->a;
      d0=a0->distancia(pt,p0,temp);
      if (d0<dist) {
        calculado=TRUE;
        dist=d0;
        pr_pt=p0;
        a_fin=lk;
        a0_fin=a0;
        t0=temp;
      }
      lk=lk->sig();
      if (lk==NIL) lk=dlist->begin;
      cont++;
    }
    lk=a_ini;
    dlist=lk->dlist;
    lk=lk->prev;
    if (lk==NIL) lk=dlist->last; 
    cont=0;
    while (cont<prof) {
      a0=lk->a;
      d0=a0->distancia(pt,p0,temp);
      if (d0<dist) {
        calculado=TRUE;
        dist=d0;
        pr_pt=p0;
        a_fin=lk;
        a0_fin=a0;
        t0=temp;
      }
      lk=lk->ant();
      if (lk==NIL) lk=dlist->last;
      cont++;
    }
  }

  if (calculado) {
    pr_pt=a0_fin->eval(t0);
  }
  else {
    pr_pt=pt;
  }
  return a_fin;
}
