 

package lista;

/*
implementira vezanu listu sastavljenu od svih objekata koji implementiraju 
sucelje (eng. interface) Cvor  deklarirano u datoteci Cvor.java
*/

public class VezanaLista {
   

    /*  klasa koristi defaultni konstruktor
        public VezanaLista() 
    */

    /* 
    jedina varijabla clanica ove klase je "pokazivac" na prvi element liste 
    primjetimo da ova varijabla je tipa sucelje -kako se sucelja ne 
    instanciraju nju moramo staviti memorijsku adresu klase koja implementira
    sucelje Cvor 
    */


    public Cvor pocetak=null; 

    /* vraca prvi cvor liste*/

    public synchronized Cvor getHead() { 
          
	return pocetak; //vraca pocetak vezane liste
}

    /*dodajmo element na pocetku liste*/
    
 public synchronized void insertAtHead(Cvor cvor) {
        cvor.setNext(pocetak);
        pocetak = cvor;
    }


    /* dodajmo element na kraju liste */

    public synchronized void insertAtTail(Cvor cvor) {
   
     if (pocetak == null) pocetak = cvor;
        else {
            Cvor p, q;

            /*
              "pokazivac" p iterira od pocetka dokraja liste  
              kraj liste ima getNext()=null
              for petlja izgleda kao uobicajene "ruzne" C-petlje
              samo iterira do kraja
	   */   
            for(p = pocetak; (q = p.getNext()) != null; p = q); 

            p.setNext(cvor); //ubacimo nodu na kraj
        }
    }


    /*izbrisi i vrati element sa pocetka vezane liste */

    public synchronized Cvor removeFromHead() {
        
       Cvor cvor = pocetak;
       
       if (cvor != null) {
	   pocetak = cvor.getNext(); //novi pocetak
	   cvor.setNext(null); //nodu smo maknuli s liste -dakle iduca 
	   //od node=null
        }
        return cvor;
    }


    /*izbrisi i vrati element s kraja liste*/

    public synchronized Cvor removeFromTail() {
        
        if (pocetak == null) return null;

        Cvor p = pocetak; //iterator
        Cvor q = null;    //pomicna varijabla 

        Cvor iduci = pocetak.getNext();

        if (iduci == null) { //oops vec smo na kraju liste
            pocetak = null; //obrisemo pocetak
            return p;  //vratimo referencu na pocetak
        }
	//ako smo ovdje postoje barem dva elementa na vezanoj listi
        //iterirajmo do kraja -ovako napisana iteracija izgleda pristojnije

       while((iduci = p.getNext()) != null) { 
            q = p; 
            p = iduci;
        }
        
       //van ispadnemo kada je iduci=null  
        q.setNext(null);
        return p;
    }


    /*
       metoda brise cvor sa liste ako se podudara s danim cvorom
       koristimo metodu equals() koja originalno pripada klasi 
       java.lang.Object.
       Ako korisnik naseg paketa preradi (kao sto je slucaj u primjeru 3)
       ovu metodu, onda donji kod koristi upravo tu preradjenu metodu.       
    */

    public synchronized void remove(Cvor cvor) {
        
        if (pocetak == null) return; //nema se sto raditi

        if (cvor.equals(pocetak)) { 
            pocetak = pocetak.getNext(); //obrisemo pocetak 
            return;
        }
        //ako smo ovdje onda pocetak nije trazeni cvor
        //moramo iterirati

        Cvor p = pocetak;
        Cvor q = null;
  
      while((q = p.getNext()) != null) {
            if (cvor.equals(q)) {
                p.setNext(q.getNext()); //iteriramo dok ne dodjemo ovdje
		//pa obrisemo q 
                return;
            }
            p = q;
        }
      //ako smo ovdje nismo nasli trazeni objekt i izlazimo van
    }
}
   
