//---------------------------------------------------------------------------
#include <io.h>
#include <vcl.h>
#pragma hdrstop

#include <winuser.h>

#include "DViewer.h"
#include "DViewer_Print.h"
#include "DViewer_PrintHistoric.h"
#include "DViewer_PrintBonos.h"
#include "DViewer_PrintClientes.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "ElastFrm"
#pragma link "ElastFrm"
#pragma resource "*.dfm"
TDViewerF *DViewerF;
//---------------------------------------------------------------------------
#define TIPO_CONEXION  1
#define CAMBIO_PERIODO 2

__fastcall TDViewerF::TDViewerF(TComponent* Owner)
    : TForm(Owner)
{
 MargenRuptura->ItemIndex = 1;
 SelIndex->ItemIndex = 1;
 MinFecha->Date = TDateTime::CurrentDate();
 MaxFecha->Date = TDateTime::CurrentDate();
 TerminalFiltered = false;
 RefiltraDatos();
 StatusBar1->Panels->Items[0]->Text = "Visualizador listo...";
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::TbHistoricoBeforeOpen(TDataSet *DataSet)
{
   // Si la tabla no existe, la creamos
 if ( access( (TbHistorico -> TableName).c_str(), 0 ) != 0 )
 {
   ShowMessage( "Esta aplicación es un complemento de visualización a CtrlMstr\nY no puede se ejecutada por separado\n(Primero a de activar el control maestro)" );
   Abort();
   Close();
 }
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::TbHistoricoCalcFields(TDataSet *DataSet)
{
  switch ( TbHistorico->FieldByName("idtc")->AsInteger )
  {
    // Internet
    case 0:        TbHistorico->FieldByName("TipoConexion")->AsString="Internet";        break;
    // Juegos
    case 1:        TbHistorico->FieldByName("TipoConexion")->AsString="Juegos";        break;
    // Otros
    case 2:        TbHistorico->FieldByName("TipoConexion")->AsString="Otros...";        break;
    // Envio de Listas
    case 3:        TbHistorico->FieldByName("TipoConexion")->AsString="Clases";        break;
    // Envio de Listas
    case 997:      TbHistorico->FieldByName("TipoConexion")->AsString="ENVIO LISTAS";        break;
    // Tiempo Anulado
    case 998:      TbHistorico->FieldByName("TipoConexion")->AsString="TIEMPO ANULADO";        break;
    // Cierre de Windows
    case 999:      TbHistorico->FieldByName("TipoConexion")->AsString="Cerrar Windows";        break;
    default:       TbHistorico->FieldByName("TipoConexion")->AsString="DESCONOCIDA";        break;
  }

}
//---------------------------------------------------------------------------
int __fastcall TDViewerF::Obten_idtc(void)
{
 int dev;
 switch( (idtConexion->ItemIndex-1) )
 {
  case 0:
   dev = 0;
   break;
  case 1:
   dev = 1;
   break;
  case 2:
   dev = 3;
   break;
  case 3:
   dev = 2;
   break;
  case 4:
   dev = 997;
   break;
  case 5:
   dev = 998;
   break;
  case 6:
   dev = 999;
   break;
  default:
   dev = 0;
   break;
 }
 return dev;
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::RefiltraDatos(void)
{
  StatusBar1->Panels->Items[0]->Text = "Evaluando filtro...";

  TDateTime FechaMin, FechaMax;
  TbHistorico->FilterOptions = TbHistorico->FilterOptions << foCaseInsensitive;

  MaxFecha->Time = 36544.9999891088;//EncodeTime( 23, 59, 59, 59 );
  FechaMax = MaxFecha->Date;
  MinFecha->Time = 0;
  FechaMin = MinFecha->Date;

  TbHistorico->Filter = "[FComienzo] >= '" + FechaMin + "' AND [FComienzo] <= '" + FechaMax +"'";
  TbHistorico->Filtered = true;

  // Refiltramos los bonos
  TbBonos->FilterOptions = TbBonos->FilterOptions << foCaseInsensitive;
  TbBonos->Filter = "[FechaCompra] >= '" + FechaMin + "' AND [FechaCompra] <= '" + FechaMax +"'";
  TbBonos->Filtered = true;

  StatusBar1->Panels->Items[0]->Text = "Rellenando gráficas...";
  CalculaGraficas();
  StatusBar1->Panels->Items[0]->Text = "";
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::CalculaGraficas(void)
{
  unsigned short hh, mm, ss, mss;
  Currency TotalF, TotalR;
  int NConF, NConR, NumBonos;

  TDateTime HoraFinAnterior;            // Hora a la que debío acabar el elto. anterior
  int EltoAnterior;                     // Elemento anterior
  TDateTime Ruptura;                    // Tiempo Maximo para admitir que la conexion actual
                                        //   es continuacion de la anterior (¿Reinicia la máquina?)

  TbHistorico->DisableControls();       // Deshabilitamos los controles asociados

  NumBonos = 0;
  NConF  = 0; NConR  = 0;
  TotalF = 0; TotalR = 0;
  ProgressBar1->Min = 0;
  ProgressBar1->Max = TbElementos->RecordCount;
  HoraFinAnterior = 0;
  EltoAnterior = 0;
  if  ( MargenRuptura->ItemIndex == -1 )
        Ruptura = EncodeTime( 0, 0, 0, 0 );
  else
        Ruptura = EncodeTime( 0, (MargenRuptura->ItemIndex + 1)*5, 0, 0 );

  // Vaciamos las conexiones / hora
  for ( int i = 0; i<48; i++ )
  {
   ConexionesHoraR[ i ] = 0;
   ConexionesHoraF[ i ] = 0;
  }
  // Vaciamos los tipos de conexiones
  for ( int i=0; i < 8; i++ )
   NConexionesTipo[i] = 0;
  // Vaciamos la parrilla de datos
  for ( int i=0; i < Equipos->Items->Count; i++ )
  {
   Parrilla[i].ConF   = 0;
   Parrilla[i].TotalF = 0;
   Parrilla[i].ConR   = 0;
   Parrilla[i].TotalR = 0;
   Parrilla[i].horasF = 0;
   Parrilla[i].horasR = 0;
   Parrilla[i].minF = 0;
   Parrilla[i].minR = 0;
  }

  TbHistorico->First();
  while ( ! TbHistorico->Eof )
  {
    // Si se trata de una conexion
    if ( TbHistorico->FieldByName("idtc")->AsInteger < 50 )
    {
            NConF  ++;
            TotalF += TbHistorico->FieldByName("Precio")->AsCurrency;
            TbHistorico->FieldByName("FComienzo")->AsDateTime. DecodeTime( &hh, &mm, &ss, &mss );
            ConexionesHoraF[hh*2+ ((mm<30)?0:1)] ++;

            // Si el elemento que estamos estudiando:
            // -- Termina su tiempo "justo" ó ANTES que cuando debía hacerlo su ultima conexion
            if (  TbHistorico->FieldByName( "NumElement" )->AsInteger == EltoAnterior &&
                 (TbHistorico->FieldByName("FComienzo")->AsDateTime +
                  TbHistorico->FieldByName("Tiempo")->AsDateTime        ) <= HoraFinAnterior
               )
            {
              // Estamos ante una conexión REAL
              InsertaEnParrilla( TbHistorico->FieldByName("NumElement")->AsInteger,
                                 TbHistorico->FieldByName("Precio" ) ->AsCurrency,
                                 TbHistorico->FieldByName("Tiempo" ) ->AsDateTime,
                                 false
                             );
            } else {
              NConR++;
              TotalR += TbHistorico->FieldByName("Precio")->AsCurrency;
              ConexionesHoraR[hh*2+ ((mm<30)?0:1)] ++;

              InsertaEnParrilla( TbHistorico->FieldByName("NumElement")->AsInteger,
                                 TbHistorico->FieldByName("Precio" ) ->AsCurrency,
                                 TbHistorico->FieldByName("Tiempo" ) ->AsDateTime,
                                 true
                             );

               switch ( TbHistorico->FieldByName("idtc")->AsInteger )
               {
                    case 0:        NConexionesTipo[0]++;        break;    // Internet
                    case 1:        NConexionesTipo[1]++;        break;    // Juegos
                    case 2:        NConexionesTipo[2]++;        break;    // Otros
                    case 3:        NConexionesTipo[3]++;        break;    // Clases
                    default:       NConexionesTipo[7]++;        break;    // -- DECONOCIDO --
               }
            }
               EltoAnterior    = TbHistorico->FieldByName("NumElement")->AsInteger;
               HoraFinAnterior = TbHistorico->FieldByName("FComienzo")->AsDateTime +
                                 TbHistorico->FieldByName("Tiempo")->AsDateTime       +
                                 Ruptura;
    } else {
               switch ( TbHistorico->FieldByName("idtc")->AsInteger )
               {
                    case 997:      NConexionesTipo[4]++;        break;    // Envio de Listas
                    case 998:      NConexionesTipo[5]++;        break;    // Tiempo Anulado
                    case 999:      NConexionesTipo[6]++;        break;    // Cierre de Windows
                    default:       NConexionesTipo[7]++;        break;    // -- DECONOCIDO --
               }

    }

    // Cuando se usa bonos
    if ( TbHistorico->FieldByName("idc")->AsInteger > 0 &&
          TbHistorico->FieldByName("precio")->AsCurrency == 0
       )
    {
      NumBonos++;
    }

    ProgressBar1->Position++;
    try { TbHistorico->Next(); } catch( ... ) { break; }
  }

  TbHistorico->EnableControls();        // Habilitamos de nuevo los controles


  ConexionesHora -> Series[0] -> Clear();
  ConexionesHora -> Series[1] -> Clear();
     for ( int i = 0; i < 24; i++ )
     {
      ConexionesHora -> Series[0] -> AddXY(i*2,   ConexionesHoraF[i*2], i, clTeeColor);
      ConexionesHora -> Series[0] -> AddXY(i*2+1, ConexionesHoraF[i*2+1], "½", clTeeColor);

      ConexionesHora -> Series[1] -> AddXY(i*2,   ConexionesHoraR[i*2], i, clTeeColor);
      ConexionesHora -> Series[1] -> AddXY(i*2+1, ConexionesHoraR[i*2+1], "½", clTeeColor);
     }


//  StatusBar1->Panels->Items[1]->Text = TotalF;
  ConexionesEquipos -> Series[0] -> Clear();
  ConexionesEquipos -> Series[1] -> Clear();
  for ( int i=0; i < Equipos->Items->Count; i++ )
  {
   StringGrid1->Cells[2][1+i] = Parrilla[i].ConF   ;
   StringGrid1->Cells[4][1+i] = Parrilla[i].TotalF ;
   StringGrid1->Cells[3][1+i] = Parrilla[i].ConR   ;
   StringGrid1->Cells[5][1+i] = Parrilla[i].TotalR ;
   StringGrid1->Cells[6][1+i] = AnsiString( Parrilla[i].horasF )+ " : " + AnsiString( Parrilla[i].minF );
   StringGrid1->Cells[7][1+i] = AnsiString( Parrilla[i].horasR )+ " : " + AnsiString( Parrilla[i].minR );
   ConexionesEquipos -> Series[0] -> Add( Parrilla[i].TotalF, Equipos->Items->Strings[i], clGreen );
   ConexionesEquipos -> Series[1] -> Add( Parrilla[i].TotalR, "", clRed );
  }

  // Etiquetas globales
  Label4->Caption = NConR;
  Label6->Caption = NConF;
  Label8->Caption = TotalR;
  Label9->Caption = TotalF;
  NBonos->Caption = NumBonos;


  // Rellenamos la gráfica TIPO de Conexion
  TipoConexion->Series[0]->Clear();
  TipoConexion->Series[0]->Add( NConexionesTipo[0], "Internet", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[1], "Juegos", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[2], "Otros", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[3], "Clases", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[4], "Env.Listas", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[5], "Anulaciones", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[6], "Cierres", clTeeColor );
  TipoConexion->Series[0]->Add( NConexionesTipo[7], "## NID ##", clTeeColor );

  TbBonos->DisableControls();       // Deshabilitamos los controles asociados
    NBonosVendidos = 0;
    TotalBonos = 0;
  TbBonos->First();
  while ( ! TbBonos->Eof )
  {
    NBonosVendidos++;
    TotalBonos += TbBonos->FieldByName("coste")->AsCurrency;
    TbBonos->Next();
  }
  TbBonos->EnableControls();       // Deshabilitamos los controles asociados
  BonosVendidos->Caption = AnsiString( NBonosVendidos ) + " ( " + TotalBonos + " )";
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::InsertaEnParrilla( int Elto, Currency CantidadF, TDateTime Tiempo, bool Repetido )
{
 unsigned short Hour, Min, Sec, MSec;
 Tiempo.DecodeTime( &Hour, &Min, &Sec, &MSec );

 // Localizamos la casilla del elemento
 for ( int i=0; i < Equipos->Items->Count; i++ )
  if ( Parrilla[i].Elto == Elto )
  {
   Parrilla[i].ConF   ++;
   Parrilla[i].TotalF = Parrilla[i].TotalF +  CantidadF;

   Parrilla[i].horasF += Hour + ( ( Parrilla[i].minF + Min ) / 60 );
   Parrilla[i].minF    = ( Parrilla[i].minF + Min ) % 60;

   if ( Repetido )
   {
        Parrilla[i].ConR   ++;
        Parrilla[i].TotalR = Parrilla[i].TotalR + CantidadF;

        Parrilla[i].horasR += Hour + ( ( Parrilla[i].minR + Min ) / 60 );
        Parrilla[i].minR    = ( Parrilla[i].minR + Min ) % 60;
   }
   break;
  }
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::MinFechaChange(TObject *Sender)
{
 RefiltraDatos();
}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::DBGrid1DrawColumnCell(TObject *Sender,
      const TRect &Rect, int DataCol, TColumn *Column,
      TGridDrawState State)
{
 if ( TbHistorico->FieldByName("idtc")->AsInteger > 900 )
 {
  if ( TbHistorico->FieldByName("idtc")->AsInteger == 998 )
    DBGrid1->Canvas -> Font -> Color = clGreen;
  else
    DBGrid1->Canvas -> Font -> Color = clRed;
  DBGrid1->DefaultDrawColumnCell( Rect, DataCol, Column, State );
 }
 if ( TbHistorico->FieldByName("idc")->AsInteger > 0 &&
      TbHistorico->FieldByName("precio")->AsCurrency == 0
    )
 {
    DBGrid1->Canvas -> Font -> Color = clPurple;
    DBGrid1->DefaultDrawColumnCell( Rect, DataCol, Column, State );
 }

}
//---------------------------------------------------------------------------
void __fastcall TDViewerF::TbElementosAfterOpen(TDataSet *DataSet)
{
  ProgressBar1->Min = 0;
  ProgressBar1->Max = TbElementos->RecordCount;
  StringGrid1->RowCount = TbElementos->RecordCount + 1;

  Parrilla = new DatosEltos[(TbElementos->RecordCount)];
  TbElementos->First();
  for (int i = ProgressBar1->Min; i < ProgressBar1->Max; i++)
  {
    ProgressBar1->Position = i;
    Equipos->Items->Add(TbElementos->FieldByName("Name")->AsString);

    Parrilla[i].Elto           = TbElementos->FieldByName("NumElement")->AsInteger;
    StringGrid1->Cells[0][i+1] = TbElementos->FieldByName("NumElement")->AsInteger;
    StringGrid1->Cells[1][i+1] = TbElementos->FieldByName("Name")->AsString;

    TbElementos->Next();
    // do something with record...
  }

  StringGrid1->Cells[2][0] = "ConexF";
  StringGrid1->Cells[3][0] = "ConexR";
  StringGrid1->Cells[4][0] = "TotalF";
  StringGrid1->Cells[5][0] = "TotalR";
  StringGrid1->Cells[6][0] = "TiempoF";
  StringGrid1->Cells[7][0] = "TiempoR";
}
//---------------------------------------------------------------------------


void __fastcall TDViewerF::FormDestroy(TObject *Sender)
{
 delete[] Parrilla;
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::idtConexionChange(TObject *Sender)
{
  TDateTime FechaMin, FechaMax;
  TbHistorico->FilterOptions = TbHistorico->FilterOptions << foCaseInsensitive;

  MaxFecha->Time = 36544.9999891088;//EncodeTime( 23, 59, 59, 59 );
  FechaMax = MaxFecha->Date;
  MinFecha->Time = 0;
  FechaMin = MinFecha->Date;

 if ( idtConexion->ItemIndex > 0 )
 {
  AnsiString CadenaFiltro = "([FComienzo] >= '" + FechaMin + "' AND [FComienzo] <= '" + FechaMax +"' AND [idtc] = '" + AnsiString( Obten_idtc() ) + "' )";
  TbHistorico->Filter = CadenaFiltro;
  TbHistorico->Filtered = true;
 } else {
  TbHistorico->Filter = "[FComienzo] >= '" + FechaMin + "' AND [FComienzo] <= '" + FechaMax +"'";
  TbHistorico->Filtered = true;
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::Button1Click(TObject *Sender)
{
  TQuickReport1 *QR;

  StatusBar1->Panels->Items[0]->Text = "Preparando documento para imprimir...";
  QR = new TQuickReport1(this);
  QR->Preview();
  StatusBar1->Panels->Items[0]->Text = "";
  delete QR;
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::Button2Click(TObject *Sender)
{
  TQRHistoric *QR;

  QR = new TQRHistoric(this);
  StatusBar1->Panels->Items[0]->Text = "Preparando documento para imprimir...";
  QR->QuickRep1->Print();
  StatusBar1->Panels->Items[0]->Text = "";
  delete QR;

}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::Edit1KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( !Edit1->Text.IsEmpty() )
  TbPersonas->Locate( SelIndex->Items->Strings[SelIndex->ItemIndex], Edit1->Text, TLocateOptions() << loCaseInsensitive << loPartialKey );
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit1KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit2->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit2KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit3->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit3KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit4->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit4KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit5->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit5KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit6->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::DBEdit6KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
 if ( Key == VK_RETURN )
 {
  if(TbPersonas->State == dsInsert || TbPersonas->State == dsEdit)
        TbPersonas->Post();
  DBEdit1->SetFocus();
 }
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::TbPersonasBeforeDelete(TDataSet *DataSet)
{
  switch( MessageDlg( "Atención, está apunto de eliminar\na un cliente...\n¡¡¡ Su historico TAMBIEN será ELIMINADO\n¿Realmente desea continuar?", mtWarning, TMsgDlgButtons() << mbNo << mbYes, 0 ) )
  {
   case mrNo:
        Abort();
        break;
   default:
        // Borramos todos los registros asociados...
	     while( TbBonosCliente -> RecordCount != 0 )
		     TbBonosCliente -> Delete();
	break;
  }

}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::TbPersonasNewRecord(TDataSet *DataSet)
{
 TbPersonas->FieldByName("FAlta")->AsDateTime = TDateTime::CurrentDateTime();
 TbPersonas->FieldByName("FModif")->AsDateTime = TDateTime::CurrentDateTime();
 TbPersonas->FieldByName("TiempoH")->AsInteger = 0;
 TbPersonas->FieldByName("TiempoM")->AsInteger = 0;
}
//---------------------------------------------------------------------------

void __fastcall TDViewerF::Button4Click(TObject *Sender)
{
  TQRBonos *QR;

  QR = new TQRBonos(this);
  StatusBar1->Panels->Items[0]->Text = "Preparando documento para imprimir...";
  QR->QuickRep1->Print();
  StatusBar1->Panels->Items[0]->Text = "";
  delete QR;

}
//---------------------------------------------------------------------------


void __fastcall TDViewerF::Button3Click(TObject *Sender)
{
  TQRClt *QR;

  QR = new TQRClt(this);
  StatusBar1->Panels->Items[0]->Text = "Preparando documento para imprimir...";
  QR->QuickRep1->Print();
  StatusBar1->Panels->Items[0]->Text = "";
  delete QR;

}
//---------------------------------------------------------------------------


void __fastcall TDViewerF::EquiposClick(TObject *Sender)
{

 if ( TbElementos->Locate( "Name", Equipos->Items->Strings[Equipos->ItemIndex], TLocateOptions() << loCaseInsensitive << loPartialKey ) )
  // Localizamos el primer registro del terminal seleccionado...
  TbHistorico->Locate( "NumElement", TbElementos->FieldByName("NumElement")->AsInteger, TLocateOptions() << loCaseInsensitive << loPartialKey );

}
//---------------------------------------------------------------------------

