#include <stdlib.h>
#include <stdio.h>
#include <conio.h>

#define MAX_CLIENTES 100 //Cantidad maxima de clientes.

typedef struct{
    char nombre[40];
    char RUT[20];
    int cuenta;
}clientes; //Se define clientes como un tipo de datos con la estructura definida.

void AgregarCliente(clientes *lista, int *n_clientes);  //Agrega un cliente al arreglo.
void ImprimirClientes(FILE *file, clientes p);     //Imprime clientes dependiendo del flujo
void MostrarClientes(clientes *lista, int n_clientes);  //Muestra clientes en pantalla
void GuardarDatos(clientes *lista, int n_clientes);     //Guarda Datos en un archivo
void CargarDatos(clientes *lista, int *n_clientes);     //Carga los datos a partir de un archivo

int main()
{
    char opcion;
    clientes lista[MAX_CLIENTES]; //Se crea un arreglo de dimensión MAX_CLIENTES

    int num_clientes=0; //Cantidad inicial de clientes = 0

    while(1)
    {
        system("cls"); //Limpiar pantalla.
        printf("***********************\n"
               "Lista de Clientes\n"
               "***********************\n");
        printf("1.- Agregar Cliente\n"
               "2.- Mostrar Clientes\n"
               "3.- Guardar Datos\n"
               "4.- Cargar Datos\n"
               "5.- Salir\n");

        while(opcion=getch(), opcion<'1'||opcion>'5'); //Menú

        switch(opcion) //Opciones del menú
        {
            case '1':
                AgregarCliente(lista, &num_clientes);break;
            case '2':
                MostrarClientes(lista, num_clientes);break;
            case'3':
                GuardarDatos(lista,num_clientes);break;
            case '4':
                CargarDatos(lista, &num_clientes);break;
            case '5':
                system("pause");return 0;
        }
        system("pause");
    }
}

void AgregarCliente(clientes *lista, int *n_clientes) //Notar paso por referencia a n_clientes
{
    int i;
    printf("***********************\n"
           "Agregar Cliente\n"
           "***********************\n");
    if(*n_clientes==MAX_CLIENTES)   //habrá celdas disponibles para agregar clientes?
    {
        printf("Capacidad llena.\n");
        return;
    }

    for(i=0;i<*n_clientes;i++); //Se suma i para agregar nuevo cliente en la última posición
    (*n_clientes)++;  //Se agrega un cliente más, por lo tanto se le suma 1 a n_clientes
    printf("Ingrese nombre: "); //Se llena cada campo del cliente.
    gets(lista[i].nombre);
    printf("Ingrese RUT: ");
    gets(lista[i].RUT);
    printf("Ingrese Dinero en Cuenta: ");
    scanf("%d", &lista[i].cuenta);
    fflush(stdin); //Se limpia el buffer de entrada estandar, por si quedó alguna pulsación de tecla en éste.
}

void ImprimirClientes(FILE *file, clientes p)
{
        fprintf(file,"%s\n", p.nombre); //Imprime variable al flujo.
        fprintf(file,"%s\n", p.RUT);
        fprintf(file,"%d\n", p.cuenta);
        fprintf(file,"\n"); //Agrega salto de línea.
}

void MostrarClientes(clientes *lista, int n_clientes)
{
    int i;
    printf("***********************\n"
           "Mostrar Clientes\n"
           "***********************\n");

    for(i=0;i<n_clientes;i++) //Ciclo para mostrar  los clientes.
    {
        printf("Cliente n%d: \n\n",i+1);
        ImprimirClientes(stdout,lista[i]); //Flujo stdout, en este caso la consola, se muestran los datos.
    }
}

void GuardarDatos(clientes *lista, int n_clientes)
{
    FILE *archivo; //Puntero a FILE.
    char n_archivo[20];
    int i;
    printf("***********************\n"
           "Guardar Datos\n"
           "***********************\n");

    printf("Ingrese el nombre del archivo:\n");
    gets(n_archivo); //Se ingresa nombre del archivo.
    archivo=fopen(n_archivo, "w"); //Se abre archivo para escritura.

    if(!archivo) //Se pudo abrir archivo?
    {
        printf("No se pudo abrir archivo.\n");
        return;
    }
    fprintf(archivo, "Datos Guardados\n\n");
    for(i=0;i<n_clientes;i++) //Se escribe sobre archivo.
        ImprimirClientes(archivo, lista[i]);

    fclose(archivo); //Se cierra el archivo.
    printf("Datos Guardados!\n");
}

void CargarDatos(clientes *lista, int *n_clientes)
{
    char n_archivo[20], buffer[80];
    FILE *archivo;
    int i;
    printf("***********************\n"
           "Cargar Datos\n"
           "***********************\n");
    printf("Ingrese nombre del archivo a cargar:\n");
    gets(n_archivo);
    archivo=fopen(n_archivo,"r");//Se abre archivo para lectura.

    if(!archivo) //Se pudo cargar archivo?
    {
        perror(n_archivo);
        return;
    }
    fgets(buffer, 80, archivo); //Se descartan las dos primeras lineas, pues no contienen información.
    fgets(buffer, 80, archivo);

    *n_clientes=0; //Inicialmente hay 0 clientes.

    for(i=0;!feof(archivo);i++)
    {
        fgets(lista[i].nombre,40,archivo); //Se leee linea a linea el archivo.
        strtok(lista[i].nombre, "\n"); //Destruye el salto de linea agregado por fgets.
        fgets(lista[i].RUT, 20, archivo);
        strtok(lista[i].RUT, "\n");
        fscanf(archivo, "%d\n\n", &lista[i].cuenta);
    }
    *n_clientes=i;  //La cantidad total de clientes ahora, es la cantidad de clientes leidos.
    fclose(archivo); //Se cierra archivo.
    printf("Carga de Datos exitosa!\n");
}
