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


#ifndef _aristaT0list_h
#define _aristaT0list_h

#include <a_t0.hxx>

  struct AristaT0_link {

     Arista_T0* a;
     AristaT0_link* suc;
    
     AristaT0_link () {a=NIL; suc=NIL;}
     AristaT0_link (Arista_T0* aa, AristaT0_link* nn) {a=aa; suc=nn;}
     AristaT0_link (Arista_T0& aa, AristaT0_link* nn) {a=&aa; suc=nn;}

     void set(Arista_T0* aa, AristaT0_link* nn) {a=aa; suc=nn;}
     void set(Arista_T0& aa, AristaT0_link* nn) {a=&aa; suc=nn;}
     AristaT0_link* sig () {return suc;}
     int operator<(AristaT0_link& aa)
      {return ((*a)<(*(aa.a)));}
  };
 

  class AristaT0_list {

     AristaT0_link* last;
     AristaT0_link* begin;
     
     friend ostream& operator<<(ostream&,  AristaT0_list& );
     
  public:
     AristaT0_list () {last=NIL;begin=NIL;}
     AristaT0_list (AristaT0_link* a) {last=begin=a;}
     void insert(AristaT0_link* a) {  //Pega a cabeza de lista.
             if (begin) {
               a->suc=begin;
               begin=a; 
             }
             else {
               last=a;
               begin=a;
             }
          }
     void append(AristaT0_link* a) {  //Pega al final de la lista.
             if (last) {
               last->suc=a;
               last=a;
             }
             else {
               last=a;
               begin=a;
             }
          }
     void enlaza(AristaT0_list& al) {  //une (this)+al
      if (begin) {
        if (al.begin) {
             last->suc=al.begin;
             last=al.last;
             al.begin=NIL;
             al.last=NIL;
        }
      }
      else {
        begin=al.begin;
        last=al.last;
        al.last=NIL;
        al.begin=NIL;
      }
     }
    void enlaza(AristaT0_list* al) {  //une (this)+al
      if (begin) {
        if (al->begin) {
             last->suc=al->begin;
             last=al->last;
             al->begin=NIL;
             al->last=NIL;
        }
      }
      else {
        begin=al->begin;
        last=al->last;
        al->begin=NIL;
        al->last=NIL;
      }
     }
     AristaT0_link* principio() {return begin;}         
     AristaT0_link* fin() {return last;}
     int num_elem() {
           int num=0;
           AristaT0_link* aux=begin;
              while (aux) {
                 num++;
                 aux=aux->suc;
              }
           return num;
         }

     int operator<(AristaT0_list& a)
      {return ((*last)<(*(a.begin)));}
     void clear() {
               AristaT0_link* aux;
               while(begin) {
                 aux=begin->suc;
                 delete begin; 
                 begin=aux;
               } 
            last=begin=NIL;
          }
     
     void operator delete (void* p)
      { 
        if (p) { 
          ((AristaT0_list*)p)->clear();
          delete p; p=NIL;
        }
      }              

    void write (ostream&);

 };

#endif
                           
