/*--------------------------------------------------------------------
 * FICHERO:  CreaBdDm.c
 * OBJETIVO: Crear el fichero Demo.dbf
 * AUTOR:    Pedro Reina
 * FECHA:    V.4.8.1995
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * Ficheros de cabecera
 *------------------------------------------------------------------*/

#include "Olimpo.h"     /* Versin 2.0 */
#include <stdio.h>      /* sprintf()   */

/*--------------------------------------------------------------------
 * Declaracin de funciones
 *------------------------------------------------------------------*/

lista FicheroLista();
lista NodoAleatorio();
void  ConstruyeClave();

/*--------------------------------------------------------------------
 * FUNCION PRINCIPAL
 * ENTRADAS: Se utilizan cuatro ficheros: Nombre.txt, Apellido.txt,
 *           Deporte.txt y Pais.txt
 *           Al usuario se le pide cuntos registros desea
 * SALIDAS:  Los ficheros Demo.dbf y Demo.ntx
 * ALGORITMO:
 *      Pedir al usuario el nmero de lneas que hay que generar
 *      Almacenarlo en la variable Total
 *      Leer el fichero Nombre.txt, generando una lista con los nombres
 *      Leer el fichero Apellido.txt, generando una lista con los apellidos
 *      Leer el fichero Deporte.txt, generando una lista con los deportes
 *      Leer el fichero Pais.txt, generando una lista con los paises
 *      Crear los ficheros de salida, Demo.dbf y Demo.ntx
 *      Iniciar la semilla del generador de nmeros aleatorios
 *      Repetir Total veces
 *        Aadir un registro nuevo, obtenido aleatoriamente, con
 *          Un nombre
 *          Un apellido
 *          Un nmero entre 1.50 y 2.10
 *          Un nmero entre 35 y 120
 *          Un deporte
 *          Un pais
 *      Cerrar los ficheros de salida
 *------------------------------------------------------------------*/
void main()
  {
  static cadena   Nombre[]   = { "NOMBRE", "APELLIDO", "ALTURA", "PESO",
                                 "DEPORTE", "PAIS", NIL };
  static char     Tipo[]     = { 'C', 'C', 'N', 'N', 'C', 'C' };
  static contador Longitud[] = { 10,  10,   4,   3,  10,   10 };
  static contador Decimal[]  = {  0,   0,   2,   0,   0,    0 };

  entero   Total, Numero;
  contador i,j,Peso;
  cadena   Aux;
  lista    ListaNombre, ListaApellido, ListaDeporte, ListaPais;
  basedato Salida;
  real     Estatura;
  indice   Indice;
  caracter Clave[21];

  Pan_Define (PAN_TEXTO);
  Prg_Presenta ("Crea Base Demo", "2.0", "Pedro Reina", "Agosto 1995");

  Pan_Color (NEGRO,BLANCO);
  Pan_PonTexto (3,3,"Este programa crea una base de datos");
  Pan_PonTexto (4,3,"llamada Demo.dbf y un fichero de ndices");
  Pan_PonTexto (5,3,"Demo.ntx para usar con la demostracin");
  Pan_PonTexto (6,3,"de Olimpo");

  Pan_Tinta (VERDE);
  Pan_PonTexto (9,3,"Nmero de registros: " );
  Total = Usr_Entero (60,3,10,200,9,24,NEGRO,BLANCO);

  if ( Tec_Ultima() == TEC_ESC )
    { Usr_PulsaUnaTecla ("Programa abortado"); }

  else
    {
    Aux = Fch_Nombre ("Nombre","txt");
    ListaNombre = FicheroLista (Aux);
    Cad_Destruye (Aux);

    Aux = Fch_Nombre ("Apellido","txt");
    ListaApellido = FicheroLista (Aux);
    Cad_Destruye (Aux);

    Aux = Fch_Nombre ("Deporte","txt");
    ListaDeporte = FicheroLista (Aux);
    Cad_Destruye (Aux);

    Aux = Fch_Nombre ("Pais","txt");
    ListaPais = FicheroLista (Aux);
    Cad_Destruye (Aux);

    Aux = Fch_Nombre ("Demo","dbf");
    Usr_Informa ("Creando base de datos");
    Salida = Bdt_Crea (Aux, Nombre, Tipo, Longitud, Decimal);
    Cad_Destruye (Aux);

    Aux = Fch_Nombre ("Demo","ntx");
    Usr_Informa ("Creando fichero ndice");
    Indice = Ind_Crea (Aux, "Apellido+Nombre", 20, 0);
    Cad_Destruye (Aux);

    if ( Salida && Indice )
      {
      Azr_Inicia();
      Usr_Informa ("Generando registros");
      Pan_Tinta (VERDE);
      Pan_PonTexto (11,3,"Ya generados: " );

      Pan_Tinta (BLANCO);
      for ( i=0 ; i<Total ; i++ )
        {
        Pan_PonEntero (11,17,i+1,3);
        Bdt_LimpiaRegistro (Salida);

        Bdt_PonCampoNumero (Salida,0,
                            Lis_Contenido(NodoAleatorio(ListaNombre)));

        Bdt_PonCampoNumero (Salida,1,
                            Lis_Contenido(NodoAleatorio(ListaApellido)));

        Aux = Cad_Crea (4);
        Estatura = Azr_Entero (150,210) / 100.0;
        sprintf (Aux,"%4.2f",Estatura);
        Bdt_PonCampoNumero (Salida,2,Aux);
        Cad_Destruye (Aux);

        Estatura = Estatura * 100 - 100;
        Peso = Azr_Entero ( (contador) (0.8 * Estatura),
                            (contador) (1.2 * Estatura));
        Aux = Cad_Entero (Peso);
        Bdt_PonCampoNumero (Salida,3,Aux);
        Cad_Destruye (Aux);

        Bdt_PonCampoNumero (Salida,4,
                            Lis_Contenido(NodoAleatorio(ListaDeporte)));

        Bdt_PonCampoNumero (Salida,5,
                            Lis_Contenido(NodoAleatorio(ListaPais)));

        Bdt_AgregaRegistro (Salida,&Numero);
        
        ConstruyeClave (Salida, Clave);
        Ind_Inserta (Indice, Numero, Clave, Cad_Compara);
        }
      }

    if ( Salida )  { Bdt_Cierra (Salida); }
    if ( Indice )  { Ind_Cierra (Indice); }

    Usr_PulsaUnaTecla ( "Programa terminado" );
    }
  Pan_Cierra();
  }

/*--------------------------------------------------------------------
 * Definicin de funciones
 *------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 * FUNCION:  FicheroLista ()
 * OBJETIVO: Leer un fichero de texto y formar una lista en memoria con
 *           las lneas del fichero. Cada lnea es un nodo.
 * ENTRADAS: El nombre del fichero
 * SALIDA:   La lista o NIL si ha habido error
 *------------------------------------------------------------------*/
lista FicheroLista ( NombreFichero )
cadena NombreFichero;
  {
  lista   Nuevo;
  cadena  Aux;
  fichero Fichero;

  Fichero = Fch_AbreLeer ( NombreFichero, FCH_TEXTO );
  if ( Fichero )
    {
    if ( Nuevo = Lis_Crea() )
      {
      while ( Aux = Fch_LeeLinea(Fichero) )
        { Nuevo = Lis_Anota (Nuevo,Aux); }
      }
    Fch_Cierra ( Fichero );
    }
  return ( Nuevo );
  }

/*-------------------------------------------------------------------------
 * FUNCION:  NodoAleatorio()
 * OBJETIVO: Dar un elemento cualquiera de una lista
 * ENTRADAS: La lista
 * SALIDAS:  Uno de los elementos
 *-----------------------------------------------------------------------*/
lista NodoAleatorio (Lista)
lista Lista;
  {
  entero Total, Fin, i;

  Total = Lis_Total (Lista);
  Fin = Azr_Entero (1,Total);

  for ( i=1 ; i<Fin ; i++ )
    { Lista = Lis_Siguiente (Lista); }

  return (Lista);
  }

/*-------------------------------------------------------------------------
 * FUNCION:  ConstruyeClave()
 * OBJETIVO: Construir la clave que se debe usar para indexar un registro
 * ENTRADAS: La base de datos (se usa el registro actual) y una cadena
 *           donde dejar la clave
 * SALIDAS:  Ninguna, la cadena queda modificada
 *-----------------------------------------------------------------------*/
void ConstruyeClave (Base, Clave)
basedato Base;
cadena   Clave;
  {
  Bdt_CampoNumero (Base, 1, Clave);
  Bdt_CampoNumero (Base, 0, Clave+10);
  }
  