/*
 * 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 <a_t1_dl.hxx>
#include <v_t1_dl.hxx>
#include <front_t1.hxx>
#include <m_t0.hxx>

void cal_long(Arista_T1_dlist* Larete, Mallado_T0* malla,int refwall,int nbs) {
  Frontera_T1* frontera;
  Triangulo_T1 t_aux;
  Arista_T1_dlink* la_lk;
  Arista_T1* a0;
  Arista_T1  a_aux;
  Vertice_T1* s0,*s1;
  R2 pt,proyec;
  Scalar dist=1e+30;
  Scalar* d;
  Scalar l_min=1e+30;
  Scalar l_max=0.0;
  Scalar d0,dt,b0,b1,pr;
  int nt[21];
  int i,ctr,pos0;
  int i_crit;
  int cont=0,nba=Larete->num_elem();
#ifdef ADAPT2D
  char path[72]="H_WALL";
#endif  /*   ADAPT2D   */
  Boolean* ct;
  
  ct=new Boolean[nbs];
  d=new Scalar[nba];
  if (d==NIL ||ct==NIL) ERROR();
  for (i=0; i<21; i++) nt[i]=0;
  for (i=0; i<nbs; i++) ct[i]=0;

  la_lk=Larete->principio();
  frontera=Larete->crea_frontera();
  if (frontera==NIL) {
    cerr<<"Sorry. Not possible to construct boundary."<<endl;
    cerr<<"Error. in cal_long"<<endl;
    exit(1);
  }
#ifdef ADAPT2D
  OPEN(escritura, path);
  escritura.setf(ios::scientific,ios::floatfield);
  while (la_lk) {
    a0=la_lk->a;
    for (i=0; i<2; i++) {
      if (a0->s[i]->fluid!=FALSE) {
        pos0=a0->s[i]->lk->pos;
        if (ct[pos0]==0) {
          pt=a0->s[i]->c;
          d0=frontera->d_frontera(pt,proyec,a_aux,t_aux,dist,refwall);
          ct[pos0]=1;
          escritura<<""<<setw(15)<<proyec.x/malla->factr()<<setw(15)
                   <<d0/malla->factr()<<endl;
        }
      }
    }
    la_lk=la_lk->sig();
  }
  escritura.close();
#endif  /*   ADAPT2D   */
  cont=0;
  l_min=1e+30;
  l_max=0.0;
  la_lk=Larete->principio();
  while (la_lk) {
    a0=la_lk->a;
    s0=a0->s[0];
    s1=a0->s[1];
    d0=distance(s0->c,s0->mtr,s1->c,s1->mtr);
    if (d0>l_max) l_max=d0;
    if (d0<l_min) l_min=d0;
    d[cont]=d0;
    la_lk=la_lk->sig();
    cont++;
  }
  dt=(l_max-l_min)/20.0;
  ctr=0;
  for (i=0; i<nba; i++) {
    i_crit=int((d[i]-l_min)/dt);
    nt[i_crit]++;
    if (d[i]>0.75 && d[i]<1.25) ctr++;
  }
#ifdef DEBUG  
  cout<<endl<<endl;
  cout<<"Maximal length:"<<l_max<<endl;
  cout<<"Minimal length:"<<l_min<<endl;
  pr=Scalar(ctr)*100.0/Scalar(nba);
  cout<<"0.75< lg[i]<1.25 ......"<<setw(6)<<ctr<<".... Percent:"<<pr<<endl;
  for (i=0;i<21; i++) {
    b0=l_min+Scalar(i)*dt;
    b1=l_min+Scalar(i+1)*dt;
    pr=Scalar(nt[i])*100.0/Scalar(nba);
    cout<<"N. of edges with length ["<<setw(3)<<b0<<","\
        <<setw(3)<<b1<<")="<<setw(6)<<nt[i]\
        <<"  ........... Percent:"<<pr<<endl;
  }
#endif /* DEBUG */
  if (d) delete[] d;
  if (ct) delete[] ct;
  if (frontera) delete frontera;
}

