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


/*   *************************************************************************
                              CARETE SUBROUTINE
     *************************************************************************

          PURPOSE:  Construcion of the edge table of a triangulation.
          -------
      
          input:  * nu[] : Table of connectivities of triangles.
          ------    nu[0+i*3],nu[1+i*3],nu[2+i*3] Vertices of triangle  'i'.
                  * nt: Number of triangles.
                  * ns: Number of vertices.
                  * lma: Number maximal of edges.

          Output:   * ma[]:  Edge table
          ------            ma[0+i*4],ma[1+i*4]   2 vertices of the edge 'i'.
                            ma[2+i*4],ma[3+i*4]   2 adjacent triangles.
                                  ma[3+i*4]=0 if boundary edge.
                    * na : Number of edges.
                    * naf: Number of boundary edges.
                    * nua []: Three edges of the triangle 'i'.
                             nua[0+i*3],nua[1+i*3],nua[2+i*3] 
                                             
                                             
     *************************************************************************
*/

#include <header.hxx>
#include <carete.hxx>

int carete (int* nu,int nt, int ns, int* ma, int& na, int& naf, \
            int* nua) { 
  
  int kx, ki, ip, ip1, k1, k2, it, is, ia, i;
  int ka [2][3];
  
  int_list* k =new int_list[ns+1] ; // List for  hashing function.
  int_link* ilk,*ilkaux;
  
  ka[0][0]=0;ka[0][1]=1;ka[0][2]=2;
  ka[1][0]=1;ka[1][1]=2;ka[1][2]=0;
  if (k==NIL) ERROR();
  na=0;
  for (i=0; i<=ns; i++)  {
    ilkaux=new int_link;        //INITIALIZATION
    if (ilkaux==NIL) ERROR();
    ilkaux->set(0,NIL);
    k[i].append(ilkaux);
  }
  
  for (it=0; it<nt; it++) {
    for (is=0; is<3; is++) {
      k1=nu[ka[0][is]+it*3];
      k2=nu[ka[1][is]+it*3];
      kx=MAX(k1,k2);
      ki=MIN(k1,k2);
      if (kx==0 || ki==0) {
        cout<<"Attention. Error in pointers triangles <--> vertices."<<endl;
        cout<<"Error in subroutine carete."<<endl;
        exit(1);
      }
      if (kx>ns) {
        cout<<"Attention. Error in pointers triangles <--> vertices."<<endl;
        cout<<"ns:"<<ns<<" kx:"<<kx<<endl;
        exit(1);
      }
      ilk=k[kx].principio();
      ip=ilk->pos;
      testear:
      if (ip==0) {
        na++;
        nua[is+it*3]=na-1;
        ma[2+(na-1)*4]=it;
        ma[0+(na-1)*4]=k1;
        ma[1+(na-1)*4]=k2;
        ilkaux=new int_link;
        if (ilkaux==NIL) ERROR();
        ilkaux->set(0,NIL);
        ilk->set(na,NIL);
        k[kx].append(ilkaux);
      }
      else {
        ip1=ip;
        ilk=ilk->sig();
        ip=ilk->pos;
        if((ma[0+(ip1-1)*4]!=ki) && (ma[1+(ip1-1)*4]!=ki)) goto testear;
        if (ma[0+(ip1-1)*4]>0) {
          ma[0+(ip1-1)*4]=-ma[0+(ip1-1)*4];
          nua[is+it*3]=ip1-1;
          ma[3+(ip1-1)*4]=it;
        }
        else {
          cout<<"Sorry. Edge in more than two triangles."<<endl;
          cout<<"Sorry not implemented. Subroutine carete."<<endl;
          cout<<"Edge:"<<-ma[0+(ip1-1)*4]<<"-"<<ma[1+(ip1-1)*4]<<endl;
          cout<<"Triangles:"<<ma[2+(ip1-1)*4]+1<<", "<<ma[3+(ip1-1)*4]+1<<", "<<it+1<<endl;
          exit(1);
        }
      }
    }
  }      
  naf=0;
  for (ia=0; ia<na; ia++) {
    if (ma[0+ia*4]<0) {
      ma[0+ia*4]=-ma[0+ia*4];
    }
    else {
      ma[3+ia*4]=-1;
      naf++;
    }
  }
  for( i=0;i<=ns;i++) k[i].clear();
  delete[] k;
  return 0;
} 
