/**********************************************************************/
/*                                                                    */
/* File name: Advanced.cpp                                            */
/*                                                                    */
/* Since:     2002/12/03                                              */
/*                                                                    */
/* Version:   1.02                                                    */
/*                                                                    */
/* Author:    MONTAGNE Xavier [XM] {link xavier.montagne@wanadoo.fr}  */
/*                                                                    */
/* Purpose: Manage the Advanced Window to program easily the          */
/*          the configuration of the LPT port.                        */
/*                                                                    */
/* Distribution: This file is part of PP18.                           */
/*               PP18 is free software; you can redistribute it       */
/*               and/or modify it under the terms of the GNU General  */
/*               Public License as published by the Free Software     */
/*               Foundation; either version 2, or (at your option)    */
/*               any later version.                                   */
/*                                                                    */
/*               PP18 is distributed in the hope that it will be      */
/*               useful, but WITHOUT ANY WARRANTY; without even the   */
/*               implied warranty of MERCHANTABILITY or FITNESS FOR A */
/*               PARTICULAR PURPOSE.  See the GNU General Public      */
/*               License for more details.                            */
/*                                                                    */
/*               You should have received a copy of the GNU General   */
/*               Public License along with PP18; see the file         */
/*               COPYING.txt. If not, write to the Free Software      */
/*               Foundation, 59 Temple Place - Suite 330,             */
/*               Boston, MA 02111-1307, USA.                          */
/*                                                                    */
/* History:                                                           */
/*      2002/12/03  [XM] Create this file                             */
/*      2003/06/26  [XM] Added Delay_Porg management & auto-setup.    */
/*                                                                    */
/**********************************************************************/

/***********************************************************************
 * INCLUDES
 **********************************************************************/
#include <vcl.h>
#include <vcl\Registry.hpp>

#include "Advanced.h"
#include "Settings.h"
#include "DLL_interface.h"
#pragma hdrstop

/***********************************************************************
 * Global variables.
 **********************************************************************/
unsigned char HexToIndex(unsigned char mask);
unsigned char IndexToHex(int Index);
static unsigned int delay_IO_tmp;
static unsigned int delay_Prog_tmp;

extern unsigned int delay_IO;
extern unsigned int delay_Prog;
extern TRegistry *regKey;
extern unsigned short LPT_adr_out;
extern unsigned short LPT_adr_in;

#pragma package(smart_init)
#pragma resource "*.dfm"
TAdvancedWindow *AdvancedWindow;
extern TSettingsWindow *SettingsWindow;

/***********************************************************************
 * Window constructor.
 *
 * @param  TComponent* Owner  IN  Parent object reference
 * @return none
 **********************************************************************/
__fastcall TAdvancedWindow::TAdvancedWindow(TComponent* Owner)
    : TForm(Owner)
{
}

/***********************************************************************
 * Quit the window and save the settings into register base (sould be).
 * Also modify the DLL structures to take into account the new
 * parameters.
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::ButtonOKClick(TObject *Sender)
{
  unsigned char mask;
  unsigned char status;
  char string[10], i;

  strcpy(string, AdrOutBox->Text.c_str());
  if ((string[0] != '0') || (string[1] != 'x'))
  {
    Application->MessageBox("Wrong LPT base address !", "LPT parameter", MB_ICONERROR + MB_OK);
    return;
  }
  for (i = 2; i < 6; i++)
    if ( (string[i] < '0') ||
        ((string[i] > '9') && (string[i] < 'A') ) ||
        ((string[i] > 'F') && (string[i] < 'a') ) ||
         (string[i] > 'f') )
    {
      Application->MessageBox("Wrong LPT base address !", "LPT parameter", MB_ICONERROR + MB_OK);
      return;
    }

  if ((IndexToHex(ComboBox_CLOCK->ItemIndex) == IndexToHex(ComboBox_DataToPIC->ItemIndex)) ||
        (IndexToHex(ComboBox_CLOCK->ItemIndex) == IndexToHex(ComboBox_VPP->ItemIndex)) ||
        (IndexToHex(ComboBox_CLOCK->ItemIndex) == IndexToHex(ComboBox_VCC->ItemIndex)) ||
        (IndexToHex(ComboBox_DataToPIC->ItemIndex) == IndexToHex(ComboBox_VPP->ItemIndex)) ||
        (IndexToHex(ComboBox_DataToPIC->ItemIndex) == IndexToHex(ComboBox_VCC->ItemIndex)) ||
        (IndexToHex(ComboBox_VPP->ItemIndex) == IndexToHex(ComboBox_VCC->ItemIndex)) )
  {
    Application->MessageBox("Warning ! You assign LPT bits to multiple signals.", "LPT parameter error", MB_ICONERROR | MB_OK);
    return;
  }

  regKey->OpenKey("\\Software\\PP18\\DLL\\Settings", false);
  
  ReadSettings(PL_CLOCK, &mask, &status);
  mask = IndexToHex(ComboBox_CLOCK->ItemIndex);
  Settings(PL_CLOCK, mask, status);
  regKey->WriteInteger("CLOCK_MASK", mask);

  ReadSettings(PL_DATA_TO_PIC, &mask, &status);
  mask = IndexToHex(ComboBox_DataToPIC->ItemIndex);
  Settings(PL_DATA_TO_PIC, mask, status);
  regKey->WriteInteger("DATA_TO_PIC_MASK", mask);

  ReadSettings(PL_VPP, &mask, &status);
  mask = IndexToHex(ComboBox_VPP->ItemIndex);
  Settings(PL_VPP, mask, status);
  regKey->WriteInteger("VPP_MASK", mask);

  ReadSettings(PL_VCC, &mask, &status);
  mask = IndexToHex(ComboBox_VCC->ItemIndex);
  Settings(PL_VCC, mask, status);
  regKey->WriteInteger("VCC_MASK", mask);

  ReadSettings(PL_DATA_FROM_PIC, &mask, &status);
  mask = IndexToHex(ComboBox_DataFromPIC->ItemIndex);
  Settings(PL_DATA_FROM_PIC, mask, status);
  regKey->WriteInteger("DATA_FROM_PIC_MASK", mask);

  delay_IO   = delay_IO_tmp;
  delay_Prog = delay_Prog_tmp;
  regKey->WriteInteger("DelayIO", delay_IO);
  regKey->WriteInteger("DelayProg", delay_Prog);

  LPT_adr_out = StrToInt(AdrOutBox->Text);
  LPT_adr_in  = LPT_adr_out + 1;
  regKey->WriteInteger("LPT_port_@", LPT_adr_out);

  SettingsWindow->Enabled = true;
  AdvancedWindow->Close();
}

/***********************************************************************
 * Quit the window and without saving.
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::ButtonCancelClick(TObject *Sender)
{
  SettingsWindow->Enabled = true;
  AdvancedWindow->Close();
}

/***********************************************************************
 * Display and initialize the window with the LPT port settings.
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::FormShow(TObject *Sender)
{
  unsigned char mask;
  unsigned char status;

  TrackBar_IO->Position   = delay_IO;
  TrackBar_Prog->Position = delay_Prog;
  delay_IO_tmp            = delay_IO;
  delay_Prog_tmp          = delay_Prog;

  ReadSettings(PL_CLOCK, &mask, &status);
  ComboBox_CLOCK->ItemIndex = HexToIndex(mask);

  ReadSettings(PL_DATA_TO_PIC, &mask, &status);
  ComboBox_DataToPIC->ItemIndex = HexToIndex(mask);

  ReadSettings(PL_VPP, &mask, &status);
  ComboBox_VPP->ItemIndex = HexToIndex(mask);

  ReadSettings(PL_VCC, &mask, &status);
  ComboBox_VCC->ItemIndex = HexToIndex(mask);

  ReadSettings(PL_DATA_FROM_PIC, &mask, &status);
  ComboBox_DataFromPIC->ItemIndex = HexToIndex(mask);

  AdrOutBox->Text = "0x" + IntToHex(LPT_adr_out, 4);
}

/***********************************************************************
 * Find the bit number set at 1 in a byte.
 *
 * @param  u_char mask        IN  Signal mask in LPT port
 * @return u_char                 Bit number of the signal
 **********************************************************************/
unsigned char HexToIndex(unsigned char mask)
{
  switch (mask)
  {
    case 0x01 : return(0);
    case 0x02 : return(1);
    case 0x04 : return(2);
    case 0x08 : return(3);
    case 0x10 : return(4);
    case 0x20 : return(5);
    case 0x40 : return(6);
    case 0x80 : return(7);
  }
  return (0);
}

/***********************************************************************
 * Convert a bit number into a byte value.
 *
 * @param  int Index          IN  Bit number
 * @return char                   Byte converted
 **********************************************************************/
unsigned char IndexToHex(int Index)
{
  switch (Index)
  {
    case 0 : return(0x01);
    case 1 : return(0x02);
    case 2 : return(0x04);
    case 3 : return(0x08);
    case 4 : return(0x10);
    case 5 : return(0x20);
    case 6 : return(0x40);
    case 7 : return(0x80);
  }
  return (0);
}

/***********************************************************************
 * Change the Delay_IO of the read / write functions in "driver.c".
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::TrackBar_IOChange(TObject *Sender)
{
  delay_IO_tmp = TrackBar_IO->Position;
}

/***********************************************************************
 * Change the Delay_Prog of the read / write functions in "driver.c".
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::TrackBar_ProgChange(TObject *Sender)
{
  delay_Prog_tmp = TrackBar_Prog->Position;
}

/***********************************************************************
 * Try to find the smallest value for Delay_IO and Delay_Prog.
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TAdvancedWindow::AutoButtonClick(TObject *Sender)
{
  char temp[10];

  delay_Prog = 0;
  InitHardware();
  PowerOn();

  while ( (ReadRevDev (&temp[0]) != PIC_DETECTED) )
  {
    delay_Prog++;
    TrackBar_Prog->Position = delay_Prog;
    if (delay_Prog == TrackBar_Prog->Max)
    {
      Application->MessageBox("No PIC detected.", "Auto setup report :",
                               MB_ICONERROR | MB_OK);
      delay_Prog = delay_Prog_tmp;
      PowerOff();
      InitHardware();
      return;
    }
  }

  Application->MessageBox("Device detected !", "Auto setup report :",
                           MB_ICONEXCLAMATION  | MB_OK);
  delay_Prog_tmp = delay_Prog;
  PowerOff();
  InitHardware();
  return;
}

/* End of file */



