// --------------------------------------------------------------------------------------------
// archivo  : xsfiles.h
// --------------------------------------------------------------------------------------------

#ifndef __xsFiles_H__
#define __xsFiles_H__

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

// Se Incluyen librerias de c
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"
#include <stdbool.h>

// Tipos de Datos
DefineTipo FILE Archivo;

// Constantes
#define LECTURA                       "r"
#define ESCRITURA                     "w"
#define AGREGAR                       "a"
#define LECTURA_ESCRITURA             "r+"
#define ESCRITURA_LECTURA             "w+"
#define AGREGAR_LECTURA_ESCRITURA     "a+"
#define B_LECTURA                     "rb"
#define B_ESCRITURA                   "wb"
#define B_AGREGAR                     "ab"
#define B_LECTURA_ESCRITURA           "r+b"
#define B_ESCRITURA_LECTURA           "w+b"
#define B_AGREGAR_LECTURA_ESCRITURA   "a+b"

#define FIN_DE_ARCHIVO           EOF
#define POSICION_INICIAL         SEEK_SET
#define POSICION_ACTUAL          SEEK_CUR
#define POSICION_FINAL           SEEK_END


// Objetivo : Abrir un archivo
// Retorna  : Retorna un apuntador a ARCHIVO
//            En caso de Error retorna NULL
Archivo* archivoAbrir(Constante Caracter *nombre, Constante Caracter *modo);


// Objetivo : Mueve el apuntador en el archivo
// Retorna  : 0 en caso de éxito
//            Si Error, un valor distinto de 0; el indicador de error es activado						 
Entero archivoApuntadorMover(Archivo        *archivo,        // Archivo
                             Largo Entero    desplazamiento, // Desplazamiento
                             Entero          origen);        // Origen

							 
// Objetivo : Obtiene la posición del apuntador
// Retorna  : Un valor mayor o igual que 0 indica éxito
//            un valor de -1l y es activado el control de error
Largo Entero archivoApuntadorPosicion(Archivo  *archivo);     // Archivo
                                   

// Objetivo : Coloca el Buffer para operaciones de entrada y salida
// Retorna  : Nada
Vacio archivoBuffer(Archivo *archivo, Caracter* buffer);


// Objetivo : Vaciar el buffer de escritura a disco
// Retorna  : En caso de éxito devuelve 0
//            En caso de Error devuelve EOF
Entero archivoBufferVaciar(Archivo *archivo);


// Objetivo : Cerrar un archivo
// Retorna  : En caso de éxito devuelve 0
//            En caso de Error devuelve EOF
Entero archivoCerrar(Archivo *archivo);


// Objetivo : Verifica si un archivo contiene el texto indicado
// Retorna  : Si es mayor que 0, el número de linea en que encontré el texto
//            Si es 0; es que no lo encontró
//            Si es -1; es que hubo un error en el proceso
Entero archivoContiene(Constante Caracter *archivo,      // Archivo que hay que verificar que exista
                       Entero    desdeLinea,   // Indica la linea desde la cual buscar
				       Logico    exacto,       // Indica si la búsqueda es exacta
					   Caracter *texto);       // El texto a buscar

					   
// Objetivo : Copiar un archivo
// Retorna  : Retorna el Número de caracteres que se copiaron
//            Retorna -1 en caso de que haya habido error
Largo Entero archivoCopiar(Constante Caracter *archivo,        // Archivo que hay que copiar
                           Constante Caracter *copia);         // Nuevo nombre
					 
					 
// Objetivo : Eliminar Un archivo en Disco
// Retorna  : Retorna 0 si se eliminó el archivo; 
//            Un valor distinto de 0 indicar error
Entero archivoEliminar(Constante Caracter *archivo);


// Objetivo : Verifica si el indicador error asociado al archivo esta activo
// Retorna  : Un valor distinto de 0 es devuelto si está activado el error
//            de otra forma devuelve 0
Entero archivoErrorActivado(Archivo *archivo);  // Archivo que hay que verificar error este activado


// Objetivo : Despliega el Actual Error activo para el archivo con un menasje previo
// Retorna  : Nada
Vacio archivoErrorImprimir(Constante Caracter *mensaje);  // Mensaje a desplegar con el del error


// Objetivo : Limpia los controles de error; el error y el eof del archivo
// Retorna  : Nada
Vacio archivoErrorLimpiar(Archivo *archivo);    // Archivo para el cual liberar el error


// Objetivo : Verifica si existe el archivo
// Retorna  : true - false
Logico archivoExiste(Constante Caracter *archivo);       // Archivo que hay que verificar que exista


// Objetivo : Verifica que se haya alcanzado el fin de archivo
// Retorna  : un valor distindo de 0 si se ha alcanzado el fin de archivo
//            0 en caso de que no se haya alcanzado el fin de archivo
Entero archivoFinDe(Archivo *archivo);       // Archivo que hay que verificar que exista


// Objetivo : Grabar una cadena en el Archivo 
// Retorna  : Un valor no negativo al tener exito al grabar
//          : EOF si hay error y el indicador de error es activado
Entero archivoGrabarCadena(Archivo      *archivo,      // Apuntador a archivo
                           Constante Caracter     *cadena);       // Cadena a grabar
                       						

// Objetivo : Grabar una cadena en el Archivo con Formato
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarCadenaFto(Archivo  *archivo,      // Apuntador a archivo
                              Constante Caracter *cadena,       // Cadena a grabar
                              Constante Caracter *formato);     // Cadena con el Formato para la grabación

							   
// Objetivo : Grabar un Caracter en el Archivo
Entero archivoGrabarCaracter(Archivo   *archivo,      // Apuntador a archivo
                             Caracter   caracter);     // caracter a grabar
							   
							   
// Objetivo : Grabar un Caracter en el Archivo con Formato
Entero archivoGrabarCaracterFto(Archivo   *archivo,      // Apuntador a archivo
                                Caracter   caracter,     // caracter a grabar
                                Constante Caracter  *formato);     // Cadena con el Formato para la grabación
							   
							   
// Objetivo : Grabar un Doble en el Archivo
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarDoble(Archivo      *archivo,            // Apuntador a archivo
                          Doble         doble);             // Doble a grabar
							 
						
// Objetivo : Grabar un Doble en el Archivo con Formato
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarDobleFto(Archivo      *archivo,     // Apuntador a archivo
                             Doble         doble,       // Flotante a grabar
                             Constante Caracter     *formato);    // Cadena con el Formato


									
// Objetivo : Grabar Elementos
// Retorna  : El Número de Elementos Grabados
//            En caso de error, un numero distinto de los elementos mandados a grabar
//            y el indicador de error es activado
SinSigno Entero archivoGrabarElementos(Archivo      *archivo,   // Apuntador a archivo
                                       Vacio        *buffer,    // Buffer con información a grabar
						               Entero        bytes,     // Bytes del Elemento
						               Entero        numero);   // Elementos a Grabar

// Objetivo : Grabar un Entero en el Archivo
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarEntero(Archivo      *archivo,            // Apuntador a archivo
                           Entero        entero);            // Entero a grabar
									   
// Objetivo : Grabar un Entero en el Archivo con Formato
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarEnteroFto(Archivo      *archivo,     // Apuntador a archivo
                              Entero        entero,      // Entero a grabar
                              Constante Caracter *formato);    // Cadena con el Formato para la grabación
							   
							   
// Objetivo : Grabar un Flotante en el Archivo
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarFlotante(Archivo      *archivo,            // Apuntador a archivo
                             Flotante      flotante);          // Flotante a grabar
							 
						
// Objetivo : Grabar un Flotante en el Archivo con Formato
// Retorna  : En caso de éxito el número de caracteres grabados
//            En caso de error, devuelve un valor negativo y activa el indicador de error (ferror)
Entero archivoGrabarFlotanteFto(Archivo      *archivo,     // Apuntador a archivo
                                Flotante      flotante,    // Flotante a grabar
                                Constante Caracter *formato);    // Cadena con el Formato

									
// Objetivo : Grabar una linea en el archivo; es decir con cambio de linea al final de la cadena
// Retorna  : Un valor no negativo al tener exito al grabar
//          : EOF si hay error y el indicador de error es activado
Entero archivoGrabarLinea(Archivo      *archivo,      // Apuntador a archivo
                          Constante Caracter     *cadena);      // Cadena a grabar


									
// Objetivo : Lee una cadena del Archivo					
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerCadena(Archivo   *archivo,     // Apuntador a archivo                         
 					     Caracter  *cadena);     // Cadena donde se almacen al resultado

						 
// Objetivo : Lee una cadena del Archivo con Formato						 
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado
Entero archivoLeerCadenaFto(Archivo   *archivo,      // Apuntador a archivo
                            Caracter  *cadena,       // Cadena a almacenar
                            Constante Caracter  *formato);     // Formato
						
						
// Objetivo : Lee una caracter del Archivo
// Retorna  : Retorna 1
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerCaracter(Archivo   *archivo,     // Apuntador a archivo                         
                           Caracter  *caracter);   // El Caracter a leer

// Objetivo : Lee una caracter del Archivo con Formato
// Retorna  : Retorna 1
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerCaracterFto(Archivo   *archivo,     // Apuntador a archivo                         
                              Caracter  *caracter,    // El Caracter a leer
							  Constante Caracter  *formato);    // Formato

                         

// Objetivo : Lee un Doble desde un Archivo
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerDoble(Archivo   *archivo,     // Archivo de donde lee
                        Doble     *doble);      // El Doble
					

// Objetivo : Lee un Doble desde un Archivo con Formato
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerDobleFto(Archivo   *archivo,      // Archivo de donde lee                           
                           Doble     *doble,        // El Doble a Leer							   
						   Constante Caracter  *formato);     // Formato

// Objetivo : Lee Elementos
// Retorna  : El Número de Elementos Leidos
//            En caso de error, un numero distinto de los elementos mandados a leer
//            y el indicador de error es activado
SinSigno Entero archivoLeerElementos(Archivo      *archivo,   // Apuntador a archivo
                                     Vacio        *buffer,    // Buffer donde se almacena lectura
						             Entero        bytes,     // Bytes del Elemento
						             Entero        numero);   // Numero de Elementos a Leer
						 
// Objetivo : Lee un entero desde un Archivo
// Retorna  : Retorna 1
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerEntero(Archivo   *archivo,     // Archivo de donde lee
                         Entero    *entero);      // El Entero a Leer

					  
// Objetivo : Lee un entero desde un Archivo con Formato
// Retorna  : Retorna 1
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerEnteroFto(Archivo   *archivo,      // Archivo de donde lee                            
                            Entero    *entero,       // El Entero a Leer
							Constante Caracter  *formato);     // Formato
					  
					  
// Objetivo : Lee un flotante desde un Archivo
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerFlotante(Archivo   *archivo,     // Archivo de donde lee
                           Flotante  *flotante);   // El Flotante
					

// Objetivo : Lee un Posiciona el Apuntador del Archivo
// Retorna  : Retorna 1
// Retorna  : 1 en caso de éxito
//            Si Error, un valor distinto de 1; el indicador de error es activado						 
Entero archivoLeerFlotanteFto(Archivo   *archivo,     // Archivo de donde lee                              
                              Flotante  *flotante,    // El Flotante a Leer							   
							  Constante Caracter  *formato);    // Formato


// Objetivo : Lee una linea de Caracteres del Archivo
// Retorna  : La Linea de Caracteres en caso de éxito
//            Devuelve NULL y el indicador de error activado
Caracter* archivoLeerLinea(Archivo   *archivo,     // Apuntador a archivo                         
                           Entero     maximo,      // Máximo de Caracteres a leer
						   Caracter  *cadena);     // Cadena donde se almacen al resultado
							  
// Objetivo : ReAbrir un archivo
// Retorna  : Retorna un apuntador a Archivo
//            En caso de Error retorna NULL
Archivo *archivoReAbrir(Constante Caracter *nombre, 
                        Constante Caracter *modo, 
						Archivo *archivo);


// Objetivo : Rebobinar un Archivo; colocar su apuntador al Inicio
// Retorna  : Vacío       
Vacio *archivoRebobinar(Archivo *archivo);


// Objetivo : Renombrar un archivo
// Retorna  : Retorna 0 si se eliminó el archivo; 
//            Un valor distinto de 0 indicar error
Entero archivoRenombrar(Constante Caracter *archivo,         // Archivo que hay que renombrar
                        Constante Caracter *nombre_nuevo);   // Nuevo nombre

#endif