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

void verifica (Triangulo_T1_dlist* Ltr, Arista_T1_dlist* Lar,\
               Vertice_T1_dlist* Lvr) {


  Triangulo_T1_dlink* Lt_lk;
  Arista_T1_dlink* La_lk;
  Vertice_T1_dlink* Lv_lk;
  
  Triangulo_T1* t0,*t1,*t2;
  Arista_T1* a0;
  Vertice_T1* v0,*s0,*s1;
  Scalar temp;
  int err=0;
  int pos=0;
  int pos0,pos1;
  int i;
#ifdef DEBUG
  cout<<"Mesh verification:"<<endl;
  cout<<"-----------------"<<endl;
  cout<<"Number of vertices:"<<(Lvr->num_elem())<<endl;
  cout<<"Vertex verification:"<<endl;
#endif /* DEBUG */
  
  Lv_lk=Lvr->principio();
  while (Lv_lk) {
    v0=Lv_lk->s;
    if (v0->lk!=Lv_lk) {
      cout<<"Error in vertex-link:"<<endl;
      cout<<*v0<<endl<<"Link:"<<Lv_lk<<endl;
      err++;
    }
    t0=v0->t;
    if (t0==NIL) {
      err++;
      cout<<"Triangle pointed by NIL vertex"<<endl;
      cout<<*v0<<endl<<t0<<endl;
    }
    else {
      pos=t0->sommet0(v0);
      if (pos==-1) {
        err++;
        cout<<"Error vertex-Triangle:"<<endl;
        cout<<*v0<<endl<<*t0<<endl;
      }
    }
    Lv_lk=Lv_lk->sig();
  }
#ifdef DEBUG
  cout<<"End testing vertices:"<<endl;
  cout<<endl<<"----------------------------------------------------"
      <<endl;
  cout<<"Number of edges:"<<(Lar->num_elem())<<endl;
  cout<<"Edge verification:"<<endl;
#endif /* DEBUG */
  La_lk=Lar->principio();
  while (La_lk) {
    a0=La_lk->a;
    if (a0->lk!=La_lk) {
      cout<<"Error edge-link:"<<endl;
      cout<<*a0<<endl<<"Link:"<<La_lk<<endl;
      err++;
    }
    s0=a0->s[0];
    s1=a0->s[1];
    t0=a0->tr;
    if (t0==NIL) {
      err++;
      cout<<"Error, Triangle pointed NIL:"<<endl;
      cout<<*a0<<endl<<t0<<endl;
    }
    else {
      if (s0==NIL || s1==NIL || s0==s1) {
        cout<<"Error, vertices NIL or identical:"<<endl;
        cout<<*a0<<endl<<s0<<"    "<<s1<<endl;
        err++;
      }
      else {
        pos0=t0->arista0(s0,s1);
        pos1=t0->arista0(a0);
        if (pos0==-1 && pos1==-1) {
          err++;
          cout<<"edge does'nt exist in triangle:"<<endl;
          cout<<*a0<<endl<<*t0<<endl;
        }
        if (pos0==-1 && pos1!=-1) {
          err++;
          cout<<"vertices don't appear:"<<endl;
          cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t0<<endl;
        }
        if (pos1==-1 && pos0!=-1) {
          err++;
          cout<<"edge does'nt appear:"<<endl;
          cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t0<<endl;
        }
        if (pos1!=-1 && pos0!=-1 && pos0!=pos1) {
          err++;
          cout<<"Edge not in the same place."<<endl;
          cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t0<<endl;
        }
        t1=t0->t[pos0];
        if (t1) {
          pos0=t1->arista0(s0,s1);
          pos1=t1->arista(a0);
          if (pos0==-1 && pos1==-1) {
            err++;
            cout<<"edge doesn't exist in triangle:"<<endl;
            cout<<*a0<<endl<<*t1<<endl;
          }
          if (pos0==-1 && pos1!=-1) {
            err++;
            cout<<"vertices don't appear:"<<endl;
            cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t1<<endl;
          }
          if (pos1==-1 && pos0!=-1) {
            err++;
            cout<<"edege doesn't appear:"<<endl;
            cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t1<<endl;
          }
          if (pos1!=-1 && pos0!=-1 && pos0!=pos1) {
            err++;
            cout<<"edge not in the same place."<<endl;
            cout<<*a0<<endl<<*s0<<endl<<*s1<<endl<<*t1<<endl;
          }
        }
      }
    }
    La_lk=La_lk->sig();
  }     
#ifdef DEBUG
  cout<<"End edge verification."<<endl;
  cout<<endl<<"----------------------------------------------------"
      <<endl;
  cout<<"Number of triangles:"<<(Ltr->num_elem())<<endl;
  cout<<"Triangle verification:"<<endl;
#endif /* DEBUG */
  Lt_lk=Ltr->principio();
  while (Lt_lk) {
    t0=Lt_lk->t;
    temp=t0->area2D();
    if (temp<1e-12) {
      cout<<"Error triangle area:"<<endl;
      cout<<*t0<<endl;
      err++;
    }
    if (t0->lk!=Lt_lk) {
      cout<<"Error triangle-link:"<<endl;
      cout<<*t0<<endl<<"Link:"<<Lt_lk<<endl;
      err++;
    }
    for (i=0; i<3; i++) {
      v0=t0->s[i];
      if (v0==NIL) {
        cout<<"Error triangle-vertex NIL:"<<endl;
        cout<<*t0<<endl<<v0<<endl;
        err++;
      }
    }
    for (i=0; i<3; i++) { 
      a0=t0->a[i];
      t1=t0->t[i];
      if (a0==NIL) {
        cout<<"Error triangle-edge NIL:"<<endl;
        cout<<*t0<<endl<<a0<<endl;
        err++;
      }
      else {
        t2=a0->tr;
        if (t1) {
          if (t2!=t1 && t2!=t0) {
            err++;
            cout<<"Error edge-triangle not equal:"<<endl;
            cout<<*t0<<endl<<*t1<<endl<<*a0<<endl;
          }
        }  
        else {
          if (t2!=t0) {
            err++;
            cout<<"Error edge-triangle not equal:"<<endl;
            cout<<*t0<<endl<<*t1<<endl<<*a0<<endl;
          }
        }
        s0=a0->s[0];
        s1=a0->s[0];
        pos=t0->arista0(a0);
        if (pos!=i) {
          err++;
          cout<<"Error edge-vertices-triangle not equal:"<<endl;
          cout<<*t0<<endl<<*a0<<endl<<*s0<<endl<<*s1<<endl;
        }
      }
    }
    for (i=0; i<3; i++) {
      t1=t0->t[i];
      if (t1) {
        a0=t0->a[i];
        pos=t1->arista0(a0);
        if (pos==-1) {
          err++;
          cout<<"Error triangle-neighboor_triangle:"<<endl;
          cout<<*t0<<endl<<*t1<<endl<<*a0<<endl;
        }
      }
    }
    Lt_lk=Lt_lk->sig();
  }
#ifdef DEBUG
  cout <<"End of verification:"<<endl;
  cout <<"Number of errors:"<<err<<endl;
  cout <<"--------------------------------------------"<<endl;
#endif /* DEBUG */
  if (err!=0) {
    cerr<<" Sorry too many errors in verifica."<<endl;
    exit(1);
  }
}
