/*
 * lista.c
 *
 * implantación de una lista como TAD
 */
#define __LISTA_C

#include <stdio.h>
#include <stdlib.h>
#include "lista.h"

/*
 * inserta x en la posicion p de la lista lis.
 * Los elementos que estan en la posición p y 
 * siguientes se corren a la posición inmediata
 * posterior.  Si p == lista_fin(lis) entonces la
 * lista tendrá a x como último elemento. Si lis
 * no tiene posición p, el resultado será indefinido.
 */
void lista_inserta(Lista * lis, Elem x, Pos p)
{
	int i;

	if (p == lista_fin(lis)) {
		if (p == MAX_ELEM_EN_LISTA) {
			printf("lista_inserta: se lleno la lista\n");
			exit(1);
		}
		lis->elem[p]= x;
		lis->ultimo= lis->ultimo + 1;
	} else {
		if (p > lis->ultimo) {
			printf("lista_inserta: se intenta insertar fuera de la lista\n");
			exit(1);
		} else {
			for (i=lis->ultimo-1; i>=p; --i)
				lis->elem[i+1]= lis->elem[i];

			lis->elem[p]= x;
			lis->ultimo= lis->ultimo + 1;
		}
	}
}


/*
 * Devuelve la posición que sigue al último elemento
 * de ls lista lis.
 */
Pos  lista_fin(Lista * lis)
{
	return lis->ultimo;
}


/*
 * Devuelve la posición de x en la lista lis.
 * Si x está más de una vez en lis, se devuelve
 * la posición de la primera ocurrencia.  Si x no
 * figura en la lista, se devuelve lista_fin(lis).
 */
Pos  lista_localiza(Lista * lis, Elem x)
{
	return 0;
}

/*
 * Devuelve el elemento que está en la posición p
 * de la lista lis.
 * El resultado no está definido si p==lista_fin(lis)
 * o si lis no tiene posición p.
 */
Elem lista_recupera(Lista * lis, Pos p)
{
	if (p >= lista_fin(lis)) {
		printf("lista_recupera: No hay elementos en la posicion solicitada\n");
		exit(1);
	}

	return lis->elem[p];
}

/*
 * Elimina el elemento en la posición p de la lista lis.
 * Los elementos siguientes a p se corren para llenar
 * el hueco dejado por el elemento eliminado.  El resultado 
 * no está definido si lis no tiene posición p o si p==lista_fin(lis).
 */
void lista_suprime(Lista * lis, Pos p)
{
}

/*
 * Devuelve la posición siguiente a la de p en la lista lis.
 * Si p es la última posición de lis, se devuelve lista_fin(lis).
 * Si p==lista_fin(lis) o si p no existe en lis, el resultado
 * no está definido.
 */
Pos  lista_siguiente(Lista * lis, Pos p)
{
	if ( (p == lista_fin(lis)) || (p >= lista_fin(lis)) ) {
		printf("lista_siguiente: No existe el siguiente elemento\n");
		exit(1);
	}

	if (p == lis->ultimo-1)
		return lista_fin(lis);
	
	return p+1;
}


/*
 * Devuelve la posición anterior a la de p en la lista lis.
 * Si p==1 o si p no existe en lis, el resultado no está definido.
 */
Pos  lista_anterior(Lista * lis, Pos p)
{
	return 0;
}

/*
 * Hace que lis se transforme en la lista vacía y
 * retorna lista_fin(lis)
 */
Pos lista_anula(Lista * lis)
{
	lis->ultimo= 0;
	return lista_fin(lis);
}

int lista_vacia(Lista * lis)
{
	return lis->ultimo == 0;
}

/*
 * Devuelve la primera posición en la lista lis.
 * Si lis está vacía, se devuelve lista_fin(lis)
 */
Pos  lista_primero(Lista * lis)
{
	if (lista_vacia(lis))
		return lista_fin(lis);
	else
		return 0;
}

/*
 * Imprime los elementos de lis en el orden
 * de aparición dentro de la lista.
 */
void lista_imprime(Lista * lis)
{
	Pos p;
	Elem e;

	p= lista_primero(lis);
	if (p != lista_fin(lis)) {
		e= lista_recupera(lis,p);
		printf("lista ( [%d] ", lista_fin(lis));
	
		for ( ; p!=lista_fin(lis); p=lista_siguiente(lis,p)) {
			e= lista_recupera(lis,p);
			printf(", %f", (double)e);
		}
		printf(" )\n");
	} else
			printf("lista ( [0] )\n");
}

#undef __LISTA_C
/* EOF lista.c */
