#ifndef LISTA_POKAZIVAC_H_INCLUDED
#define LISTA_POKAZIVAC_H_INCLUDED
#endif // LISTA_POKAZIVAC_H_INCLUDED

struct podaci {
       int sifra;
       char oprema[100];
       char proizvodj[100];
       int god_proizv;
       int mbr_zaposlenika;
};

typedef struct zapis {
           podaci pod;
           zapis *sljedeci;
} lista_pok;

int Dodaj(zapis *);
void IspisOdKraja(zapis *);
void print_podaci(podaci);
int OpremaNakon2009(zapis *);
bool BrisiOpremu(zapis *, int );
void RazduziZaposlenika(zapis *, int);
void SilaznoSortiranje(zapis *);


void initL(zapis *lista)
{
    lista->sljedeci = NULL;
}
int InsertL(zapis *lista)
{
        //cout <<"Broj elemenata u listi: " << broj_elemenata_i_ispis(lista) << endl;
        static int sifra = 1;

        //lista is head
        //reallocate pointers
        zapis *novi, *zadnji;
        zadnji = lista;
        while (zadnji->sljedeci)
              zadnji = zadnji->sljedeci;
        novi = new zapis;

        if(!novi) //neuspjesna alokacija
            return false;


        novi -> sljedeci = NULL;
        zadnji -> sljedeci = novi;

        novi->pod.sifra = sifra;
        cout << "Naziv opreme: ";
        cin >> novi->pod.oprema;
        cout << "Naziv proizvodjaca: ";
        cin >> novi->pod.proizvodj;
        cout << "Godina proizvodnje: ";
        cin >> novi->pod.god_proizv;
        cout << "MBR zaposlenika: ";
        cin >> novi->pod.mbr_zaposlenika;

        //IspisOdKraja(lista);
        ++sifra;

        return true;
}


void IspisOdKraja(zapis *lista)
{
       if(!lista->sljedeci)
            return;
       zapis *tekuci = lista->sljedeci;

       if(tekuci->sljedeci)
            IspisOdKraja(tekuci);

       print_podaci(tekuci->pod);
       return;

}

void print_podaci(podaci pod)
{
        cout << "Sifra: " << pod.sifra << endl;
        cout << "Oprema: " << pod.oprema << endl;
        cout << "Proizvodjac: " << pod.proizvodj << endl;
        cout << "Godine proizvodnje: " << pod.god_proizv << endl;
        cout << "Maticni broj zaposlenika: " << pod.mbr_zaposlenika << endl;
        cout << "-------------------------\n\n";
}

int OpremaNakon2009(zapis *lista)
{
     int broj_oprema = 0;
     zapis *brojac = lista;

     cout << "\n\n----------Racunalna oprema proizvodena nakon 2009. godine--------\n\n" << endl;
     while (brojac->sljedeci) {
           brojac = brojac->sljedeci;

           if(brojac->pod.god_proizv >= 2009) {
                print_podaci(brojac->pod);

                ++broj_oprema;
                cout << "----------------";
            }
     }
     return broj_oprema;
}

bool DeleteL(zapis *lista, int sifra)
{
     if (!lista) {
        return false;
     }
     zapis *zadnji = lista -> sljedeci, *prethodni = lista;
     while(zadnji){
		   if(zadnji -> pod.sifra == sifra){
                prethodni -> sljedeci = zadnji -> sljedeci;
                delete zadnji;
                return true;
           }
           prethodni = zadnji;
           zadnji = zadnji -> sljedeci;
     }
     return false;
};

void RazduziZaposlenika(zapis *lista, int mbr_zaposlenika)
{
     zapis *brojac = lista;

     while (brojac->sljedeci) {
           brojac = brojac->sljedeci;

           if(brojac->pod.mbr_zaposlenika == mbr_zaposlenika) {
                int sifra = brojac->pod.sifra;
                if(brojac->sljedeci)
                    brojac = brojac->sljedeci;
                DeleteL(lista, sifra);
            }
     }
}


void SilaznoSortiranje(zapis *lista)
{
     zapis *prvi = lista, *sljedeci, *tekuci, *prethodni;
     bool w;
     do { //bubble sort
         w = false;
         tekuci=prvi->sljedeci;
         prethodni=prvi;
         while (tekuci->sljedeci) {
               sljedeci=tekuci->sljedeci;
               if (strcmp(tekuci->pod.proizvodj, sljedeci->pod.proizvodj) > 0) {
                        prethodni->sljedeci=sljedeci;
                        tekuci->sljedeci=sljedeci->sljedeci;
                        sljedeci->sljedeci=tekuci;
                        w=true;
               }
               prethodni=prethodni->sljedeci;
               tekuci=prethodni->sljedeci;
         }
     } while (w);

    return;
}

struct EmptyException { };
struct RangeException {} ;
struct PreviousException { };

lista_pok *EndL(lista_pok *lp)
{
    lista_pok *it;
    for(it = lp->sljedeci; it; it = it->sljedeci)
        ;
    return it;
}

lista_pok *FirstL(lista_pok *lp)
{
    if(lp->sljedeci == NULL)
        return EndL(lp);
    return lp->sljedeci;
}


lista_pok *NextL(zapis *z, lista_pok *lp)
{
    if(lp->sljedeci == NULL)
        throw new EmptyException;
    if(z->sljedeci)
        if(!z->sljedeci->sljedeci)
            return EndL(lp);
        else
            return z->sljedeci;
    return NULL;
}

struct NotFound { };
lista_pok *PreviousL(zapis *z, lista_pok *lp)
{
    lista_pok *it;
    lista_pok *preth = lp;
    for(it = lp->sljedeci; it != z && it; it = it->sljedeci)
    {
        preth = it;
    }
    if(!it)
        throw new NotFound();
    return preth;
}

void DeleteAll(lista_pok *lp)
{
    lista_pok *it;
    for(it = lp->sljedeci; it; )
    {
        lista_pok *temp = it->sljedeci;
        delete it;
        it = temp;
    }
    lp->sljedeci = NULL;
}

lista_pok *LocateL(int sifra, lista_pok *lp)
{
    lista_pok *it;
    for(it = lp->sljedeci; it; it = it->sljedeci)
    {
        if(it->pod.sifra == sifra)
            return it;
    }
    return NULL;
}


podaci RetreiveL(zapis *p)
{
    if(!p)
        throw new RangeException;
    return p->pod;
}