// --------------------------------------------------------------------------------------------
// archivo  : xslists
// objetivo : header de funciones para manejo de listas
// --------------------------------------------------------------------------------------------

#ifndef __xsLists_H__
#define __xsLists_H__

// Incluyo la librería Easy
#include "xsEasyC.h"

// Se Incluyen librerías de c
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"
#include <stdbool.h>
#include <stdarg.h>

// Constantes
#define TIPO_ENTERO       0
#define TIPO_CARACTER     1
#define TIPO_DOBLE        2
#define TIPO_CADENA       3

#define ORDEN_ASCENDENTE  0
#define ORDEN_DESCENDENTE 1

// Define union del Dato
Union stcDato 
{
	Entero    entero;		
	Caracter  caracter;
	Doble     doble;
	Cadena    cadena;
};

// Define el tipo de acuerdo a la Union
DefineTipo Union stcDato xDato;


// Define la Estructura para los Nodos
Estructura stcNodo
{
	
	// Tipo de Dato	
	Entero    tipo;
	xDato     dato;
    // Entero    entero;		
	// Caracter  caracter;
	// Doble     doble;
	// Cadena    cadena;
	
	// apuntador a siguiente
    Estructura stcNodo *pSiguiente;
	
};

// Define el tipo de acuerdo a la Estructura
DefineTipo Estructura stcNodo nodo;

// Define la Estructura para lista
Estructura stcLista
{	
	// apuntador a cabeza
    Estructura stcNodo* pCabeza;	
	Entero     elementos;
};

// Define el tipo de acuerdo a la Estructura
DefineTipo Estructura stcLista Lista;

// Define la Estructura para los Nodos
Estructura elementoLista
{	
	// Tipo de Dato	
	Entero    tipo;
	xDato     dato;
    // Entero    entero;		
	// Caracter  caracter;
	// Doble     doble;
	// Cadena    cadena;		
};

DefineTipo Estructura elementoLista ElementoLista;

// Objetivo : Crear un Nodo
// Retorna  : el apuntador al Nodo
nodo* NodoCrear(Entero tipo,   // El Tipo de Dato
                ...);          // El Dato

				
// Objetivo : Actualizar un dato en la lista
// Retorna  : VERDAD/FALSO
Logico listaActualizar(Lista  lista,    // Lista donde se actualizara
                       Entero indice,   // El indice del Elemento a actualizar
                       Entero tipo,     // El tipo de dato
					   ...);            // El dato

// Objetivo : Agregar una Lista a la Lista
// Retorna  : Nada. La lista es actualizada agregandole otra
Vacio  listaAgregarLista(Lista*  listaOrigen,   // Lista origen donde se agregan
                         Lista   listaAgregar); // La lista a agregar
							 
// Objetivo : Agregar un Vector a la Lista
// Retorna  : Nada. La lista es actualizada agregandole el vector
Vacio  listaAgregarVector(Lista*   lista,     // Lista origen donde se agregan
                          Entero   tipo,      // El Vector a agregar
					      Entero   elementos, // Elementos del Vector
						  ...);                 // El Vector
						   
// Objetivo : Buscar un Elemento en la Lista
// Retorna  : Un valor mayor que 0 para indicar que lo encontro
//            0 si no lo encontró
Entero listaBuscar(Lista* lista,    // Lista donde se busca
                   Entero tipo,     // tipo de dato
			       ...);            // El dato

					   
// Objetivo : Cuenta un Elemento en la Lista
// Retorna  : Cuantas veces encontré el dato; 0 si no lo encontró
Entero listaContar(Lista  lista,    // Lista donde se busca
                   Entero tipo,     // tipo de dato
			       ...);            // El dato					   

// Objetivo : Devolver una lista convertida en un vector; la lista debe tener un solo tipo de dato
// Retorna  : La dirección al Nuevo Vector; NULL en caso de error
Vacio* listaConvertirAVector(Lista  lista,    // Lista que se va a convertir en Vector
                             Entero tipo);    // tipo de dato que será el vector
					   
// Objetivo : Crear una lista desde una Cadena en Formato CSV
// Retorna  : La lista
Lista listaDesdeCSV(Caracter* cadenaCSV); // Cadena en Formato CSV
					   
// Objetivo : Obtiene un Elemento de la Lista
// Retorna  : El Elemento de la Lista; el cual puede estar vacío si el indice es erroneo
ElementoLista listaElemento(Lista lista,    // Lista                                 
                            Entero indice); // El indice del Elemento a obtener

// Objetivo : Obtiene el Elemento Max de la Lista
// Retorna  : El Elemento Maximo de la Lista; el cual puede estar vacío si el indice es 
ElementoLista listaElementoMax(Lista   lista,   // Lista 
                               Entero  tipo,    // EL tipo del Cual desea el Maximo
                               Entero* indice); // El indice donde se encontró

// Objetivo : Obtiene el Elemento Min la Lista
// Retorna  : El Elemento Minimo de la Lista; el cual puede estar vacío si el indice es erroneo
ElementoLista listaElementoMin(Lista   lista,   // Lista 
                               Entero  tipo,    // EL tipo del Cual desea el Minimo
                               Entero* indice); // El indice donde se encontró
								

// Objetivo : Eliminar un Elemento en la Lista por Dato
// Retorna  : VERDAD/FALSO
Logico listaEliminarElemento(Lista* lista,    // Lista donde se eliminará
                             Entero tipo,     // El tipo de dato
					         ...);              // El dato

// Objetivo : Elimina un Elemento en la Lista por índice
// Retorna  : VERDAD/FALSO
Logico listaEliminarIndice(Lista* lista,    // Lista donde se eliminará
                           Entero indice);  // El índice del elemento a borra

// Objetivo : Imprimir los Elementos de la lista
// Retorna  : Nada
Vacio listaImprimir(Lista lista);

// Objetivo : Imprimir la información de un Elemento de la lista
// Retorna  : Nada
Vacio listaImprimirElemento(ElementoLista elemento);

// Objetivo : Inicializar la Lista
// Retorna  : Nada
Vacio listaInicializar(Lista* lista);  // Lista a Inicializar

// Objetivo : Insertar un Elemento en el final de la lista
// Retorna  : Verdad/Falso
Logico listaInsertar(Lista* lista, // Lista donde se inserta
                     Entero tipo,  // El tipo de dato
			  		 ...);         // El tipo de dato

// Objetivo : Insertar un Elemento en la Lista
// Retorna  : Verdad/Falso
Logico listaInsertarIndice(Lista* lista,  // Lista donde se inserta
                           Entero tipo,   // El tipo de dato
						   Entero indice, // El Indice donde se insertara el Nodo
			  		       ...);          // El Dato

// Objetivo : Insertar un Elemento en el Inicio de la Lista
// Retorna  : VERDAD/FALSO
Logico listaInsertarInicio(Lista* lista, // Lista donde se inserta
                           Entero tipo,  // El tipo de dato
		 		           ...);         // El tipo de dato

// Objetivo : Insertar N Elementos en la Lista
// Retorna  : El numero de elementos insertados; si difiere de numero es que hubo un error
Entero listaInsertarN(Lista* lista,  // Lista donde se inserta
                      Entero tipo,   // El tipo de dato
					  Entero numero, // Numero de Elementos a Insertar
			  		  ...);          // El tipo de dato
							   
// Objetivo : Invertir los Elementos en la Lista
// Retorna  : Nada. La lista queda invertida
Vacio listaInvertir(Lista* lista); // Lista a invertir

// Objetivo : Obtener el Número de Elementos de la Lista
// Retorna  : el Número de Elementos de la Lista; 0 si está vacía
Entero listaLongitud(Lista lista); // Lista a invertir

// Objetivo : Ordenar los Elementos en la Lista
// Retorna  : La lista queda ordenada si los elementos son todos del mismo tipo
//            VERDA/FALSO
Logico listaOrdenar(Lista* lista,          // Lista a invertir
                    Entero ordenamiento);  // Indica si sera ascendente o descendente

// Objetivo : Obtener el Tipo de Elemento de la lista, que todos tengan el mismo tipo
// Retorna  : TIPO_ENTERO, TIPO_CARACTER, TIPO_DOBLE, TIPO_CADENA
//            -1 en caso de que haya algun elemento con tipo distinto
Entero listaTipo(Lista  lista);    // Lista de la que se obtiene el tipo
							 
// Objetivo : Obtener el Tipo de Elemento indicado
// Retorna  : TIPO_ENTERO, TIPO_CARACTER, TIPO_DOBLE, TIPO_CADENA
//            -1 en caso de que no existe el indice del Elemento
Entero listaTipoElemento(Lista  lista,    // Lista en la que se buscar
                         Entero indice);  // El índice del Elemento


// Objetivo : Verifica si la Lista está vacía
// Retorna  : VERDAD/FALSO
Logico listaVacia(Lista lista);    
						 
// Objetivo : Vaciar la lista, eliminando todos sus elementos
// Retorna  : Nada
Vacio listaVaciar(Lista* lista);    // Lista donde se eliminará



// fin de la Definición del Archivo
#endif