/* semplici primitive di gestione di una lista ordinata (numerica)
 *  * tramite array */
#include<stdio.h>
#include<stdlib.h>
#include"lista.h"

static type_lista *elementi;
static int numelementi=0;
static int maxnelem=0;

int creaLISTA(int numel){
 if((elementi=calloc(numel,sizeof(type_lista)))==NULL)
  return LISTA_ERR;
 maxnelem=numel;
 return LISTA_OK;
}

/* elimina la lista */
void destroyLISTA(void){
 free(elementi);
 maxnelem=numelementi=0;
}

/* ritorna numero elementi lista */
int elementiinLISTA(void){
 return numelementi;
}

/* inserisce elemento in lista ritorna OK o ERR */
int inserisciinLISTA(type_lista new){
 int ii,a,b;
 int puntoins;

 /* controllo che ci sia spazio */
 if(numelementi==maxnelem)
  return LISTA_ERR;
 /*devo ricercare il punto di inserzione */
 a=0;
 b=numelementi-1;



 /* utilizzo una ricerca binaria */
 ii=0;
 while(a<b){
  ii=(a+b)/2;
  if(elementi[ii]==new)
   return LISTA_ERR;
  if(elementi[ii]>new)
   b=ii-1;
  else
   a=ii+1;
  }
 puntoins=(a+b)/2;

 if((puntoins!=numelementi)&&(elementi[puntoins]<new))
  puntoins++;

 /* sposto i dati nell'array C */
 for(ii=numelementi;ii>puntoins;--ii)
  elementi[ii]=elementi[ii-1];
 
 elementi[puntoins]=new;
 ++numelementi;
 return LISTA_OK;
}

/* ricerca l'elemento ne ritorna l'indice */
int trovainLISTA(type_lista ric, int * index){
 int ii, a, b;

 a=0;
 b=numelementi-1;

 ii=0;
 while(a<b){
  ii=(a+b)/2;
  if(elementi[ii]==ric){
   *index=ii;
   return LISTA_OK;
  }
  if(elementi[ii]>ric)
   b=ii-1;
  else
   a=ii+1;
  }

 return LISTA_ERR;
}

/* rimuove l'elemento in funzione dell'indice
 *  * e ritorna l'esito */
int rimuovidaLISTA(int indice){
 register int ii;

 /* controllo il valore dell'indice */
 if((indice>numelementi)||(indice<0))
  return LISTA_ERR;

 for(ii=indice;ii<numelementi-1;++ii)
  elementi[ii]=elementi[ii+1];

 --numelementi;

 return LISTA_OK;
}

/* recupera l'elemento in funzione dell'indice
 *  * ritorna lo stato dell'operazione */
int indiceLISTA(int indice, type_lista* ret_value){
 
 /* controllo il valore dell'indice */
 if((indice>numelementi)||(indice<0))
  return LISTA_ERR;

 *ret_value=elementi[indice];

 return LISTA_OK;
}

/* inverte l'ordine della lista */
void invertiLISTA(void){
  int ii,t;

  if(numelementi<=1)
    return;
  for(ii=0;ii<numelementi/2;++ii){
    t=elementi[ii];
    elementi[ii]=elementi[numelementi-1-ii];
    elementi[numelementi-1-ii]=t;
  }
}