#include <time.h>
#include <alloc.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <graphics.h>

#include "c:\program\src_dos\libs\make_bot\make_bot.h"
#include "c:\program\src_dos\libs\bdatos\bdatos.hh"
#include "tpv_def.h"
#include "tpv_num.h"


BDatos   BProtector;             // Base de datos para el protector
MENSAJES SProtector;             // Para guardar los mensajes del protector



char BufferM[6][65 + 1];

 /*************************************\
|                                       |
|      Parte Principal del M¢dulo       |
|                                       |
 \*************************************/
int  far RatonMensajes( void );
void ConfigurarMensajes( void );
void CargaDatosProtector( void );
void MuestraAyudaProtector( char columna );
void MuestraDatosProtector( int RowStart );
void EditItemProtector( char columna, int linea );
void NuevoRegistroProtector( MENSAJES *NSProtector );
void MuestraMensajes( char columna, int linea, char como );
void ObtenCoordenadasProtector( char columna, char linea, int *X0, int *Y0, int *X1, int *Y1 );


p_Ampliada *LetraG[6];


//  ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß
// Û                     Parte principal del m¢dulo                       Û
//  ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ

 /**************************************************************************\
|*                                                                          *|
|*  ConfigurarMensajes                                                      *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Gestiona los mensajes que se mostraran en el protector      *|
|*                                                                          *|
|*  Entradas: (ninguna)                                                     *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void ConfigurarMensajes(void)
{
 char i, buffer[80], key;
 char CurrProtector, CurrRow, CurrCol, oldCol;
 int BPush, ok;
 int X0, Y0, X1, Y1;

 LeeFuentes(Config.Prot_fnt);


  for ( i = 0; i < 6; i++ )
      if ( ( LetraG[i] = ( p_Ampliada * )malloc( sizeof( p_Ampliada ) ) ) == NULL )
      {
       for ( i=0; i < 6; i++ )
                free( LetraG[i] );
       return;
      }

 sprintf( buffer, "datos\\%s\\mensajes.dbf", NEmpresa );
 if ( BProtector.AbrirReg( buffer, sizeof( MENSAJES ) ) == ERROR )
                                                             Error(0x01, BProtector.cError);

 // Si no hay registros, creamos uno almenos.
 if ( BProtector.Registros() != 0 )
 {
   if ( BProtector.LeeReg( (void *)&SProtector, 0         ) == ERROR )
                                                             Error(0x01, BProtector.cError);
 } else {
   NuevoRegistroProtector( &SProtector );
   if ( BProtector.InsReg( (void *)&SProtector, 0, ARRIBA ) == ERROR )
                                                             Error(0x01, BProtector.cError);
 }


 LetraG[0] -> x = 17;                 LetraG[0] -> y = 32;
 LetraG[0] -> ndigitos = 20;
 LetraG[0] -> AX =  2;                LetraG[0] -> AY =  2;

 *LetraG[5] = *LetraG[4] = *LetraG[3] = *LetraG[2] = *LetraG[1] = *LetraG[0];

 LetraG[1] -> y = 64;
 LetraG[2] -> y = 96;
 LetraG[3] -> y = 128;
 LetraG[4] -> y = 160;
 LetraG[5] -> y = 192;

 for ( i = 0; i < 6; i++ )
 {
  LetraG[i] -> C1 = SProtector.CBg[i];
  LetraG[i] -> C2 = SProtector.CFg[i];
 }


 // Rellenamos la pantalla con un fondo atractivo...
 setfillstyle( Config.FillBgS, Config.FillBgC );
 bar( 0, 0, 640, 480 );

 Imprime_Estaticos( 50, "systm\\Tpv.img");     // Imprime botones estaticos 'Seccion 1'

 for ( i = 0; i < 6; i++ )
    sprintf( BufferM[i], "%-20s%-20s%-20s", SProtector.Mensaje1[i], SProtector.Mensaje2[i], SProtector.Mensaje3[i] );

 CurrProtector = 0; CurrRow = 0;

 // Mostramos datos hasta que se nos acabe la pantalla
 MuestraDatosProtector( CurrProtector*6 + CurrRow );

 CurrCol =  0; ok = 0;
 oldCol  = -1;

 do {
      if ( CurrCol != oldCol )
      {
       oldCol = CurrCol;       MuestraAyudaProtector( CurrCol );
      }

      MuestraMensajes( CurrCol, CurrRow, INTENSO );
      BPush = Comprueba_Secuencia( 8, RatonMensajes );
      MuestraMensajes( CurrCol, CurrRow, NORMAL  );

      switch ( BPush )
      {
       case  0:				  // No se pulso ningun BOTON
	       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
	       break;
       case -2:				  // Hay una tecla normal en BUFFER
               if ( ( key = getch() ) != 27 )
               {
                if ( key != 13 )
                                      ungetch( key );
                EditItemProtector( CurrCol, CurrRow );

                for ( i = 0; i < 6; i++ )
                    sprintf( BufferM[i], "%-20s%-20s%-20s", SProtector.Mensaje1[i], SProtector.Mensaje2[i], SProtector.Mensaje3[i] );

               }
               break;
       case -1:				  // Hay una tecla especial en BUFFER
               switch( getch() )
               {
                // Flecha Izquierda
                case  75:
                case  15:
                       CurrCol--; if ( CurrCol <  0 ) CurrCol = 2;
                       break;
                // Flecha Derecha
                case  77:
                case   9:
                       CurrCol ++; if ( CurrCol > 2 ) CurrCol = 0;
                       break;
                // Flecha Arriba
                case  72:
                       CurrRow --; if ( CurrRow < 0 ) CurrRow = 5;
                       break;
                // Flecha Abajo
                case  80:
                       CurrRow ++; if ( CurrRow > 5 ) CurrRow = 0;
                       break;
               }
	       break;
       // Cambiar Fuente
       case  1:
	       break;
       // Menu Principal
       case  2:
               ok = 1;
               break;
       case  3:
       case  4:
       case  5:
       case  6:
       case  7:
       case  8:
               ObtenCoordenadasProtector( BPush, CurrRow, &X0, &Y0, &X1, &Y1 );
               if ( SProtector.Desplaz[ BPush - 3 ] )
               {
                  SProtector.Desplaz[ BPush - 3 ] = 0;
                  ponicono( X0+5, Y0+5, led_off, 1 );
               } else {
                  SProtector.Desplaz[ BPush - 3 ] = 1;
                  ponicono( X0+5, Y0+5, led_on,  1 );
               }
               break;
       case  9:
               CurrProtector--; if ( CurrProtector < 0 ) CurrProtector = 0;
               break;
       case 10:
               CurrProtector++; if ( CurrProtector > 5 ) CurrProtector = 5;
               break;
       case 11:
               LetraG[CurrRow] -> C2 =SProtector.CFg[CurrRow] = (SProtector.CFg[CurrRow] + 1) % 256;
               break;
       case 12:
               LetraG[CurrRow] -> C1 =SProtector.CBg[CurrRow] = (SProtector.CBg[CurrRow] + 1 ) % 256;
               break;
       case 13:
               LetraG[CurrRow] -> C2 =SProtector.CFg[CurrRow] = (SProtector.CFg[CurrRow] - 1 ) % 256;
               break;
       case 14:
               LetraG[CurrRow] -> C1 =SProtector.CBg[CurrRow] = (SProtector.CBg[CurrRow] - 1 ) % 256;
               break;
       default:
	       break;
      }

 } while( !ok );


 if ( BProtector.EscribeReg( (void *)&SProtector, 0    ) == ERROR )
                                                             Error(0x01, BProtector.cError);
 BProtector.CerrarReg();


 for ( i=0; i < 6; i++ )
            free( LetraG[i] );
}


 /**************************************************************************\
|*                                                                          *|
|*  MuestraDatosSProtector                                                    *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Dado un registro, se muestran sucesivamente este y todos    *|
|*              los que hay por debajo de ‚l, hasta que se agote la base    *|
|*              o no quepan mas en la pantalla.                             *|
|*                                                                          *|
|*  Entradas: Registro por el que comenzar                                  *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void MuestraDatosProtector( int RowStart )
{
 int linea, campo;
 int X0, Y0, X1, Y1;

 // Imprimo la NLINEAS_EMPL que caben en la pantalla

 for ( linea=0; linea < 6; linea++ )
 {
   // Por cada linea hay 3 campos, ehhh!!!
      for  ( campo=0; campo < 3; campo++ )
                                  MuestraMensajes( campo, linea, NORMAL );
 }

 // Ahora limpio los restantes huecos si los hay
   setfillstyle( SOLID_FILL, Config.TxtBgN );
   for ( ; linea < 6; linea++ )
     for  ( campo=0; campo < 3; campo++ )
     {
        ObtenCoordenadasProtector( campo, linea, &X0, &Y0, &X1, &Y1 );
        bar( X0, Y0, X1, Y1 );
     }

 for  ( campo=3; campo < 9; campo++ )
 {
  ObtenCoordenadasProtector( campo, 1, &X0, &Y0, &X1, &Y1 );
  if ( SProtector.Desplaz[ campo - 3 ] )
  {
     ponicono( X0+5, Y0+5, led_on,  1 );
  } else {
     ponicono( X0+5, Y0+5, led_off, 1 );
  }
 }

}

 /**************************************************************************\
|*                                                                          *|
|*  MuestraMensajes                                                          *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Reescribe el campo dado, seg£n la fila, y la intensidad     *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*            columna    campo ha mostar                                    *|
|*            linea      linea en la que nos encontramos                    *|
|*            como       intensidad del texto (NORMAL/INTENSO)              *|
|*                                                                          *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void MuestraMensajes( char columna, int linea, char como )
{
 char buffer[80];

 int X0, Y0, X1, Y1;

 ObtenCoordenadasProtector( columna, linea, &X0, &Y0, &X1, &Y1 );

 switch( columna )
 {
  case  0:
       sprintf ( buffer, "%s", SProtector.Mensaje1[linea] );
       break;
  case  1:
       sprintf ( buffer, "%s", SProtector.Mensaje2[linea] );
       break;
  case  2:
       sprintf ( buffer, "%s", SProtector.Mensaje3[linea] );
       break;
 }

  setfillstyle( SOLID_FILL, ( como == NORMAL ) ? Config.TxtBgN : Config.TxtBgI );
  bar( X0, Y0, X1, Y1 );
  setcolor ( ( como == NORMAL ) ? Config.TxtFgN : Config.TxtFgI );
  outtextxy( X0+2, Y0, buffer );

}

 /**************************************************************************\
|*                                                                          *|
|*  MuestraAyudaSProtector                                                    *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Muestra una peque¤a descripcion del contenido para el campo *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*            columna    campo ha mostar su ayuda                           *|
|*                                                                          *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void MuestraAyudaProtector( char columna )
{
 char buffer1[80];

 buffer1[0] = '\0';

 switch( columna )
 {
  case  0:
       sprintf ( buffer1, "Introduzca mensaje del 1er Bloque" );
       break;
  case  1:
       sprintf ( buffer1, "Introduzca mensaje del 2er Bloque" );
       break;
  case  2:
       sprintf ( buffer1, "Introduzca mensaje del 3er Bloque" );
       break;
 }

 // Ayuda reducida
 setfillstyle( SOLID_FILL, EGA_BLACK );  bar( 7, 457, 498, 473 );
 // Imprime la ayudita
 setcolor( EGA_WHITE ); outtextxy( 7, 457, buffer1 );

}

 /**************************************************************************\
|*                                                                          *|
|*  EditItemSProtector                                                        *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Se encarga de editar y validar el campo.                    *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*            columna    campo ha editar                                    *|
|*            linea      linea en la que nos encontramos                    *|
|*                                                                          *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void EditItemProtector( char columna, int linea )
{
 char buffer[80];

 int X0, Y0, X1, Y1;

 ObtenCoordenadasProtector( columna, linea, &X0, &Y0, &X1, &Y1 );

 switch( columna )
 {
  case  0:
       sprintf ( buffer, "%s", SProtector.Mensaje1[linea]  );
       if ( !( InputCadenaG( buffer, 0, 20, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       strcpy( SProtector.Mensaje1[linea], buffer );
       break;
  case  1:
       sprintf ( buffer, "%s", SProtector.Mensaje2[linea]  );
       if ( !( InputCadenaG( buffer, 0, 20, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       strcpy( SProtector.Mensaje2[linea], buffer );
       break;
  case  2:
       sprintf ( buffer, "%s", SProtector.Mensaje3[linea]  );
       if ( !( InputCadenaG( buffer, 0, 20, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       strcpy( SProtector.Mensaje3[linea], buffer );
       break;
 }
 while( kbhit() ) getch();

}


 /**************************************************************************\
|*                                                                          *|
|*  ObtenCoordenadasProtector                                                *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Obtiene las coordenadas de acotacion para el campo pedido   *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*            columna    campo del que obtener las coordenadas              *|
|*            linea      linea en la que nos encontramos                    *|
|*            X0 Y0 X1 Y1  Punteros para devolver las coordenadas           *|
|*                                                                          *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void ObtenCoordenadasProtector( char columna, char linea, int *X0, int *Y0, int *X1, int *Y1 )
{

 // Calculamos la Y0, Y1 para la linea dada ( SOLO columna < 3 )
 *Y0 = 280 + 19*linea;
 *Y1 = *Y0 + 17;

 switch( columna )
 {
  case  0:
       *X0 =   7;       *X1 = 209;
       break;
  case  1:
       *X0 = 219;       *X1 = 421;
       break;
  case  2:
       *X0 = 431;       *X1 = 633;
       break;


  case  3:
       *X0 = 350;       *X1 = 380;
       *Y0 =  27;       *Y1 =  57;
       break;
  case  4:
       *X0 = 350;       *X1 = 380;
       *Y0 =  61;       *Y1 =  91;
       break;
  case  5:
       *X0 = 350;       *X1 = 380;
       *Y0 =  95;       *Y1 = 125;
       break;
  case  6:
       *X0 = 350;       *X1 = 380;
       *Y0 = 129;       *Y1 = 159;
       break;
  case  7:
       *X0 = 350;       *X1 = 380;
       *Y0 = 163;       *Y1 = 193;
       break;
  case  8:
       *X0 = 350;       *X1 = 380;
       *Y0 = 197;       *Y1 = 227;
       break;
 }

 *X0 += 2;
 *X1 -= 2;

}



 /**************************************************************************\
|*                                                                          *|
|*  CargaDatosProtextor                                                     *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*               Carga los datos del Protector                              *|
|*                                                                          *|
|*  Entradas:(ninguna)                                                      *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void CargaDatosProtector( void )
{
 char buffer[80];

 sprintf( buffer, "datos\\%s\\mensajes.dbf", NEmpresa );
 if ( BProtector.AbrirReg( buffer, sizeof( MENSAJES ) ) == ERROR )
                                                             Error(0x01, BProtector.cError);

 // Si no hay registros, creamos uno almenos.
 if ( BProtector.Registros() != 0 )
 {
   if ( BProtector.LeeReg( (void *)&SProtector, 0         ) == ERROR )
                                                             Error(0x01, BProtector.cError);
 } else {
   NuevoRegistroProtector( &SProtector );
   if ( BProtector.InsReg( (void *)&SProtector, 0, ARRIBA ) == ERROR )
                                                             Error(0x01, BProtector.cError);
 }

 BProtector.CerrarReg();

}

void NuevoRegistroProtector( MENSAJES *NSProtector )
{
 int i;


 NSProtector ->TEspera = 15;          // Segundos de espera para pasar al siguiente bloque

 for ( i = 0; i < 6; i++ )
 {
  NSProtector ->Desplaz[i] = 0;       // Indicador si se desplaza o no.

  NSProtector ->Mensaje1[i][0] = '\0';// Mensaje que se va a mostrar
  NSProtector ->Mensaje2[i][0] = '\0';// Mensaje que se va a mostrar
  NSProtector ->Mensaje3[i][0] = '\0';// Mensaje que se va a mostrar

  NSProtector ->CFg[i] = 63;
  NSProtector ->CBg[i] =  0;
 }

 NSProtector ->Desplaz[3] = 1;                 // Indicador si se desplaza o no.
 strcpy(   NSProtector ->Mensaje1[3], "Programa realizado p" );
 strcpy(   NSProtector ->Mensaje2[3], "or:  Jose David Guil" );// Mensaje que se va a mostrar
 strcpy(   NSProtector ->Mensaje3[3], "len" );// Mensaje que se va a mostrar


}

 /**************************************************************************\
|*                                                                          *|
|*  PreviewPantalla                                                         *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Muestra un preview de como quedar  el mensaje del protector *|
|*                                                                          *|
|*  Entradas:(ninguna)                                                      *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void PreviewPantalla(void)
{
 static int  Pasadas = 20*8 - 1;
 static time_t first;
 static char Paso = 0;
 char i;

 if ( Pasadas == -1 && difftime( time(NULL), first ) >= SProtector.TEspera )
 {
  Pasadas = 0;
  if ( Paso == 4 ) Paso = 1;
 }

 if ( Pasadas >= 0 )
 {
                   Pasadas ++;
                   if ( Pasadas > (Paso != 3 ? 20*8 : 25*8 ) )
                   {
                                         time( &first );
                                         Pasadas = -1;
                                         Paso++;
                   }
 }

 for ( i = 0; i < 6; i++ )
 {
      if ( SProtector.Desplaz[i] || Pasadas != -1 )
                Fuente_Amplia3( BufferM[i], LetraG[i] );
 }


}


 /**************************************************************************\
|*                                                                          *|
|*  RatonMensajes                                                           *|
|*                                                                          *|
|*  Descripci¢n:                                                            *|
|*              Funci¢n soporte para el control del raton, que ademas se    *|
|*              encarga de mostrar el letrero digital y el protector de     *|
|*              pantalla.                                                   *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Linea en la que se inserta y posici¢n f¡sica, y columna        *|
|*                                                                          *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
int far RatonMensajes(void)
{

//  inicializa_raton_grafico(0, 0, 624, 464);
// char boton_izq, boton_der;
 char Que;

  activa_raton();

  union REGS io;
  io.x.ax = 3;



  do{
      PreviewPantalla();

      int86(0x33, &io, &io);    // lee posici¢n y estados del bot¢n

      x_raton = io.x.cx;
      y_raton = io.x.dx;

  }while( (io.x.bx & 1) == 0 && ((io.x.bx >> 1) & 1) == 0 && !kbhit() );


  /////////////////////////////////////////
  //     RETURN    Derecho   Izquierdo   //
  //                                     //
  //       0         0           0       //
  //       1         1           0       //
  //       2         0           1       //
  //       3         1           1       //
  //                                     //
  /////////////////////////////////////////


  if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==0 ) Que = 0;
  if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==0 ) Que = 1;
  if ( ((io.x.bx >> 1) & 1)==0 && (io.x.bx & 1)==1 ) Que = 2;
  if ( ((io.x.bx >> 1) & 1)==1 && (io.x.bx & 1)==1 ) Que = 3;

  desactiva_raton();
  return Que;
}