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

#include "d:\program\src_dos\libs\bdatos\bdatos.hh"
#include "zorr.h"

#define NLINEAS_REF 18

BDatos BPrecios;            // Base de datos de Precioserencias
INFO_ARTICULOS SPrecios;     // Estructura de referencias

int OrdenPrecios;

extern CONFIG Config;

void RastreaFicheroGastosi(void);

void Error( int code );
void MuestraDatosPrecios( int RowStart );

int ComparaRegistrosPrecio( const void *A, const void *B );

void EditItemPrecios( char columna, int linea );
void PreciosNuevoRegistro( INFO_ARTICULOS *MSPrecios );
void MuestraPrecios( char columna, int linea, char como );
void ObtenCoordenadasPrecios( char columna, char linea, int *X0, int *Y0, int *X1, int *Y1 );
void OrdenaPrecios(void);

void ObtenCoordenadasMatchPr( char Row, int *X0, int *Y0, int *X1, int *Y1 );
void MatchDrawPrecios( char Row, INFO_ARTICULOS MPrecios,  char como );
void BuscaPrecios( char TipoBusqueda, char *CurrRow, int *CurrPrecios );
int  Match_Precios( INFO_ARTICULOS A, INFO_ARTICULOS B );
void EditMatchPrecios( char Row, INFO_ARTICULOS * MPrecios );
int  ObtenMatchPrecios( INFO_ARTICULOS *MPrecios );



void ImprimePrecioserencias( char como );
void ImprimeCabeceraPrecios( char como, FILE *file_out );
void DibujaPantallaArticulos( void );


//  ���������������������������������������������������������������������
// �                     Parte principal del m�dulo                       �
//  ���������������������������������������������������������������������


 /**************************************************************************\
|*                                                                          *|
|*  InfoProducto                                                            *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Controla la introduccion de datos y muestreo asi como todo  *|
|*              el interfaz de usuario...                                   *|
|*                                                                          *|
|*  Entradas: (ninguna)                                                     *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void ListaPrecios(void)
{
struct Boton_Texto BT[6];


BT[0].x =  1; BT[0].y =  1; strcpy( BT[0].Texto, " &Men� Principal "); BT[0].ID_T1 =  0; BT[0].ID_T2 = 50;
BT[1].x = 20; BT[1].y =  1; strcpy( BT[1].Texto, " &Ins. Art."); BT[1].ID_T1 =  0; BT[1].ID_T2 = 23;

BT[2].x = 33; BT[2].y =  1; strcpy( BT[2].Texto, " &Borr. Art."); BT[2].ID_T1 =  0; BT[2].ID_T2 = 48;
BT[3].x = 47; BT[3].y =  1; strcpy( BT[3].Texto, " &Ordenar");    BT[3].ID_T1 =  0; BT[3].ID_T2 = 24;

BT[4].x = 58; BT[4].y =  1; strcpy( BT[4].Texto, " &Buscar"); BT[4].ID_T1 =  0; BT[4].ID_T2 = 48;
BT[5].x = 72; BT[5].y =  1; strcpy( BT[5].Texto, " Im&pr. ");         BT[5].ID_T1 =  0; BT[5].ID_T2 = 25;

 char buffer[100], ok = 0;
 int BPush, key;

 char oldCol;
 char CurrRow;         // Linea sobre la que estamos
 char CurrCol;         // Columna sobre la que estamos
 int CurrPrecios;         // Producto sobre el que estamos posicionados a golpes

 _setcursortype( _NOCURSOR );
 DibujaPantallaArticulos();

 if ( BPrecios.AbrirReg( "Articulo.dbf", sizeof( INFO_ARTICULOS ) ) == ERROR )
                                                             Error(0x00);

 // Si no hay registros, creamos uno almenos.
 if ( BPrecios.Registros() == 0 )
 {
      PreciosNuevoRegistro( &SPrecios );
      if ( BPrecios.InsReg( (void *)&SPrecios, BPrecios.Registros(), ARRIBA ) == ERROR )
                                                             Error(0x00);
 }

 CurrPrecios = 0; CurrRow = 0;

 // Mostramos datos hasta que se nos acabe la pantalla
 MuestraDatosPrecios( CurrRow + CurrPrecios );
 if ( BPrecios.LeeReg( (void *)&SPrecios, 0      ) == ERROR )
                                                             Error(0x00);

 CurrCol = 0; oldCol = -1;

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

      MuestraPrecios( CurrCol, CurrRow, INTENSO );
      BPush = Funcion_Botones(STD_BY, 6, BT);
      MuestraPrecios( 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() ) != 13 && key != 27 )
                                      ungetch( key );
               EditItemPrecios( CurrCol, CurrRow );
               _setcursortype( _NOCURSOR );
               if ( BPrecios.EscribeReg( (void *)&SPrecios, (CurrRow + CurrPrecios) ) == ERROR )
                                                             Error(0x00);
	       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
               break;
       case -1:				  // Hay una tecla especial en BUFFER
               switch( getch() )
               {
                // Flecha Izquierda
                case  75:
                case  15:
                       CurrCol--; if ( CurrCol <  0 ) CurrCol = 3;
                       break;
                // Flecha Derecha
                case  77:
                case   9:
                       CurrCol++; if ( CurrCol > 3 ) CurrCol =  0;
                       break;
                // Flecha Arriba
                case  72:
                        if ( (CurrRow + CurrPrecios) > 0 )
                        {
                         if ( ( CurrRow ) <= 0 )
                         {
                          CurrRow = NLINEAS_REF - 1;          CurrPrecios -= NLINEAS_REF;
                          if ( CurrPrecios < 0 ) CurrPrecios = 0;

                          while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrRow > 0 ) CurrRow--;
                          while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrPrecios > 0 ) CurrPrecios++;

                          // Mostramos datos hasta que se nos acabe la pantalla
                          MuestraDatosPrecios( CurrPrecios );
                         } else {
                          CurrRow --; if ( CurrRow < 0 ) CurrRow = 0;
                         }
                        }

                        if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);
                       break;
                // Flecha Abajo
                case  80:
                        if ( ( CurrRow + CurrPrecios ) < BPrecios.Registros() - 1 )
                        {

                         if ( ( CurrRow ) >= NLINEAS_REF - 1 )
                         {
                           CurrRow = 0;		CurrPrecios += NLINEAS_REF;

                           while ( (CurrPrecios + CurrRow) >= BPrecios.Registros() ) CurrPrecios--;

                           // Mostramos datos hasta que se nos acabe la pantalla
                           MuestraDatosPrecios( CurrPrecios );
                         } else
                         	CurrRow++;
                        }
                        if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);
                       break;
                // Inicio
                case  71:
                       CurrRow = 0;
                       if ( CurrPrecios != 0 )
                       {
                        CurrPrecios = 0;

                        // Mostramos datos hasta que se nos acabe la pantalla
                        MuestraDatosPrecios( CurrPrecios );
                       }

                       if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);

                       break;
                // Fin
                case  79:
                       CurrRow = 0;
                       if ( CurrPrecios != BPrecios.Registros() - NLINEAS_REF )
                       {
                        CurrPrecios = BPrecios.Registros() - NLINEAS_REF;
                        while( CurrPrecios >= BPrecios.Registros() ) CurrPrecios--;
                        if ( CurrPrecios < 0 )
                        {
                         CurrPrecios = 0;
                         CurrRow = BPrecios.Registros()-1;
                        }

                        // Mostramos datos hasta que se nos acabe la pantalla
                        MuestraDatosPrecios( CurrPrecios );
                       }

                       if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);

                       break;
       // AvanceR�pido
       case  81:
	       CurrRow = 0;		CurrPrecios += NLINEAS_REF;

               while ( (CurrPrecios + CurrRow) >= BPrecios.Registros() ) CurrPrecios--;

               // Mostramos datos hasta que se nos acabe la pantalla
               MuestraDatosPrecios( CurrPrecios );
               if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);

	       break;
       // Retroceso R�pido
       case  73:
               CurrRow = NLINEAS_REF - 1;          CurrPrecios -= NLINEAS_REF;
               if ( CurrPrecios < 0 ) CurrPrecios = 0;

               while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrRow > 0 ) CurrRow--;
               while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrPrecios > 0 ) CurrPrecios++;

               // Mostramos datos hasta que se nos acabe la pantalla
               MuestraDatosPrecios( CurrPrecios );
               if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);

	       break;
       // Gastos por proveedor
       case 82:
               BuscaPrecios( ATRAS, &CurrRow, &CurrPrecios );
	       break;
       // Gastos por proveedor
       case 83:
               BuscaPrecios( ADELANTE, &CurrRow, &CurrPrecios );
	       break;

               }
	       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
	       break;
       // Imprimir Lista de socios
       case  6:
//               MuestraImpresionesPrecios();
	       break;
       // Menu Principal
       case  1:
               ok = 1;
               break;
       // Eliminar
       case  3:
       while( kbhit() ) getch();
               if ( Optar( 1, "ATENCION", "Eliminar� un articulo", "confirme eliminacion",  NULL ) )
               {
                if ( BPrecios.DelReg( CurrPrecios + CurrRow ) == ERROR )
                                                              Error(0x00);
                if ( BPrecios.Registros() == 0 )
                {
                  PreciosNuevoRegistro( &SPrecios );
                  if ( BPrecios.InsReg( (void *)&SPrecios, BPrecios.Registros(), ARRIBA ) == ERROR )
                                                                               Error(0x00);
                  CurrRow = 0;
                } else

                // Si he borrado el �ltimo registro subo una linea
                if ( (CurrPrecios+CurrRow) >= ( BPrecios.Registros() - 2 ) )
                {
                         if ( (CurrRow + CurrPrecios) > 0 )
                         {
                          if ( ( CurrRow ) <= 0 )
                          {
                           CurrRow = NLINEAS_REF - 1;          CurrPrecios -= NLINEAS_REF;
                           if ( CurrPrecios < 0 ) CurrPrecios = 0;

                           while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrRow > 0 ) CurrRow--;
                           while( ( CurrRow + CurrPrecios ) >= BPrecios.Registros() && CurrPrecios > 0 ) CurrPrecios++;

                           // Mostramos datos hasta que se nos acabe la pantalla
                           MuestraDatosPrecios( CurrPrecios );
                          } else {
                           CurrRow --; if ( CurrRow < 0 ) CurrRow = 0;
                          }
                         }

                         if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                              Error(0x00);
                }

                // Mostramos datos hasta que se nos acabe la pantalla
                MuestraDatosPrecios( CurrPrecios );
                if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                              Error(0x00);
               }
	       break;
       // Insertar
       case  2:
               PreciosNuevoRegistro( &SPrecios );
               if ( BPrecios.InsReg( (void *)&SPrecios, (CurrPrecios + CurrRow), ARRIBA ) == ERROR )
                                                             Error(0x00);
               if ( ( CurrRow + CurrPrecios ) < BPrecios.Registros() - 1 )
               {

                if ( ( CurrRow ) >= NLINEAS_REF - 1 )
                {
                   CurrRow = 0;		CurrPrecios += NLINEAS_REF;

                   while ( (CurrPrecios + CurrRow) >= BPrecios.Registros() ) CurrPrecios--;

                 } else
                   CurrRow++;
                 }

                 // Mostramos datos hasta que se nos acabe la pantalla
                 MuestraDatosPrecios( CurrPrecios );
                 if ( BPrecios.LeeReg( (void *)&SPrecios, (CurrPrecios + CurrRow) ) == ERROR )
                                                             Error(0x00);

	       break;

       // Ordenar
       case  4:
               OrdenaPrecios();
 CurrPrecios = 0; CurrRow = 0;

 // Mostramos datos hasta que se nos acabe la pantalla
 MuestraDatosPrecios( CurrRow + CurrPrecios );
 if ( BPrecios.LeeReg( (void *)&SPrecios, 0      ) == ERROR )
                                                             Error(0x00);

 CurrCol = 0;

	       break;
       // Gastos por proveedor
       case  5:
               BuscaPrecios( NUEVA_BUSQUEDA, &CurrRow, &CurrPrecios );
	       break;
       default:
               while( kbhit() ) getch();
	       break;
      }

 } while( !ok );

 BPrecios.CerrarReg();
}



 /**************************************************************************\
|*                                                                          *|
|*  MuestraDatosPrecios                                                         *|
|*                                                                          *|
|*  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 MuestraDatosPrecios( int RowStart )
{
 int linea, campo;
 char dev;

 // Imprimo la NLINEAS_REF que caben en la pantalla
 dev = OK;
 for ( linea=0; linea < NLINEAS_REF && dev == OK; linea++ )
 {
   dev = BPrecios.LeeReg( (void *)&SPrecios, RowStart + linea );
   if ( dev == OK )
   // Por cada linea hay 4 campos, ehhh!!!
      for  ( campo=0; campo < 4; campo++ )
                                  MuestraPrecios( campo, linea, NORMAL );
 }

 // Ahora limpio los restantes huecos si los hay
 if ( dev != OK )
 {
   linea--;

   textbackground( BLACK );
   textcolor( WHITE );
   for ( ; linea < NLINEAS_REF; linea++ )
      gotoxy(  1, linea +  6 );
      cprintf( "�                                          �           �           �           �");

 }
}

 /**************************************************************************\
|*                                                                          *|
|*  MuestraPrecios                                                              *|
|*                                                                          *|
|*  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 MuestraPrecios( char columna, int linea, char como )
{
 char buffer[80];
 char buffer1[80];

 int X0, Y0, X1, Y1;

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

 switch( columna )
 {
  // Articulo
  case  0:
       sprintf ( buffer, "%42s", (int)SPrecios.Articulo  );
       break;
  // Precio Articulo
  case  1:
       formatea_u_long( SPrecios.Precio, buffer1 );
       sprintf ( buffer, "%11s",  buffer1  );
       break;
  // Precio Articulo2
  case  2:
       formatea_u_long( SPrecios.PrecioArt, buffer1 );
       sprintf ( buffer, "%11s",  buffer1  );
       break;
  // Ubicacion
  case  3:
       sprintf ( buffer, "%11s",  SPrecios.Ubicacion );
       break;
 }

 textbackground( ( como == NORMAL ) ? Config.TxtBgN : Config.TxtBgI );
 strnset( buffer1, 32, X1 );

 textcolor( ( como == NORMAL ) ? Config.TxtFgN : Config.TxtFgI );
 gotoxy( X0, Y0 );
 cprintf( "%s", buffer );

}


 /**************************************************************************\
|*                                                                          *|
|*  EditItemPrecios                                                             *|
|*                                                                          *|
|*  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 EditItemPrecios( char columna, int linea )
{
 char buffer[80];

 int X0, Y0, X1, Y1;

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

 switch( columna )
 {
  // Articulo
  case  0:
       strcpy ( buffer, SPrecios.Articulo   );
       if ( !( InputCadenaG( buffer, 0, 42, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       strcpy ( SPrecios.Articulo, buffer   );
       break;
  // Precio Articulo
  case  1:
       sprintf ( buffer, "%ld", SPrecios.Precio );
       if ( !( InputCadenaG( buffer, 1,  9, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       SPrecios.Precio = atol( buffer );
       break;
  // Precio Articulo
  case  2:
       sprintf ( buffer, "%ld", SPrecios.PrecioArt );
       if ( !( InputCadenaG( buffer, 1,  9, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       SPrecios.PrecioArt = atol( buffer );
       break;
  // Ubicacion
  case  3:
       strcpy ( buffer, SPrecios.Ubicacion   );
       if ( !( InputCadenaG( buffer, 0, 11, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
       strcpy ( SPrecios.Ubicacion, buffer   );
       break;
  }
}

 /**************************************************************************\
|*                                                                          *|
|*  ObtenCoordenadasPrecios                                                     *|
|*                                                                          *|
|*  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 ObtenCoordenadasPrecios( char columna, char linea, int *X0, int *Y0, int *X1, int *Y1 )
{

 // Calculamos la Y0, Y1 para la linea dada ( SOLO columna < 6 )
 *Y0 = 6 + linea;
 *Y1 = 6 + linea;

 switch( columna )
 {
  case 0:
       *X0 =   2;       *X1 =  42;
       break;
  case 1:
       *X0 =  45;       *X1 =  11;
       break;
  case 2:
       *X0 =  57;       *X1 =  11;
       break;
  case 3:
       *X0 =  69;       *X1 =  11;
       break;
 }


}

 /**************************************************************************\
|*                                                                          *|
|*  PreciosNuevoRegistro                                                        *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Limpia el buffer, para un nuevo registro.                   *|
|*                                                                          *|
|*  Entradas: (ninguna)                                                     *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void PreciosNuevoRegistro( INFO_ARTICULOS *NSPrecios )
{


 NSPrecios -> Articulo[0]   = '\0';
 NSPrecios -> Ubicacion[0]  = '\0';
 NSPrecios -> Precio    = 0;
 NSPrecios -> PrecioArt = 0;

}




//  ���������������������������������������������������������������������
// �                     Parte secundaria del m�dulo                      �
// �                                                                      �
// �                  Secci�n de Busqueda de refecencias                  �
//  ���������������������������������������������������������������������

 /**************************************************************************\
|*                                                                          *|
|*  MuestraImpresionesRed                                                      *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Muestra un cuadro con las distintas opciones de impresi�n   *|
|*                                                                          *|
|*  Entradas:(ninguna)                                                      *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/


 /**************************************************************************\
|*                                                                          *|
|*  ImprimePrecioserencias                                                      *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Imprime todas las referencias seg�n se le indique           *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Como imprimir las referencias                                  *|
|*                                                                          *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void ImprimePrecioserencias( char como )
{
 long i, old_reg;
 FILE *file_out;

 old_reg = BPrecios.RegActual();

 if ( !Config.Printer )
 {
   if ( ( file_out = fopen( Config.PrintTo, "w" ) ) == NULL )
                                                            return;
 } else
      file_out = stdprn;

 ImprimeCabeceraPrecios( como, file_out );

 for ( i=0; i<BPrecios.Registros(); i++ )
 {
  BPrecios.LeeReg( (void *)&SPrecios, i );
  switch( como )
  {
/*
   // Listado R�pido
   case 1:

        formatea_u_long( (unsigned long)SPrecios.CantUnitaria, buffer );
        fprintf( file_out, "%9lu  %-30s  %-6s  ", SPrecios.CodigoR, SPrecios.Descripcion, buffer );
        formatea_u_long( (unsigned long)SPrecios.PrecioCosto,    buffer );
        fprintf( file_out, "%-7s  ", buffer );
        formatea_u_long( (unsigned long)SPrecios.PrecioVenta[0], buffer );
        fprintf( file_out, "%-7s  %-10s\n\r", buffer, SPrecios.Combinado ? "Combinado" : "" );
        break;
   // Listado Completo
   case 2:
        formatea_u_long( (unsigned long)SPrecios.CantUnitaria, buffer );
        fprintf( file_out, "%9lu  %-30s  %-6s  ", SPrecios.CodigoR, SPrecios.Descripcion, buffer );
        formatea_u_long( (unsigned long)SPrecios.PrecioCosto,    buffer );
        fprintf( file_out, "%-7s  ", buffer );
        formatea_u_long( (unsigned long)SPrecios.PrecioVenta[0], buffer );
        fprintf( file_out, "%-7s  %-10s\n\r", buffer, SPrecios.Combinado ? "Combinado" : "" );
        if ( SPrecios.Combinado )
        {
         for ( j=0; j<10; j++ )
          if ( SPrecios.CodigosAsociados[j] != 0 )
                   fprintf( file_out, "                                                           %-7s     %9lu", j < 4 ? SPrecios.PrecioVenta[j+1] : 0, SPrecios.CodigosAsociados[j] );
        }
        break;
   // C�digos de barra
   case 3:
        break;
*/
  }
 }

 if ( !Config.Printer )
                      fclose( file_out );

 BPrecios.LeeReg( (void *)&SPrecios, old_reg );

}

void ImprimeCabeceraPrecios( char como, FILE *file_out )
{
  switch( como )
  {
   // Listado R�pido
   case 1:
        fprintf( file_out, "C�digo     Proveedor                      Cant.Unt P.Costo  P.Venta  Combinado\n\r" );
        break;
   // Listado Completo
   case 2:
        fprintf( file_out, "C�digo     Proveedor                      Cant.Unt P.Costo  P.Venta  Cod. Combinado\n\r" );
        break;
   // C�digos de barra
   case 3:
        break;
  }

}








void DibujaPantallaArticulos(void)
{
  int i;
  textcolor( WHITE );
  textbackground( BLACK );
          // 145678 123456789-123456789-123 12345  345.789 123.123.123 123456789-123456789-

  cprintf( "\r                                                                                ");
  cprintf( "                                                                                ");
  cprintf( "������������������������������������������������������������������������������Ŀ");
  cprintf( "�  Articulo                                � P no Soc  �  P. Soc   � Ubicaci�n �");
  cprintf( "������������������������������������������������������������������������������Ĵ");

  for ( i=0; i<18; i++ )
  cprintf( "�                                          �           �           �           �");
  cprintf( "��������������������������������������������������������������������������������");



}





int ComparaRegistrosPrecio( const void *A, const void *B )
{
 // Tipos de ordenaciones posibles
 switch( OrdenPrecios )
 {
  // Por Precio
  case 3:
   if ( ( ((INFO_ARTICULOS *)A) -> Precio ) <  ( ((INFO_ARTICULOS *)B) -> Precio ) ) return -1;
   if ( ( ((INFO_ARTICULOS *)A) -> Precio ) == ( ((INFO_ARTICULOS *)B) -> Precio ) ) return  0;
   if ( ( ((INFO_ARTICULOS *)A) -> Precio ) >  ( ((INFO_ARTICULOS *)B) -> Precio ) ) return  1;
   break;
  // Por Precio
  case 2:
   return strcmpi( ( ((INFO_ARTICULOS *)A) -> Articulo ), ( ((INFO_ARTICULOS *)B) -> Articulo ) );
  case 1:
   return strcmpi( ( ((INFO_ARTICULOS *)A) -> Ubicacion ), ( ((INFO_ARTICULOS *)B) -> Ubicacion ) );
 }

 return -1;
}


void OrdenaPrecios(void)
{
/*
BDatos BPrecios;            // Base de datos de Precioserencias
INFO_ARTICULOS SPrecios;     // Estructura de referencias

int OrdenPrecios;
*/
struct Boton_Texto BT[4];
int devolver;

BT[0].x = 32; BT[0].y =  9; strcpy( BT[0].Texto, " &Ubicacion         "); BT[0].ID_T1 =  0; BT[0].ID_T2 = 0;
BT[1].x = 32; BT[1].y = 11; strcpy( BT[1].Texto, " &Nombre de Articulo"); BT[1].ID_T1 =  0; BT[1].ID_T2 = 0;
BT[2].x = 32; BT[2].y = 13; strcpy( BT[2].Texto, " &Precio de Articulo"); BT[2].ID_T1 =  0; BT[2].ID_T2 = 0;
BT[3].x = 32; BT[3].y = 15; strcpy( BT[3].Texto, " &Cancelar operacion"); BT[3].ID_T1 =  0; BT[3].ID_T2 = 0;

 Optar( ENCUADRE, "Elija orden a seguir", NULL );

 while( ( devolver = Funcion_Botones(STD_BY, 4, BT) ) < 1 || devolver > 4 ) while ( kbhit() ) getch();

 if ( devolver != 4 )
 {
  OrdenPrecios = devolver;
  BPrecios.SortReg( ComparaRegistrosPrecio );
 }

 Optar( ENCUADRE, NULL );

}



 /**************************************************************************\
|*                                                                          *|
|*  BuscaPrecios                                                                *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Busca una referencia por su n� o descripcion                *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           ATRAS             Busca otra coincidencia hacia atras          *|
|*           NUEVA_BUSQUEDA    Inicia una nueva busqueda                    *|
|*           ADELANTE          Busca otra coincidencia hacia delante        *|
|*                                                                          *|
|*  Salidas:  (ninguna)                                                     *|
|*                                                                          *|
 \**************************************************************************/
void BuscaPrecios( char TipoBusqueda, char *CurrRow, int *CurrPrecios )
{
 static INFO_ARTICULOS MPrecios;
 char enc; long i;


 switch ( TipoBusqueda )
 {
    case NUEVA_BUSQUEDA:
         if ( ObtenMatchPrecios( &MPrecios ) != OK )
                                           return;
         i = 0;
         break;
    case ATRAS:
    case ADELANTE:
         i = ( *CurrRow + *CurrPrecios )+TipoBusqueda;
         if ( i < 0 || i >= BPrecios.Registros() ) return;
         break;
 }

 Optar( ENCUADRE, "Comando: Buscar", "Ahora se inica", "la busqueda elegida", NULL );
 enc = 0;
 while ( i < BPrecios.Registros() && !enc )
 {
  if ( BPrecios.LeeReg( (void *)&SPrecios, i ) == ERROR )
                                                   Error( 0x00 );
  if ( Match_Precios( SPrecios, MPrecios ) )
                                enc = 1;
  else
                                i++;
 }

 Optar( ENCUADRE, NULL );

 if ( enc )
 {
  *CurrRow = 0; *CurrPrecios = i;
  // Mostramos datos hasta que se nos acabe la pantalla
  MuestraDatosPrecios( *CurrRow + *CurrPrecios );
  if ( BPrecios.LeeReg( (void *)&SPrecios, 0      ) == ERROR )
                                                             Error(0x00);
 } else
   switch( TipoBusqueda )
   {
    case NUEVA_BUSQUEDA:
         Optar( 0, "Comando: Buscar", "No se encontr�", "ninguna coincidencia", NULL );
         break;
    case ATRAS:
    case ADELANTE:
         Optar( 0, "Comando: Buscar", "No se encontr�", "ninguna coincidencia", NULL );
         break;
   }

 if ( BPrecios.LeeReg( (void *)&SPrecios, (*CurrRow + *CurrPrecios) ) == ERROR )
                                                                 Error( 0x00 );


}

 /**************************************************************************\
|*                                                                          *|
|*  Match_Precios                                                               *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Compara dos registros y devuelve la posible coincidencia    *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Registros a comparar                                           *|
|*                                                                          *|
|*  Salidas:                                                                *|
|*           Resultado de la comparaci�n                                    *|
|*                                                                          *|
 \**************************************************************************/
int Match_Precios( INFO_ARTICULOS A, INFO_ARTICULOS B )
{
  if ( B.Precio != 0 )
                 return (A.Precio == B.Precio );
  if ( B.Articulo[0] != '\0' )
                 return ( strncmpi( A.Articulo, B.Articulo, strlen( B.Articulo ) ) == 0 );
  if ( B.Ubicacion[0] != '\0' )
                 return ( strncmpi( A.Ubicacion, B.Ubicacion, strlen( B.Ubicacion ) ) == 0 );
  return 0;
}

 /**************************************************************************\
|*                                                                          *|
|*  ObtenMatchPrecios                                                           *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Obtine los patrones de busqueda necesarios                  *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Estructura donde guardar el patron de busqueda                 *|
|*                                                                          *|
|*  Salidas:                                                                *|
|*           OK     La entrada es correcta                                  *|
|*           ERROR  El usuario interrumpio la busqueda                      *|
|*                                                                          *|
 \**************************************************************************/
int ObtenMatchPrecios( INFO_ARTICULOS *MPrecios )
{
struct Boton_Texto BT[6];

BT[0].x = 22; BT[0].y = 15; strcpy( BT[0].Texto, " &Aceptar "); BT[0].ID_T1 = 00; BT[0].ID_T2 = 0;
BT[1].x = 51; BT[1].y = 15; strcpy( BT[1].Texto, " &Cancelar"); BT[1].ID_T1 = 00; BT[1].ID_T2 = 0;

 char Row, ok, i;
 int BPush, key, DEV;

 Optar( ENCUADRE, "Comando: Buscar", "Articulo:                          ", "Precio:                            ", "Ubicaci�n:                         ", NULL );

 ok = 0; Row = 0;

 PreciosNuevoRegistro( MPrecios );

 do
 {
  MatchDrawPrecios(Row, *MPrecios, INTENSO);
  BPush = Funcion_Botones(STD_BY, 2, BT);
  MatchDrawPrecios(Row, *MPrecios, NORMAL);

  switch ( BPush )
  {
       case  0:				  // No se pulso ningun BOTON
	       while( kbhit() ) getch();  // Limpiamos posibles teclas en BUFFER
       case -2:
               if ( ( key = getch() ) != 13 && key != 27 )
                                      ungetch( key );
               EditMatchPrecios( Row, MPrecios );
               for ( i=0; i < 6; i++ )
                     MatchDrawPrecios(i, *MPrecios, NORMAL);
	       break;
       case -1:
	       switch ( getch() )
               {
                // Flecha Izquierda
                case  75:
                case  15:
                // Flecha Arriba
                case  72:
                       Row--; if ( Row < 0 ) Row = 2;
                       break;
                // Flecha Derecha
                case  77:
                case   9:
                // Flecha Abajo
                case  80:
                       Row++; if ( Row > 2 ) Row = 0;
                       break;
               }
	       break;
       case  1:
               DEV = OK; ok = 1;
               break;
       case  2:
               DEV = ERROR; ok = 1;
               break;
  }

 } while ( !ok );

 Optar( ENCUADRE, NULL );

 return DEV;

}

 /**************************************************************************\
|*                                                                          *|
|*  EditMatchPrecios                                                            *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Edita el patron de busqueda                                 *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Campo a editar, y lugar donde almacenarlo                      *|
|*                                                                          *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void EditMatchPrecios( char Row, INFO_ARTICULOS * MPrecios )
{
 int X0, Y0, X1, Y1;
 char buffer[80];

 ObtenCoordenadasMatchPr( Row, &X0, &Y0, &X1, &Y1 );

 switch( Row )
 {
  case 1:
         sprintf( buffer, "%lu", MPrecios -> Precio );
         if ( !( InputCadenaG( buffer, 1,  9, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
         {
          PreciosNuevoRegistro( MPrecios );
          MPrecios -> Precio = atol(buffer);
         }
         break;
  case 0:
         strcpy( buffer, MPrecios -> Articulo );
         if ( !( InputCadenaG( buffer, 0, 20, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
         {
          PreciosNuevoRegistro( MPrecios );
          strcpy ( MPrecios -> Articulo, buffer );
         }
         break;
  case 2:
         strcpy( buffer, MPrecios -> Ubicacion );
         if ( !( InputCadenaG( buffer, 0, 15, Config.TxtBgN, Config.TxtFgN, X0, Y0, X1, Y1) >> 8 ) )
         {
          PreciosNuevoRegistro( MPrecios );
          strcpy ( MPrecios -> Ubicacion, buffer );
         }
         break;
 }



}

 /**************************************************************************\
|*                                                                          *|
|*  MatchDrawPrecios                                                            *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Escribe los distintos campos seg�n se le indique            *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Campo a mostrar, lugar donde se encuentra, y como mostrarlo    *|
|*                                                                          *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void MatchDrawPrecios( char Row, INFO_ARTICULOS MPrecios,  char como )
{
 int X0, Y0, X1, Y1;
 char buffer[80], buffer1[80];

 ObtenCoordenadasMatchPr( Row, &X0, &Y0, &X1, &Y1 );

 switch( Row )
 {
  case 1:
         sprintf( buffer, " %9ld", MPrecios.Precio );
         break;
  case 0:
         sprintf( buffer, "%15s", MPrecios.Articulo );
         break;
  case 2:
         sprintf( buffer, "%20s", MPrecios.Ubicacion );
         break;
 }

 textbackground( ( como == NORMAL ) ? Config.TxtBgN : Config.TxtBgI );
 textcolor ( ( como == NORMAL ) ? Config.TxtFgN : Config.TxtFgI );

 gotoxy( X0, Y0 );
 cprintf( "%s", buffer );

}

 /**************************************************************************\
|*                                                                          *|
|*  MatchDrawPrecios                                                            *|
|*                                                                          *|
|*  Descripci�n:                                                            *|
|*              Obtiene las coordenadas relativas al campo dado.            *|
|*                                                                          *|
|*  Entradas:                                                               *|
|*           Campo a obtener las coordenadas, y coordenadas de salida       *|
|*                                                                          *|
|*  Salidas: (ninguna)                                                      *|
|*                                                                          *|
 \**************************************************************************/
void ObtenCoordenadasMatchPr( char Row, int *X0, int *Y0, int *X1, int *Y1 )
{

 switch( Row )
 {
  case 0:
         *X0 =  35;  *X1 =  10;
         *Y0 =   9;  *Y1 =   9;
         break;
  case 1:
         *X0 =  35;  *X1 =  15;
         *Y0 =  10;  *Y1 =  10;
         break;
  case 2:
         *X0 =  35;  *X1 =  20;
         *Y0 =  11;  *Y1 =  11;
         break;
 }

}