/*
 * 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 _verticeT1list_h
#define _verticeT1list_h

#include <v_t1.hxx>

   struct Vertice_T1_lk {
       Vertice_T1* s;
       Vertice_T1_lk* suc;
       Vertice_T1_lk* prev;

       Vertice_T1_lk () {s=NIL; suc=NIL; prev=NIL;}
       Vertice_T1_lk (Vertice_T1& so, Vertice_T1_lk* ss,\
                         Vertice_T1_lk* pp)
            {s=&so;suc=ss;prev=pp;}
       Vertice_T1_lk (Vertice_T1* so, Vertice_T1_lk* ss,\
                         Vertice_T1_lk* pp) {
             s=so; suc=ss; prev=pp;} 

       void set (Vertice_T1& so, Vertice_T1_lk* ss,\
                 Vertice_T1_lk* pp)
            {s=&so; suc=ss;prev=pp;}
       void set (Vertice_T1* so, Vertice_T1_lk* ss,\
                 Vertice_T1_lk* pp) {
              s=so; suc=ss; prev=pp;} 

       Vertice_T1_lk* sig() {return suc;}
       Vertice_T1_lk* ant() {return prev;}
 
    };

    class Vertice_T1_list {

       Vertice_T1_lk* last;
       Vertice_T1_lk* begin;

       friend ostream& operator<<(ostream&, Vertice_T1_list&);

   public:
       Vertice_T1_list () {last=NIL; begin=NIL;}
       Vertice_T1_list (Vertice_T1_lk* r) {last=begin=r;}
       void insert (Vertice_T1_lk* r) {//pega al principio de list
           if (begin) {
               r->suc=begin;
               begin->prev=r;
               begin=r;

           }
           else {
               last=r;
               begin=r;
           }
       }
       void append(Vertice_T1_lk* r) {//pega al final de list
           if (last) {
              last->suc=r;
              r->prev=last;
              last=r;
           }
           else {
              last=r;
              begin=r;
           }
       }
       void  enlaza (Vertice_T1_list* rll) {  //une this+rll
        if (begin) {
           if (rll->begin) {
              last->suc=rll->begin;
              (rll->begin)->prev=last;
              last=rll->last;
              rll->begin=NIL;
              rll->last=NIL;
           }
        }
        else {
           begin=rll->begin;
           last=rll->last;
           rll->begin=NIL;
           rll->last=NIL;
       }
   }
       void  enlaza (Vertice_T1_list& rll) {  //une this+rll
        if (begin) {
           if (rll.begin) {
              last->suc=rll.begin;
              (rll.begin)->prev=last;
              last=rll.last;
              rll.begin=NIL;
              rll.last=NIL;
           }
        }
        else {
           begin=rll.begin;
           last=rll.last;
           rll.begin=NIL;
           rll.last=NIL;
       }

    }
       void kill (Vertice_T1_lk* r) { //elimina un elmento de la lista
           if (r==begin) {
              begin=r->suc;
              if (begin) begin->prev=NIL;
           }
           else {
             if (r==last) {
                last=r->prev;
                last->suc=NIL;
             }
             else {
               (r->prev)->suc=r->suc;
               (r->suc)->prev=r->prev;
             }
           }
           delete r;
       }

       Vertice_T1_lk* principio () {return begin;}
       Vertice_T1_lk* fin () {return last;}
       int num_elem () {
           int num=0;
           Vertice_T1_lk* aux=begin;
           while (aux) {
            num++;
            aux=aux->suc;
           }
           return num;
       } 
       void clear () {
           Vertice_T1_lk* aux;
           while (begin) {
              aux=begin->suc;
              delete begin;
              begin=aux;
           }
           last=begin=NIL;
       }                             
       void operator delete (void* p){
         if (p) {
           ((Vertice_T1_list*)p)->clear();
           delete p;
         }
       }
       void write (ostream&);

    };
#endif       
