//---------------------------------------------------------------------------

#include <vcl.h>
#include <inifiles.hpp>
#include <math.h>
#pragma hdrstop

#include "TwoDCalibrationGuide_Form.h"
#include "AdvMachineControl_Form.h"
#include "Environment.h"
#include "Keyboard_Form.h"
#include "Capture_Frame.h"
#include "MultiLanguage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)                                                   
#pragma link "Capture_Frame"
#pragma link "TntButtons"
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma link "TntComCtrls"
#pragma resource "*.dfm"
TTwoDCalibrationGuideForm *TwoDCalibrationGuideForm;
//---------------------------------------------------------------------------
__fastcall TTwoDCalibrationGuideForm::TTwoDCalibrationGuideForm(TComponent* Owner)
  : TTntForm(Owner)
{
  MachineControlParams.SuctionDisk1InverterSpeed = StrToInt(RB1InverterSpeedEdit1->Text);
  MachineControlParams.SuctionDisk2InverterSpeed = StrToInt(RB2InverterSpeedEdit1->Text);


  CAM_Width = SYSTEM_CAMERA_WIDTH;
  CAM_Height = SYSTEM_CAMERA_HEIGHT;
  for(int i = 0; i < SYSTEM_TOTAL_CAMERA_COUNT; ++i)
  {
    SubsamplingModeList[i] = RESOLUTION_NORMAL_QUALITY;
  }


  MousePos.x = CAM_Width / 2;
	MousePos.y = CAM_Height / 2;

  LEDOnMask[0] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
	LEDOnMask[1] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
	LEDOnMask[2] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
	LEDOnMask[3] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
  LEDOnMask[4] =  0;
  LEDOnMask[5] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
	LEDOnMask[6] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);
	LEDOnMask[7] =  (0x0001 << 0) | (0x0001 << 1) | (0x0001 << 2) | (0x0001 << 3) | (0x0001 << 4);

  LEDOnMask[8] =  (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
  LEDOnMask[9] =  (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
	LEDOnMask[10] = (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
	LEDOnMask[11] = (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
	LEDOnMask[12] = 0;
	LEDOnMask[13] = (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
	LEDOnMask[14] = (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);
	LEDOnMask[15] = (0x0001 << 6) | (0x0001 << 7) | (0x0001 << 8) | (0x0001 << 9) | (0x0001 << 10);

  GlobalCameraIndex = 0;
  ChangeCamera();


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::FormCreate(TObject *Sender)
{
 	LoadSystemInfor();
  //CameraSpeedButton1->OnClick;
  // 확인
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  if(FileExists(fileName))
  ReadCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex);

  int WhiteBalanceValue[3];

  WhiteBalanceValue[0] = WhiteBalanceInfo[GlobalCameraIndex].BColorInfo;
  WhiteBalanceValue[1] = WhiteBalanceInfo[GlobalCameraIndex].GColorInfo;
  WhiteBalanceValue[2] = WhiteBalanceInfo[GlobalCameraIndex].RColorInfo;

  SetWhiteBalanceValue(WhiteBalanceValue[0], 0);
  SetWhiteBalanceValue(WhiteBalanceValue[1], 1);
  SetWhiteBalanceValue(WhiteBalanceValue[2], 2);

  CameraNumberLabel->Caption = "Camera Number : #" + IntToStr(GlobalCameraIndex + 1);

  WhiteBalanceBValue->Position = WhiteBalanceInfo[GlobalCameraIndex].BColorInfo;
  WhiteBalanceGValue->Position = WhiteBalanceInfo[GlobalCameraIndex].GColorInfo;
  WhiteBalanceRValue->Position = WhiteBalanceInfo[GlobalCameraIndex].RColorInfo;

  WhiteBalanceBValueEdit->Text = IntToStr(WhiteBalanceBValue->Position);
  WhiteBalanceGValueEdit->Text = IntToStr(WhiteBalanceGValue->Position);
  WhiteBalanceRValueEdit->Text = IntToStr(WhiteBalanceRValue->Position);


  ActiveCameraSW = 0;
  stepSW = NoneStart;
  FirstDiskPanel->DoubleBuffered = true;
  SecondDiskPanel->DoubleBuffered = true;

  ImageInitBlue();

  RGBImageInit();

}
//----------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RGBImageInit(void)
{
  RedImage->Canvas->Brush->Color = clRed;
	RedImage->Canvas->Brush->Style = bsSolid;
	RedImage->Canvas->FillRect(Rect(0, 0, RedImage->Picture->Bitmap->Width, RedImage->Picture->Bitmap->Height));
  RedImage->Canvas->Font->Color = clWhite;
  RedImage->Canvas->TextOutW(RedImage->Width / 2,RedImage->Height / 3,"0");

  GreenImage->Canvas->Brush->Color = clGreen;
	GreenImage->Canvas->Brush->Style = bsSolid;
	GreenImage->Canvas->FillRect(Rect(0, 0, GreenImage->Picture->Bitmap->Width, GreenImage->Picture->Bitmap->Height));
  GreenImage->Canvas->Font->Color = clWhite;
  GreenImage->Canvas->TextOutW(GreenImage->Width / 2,GreenImage->Height / 3,"0");

  BlueImage->Canvas->Brush->Color = clBlue;
	BlueImage->Canvas->Brush->Style = bsSolid;
	BlueImage->Canvas->FillRect(Rect(0, 0, BlueImage->Picture->Bitmap->Width, BlueImage->Picture->Bitmap->Height));
  BlueImage->Canvas->Font->Color = clWhite;
  BlueImage->Canvas->TextOutW(BlueImage->Width / 2,BlueImage->Height / 3,"0");


}
//----------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::ImageInitBlue(void)
{
  FirstDiskSelectImage->Canvas->Brush->Color = clSilver;
	FirstDiskSelectImage->Canvas->Brush->Style = bsSolid;
	FirstDiskSelectImage->Canvas->FillRect(Rect(0, 0, FirstDiskSelectImage->Picture->Bitmap->Width, FirstDiskSelectImage->Picture->Bitmap->Height));

  SecondDiskSelectImage->Canvas->Brush->Color = clSilver;
	SecondDiskSelectImage->Canvas->Brush->Style = bsSolid;
	SecondDiskSelectImage->Canvas->FillRect(Rect(0, 0, SecondDiskSelectImage->Picture->Bitmap->Width, SecondDiskSelectImage->Picture->Bitmap->Height));

  for(int i = 1; i <= 16; i++)
  {
    if(i != 5 && i != 13)
    {
      TTntImage *InitImage;
      InitImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(i));

      InitImage->Canvas->Brush->Color = clSilver;
	    InitImage->Canvas->Brush->Style = bsSolid;
	    InitImage->Canvas->FillRect(Rect(0, 0, InitImage->Picture->Bitmap->Width, InitImage->Picture->Bitmap->Height));
    }
  }


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::LoadSystemInfor(void)
{
  TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\SystemInfor.ini");
  float frameTime;
  int ledOnTime;
  float shutterDelay;

  if (iniFile)
  {
    frameTime = iniFile->ReadFloat("Calibration", "Frame Time", 100);
    ledOnTime = 13;//iniFile->ReadInteger("Calibration", "LED On Time", 3);
    shutterDelay = iniFile->ReadFloat("Calibration", "Shutter Delay", 1);

   // FrameTimeEdit->Text = FloatToStr(frameTime);
   // LedOnTimeEdit->Text = FloatToStr(ledOnTime);
   // ShutterDelayEdit->Text = FloatToStr(shutterDelay);

    delete iniFile;
  }
  else
  {
    ShowMessageW(CAPTUREFORM_MSG_01);
  }


  if(!ProductData.ProductName.IsEmpty())
  {
     for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      ShutterSpeedList[globalCameraIndex] = ProductData.ShutterSpeed[globalCameraIndex];
      DigitalGainList[globalCameraIndex] = ProductData.DigitalGainV[globalCameraIndex];
     /*
      TTntEdit *shutterSpeedEdit = (TTntEdit *) FindComponent("ShutterSpeedEdit" + IntToStr(globalCameraIndex + 1));
      shutterSpeedEdit->Text = IntToStr(ShutterSpeedList[globalCameraIndex]);

      if(globalCameraIndex == 4 || globalCameraIndex == 12) continue;

      TTntEdit *CameraGainEdit = (TTntEdit *) FindComponent("CameraGainEdit" + IntToStr(globalCameraIndex + 1));
      CameraGainEdit->Text = IntToStr(DigitalGainList[globalCameraIndex]);
      */

    }
  }
  else
  {
     for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      ShutterSpeedList[globalCameraIndex] = InitialValues.ShutterSpeed[globalCameraIndex];
      DigitalGainList[globalCameraIndex] = InitialValues.DigitalGain[globalCameraIndex];

     // TTntEdit *shutterSpeedEdit = (TTntEdit *) FindComponent("ShutterSpeedEdit" + IntToStr(globalCameraIndex + 1));
     // shutterSpeedEdit->Text = IntToStr(ShutterSpeedList[globalCameraIndex]);

   //   if(globalCameraIndex == 4 || globalCameraIndex == 12) continue;

    //  TTntEdit *CameraGainEdit = (TTntEdit *) FindComponent("CameraGainEdit" + IntToStr(globalCameraIndex + 1));
    //  CameraGainEdit->Text = IntToStr(DigitalGainList[globalCameraIndex]);

    }
  }
 // ColorCodeEdit->Text = ProductData.TabletColorCode;
 // CaptureTabletColor = GetColorByCode(ProductData.TabletColorCode);
//  TabletColorShape->Brush->Color = CaptureTabletColor;
//  TabletColorLabelR->Caption = "R = " + IntToStr((CaptureTabletColor >> 0)  & 0xFF);
//  TabletColorLabelG->Caption = "G = " + IntToStr((CaptureTabletColor >> 8)  & 0xFF);
 // TabletColorLabelB->Caption = "B = " + IntToStr((CaptureTabletColor >> 16) & 0xFF);
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::CloseButtonClick(
      TObject *Sender)
{

  if(stepSW == FirstDiskStart)
  {
    // 석션 1 OFF
    int blowerIndex = 0;
	  Machine.RingBlowerOff(blowerIndex);
  }

  else if(stepSW == SecondDiskStart)
  {
    // 석션 2 OFF
    int blowerIndex = 1;
	  Machine.RingBlowerOff(blowerIndex);
    stepSW = FirstDiskStart;
  }

  Machine.RingBlowerOff(0);
  Machine.RingBlowerOff(1);

  TCaptureCommandParam_HCB captureCommandParam_HCB;
  captureCommandParam_HCB.Action = 0;

  for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
    int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

    if (Comm_IsConnected(COMM_SPB + spbIndex))
    {
      Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
    }
  }

  if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
    NULL, 0))
  {
  }

  else if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK)
  {
    DiskImageLoadTimer->Enabled = false;
    ValueSetTimer->Enabled = false;
  }

  this->Close();
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RBOnSpeedButton1Click(
      TObject *Sender)
{
  try
	{
		TTntSpeedButton *theButton = (TTntSpeedButton *)Sender;

		int blowerIndex = 0;
		int speed1 = MachineControlParams.SuctionDisk1InverterSpeed;
		int speed2 = MachineControlParams.SuctionDisk2InverterSpeed;

		if (theButton->Tag < 4)
		{
			blowerIndex = theButton->Tag;
		}
		else
		{
			blowerIndex = 0xFF;
		}

		Machine.RingBlowerOn(blowerIndex, speed1, speed2);
	}
	catch (Exception &ec)
	{
		ShowMessageFA(ec.Message);
	}
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::RBOffSpeedButton1Click(
      TObject *Sender)
{
  int blowerIndex = 0;
	TTntSpeedButton *theButton = (TTntSpeedButton *)Sender;
	if (theButton->Tag < 4)
	{
		blowerIndex = theButton->Tag;
	}

	else
	{
		blowerIndex = 0xFF;
	}

	Machine.RingBlowerOff(blowerIndex);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::RB1InverterSpeedEdit11Change(TObject *Sender)
{
  try
	{
		MachineControlParams.SuctionDisk1InverterSpeed = StrToInt(RB1InverterSpeedEdit1->Text);
	}
	catch (...)
	{

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

void __fastcall TTwoDCalibrationGuideForm::RB2InverterSpeedEdi1t1Change(TObject *Sender)
{
  try
	{
		MachineControlParams.SuctionDisk2InverterSpeed = StrToInt(RB2InverterSpeedEdit1->Text);
	}
	catch (...)
	{

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

void __fastcall TTwoDCalibrationGuideForm::RB1InverterSpeedEdit11Click(
      TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  /*
  if(DefaultLCID != 1042 && DefaultLCID != 2066 && DefaultLCID != 1033)
  {
    KeyboardForm->SetWindowsKeyboard();
  }
  else*/
  {
  	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
		  theEdit->Text = KeyboardForm->Text;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::ChangeCamera(void)
{
  RefreshLEDCheckBox();
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RefreshLEDCheckBox(void)
{
	for (int ledIndex = 0; ledIndex < SYSTEM_TOTAL_LED_COUNT; ledIndex++)
  {
		TTntCheckBox *theCheckBox = (TTntCheckBox *) FindComponent("LEDCheckBox" + IntToStr(ledIndex + 1));
    if (theCheckBox)
    {
			if (LEDOnMask[GlobalCameraIndex] & (0x0001 << ledIndex))
      {
				theCheckBox->Checked = true;
      }
      else
      {
        theCheckBox->Checked = false;
      }
    }
  }
}
//---------------------------------------------------------------------------
bool __fastcall TTwoDCalibrationGuideForm::SendSPBCaptureSetup(void)
{
	bool returnValue = true;
  int startCameraIndex,endCameraIndex;
  if(ImageLoadType == FIRSTDISK)
  {
    //0~7 = 1~8번 카메라
    //150 포팅시 수정
    startCameraIndex = 0;
    endCameraIndex = 8;
  }
  else if(ImageLoadType == SECONDDISK)
  {
    //8~15 = 9~16 카메라
    startCameraIndex = 8;
    endCameraIndex = 16;
  }
	TCaptureSetupData captureSetupData;

	int spbIndex = CameraMapInfo[GlobalCameraIndex].SPBIndex;

	captureSetupData.CaptureType = CAPTURE_TYPE_SINGLE_CAPTURE;
	captureSetupData.CaptureMode = CAPTURE_MODE_DEFAULT;
	captureSetupData.FrameBufferCount = 3;

  /*
  if(ImageLoadRadioBtn->ItemIndex == 0)    //Each Cam
  {
    int camIndex = CameraMapInfo[GlobalCameraIndex].CamIndex;

  	captureSetupData.CameraMask = (0x0001 << camIndex);

    RefreshCameraInfo(GlobalCameraIndex);

    captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[GlobalCameraIndex];
    captureSetupData.SubsamplingMode[camIndex] = SubsamplingModeList[GlobalCameraIndex];
	  captureSetupData.ShutterDelay[camIndex] = 0;

    int LineScanTime = 0;//StrToInt(TriggerFreqEdit->Text);

    if (GlobalCameraIndex + 1 < HALF_INSPECTION_CAMERA_INDEX) // 모듈(SD1, 2) 구분
    {
      if(LineScanTime == 0)
        captureSetupData.TriggerFreq[camIndex] = RANGER_3D_BASE_SHUTTER_SPEED * MachineOperationInfo.ServoMotorSpeed[SD1_MOTOR_INDEX] / MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed; // 3D 이미지 원형 복원 check by moon
      else
        captureSetupData.TriggerFreq[camIndex] = LineScanTime;
    }
    else
    {
      if(LineScanTime == 0)
        captureSetupData.TriggerFreq[camIndex] = RANGER_3D_BASE_SHUTTER_SPEED2 * MachineOperationInfo.ServoMotorSpeed[SD2_MOTOR_INDEX] / MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed;
      else
        captureSetupData.TriggerFreq[camIndex] = LineScanTime;
    }


    captureSetupData.ContainParams = 1;

	  if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
    {
      returnValue = false;
    }

  }

  else if(ImageLoadRadioBtn->ItemIndex == 1)       // New Position Cam
  {
    int maxImage;
    int globalCameraIndex;
    if(cam3 == 100) maxImage = 2;
    else maxImage = 4;
    for(int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
    {
      if(Comm_IsConnected(COMM_SPB + spbIndex))
      {
        captureSetupData.CameraMask = 0;
        memset(captureSetupData.ShutterSpeed, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.SubsamplingMode, 0, sizeof(unsigned char) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.ShutterDelay, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.TriggerFreq, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);

        for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
        {
          if(globalCameraIndex == cam1 || globalCameraIndex == cam2 || globalCameraIndex == cam3 || globalCameraIndex == cam4)
          {
            if(spbIndex == CameraMapInfo[globalCameraIndex].SPBIndex)
            {
              RefreshCameraInfo(globalCameraIndex);

              int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
              captureSetupData.CameraMask |= (0x0001 << camIndex);
              captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[globalCameraIndex];
              captureSetupData.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
              captureSetupData.ShutterDelay[camIndex] = 0;
            }
          }
        }

        captureSetupData.ContainParams = 1;
        if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
        {
          returnValue = false;
        }
      }
    }
  }

  else if (ImageLoadRadioBtn->ItemIndex == 2) // All Cam
  {
    for(int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
    {
      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        captureSetupData.CameraMask = 0;
        memset(captureSetupData.ShutterSpeed, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.SubsamplingMode, 0, sizeof(unsigned char) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.ShutterDelay, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.TriggerFreq, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);

        for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
        {
          if(spbIndex == CameraMapInfo[globalCameraIndex].SPBIndex)
          {
            RefreshCameraInfo(globalCameraIndex);

            int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
            captureSetupData.CameraMask |= (0x0001 << camIndex);
            captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[globalCameraIndex];
            captureSetupData.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
            captureSetupData.ShutterDelay[camIndex] = 0;
          }
        }

        captureSetupData.ContainParams = 1;
        if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
        {
          returnValue = false;
        }
      }
    }
  }

  */

  if(ImageLoadType == ALLCAM)
  {
    for(int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
    {
      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        captureSetupData.CameraMask = 0;
        memset(captureSetupData.ShutterSpeed, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.SubsamplingMode, 0, sizeof(unsigned char) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.ShutterDelay, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.TriggerFreq, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);

        for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
        {
          if(spbIndex == CameraMapInfo[globalCameraIndex].SPBIndex)
          {
            RefreshCameraInfo(globalCameraIndex);

            int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
            captureSetupData.CameraMask |= (0x0001 << camIndex);
            captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[globalCameraIndex];
            captureSetupData.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
            captureSetupData.ShutterDelay[camIndex] = 0;
          }
        }

        captureSetupData.ContainParams = 1;
	  captureSetupData.TabletType = ProductData.TabletType;
	  captureSetupData.SensorLength= ProductData.StudiedSensor1Length;
        if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
        {
          returnValue = false;
        }
      }
    }
  }

  else if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK)
  {
    for(int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
    {
      if(Comm_IsConnected(COMM_SPB + spbIndex))
      {
        captureSetupData.CameraMask = 0;
        memset(captureSetupData.ShutterSpeed, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.SubsamplingMode, 0, sizeof(unsigned char) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.ShutterDelay, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);
        memset(captureSetupData.TriggerFreq, 0, sizeof(unsigned short) * SYSTEM_SPB_CAMERA_MAX_COUNT);

        for(int allCameraIndex = startCameraIndex; allCameraIndex < endCameraIndex; allCameraIndex++)
        {
            if(spbIndex == CameraMapInfo[allCameraIndex].SPBIndex)
            {
              RefreshCameraInfo(allCameraIndex);     // 카메라 ShutterSpeed, Gain값등을 set
              int camIndex = CameraMapInfo[allCameraIndex].CamIndex;
              captureSetupData.CameraMask |= (0x0001 << camIndex);
              captureSetupData.ShutterSpeed[camIndex] = ShutterSpeedList[allCameraIndex];
	            captureSetupData.ShutterDelay[camIndex] = 0;
              captureSetupData.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
            }
          }
	   captureSetupData.ContainParams = 1;
	   captureSetupData.TabletType = ProductData.TabletType;
	   captureSetupData.SensorLength= ProductData.StudiedSensor1Length;
          if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_SETUP, &captureSetupData, sizeof(TCaptureSetupData), NULL, 0))
          {
            returnValue = false;
          }

      }
    }
  }


  return returnValue;
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RefreshCameraInfo(int cameraIndex)
{
  // 사용자가 설정한 ShutterSpeed, Threshold, ROI(는 사실 Default) 를 반영
  int ShutterSpeed = 0;
  int Threshold = 0;
  int WriteMask = 0;
  int cameraGain = 1;

  /*
  TTntEdit *shutterSpeedEdit = (TTntEdit *) FindComponent("ShutterSpeedEdit" + IntToStr(cameraIndex + 1));
  TTntEdit *CameraGainEdit = (TTntEdit *) FindComponent("CameraGainEdit" + IntToStr(cameraIndex + 1));

  if(shutterSpeedEdit)
    ShutterSpeed = StrToInt(shutterSpeedEdit->Text);

  if(CameraGainEdit)
    cameraGain = StrToInt(CameraGainEdit->Text);

  */
  if(CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
    WriteMask |= CAMERA_WRITE_MASK_3D_SH;
  else
    WriteMask |= CAMERA_WRITE_MASK_2D_SH;

  if(CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    Threshold = ProductData.ThresholdFor3D[cameraIndex];
    WriteMask |= CAMERA_WRITE_MASK_TH;
  }

  TROIInfo DefaultROIInfo, ApplyROIInfo;
  AnsiString filePath;
  filePath = ProgramPath.Env + "\\NFACameraInformation.ini";
  DefaultROIInfo = ReadCameraInformation(filePath, cameraIndex);

  // Calibration 화면에서는 Default 값으로 ROI를 설정한다.
  memcpy(&ApplyROIInfo, &DefaultROIInfo, sizeof(TROIInfo));

  if(CameraMapInfo[cameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
  {
    WriteMask |= CAMERA_WRITE_MASK_2D_ROI;
  }
  else
  {
    WriteMask |= CAMERA_WRITE_MASK_3D_ROI;
  }

  if(CameraMapInfo[cameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
  {
    WriteMask |= CAMERA_WRITE_MASK_2D_SUBSAMPLING_MODE;
  }

 // SetCameraInformation(ApplyROIInfo, ShutterSpeed, Threshold,ResolutionRadioGroup->ItemIndex, cameraIndex, WriteMask);
 // SetCameraInformation(ApplyROIInfo, ShutterSpeed, Threshold , 0 , cameraIndex, WriteMask);
 // SetCameraGain(cameraIndex + 1, 2, cameraGain, 0);    // calibration 전용값으로 2를 할당

  // Analog Gain : 2
  // ShutterSpeed : 5
  // Digital Gain : 1


  // 2D Calibration전용 shutterSpeed, Gain 지정
  // 아날로그 gain 2, 디지털 gain 1 , shutterSpeed 5
  SetCameraInformation(ApplyROIInfo, 5, Threshold , 0 , cameraIndex, WriteMask);
  SetCameraGain(cameraIndex + 1, 2, 1, 0);
}

//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::DiskImageLoadTimerTimer(
      TObject *Sender)
{
  bool bCaptureExist;
	unsigned int data[2];
	unsigned int receivedData[2];
  int startCameraIndex, endCameraIndex;
  bool timerEnalbed = DiskImageLoadTimer->Enabled;

  DiskImageLoadTimer->Enabled = false;

  if(ImageLoadType == FIRSTDISK)
  {
    //0~7 = 1~8번 카메라
    //150 포팅시 수정
    startCameraIndex = 0;
    endCameraIndex = 8;
  }
  else if(ImageLoadType == SECONDDISK)
  {
    //8~15 = 9~16 카메라
    startCameraIndex = 8;
    endCameraIndex = 16;
  }

  for(int globalCameraIndex = startCameraIndex; globalCameraIndex < endCameraIndex; globalCameraIndex++)
  {
    if(globalCameraIndex != 4 && globalCameraIndex != 12)          //150 포팅시 수정
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
      data[0] = camIndex;

      try
      {
        if (Comm_IsConnected(COMM_SPB + spbIndex))
        {
          if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
            receivedData, sizeof(unsigned int) * 2))
          {

          }

          if (receivedData[0])
          {
            bCaptureExist = true;
          }

          else
          {
            bCaptureExist = false;
          }

          if (bCaptureExist)
          {
            data[1] = MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT;
            if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
              CaptureData, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT))
            {

            }
            TTntImage *DestImage;
            DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));

            GetNFACamera2DColorImage(DestImage->Picture->Bitmap, CaptureData, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT, globalCameraIndex, false, NULL, 0);


            // For SELMA200, 영상 반전 수정 예정
            if (globalCameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                globalCameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX - 1)
            {
              byte *pTempLine = new byte[DestImage->Picture->Bitmap->Width * 3];
              for (int y = 0; y < (DestImage->Picture->Bitmap->Height); y++)
              {
                byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

                for (int x = 0; x < DestImage->Picture->Bitmap->Width; x++)
                {
                  pTempLine[x * 3 + 0] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 0];
                  pTempLine[x * 3 + 1] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 1];
                  pTempLine[x * 3 + 2] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 2];
                }
                memcpy(pBitmap, pTempLine, DestImage->Picture->Bitmap->Width * 3);
              }
              delete[] pTempLine;
            }
            else if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX - 1)
            {
              byte *pTempLineT = new byte[DestImage->Picture->Bitmap->Width * 3];
              byte *pTempLineB = new byte[DestImage->Picture->Bitmap->Width * 3];
              for (int y = 0; y < (DestImage->Picture->Bitmap->Height + 1) / 2; y++)
              {
                byte *pBitmapT = (byte *)DestImage->Picture->Bitmap->ScanLine[y];
                byte *pBitmapB = (byte *)DestImage->Picture->Bitmap->ScanLine[DestImage->Picture->Bitmap->Height - 1 - y];

                memcpy(pTempLineT, pBitmapB, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pTempLineB, pBitmapT, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pBitmapT, pTempLineT, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pBitmapB, pTempLineB, DestImage->Picture->Bitmap->Width * 3);
              }
              delete[] pTempLineT;
              delete[] pTempLineB;
            }
            DestImage->Repaint();


            if(ShowGuideLine->Down)
            {
              DestImage->Canvas->Pen->Color = clRed;
              DestImage->Canvas->Pen->Style = psSolid;
              DestImage->Canvas->Pen->Width = 3;
              DestImage->Canvas->MoveTo(DestImage->Picture->Width / 2 , 0);
              DestImage->Canvas->LineTo(DestImage->Picture->Width / 2 , DestImage->Picture->Height);
              DestImage->Canvas->MoveTo(0 , DestImage->Picture->Height / 2);
              DestImage->Canvas->LineTo(DestImage->Picture->Width ,DestImage->Picture->Height / 2);
              if(ProductGuideLine->Checked)
              {
                int Fov = StrToInt(FovSize->Text);
                double pixelRealDistance;
                double ProductHalfSize;
                int CenterDistance;

                ProductHalfSize = StrToFloat(ProductWidthEdit->Text) / 2;
                pixelRealDistance = (Fov * 1000000)/640;
                pixelRealDistance = pixelRealDistance * 0.000001;
                CenterDistance =  ProductHalfSize / pixelRealDistance ;

                DestImage->Canvas->Pen->Color = clAqua;
                DestImage->Canvas->MoveTo(DestImage->Picture->Width / 2 - CenterDistance , 0);
                DestImage->Canvas->LineTo(DestImage->Picture->Width / 2 - CenterDistance , DestImage->Picture->Height);
                DestImage->Canvas->MoveTo(DestImage->Picture->Width / 2 + CenterDistance , 0);
                DestImage->Canvas->LineTo(DestImage->Picture->Width / 2 + CenterDistance , DestImage->Picture->Height);

              }
              DestImage->Update();
            }



            if(ActiveCameraNumber != -1)
            {
             /*
              if(ActiveCameraNumber == globalCameraIndex)
              {
                TTntImage *SelectImage;
                SelectImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));
                SelectImage->Canvas->Pen->Width = 10;
                SelectImage->Canvas->Pen->Color = clRed;
                SelectImage->Canvas->Brush->Style = bsClear;
                SelectImage->Canvas->Rectangle(0,0,640,480);
                SelectImage->Repaint();
              }
              */
              //Test1
              // 센터좌표 클릭을 위해 이미지를 클릭함
              if(ImageLoadType == FIRSTDISK)
              {
                FirstDiskSelectImage->Picture->Bitmap->Assign(ActiveCameraImage->Picture->Bitmap);
                FirstDiskSelectImage->Refresh();

                if(CenterPosition[ActiveCameraNumber].Alpa && CenterPosition[ActiveCameraNumber].Beta)
                {
                  TrackCenterPosition(ActiveCameraNumber);
                }

                RefreshPixelInfo(CenterPosition[ActiveCameraNumber].CenterX, CenterPosition[ActiveCameraNumber].CenterY);

                FirstDiskSelectImage->Canvas->Brush->Color = clAqua;
                FirstDiskSelectImage->Canvas->Brush->Style = bsSolid;
                FirstDiskSelectImage->Canvas->Ellipse(CenterPosition[ActiveCameraNumber].CenterX - 3, CenterPosition[ActiveCameraNumber].CenterY - 3, CenterPosition[ActiveCameraNumber].CenterX + 3, CenterPosition[ActiveCameraNumber].CenterY + 3);
                FirstDiskSelectImage->Refresh();

              }
              else if(ImageLoadType == SECONDDISK)
              {
                SecondDiskSelectImage->Picture->Bitmap->Assign(ActiveCameraImage->Picture->Bitmap);
                SecondDiskSelectImage->Refresh();

                if(CenterPosition[ActiveCameraNumber].Alpa && CenterPosition[ActiveCameraNumber].Beta)
                {
                  TrackCenterPosition(ActiveCameraNumber);
                }

                RefreshPixelInfo(CenterPosition[ActiveCameraNumber].CenterX, CenterPosition[ActiveCameraNumber].CenterY);
                SecondDiskSelectImage->Canvas->Brush->Color = clAqua;
                SecondDiskSelectImage->Canvas->Brush->Style = bsSolid;
                SecondDiskSelectImage->Canvas->Ellipse(CenterPosition[ActiveCameraNumber].CenterX - 3, CenterPosition[ActiveCameraNumber].CenterY - 3, CenterPosition[ActiveCameraNumber].CenterX + 3, CenterPosition[ActiveCameraNumber].CenterY + 3);
                SecondDiskSelectImage->Refresh();

              }

            }

            if(CenterPosition[globalCameraIndex].CenterX && CenterPosition[globalCameraIndex].CenterY)
            {
              RefreshPixelInfo1(CenterPosition[globalCameraIndex].CenterX, CenterPosition[globalCameraIndex].CenterY, globalCameraIndex);
              GradeGVerify(globalCameraIndex);
            }



            if(GradeNext[globalCameraIndex])
            {
              if(globalCameraIndex == 2 || globalCameraIndex == 6 || globalCameraIndex == 10 || globalCameraIndex == 14)        //150 포팅시 수정 
              {
                // 수평 검증 추가
                HorizontalVerification(globalCameraIndex);
                if(InclineCheck[globalCameraIndex]) // 수평검증이 O 의 결과일 경우
                {
                  PositionVerificationForAllCam(globalCameraIndex);
                }
              }
              // 좌우대칭 확인
              else
              {
                PositionVerificationForAllCam(globalCameraIndex);
              }
            }

            else
            {
              // G값 검증이 O->X로 변경시 좌우 ,상하대칭값도 측정안하고, X로 모두 변경하기
              TTntLabel *LRVerifyLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(globalCameraIndex + 1) + "LRLabel");
              TTntLabel *UBVerifyLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(globalCameraIndex + 1) + "UBlabel");

              LRVerifyLabel->Caption = "X";
              UBVerifyLabel->Caption = "X";

            }
          }
        }
      }

      catch (...)
      {
        DiskImageLoadTimer->Enabled = false;
      }
    }

  }



  DiskImageLoadTimer->Enabled = timerEnalbed;
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::SubCaptureFrameCaptureCheckTimerTimer(
      TObject *Sender)
{
  /*
  int RepCamIndex;

  try
  {

    RefreshPixelInfo(MousePos.x, MousePos.y);

    if(ShowGuideLine->Down)
    {
      if(GlobalCameraIndex != 0 && GlobalCameraIndex != 1 && GlobalCameraIndex != 2 && GlobalCameraIndex != 3 && GlobalCameraIndex != 8)     // 정면과 측면대표카메라가 아닐경우
      {
        switch(GlobalCameraIndex)
        {
          case 5 :
            RepCamIndex = 1;
            break;
          case 9 :
            RepCamIndex = 1;
            break;
          case 13 :
            RepCamIndex = 1;
            break;

          case 6 :
            RepCamIndex = 2;
            break;
          case 10 :
            RepCamIndex = 2;
            break;
          case 14 :
            RepCamIndex = 2;
            break;

          case 7 :
            RepCamIndex = 3;
            break;
          case 11 :
            RepCamIndex = 3;
            break;
          case 15 :
            RepCamIndex = 3;
            break;


        }

        CaptureImage->Canvas->Pen->Color = clYellow;
        CaptureImage->Canvas->MoveTo(0,SideFaceLine[RepCamIndex].Y * 4);
        CaptureImage->Canvas->LineTo(640,SideFaceLine[RepCamIndex].Y * 4) ;
      }

      if(NormalGuideLine->Checked && !(ProductGuideLine->Checked))
      {

        CaptureImage->Canvas->Pen->Color = clRed;
        CaptureImage->Canvas->MoveTo(320,0);
        CaptureImage->Canvas->LineTo(320,480);
        CaptureImage->Canvas->MoveTo(0,240);
        CaptureImage->Canvas->LineTo(640,240);

      }

      else if(!(NormalGuideLine->Checked) && ProductGuideLine->Checked)
      {
        int Fov = StrToInt(FovSize->Text);
        double pixelRealDistance;
        double ProductHalfSize;
        int CenterDistance;

        ProductHalfSize = 3.5; // 임시 GJ 기준
        pixelRealDistance = (Fov * 1000000)/640;
        pixelRealDistance = pixelRealDistance * 0.000001;
        CenterDistance =  ProductHalfSize / pixelRealDistance ;

        CaptureImage->Canvas->Pen->Color = clAqua;
        CaptureImage->Canvas->MoveTo(320 - CenterDistance , 0);
        CaptureImage->Canvas->LineTo(320 - CenterDistance , 480);
        CaptureImage->Canvas->MoveTo(320 + CenterDistance , 0);
        CaptureImage->Canvas->LineTo(320 + CenterDistance , 480);

      }

      else if(NormalGuideLine->Checked && ProductGuideLine->Checked)
      {

        int Fov = StrToInt(FovSize->Text);
        double pixelRealDistance;
        double ProductHalfSize;
        int CenterDistance;

        ProductHalfSize = 3.5; // 임시 GJ 기준
        pixelRealDistance = (Fov* 1000000)/640 ;
        pixelRealDistance = pixelRealDistance * 0.000001;
        CenterDistance =  ProductHalfSize / pixelRealDistance ;

        CaptureImage->Canvas->Pen->Color = clRed;
        CaptureImage->Canvas->MoveTo(320,0);
        CaptureImage->Canvas->LineTo(320,480);
        CaptureImage->Canvas->MoveTo(0,240);
        CaptureImage->Canvas->LineTo(640,240);

        CaptureImage->Canvas->Pen->Color = clAqua;
        CaptureImage->Canvas->MoveTo(320 - CenterDistance , 0);
        CaptureImage->Canvas->LineTo(320 - CenterDistance , 480);
        CaptureImage->Canvas->MoveTo(320 + CenterDistance , 0);
        CaptureImage->Canvas->LineTo(320 + CenterDistance , 480);

      }
    }
    CaptureImage->Refresh();
  }
  catch(...)
  {

  }

  */
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::LEDAllOn(void)
{
  RefreshLEDCheckBox();
  for (int ledIndex = 0; ledIndex < SYSTEM_TOTAL_LED_COUNT; ledIndex++)
  {
		TTntCheckBox *theCheckBox = (TTntCheckBox *) FindComponent("LEDCheckBox" + IntToStr(ledIndex + 1));
    if (theCheckBox)
    {
			if (ledIndex == 5 || ledIndex == 11)
      {
				theCheckBox->Checked = false;
      }
      else
      {
        theCheckBox->Checked = true;
      }
    }
  }


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



void __fastcall TTwoDCalibrationGuideForm::Cam1ButtonClick(TObject *Sender)
{
  TTntSpeedButton *theSpeedButton = (TTntSpeedButton *) Sender;
  GlobalCameraIndex = theSpeedButton->Tag;
  VerifyCamNum = theSpeedButton->Tag;
  ChangeCamera();

  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  ReadCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex);

  int WhiteBalanceValue[3];

  WhiteBalanceValue[0] = WhiteBalanceInfo[GlobalCameraIndex].BColorInfo;
  WhiteBalanceValue[1] = WhiteBalanceInfo[GlobalCameraIndex].GColorInfo;
  WhiteBalanceValue[2] = WhiteBalanceInfo[GlobalCameraIndex].RColorInfo;

  SetWhiteBalanceValue(WhiteBalanceValue[0], 0);
  SetWhiteBalanceValue(WhiteBalanceValue[1], 1);
  SetWhiteBalanceValue(WhiteBalanceValue[2], 2);

  CameraNumberLabel->Caption = "Camera Number : #" + IntToStr(GlobalCameraIndex + 1);

  WhiteBalanceBValue->Position = WhiteBalanceInfo[GlobalCameraIndex].BColorInfo;
  WhiteBalanceGValue->Position = WhiteBalanceInfo[GlobalCameraIndex].GColorInfo;
  WhiteBalanceRValue->Position = WhiteBalanceInfo[GlobalCameraIndex].RColorInfo;

  WhiteBalanceBValueEdit->Text = IntToStr(WhiteBalanceBValue->Position);
  WhiteBalanceGValueEdit->Text = IntToStr(WhiteBalanceGValue->Position);
  WhiteBalanceRValueEdit->Text = IntToStr(WhiteBalanceRValue->Position);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::InitCaptureComponent()
{
  if(ImageLoadType == ALLCAM)
  {
    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      if(globalCameraIndex != 4 && globalCameraIndex != 12)
      {
        TImage *tempImage;
        tempImage = (TImage *) FindComponent("CameraImage" + IntToStr(globalCameraIndex + 1));

        if(tempImage)
        {
          tempImage->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
          tempImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
          tempImage->Picture->Bitmap->PixelFormat = pf24bit;

          tempImage->Canvas->Brush->Color = clBlue;
          tempImage->Canvas->Brush->Style = bsSolid;
	        tempImage->Canvas->FillRect(Rect(0, 0, tempImage->Picture->Bitmap->Width, tempImage->Picture->Bitmap->Height));

          tempImage->Refresh();
        }
      }
    }
  }
  else if(ImageLoadType == FIRSTDISK)
  {
    for(int globalCameraIndex = 0; globalCameraIndex < 8; globalCameraIndex++)
    {
      if(globalCameraIndex != 4)
      {
        TImage *tempImage;
        tempImage = (TImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));

        if(tempImage)
        {
          tempImage->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
          tempImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
          tempImage->Picture->Bitmap->PixelFormat = pf24bit;

          tempImage->Canvas->Brush->Color = clBlue;
          tempImage->Canvas->Brush->Style = bsSolid;
	        tempImage->Canvas->FillRect(Rect(0, 0, tempImage->Picture->Bitmap->Width, tempImage->Picture->Bitmap->Height));

          tempImage->Refresh();
        }
      }
    }
  }

  else if(ImageLoadType == SECONDDISK)
  {
    for(int globalCameraIndex = 8; globalCameraIndex < 16; globalCameraIndex++)
    {
      if(globalCameraIndex != 12)
      {
        TImage *tempImage;
        tempImage = (TImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));

        if(tempImage)
        {
          tempImage->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
          tempImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
          tempImage->Picture->Bitmap->PixelFormat = pf24bit;

          tempImage->Canvas->Brush->Color = clBlue;
          tempImage->Canvas->Brush->Style = bsSolid;
	        tempImage->Canvas->FillRect(Rect(0, 0, tempImage->Picture->Bitmap->Width, tempImage->Picture->Bitmap->Height));

          tempImage->Refresh();
        }
      }
    }
  }
  ActiveCameraNumber = -1;
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::InitCaptureComponent1()
{
  for(int globalCameraIndex = 0; globalCameraIndex < 4; globalCameraIndex++)
  {
    TImage *tempImage;
    tempImage = (TImage *) FindComponent("PositionCam" + IntToStr(globalCameraIndex + 1));

    if(tempImage)
    {
      tempImage->Picture->Bitmap->Width = MAX_IMAGE_WIDTH;
      tempImage->Picture->Bitmap->Height = MAX_IMAGE_HEIGHT;
      tempImage->Picture->Bitmap->PixelFormat = pf24bit;

      tempImage->Canvas->Brush->Color = clBlue;
      tempImage->Canvas->Brush->Style = bsSolid;
	    tempImage->Canvas->FillRect(Rect(0, 0, tempImage->Picture->Bitmap->Width, tempImage->Picture->Bitmap->Height));

      tempImage->Refresh();
    }

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




void __fastcall TTwoDCalibrationGuideForm::FovSizeClick(TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  /*
  if(DefaultLCID != 1042 && DefaultLCID != 2066 && DefaultLCID != 1033)
  {
    KeyboardForm->SetWindowsKeyboard();
  }
  else*/
  {
  	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
		  theEdit->Text = KeyboardForm->Text;
    }
  }  
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::VerifyOkButtonClick(
      TObject *Sender)
{
  if(stepSW == FirstDiskStart || stepSW == FirstDiskValueSet)
  {
    StartButton1->Enabled = true;

    // 석션 1 OFF
    int blowerIndex = 0;
	  Machine.RingBlowerOff(blowerIndex);
  }

  else if(stepSW == SecondDiskStart || stepSW == SecondDiskValueSet)
  {
    StartButton1->Enabled = true;
    // 석션 2 OFF
    int blowerIndex = 1;
	  Machine.RingBlowerOff(blowerIndex);
  }

  TCaptureCommandParam_HCB captureCommandParam_HCB;
  captureCommandParam_HCB.Action = 0;

  for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
    int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

    if (Comm_IsConnected(COMM_SPB + spbIndex))
    {
      Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
    }
  }

  if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
    NULL, 0))
  {
  }

  else if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK)
  {
    DiskImageLoadTimer->Enabled = false;
    ValueSetTimer->Enabled = false;
  }


  //WhiteBalanceButton->Visible = true;
}
//---------------------------------------------------------------------------




void __fastcall TTwoDCalibrationGuideForm::WhiteBalanceRValueChange(
      TObject *Sender)
{
  int WhiteBalanceValue;

  WhiteBalanceValue = WhiteBalanceRValue->Position;

  WhiteBalanceInfo[GlobalCameraIndex].RColorInfo = WhiteBalanceRValue->Position;

  SetWhiteBalanceValue(WhiteBalanceValue, 2);

  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  WriteCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex, 2);

  WhiteBalanceRValueEdit->Text = IntToStr(WhiteBalanceRValue->Position);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::WhiteBalanceGValueChange(
      TObject *Sender)
{
  int WhiteBalanceValue;

  WhiteBalanceValue = WhiteBalanceGValue->Position;

  WhiteBalanceInfo[GlobalCameraIndex].GColorInfo = WhiteBalanceGValue->Position;

  SetWhiteBalanceValue(WhiteBalanceValue, 1);

  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  WriteCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex, 1);

  WhiteBalanceGValueEdit->Text = IntToStr(WhiteBalanceGValue->Position);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::WhiteBalanceBValueChange(
      TObject *Sender)
{
  int WhiteBalanceValue;

  WhiteBalanceValue = WhiteBalanceBValue->Position;

  WhiteBalanceInfo[GlobalCameraIndex].BColorInfo = WhiteBalanceBValue->Position;

  SetWhiteBalanceValue(WhiteBalanceValue, 0);

  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  WriteCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex, 0);

  WhiteBalanceBValueEdit->Text = IntToStr(WhiteBalanceBValue->Position);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::WhiteBalanceRValueEditClick(
      TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
		theEdit->Text = KeyboardForm->Text;

    if(theEdit->Tag == 0)
    {
      WhiteBalanceBValue->Position = StrToInt(theEdit->Text);
    }
    else if(theEdit->Tag == 1)
    {
      WhiteBalanceGValue->Position = StrToInt(theEdit->Text);
    }
    else if(theEdit->Tag == 2)
    {
      WhiteBalanceRValue->Position = StrToInt(theEdit->Text);
    }
	}
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::CaptureImageMouseMove(
      TObject *Sender, TShiftState Shift, int X, int Y)
{
  MousePos.x = X;
	MousePos.y = Y;

	//RefreshPixelInfo(MousePos.x, MousePos.y);
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RefreshSubImage(void)
{

}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RefreshPixelInfo(int X, int Y)
{
  TTntImage *DestImage1;
  if (ImageLoadType == FIRSTDISK)DestImage1 = (TTntImage *) FirstDiskSelectImage;
  else if(ImageLoadType == SECONDDISK)DestImage1 = (TTntImage *) SecondDiskSelectImage;

  TColor color = DestImage1->Canvas->Pixels[X][Y];
	int redVal = color & 0xFF;
	int greenVal = (color >> 8) & 0xFF;
	int blueVal = (color >> 16) & 0xFF;
	AnsiString redText = IntToStr(redVal);
	AnsiString greenText = IntToStr(greenVal);
	AnsiString blueText = IntToStr(blueVal);

	RedImage->Canvas->Brush->Color = clRed;
	RedImage->Canvas->Font->Color = clWhite;
	RedImage->Canvas->TextRect(Rect(0, 0, redVal, RedImage->Height),
		(RedImage->Width - RedImage->Canvas->TextWidth(redText)) / 2,
		(RedImage->Height - RedImage->Canvas->TextHeight(redText)) / 2, redText);
	RedImage->Canvas->Brush->Color = clWhite;
	RedImage->Canvas->Font->Color = clRed;
	RedImage->Canvas->TextRect(Rect(redVal, 0, RedImage->Width, RedImage->Height),
		(RedImage->Width - RedImage->Canvas->TextWidth(redText)) / 2,
		(RedImage->Height - RedImage->Canvas->TextHeight(redText)) / 2, redText);

	GreenImage->Canvas->Brush->Color = clGreen;
	GreenImage->Canvas->Font->Color = clWhite;
	GreenImage->Canvas->TextRect(Rect(0, 0, greenVal, GreenImage->Height),
		(GreenImage->Width - GreenImage->Canvas->TextWidth(greenText)) / 2,
		(GreenImage->Height - GreenImage->Canvas->TextHeight(greenText)) / 2, greenText);
	GreenImage->Canvas->Brush->Color = clWhite;
	GreenImage->Canvas->Font->Color = clGreen;
	GreenImage->Canvas->TextRect(Rect(greenVal, 0, GreenImage->Width, GreenImage->Height),
		(GreenImage->Width - GreenImage->Canvas->TextWidth(greenText)) / 2,
		(GreenImage->Height - GreenImage->Canvas->TextHeight(greenText)) / 2, greenText);

	BlueImage->Canvas->Brush->Color = clBlue;
	BlueImage->Canvas->Font->Color = clWhite;
	BlueImage->Canvas->TextRect(Rect(0, 0, blueVal, BlueImage->Height),
		(BlueImage->Width - BlueImage->Canvas->TextWidth(blueText)) / 2,
		(BlueImage->Height - BlueImage->Canvas->TextHeight(blueText)) / 2, blueText);
	BlueImage->Canvas->Brush->Color = clWhite;
	BlueImage->Canvas->Font->Color = clBlue;
	BlueImage->Canvas->TextRect(Rect(blueVal, 0, BlueImage->Width, BlueImage->Height),
		(BlueImage->Width - BlueImage->Canvas->TextWidth(blueText)) / 2,
		(BlueImage->Height - BlueImage->Canvas->TextHeight(blueText)) / 2, blueText);


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::RefreshPixelInfo1(int X, int Y, int globalCameraIndex)
{
  TTntImage *DestImage;
  DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));
  int greenVal;

  greenVal = 0;
  for(int i = -1; i <= 1; i++)
  {
    for(int j = -1; j <= 1; j++)
    {
      TColor color = DestImage->Canvas->Pixels[X+i][Y+j];
      greenVal += (color >> 8) & 0xFF;
    }
  }

  CheckgreenVal = greenVal / 9;

}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::FrontCamButtonClick(
      TObject *Sender)
{
  TTntSpeedButton *theSpeedButton = (TTntSpeedButton *) Sender;
  int MultiCamera = theSpeedButton->Tag;
  //GlobalCameraIndex = theSpeedButton->Tag;
  ChangeCamera();

  switch(MultiCamera)
  {
    case 20 :
      cam1 = 0;
      cam2 = 8;
      cam3 = 100;
      cam4 = 100;
      break;

    case 21 :
      cam1 = 1;
      cam2 = 5;
      cam3 = 9;
      cam4 = 14;
      break;


    case 22 :
      cam1 = 2;
      cam2 = 6;
      cam3 = 10;
      cam4 = 14;
      break;

    case 23 :
      cam1 = 3;
      cam2 = 7;
      cam3 = 11;
      cam4 = 15;
      break;

  }

  LEDAllOn();    // 카메라 번호에 따라 조명번호 set  //기능 부분이였지만, 이경우 1,2번 LED 모두 ALL 해주어야해서 번호와 상관없이 조명 모두 ON

  /*
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";

  ReadCameraWhiteBalanceColorInfo(fileName, GlobalCameraIndex);

  int WhiteBalanceValue[3];

  WhiteBalanceValue[0] = WhiteBalanceInfo[GlobalCameraIndex].BColorInfo;
  WhiteBalanceValue[1] = WhiteBalanceInfo[GlobalCameraIndex].GColorInfo;
  WhiteBalanceValue[2] = WhiteBalanceInfo[GlobalCameraIndex].RColorInfo;
   */


}
//---------------------------------------------------------------------------
int __fastcall TTwoDCalibrationGuideForm::LabellingForTabletImage(short *label_Image, unsigned char *smallSizeBinaryImage, int startX, int endX, int startY, int endY, int imageWidth, int imageHeight)
{
	int i, x, y;
	int temp_address;
	int currentLabel;
	int new_count;
	short CollisionArray[MAX_LABEL_COUNT];
	int newLval;
	int temp;
	// int checkSW;
	//  int minValue;
	int tempAddress;
	// int smallSizeImagWidth;
	//  int smallSizeImagHeight;
	int maxLabelN;
	int maxLabelCount;
	int breakSW;
	unsigned short Pixel_N_Of_Label[MAX_LABEL_COUNT]; //4k
	int StartX_Label[MAX_LABEL_COUNT];
	int EndX_Label[MAX_LABEL_COUNT];
	int StartY_Label[MAX_LABEL_COUNT];
	int EndY_Label[MAX_LABEL_COUNT];

	currentLabel = 0;
	for (i = 0; i < MAX_LABEL_COUNT; i++)
	{
		CollisionArray[i] = i;
		Pixel_N_Of_Label[i] = 0;
		StartX_Label[i] = 640;
		EndX_Label[i] = 0;
		StartY_Label[i] = 640;
		EndY_Label[i] = 0;
	}
	breakSW = 0;
	for (y = startY; y < endY; y++)
	{
		for (x = startX; x < endX; x++)
		{
			temp_address = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + temp_address))
			{
				if (*(label_Image + temp_address - imageWidth) == 0)     // up is background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is also background
					{
						currentLabel++;
						*(label_Image + temp_address) = currentLabel; // first label number is '1'
					}
					else                        // left is not background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - 1);
					}
				}
				else                // up is not background
				{
					if (*(label_Image + temp_address - 1) == 0)       // left is background
					{
						*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
					}
					else                        // left is not background
					{
						if (*(label_Image + temp_address - imageWidth) == *(label_Image + temp_address - 1))
						{
							*(label_Image + temp_address) = *(label_Image + temp_address - imageWidth);
						}
						else        // collision detected
						{           // Left label이 Up label보다 항상 크다
							CollisionArray[max(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth))] =
								min(*(label_Image + temp_address - 1), *(label_Image + temp_address - imageWidth));
							*(label_Image + temp_address) = CollisionArray[*(label_Image + temp_address - imageWidth)];
						}
					}
				}
				if (currentLabel >= MAX_LABEL_COUNT - 1)
				{
					breakSW = 1;
					break;
				}
			}
		}
		if (breakSW == 1)
			break;
	}
	newLval = 1;
	for (i = 1; i <= currentLabel; i++)
	{
		if (CollisionArray[CollisionArray[i]] > newLval)
		{
			newLval++;
			CollisionArray[i] = newLval;
		}
		else
		{
			CollisionArray[i] = CollisionArray[CollisionArray[i]];
		}
	}
	if (newLval > MAX_LABEL_COUNT)  newLval = MAX_LABEL_COUNT - 1;
	new_count = newLval;

	for (y = 0; y < imageHeight; y++)
	{
		for (x = 0; x < imageWidth; x++)
		{
			tempAddress = imageWidth * (y)+x;
			if (*(smallSizeBinaryImage + tempAddress))
			{
				temp = *(label_Image + tempAddress);
				temp = CollisionArray[temp];
				*(label_Image + tempAddress) = temp;
				Pixel_N_Of_Label[temp]++;
				if (StartX_Label[temp] > x)  StartX_Label[temp] = x;
				if (StartY_Label[temp] > y)  StartY_Label[temp] = y;
				if (EndX_Label[temp] < x)  EndX_Label[temp] = x;
				if (EndY_Label[temp] < y)  EndY_Label[temp] = y;
			}
		}
	}
	maxLabelN = 0;
	maxLabelCount = 0;
	for (i = 1; i <= new_count; i++)
	{
		if (Pixel_N_Of_Label[i] > maxLabelCount)
		{
			maxLabelN = i;
			maxLabelCount = Pixel_N_Of_Label[i];
		}
	}
	return(maxLabelN);
}




void __fastcall TTwoDCalibrationGuideForm::sleeptimeEditClick(
      TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  /*
  if(DefaultLCID != 1042 && DefaultLCID != 2066 && DefaultLCID != 1033)
  {
    KeyboardForm->SetWindowsKeyboard();
  }
  else*/
  {
  	KeyboardForm->Text = theEdit->Text;
    if (KeyboardForm->ShowKeypad() == mrOk)
    {
		  theEdit->Text = KeyboardForm->Text;
    }
  }
}
//---------------------------------------------------------------------------



void __fastcall TTwoDCalibrationGuideForm::SaveDefaultShutterSpeedButtonClick(
      TObject *Sender)
{
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		InitialValues.ShutterSpeed[globalCameraIndex] = ShutterSpeedList[globalCameraIndex];
    InitialValues.DigitalGain[globalCameraIndex] = DigitalGainList[globalCameraIndex];
	}

	WriteInitialValues(ProgramPath.Env + "\\Initials.ini");    
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::ShutterSpeedEdit1Change(
      TObject *Sender)
{
	TTntEdit *shutterSpeedEdit = (TTntEdit *) Sender;
  int globalCameraIndex = shutterSpeedEdit->Tag;
	try
  {
    int shutterSpeed = StrToInt(shutterSpeedEdit->Text);
		double shuterSpeedMS = shutterSpeed / 1000.0;
    TTntLabel *shutterSpeedLabel = (TTntLabel *) FindComponent("ShutterSpeedLabel" + IntToStr(globalCameraIndex + 1));
    WCHAR TempString[100];
    wsprintfW(TempString, L"%Sms", FloatToStrF( shuterSpeedMS, ffFixed, 10, 3));
    shutterSpeedLabel->Caption = TempString;
    ShutterSpeedList[globalCameraIndex] = shutterSpeed;
  }
  catch(...)
  {

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

void __fastcall TTwoDCalibrationGuideForm::CameraGainEdit1Change(
      TObject *Sender)
{
  TTntEdit *gainEdit = (TTntEdit *) Sender;
  int globalCameraIndex = gainEdit->Tag;
	try
  {
    int Gain = StrToInt(gainEdit->Text);
    DigitalGainList[globalCameraIndex] = Gain;
  }
  catch(...)
  {

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



void __fastcall TTwoDCalibrationGuideForm::ShutterSpeedEdit1Click(
      TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
		theEdit->Text = KeyboardForm->Text;
	}
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::LoadSystemDefaultButtonClick(
      TObject *Sender)
{
	if (MessageDlgFA(CAPTUREFORM_GROUPBOX_CAPTION_01, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
  {
    for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {

      ShutterSpeedList[globalCameraIndex] = InitialValues.ShutterSpeed[globalCameraIndex];
      DigitalGainList[globalCameraIndex] = InitialValues.DigitalGain[globalCameraIndex];

      TTntEdit *shutterSpeedEdit = (TTntEdit *) FindComponent("ShutterSpeedEdit" + IntToStr(globalCameraIndex + 1));
      shutterSpeedEdit->Text = IntToStr(ShutterSpeedList[globalCameraIndex]);

		if(globalCameraIndex == 4 || globalCameraIndex == 12) continue;

      TTntEdit *CameraGainEdit = (TTntEdit *) FindComponent("CameraGainEdit" + IntToStr(globalCameraIndex + 1));
      CameraGainEdit->Text = IntToStr(DigitalGainList[globalCameraIndex]);
    }
  }  
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::SaveProductShutterSpeedButtonClick(
      TObject *Sender)
{
  for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    ProductData.ShutterSpeed[globalCameraIndex] = ShutterSpeedList[globalCameraIndex];
    ProductData.DigitalGainV[globalCameraIndex] = DigitalGainList[globalCameraIndex];
  }

  ProductData.StudyStep = STUDY_STEP_NONE;

  AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
  if (WriteProductData(fileName, ProductData))
  {
    ShowMessageFA(CAPTUREFORM_MSG_05);
  }
  else
  {
    ShowMessageFA(CAPTUREFORM_MSG_06);
  }
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::SetWhiteBalanceValue(int Value, int rgbIndex)
{
  whiteBalance[rgbIndex] = Value;
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::PositionVerificationForAllCam(int globalcameraIndex)
{
  int x,y;
  byte *ptr;
  int tempAddress ;
  int protoThreshold = 80;
  int startX, endX, startY, endY;
  unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];
  short smallSizeLabelImage[(640 / 4)*(480 / 4)];
  int smallSizeImagWidth;
  int ImageWidth, ImageHeight;
  int maxLabelN;
  int minX,minY,maxX,maxY;

  int SumX,SumY,SumCount;
  int CenterX,CenterY;
  int CameraIndex;

  SumX = SumY = SumCount = 0;
  minX = minY = 100000;
  maxX = maxY = 0;
  startX = 10;
  endX = 640 - 10;
  startY = 10;
  endY = 480 - 10;
  ImageWidth = 640;
  ImageHeight = 480;
  smallSizeImagWidth = ImageWidth / 4;

  memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);

  CameraIndex = globalcameraIndex;

  TTntImage *DestImage;
  if(ImageLoadType == ALLCAM)
  {
    DestImage = (TTntImage *) FindComponent("CameraImage" + IntToStr(CameraIndex + 1));
  }
  else
  {
    DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(CameraIndex + 1));
  }
  for (y = 0; y < 480; y++)
  {
    ptr = (Byte*)DestImage->Picture->Bitmap->ScanLine[y];
    for (x = 0; x < 640; x++)
    {
      tempAddress = 640 * y + x;
      ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
      ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
      ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];


    }
  }
  //ch

  // calibration에서 사용할때는, 흰색정제를 이용하므로 임계값을 러프하게 설정하여도 배경과 구분이 될 수있을거라 예상.
  for (int y = startY; y < endY; y++)
  {
    for (int x = startX; x < endX; x++)
    {
      if (*(ColorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 0) > protoThreshold)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
    }
  }

  maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);

  int tempX, tempY;
  for (int y = startY + 1; y < endY - 1; y++)
  {
    for (int x = startX + 1; x < endX - 1; x++)
    {
      tempX = x / 4;
      tempY = y / 4;

      if (smallSizeLabelImage[(tempY) * smallSizeImagWidth + (tempX)] == maxLabelN)
      {
        for (int i = tempY - 1; i <= tempY + 1; i++)
        {
          for (int j = tempX - 1; j <= tempX + 1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)
        {
          minX = x;
          // FOV 검증을 위해 minx일때의 좌표 추출
          VerifyFOVInform[CameraIndex].minX = x;
          VerifyFOVInform[CameraIndex].fminX = y;
        }
        if(minY > y)minY = y;
        if(maxX < x)
        {
          maxX = x;
          // FOV 검증을 위해 maxX일때의 좌표 추출
          VerifyFOVInform[CameraIndex].maxX = x;
          VerifyFOVInform[CameraIndex].fmaxX = y;
        }
        if(maxY < y)maxY = y;
      }
    }
  }
  /*
  for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
        for (int i = y-1; i <= y+1; i++)
        {
          for (int j = x-1; j <= x+1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)
        {
          minX = x;
          // FOV 검증을 위해 minx일때의 좌표 추출
          VerifyFOVInform[CameraIndex].minX = x;
          VerifyFOVInform[CameraIndex].fminX = y;
        }
        if(minY > y)minY = y;
        if(maxX < x)
        {
          maxX = x;
          // FOV 검증을 위해 maxX일때의 좌표 추출
          VerifyFOVInform[CameraIndex].maxX = x;
          VerifyFOVInform[CameraIndex].fmaxX = y;
        }
        if(maxY < y)maxY = y;
			}
		}
	}

  minX *= 4;
  minY *= 4;
  maxX *= 4;
  maxY *= 4;
  */



  L1[CameraIndex] = minX - (startX);
  R1[CameraIndex] = (endX) - maxX;
  U1[CameraIndex] = minY - (startY);
  B1[CameraIndex] = (endY) - maxY;




  TTntLabel *LRVerifyLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(CameraIndex + 1) + "LRLabel");
  TTntLabel *UBVerifyLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(CameraIndex + 1) + "UBLabel");


  if(CameraIndex== 0 || CameraIndex == 8)  //정면의 경우만 상하 Position 확인
  {
    if(abs(U1[CameraIndex]-B1[CameraIndex]) > 20)   //상하
    {
      UBVerifyLabel->Canvas->Pen->Color = clRed;
      UBVerifyLabel->Caption = "X";
      NextCount[1][CameraIndex] = 0;
    }
    else
    {
      UBVerifyLabel->Canvas->Pen->Color = clLime;
      UBVerifyLabel->Caption = "O";
      NextCount[1][CameraIndex] = 1;
    }

    if(abs(L1[CameraIndex] - R1[CameraIndex]) > 20)    //좌우
    {
      LRVerifyLabel->Canvas->Pen->Color = clRed;
      LRVerifyLabel->Caption = "X";
      NextCount[0][CameraIndex] = 0;
    }
    else
    {
      LRVerifyLabel->Canvas->Pen->Color = clLime;
      LRVerifyLabel->Caption = "O";
      NextCount[0][CameraIndex] = 1;
    }
  }
  else
  {
    if(abs(L1[CameraIndex] - R1[CameraIndex]) > 20)    //좌우
    {
      LRVerifyLabel->Canvas->Pen->Color = clRed;
      LRVerifyLabel->Caption = "X";
      NextCount[0][CameraIndex] = 0;
    }
    else
    {
      LRVerifyLabel->Canvas->Pen->Color = clLime;
      LRVerifyLabel->Caption = "O";
      NextCount[0][CameraIndex] = 1;
    }

    UBVerifyLabel->Canvas->Pen->Color = clLime;
    UBVerifyLabel->Caption = "O";
    NextCount[1][CameraIndex] = 1;
  }


  // 어느쪽으로 치우쳐졌는지 사용자에게 알리기
  if(ActiveCameraNumber == 0 || ActiveCameraNumber == 8)
  {
    if(U1[ActiveCameraNumber] != 0 && B1[ActiveCameraNumber] != 0 && L1[ActiveCameraNumber] != 0 && R1[ActiveCameraNumber] != 0)
    {
      if(abs(U1[ActiveCameraNumber]-B1[ActiveCameraNumber]) > 20) // 정면의 경우 상하정렬 (Y축 정렬)까지 검사함 . 만약 정렬이안된 경우임
      {
        if(U1[ActiveCameraNumber]-B1[ActiveCameraNumber] > 0) // U1 > B1 이므로 아래쪽으로 치우쳐진 경우
        {
          UBEXLabel->Caption = "이미지에서 정제가 아래쪽으로 치우쳐져 있습니다. ";
        }
        else    // 위쪽으로 치우쳐진 경우
        {
          UBEXLabel->Caption = "이미지에서 정제가 위쪽으로 치우쳐져 있습니다. ";
        }
      }
      else
      {
        UBEXLabel->Caption = " ";
      }


      if(abs(L1[ActiveCameraNumber] - R1[ActiveCameraNumber]) > 20)// 좌우 정렬 (X축 정렬)이 안된경우
      {
        if((L1[ActiveCameraNumber] - R1[ActiveCameraNumber]) > 0 ) // L1이 더 크므로 오른쪽으로 치우쳐짐
        {
          LREXLabel->Caption = "이미지에서 정제가 오른쪽으로 치우쳐져 있습니다.";



        }
        else
        {
          LREXLabel->Caption = "이미지에서 정제가 왼쪽으로 치우쳐져 있습니다.";
        }
      }
      else
      {
        LREXLabel->Caption = " ";
      }
    }

  }
  else  // 측면카메라의 경우 좌우정렬만 확인
  {
    if(L1[ActiveCameraNumber] != 0 && R1[ActiveCameraNumber] != 0)
    {
      if(abs(L1[ActiveCameraNumber] - R1[ActiveCameraNumber]) > 20)   // 정렬안된경우
      {
        if((L1[ActiveCameraNumber] - R1[ActiveCameraNumber]) > 0 ) // L1이 더 크므로 오른쪽으로 치우쳐짐
        {
          LREXLabel->Caption = "이미지에서 정제가 오른쪽으로 치우쳐져 있습니다.";
        }
        else
        {
          LREXLabel->Caption = "이미지에서 정제가 왼쪽으로 치우쳐져 있습니다.";
        }
      }
      else
      {
        LREXLabel->Caption = " ";
      }
    }
  }



  //FOV 검증
  // ProductWidth : (maxX-minX) = FOV : ImageWidth
  // FOV = ProductWidth * ImageWidth / (maxX - minX)
  TTntLabel *FOVLabel = (TTntLabel *) FindComponent("FOV" + IntToStr(CameraIndex + 1));
  //TTntLabel *FOVValueLabel = (TTntLabel *) FindComponent("FOV" + IntToStr(CameraIndex + 1) + "Value" );
  if(CameraIndex == 0 || CameraIndex == 8 || CameraIndex == 2 || CameraIndex == 6 || CameraIndex == 10 || CameraIndex == 14 ) // 정면
  {
    VerifyFOVInform[CameraIndex].ProductWidth = StrToFloat(ProductWidthEdit->Text);
    VerifyFOVInform[CameraIndex].FOV = (VerifyFOVInform[CameraIndex].ProductWidth * ImageWidth) / (VerifyFOVInform[CameraIndex].maxX - VerifyFOVInform[CameraIndex].minX) + 0.5; // 반올림
    if(VerifyFOVInform[CameraIndex].FOV <= StrToInt(FovSize->Text) + 1 && VerifyFOVInform[CameraIndex].FOV >= StrToInt(FovSize->Text) - 1)
    {
      //FOVLabel->Font->Color  = clLime;
      FOVLabel->Caption = "O ( " + IntToStr(VerifyFOVInform[CameraIndex].FOV) + " )";
      NextCount[2][CameraIndex] = 1;
    }
    else
    {
      //FOVLabel->Font->Color  = 0x00004200;
      FOVLabel->Caption = "X ( " + IntToStr(VerifyFOVInform[CameraIndex].FOV) + " )";
      NextCount[2][CameraIndex] = 0;
    }

  }
  else if(CameraIndex == 1 || CameraIndex == 3 || CameraIndex == 5 || CameraIndex == 7 || CameraIndex == 9 || CameraIndex == 11 || CameraIndex == 13|| CameraIndex == 15) // 기울어진 경우
  {
    VerifyFOVInform[CameraIndex].ProductHeight = StrToFloat(ProductHeightEdit->Text);
    double ProductWidth = StrToFloat(ProductWidthEdit->Text);
    double ProductHeight = StrToFloat(ProductHeightEdit->Text);

    double whwh = sqrt( (ProductWidth * ProductWidth) + (ProductHeight * ProductHeight) );  // 실제 정제의 대각선 길이

    double distance = sqrt( (VerifyFOVInform[CameraIndex].maxX - VerifyFOVInform[CameraIndex].minX)*(VerifyFOVInform[CameraIndex].maxX - VerifyFOVInform[CameraIndex].minX)
    + (VerifyFOVInform[CameraIndex].fmaxX - VerifyFOVInform[CameraIndex].fminX)*(VerifyFOVInform[CameraIndex].fmaxX - VerifyFOVInform[CameraIndex].fminX) );             // 이미지에서 대각선 길이 픽셀수


    // 실제 정제의 대각선 길이 : 이미지에서 대각선길이 = FOV(x) : 이미지 Width
    // whwh : distance = FOV : Width 공식을 적용하여 아래 식이 나옴

    VerifyFOVInform[CameraIndex].FOV = ((ImageWidth * whwh) / distance ) + 0.5;


   // int WHWH;
   // WHWH = int(whwh);
    if(VerifyFOVInform[CameraIndex].FOV <= StrToInt(FovSize->Text) + 1 && VerifyFOVInform[CameraIndex].FOV >= StrToInt(FovSize->Text) - 1)
    {
      //FOVLabel->Font->Color = clLime;
      FOVLabel->Caption = "O ( " + IntToStr(VerifyFOVInform[CameraIndex].FOV) + " )";
      NextCount[2][CameraIndex] = 1;
    }
    else
    {
      //FOVLabel->Font->Color = 0x00004200;
      FOVLabel->Caption = "X ( " + IntToStr(VerifyFOVInform[CameraIndex].FOV) + " )";
      NextCount[2][CameraIndex] = 0;
    }
  }

 // FOVValueLabel->Caption = "( " + IntToStr(VerifyFOVInform[CameraIndex].FOV) + " )";


  // 표값 확인
  int Check = 0;
  int startP, endP;
  if(stepSW == FirstDiskStart)
  {
    startP = 0;
    endP = 9;
  }
  else if (stepSW == SecondDiskStart)
  {
    startP = 8;
    endP = 16;
  }
  for(int k = 0; k < 5; k++)
  {
    for(int p = startP; p < endP; p++)
    {
      if(NextCount[k][p] == 1)
      {
        Check++;
      }
    }
  }

  if(Check == 30) // 모두 "O"를 띄움
  {
    //VerifyOkButton->Enabled = true;
    if(stepSW == FirstDiskStart)
    {
      StartButton1->Caption = "다음";
      StartButton1->Enabled = true;
      stepSW = FirstDiskValueSet;
    }
    else if(stepSW = SecondDiskStart)
    {
      StartButton1->Caption = "다음";
      StartButton1->Enabled = true;
      stepSW = SecondDiskValueSet;
    }

  }





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


void __fastcall TTwoDCalibrationGuideForm::CameraImage1Click(
      TObject *Sender)
{
  TTntImage *tempImage = (TTntImage *) Sender;
  ActiveCameraNumber = tempImage->Tag;
  ActiveCameraImage = tempImage;

  TTntLabel *SelectLabel;
  SelectLabel = (TTntLabel *) FindComponent("CamLabel" + IntToStr(ActiveCameraNumber+1));

  for(int i = 0; i < 16; i++)
  {
    if(i != ActiveCameraNumber)
    {
      if(i != 4 && i!= 12)
      {
        TTntLabel *UnSelectLabel;
        UnSelectLabel = (TTntLabel *) FindComponent("CamLabel" + IntToStr(i+1));

        UnSelectLabel->Font->Color = clCream;

        UnSelectLabel->Refresh();
      }
    }
    SelectLabel->Font->Color = clRed;
    SelectLabel->Refresh();
  }



  /*
  if(!ActiveCameraSW)
  {
    ActiveCameraSW = 1;
    BeforeSW = ActiveCameraNumber;
    ActiveCameraImage->Canvas->Pen->Width = 1;

    ActiveCameraImage->Canvas->Pen->Color = clRed;
    ActiveCameraImage->Canvas->Brush->Style = bsClear;
    ActiveCameraImage->Canvas->Rectangle(0,0,ActiveCameraImage->Width,ActiveCameraImage->Height);
    ActiveCameraImage->Repaint();
  }

  else
  {
    //이전 선택된 이미지의 테두리 지우기 //
    TTntImage *DestImage;
    DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(BeforeSW + 1));

    DestImage->Canvas->Pen->Width = 1;
    DestImage->Canvas->Pen->Color = clAqua;
    DestImage->Canvas->Brush->Style = bsClear;
    DestImage->Canvas->Rectangle(0,0,DestImage->Width,DestImage->Height);
    DestImage->Repaint();


    ActiveCameraImage->Canvas->Pen->Width = 1;
    ActiveCameraImage->Canvas->Pen->Color = clRed;
    ActiveCameraImage->Canvas->Brush->Style = bsClear;
    ActiveCameraImage->Canvas->Rectangle(0,0,ActiveCameraImage->Width,ActiveCameraImage->Height);
    ActiveCameraImage->Repaint();
    BeforeSW = ActiveCameraNumber;

  }
  */
 // memset(GradeCheck,0,10);
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::FirstDiskSelectImageMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  // 클릭한좌표를 해당카메라의 센터 좌표로 저장
  CenterPosition[ActiveCameraNumber].CenterX = X;
  CenterPosition[ActiveCameraNumber].CenterY = Y;



  // 정제를 라벨링하여 정제에서 Center좌표가 어디 위치하는지 정보를 추출한다.
  // 알파와 베타를 추출
  if(stepSW != NoneStart)
  {
    FindAlpa(ActiveCameraNumber);
  }  
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::SecondDiskSelectImageMouseDown(
      TObject *Sender, TMouseButton Button, TShiftState Shift, int X,
      int Y)
{
  // 클릭한좌표를 해당카메라의 센터 좌표로 저장
  CenterPosition[ActiveCameraNumber].CenterX = X;
  CenterPosition[ActiveCameraNumber].CenterY = Y;

  // 클릭한 센터좌표의 G값을 띄움
 
  // 정제를 라벨링하여 정제에서 Center좌표가 어디 위치하는지 정보를 추출한다.
  // 알파와 베타를 추출
  FindAlpa(ActiveCameraNumber);
}
//---------------------------------------------------------------------------

void __fastcall TTwoDCalibrationGuideForm::GradeGVerify(int globalCameraIndex)
{
  int avgGGrade = 0;
  TTntLabel *GradeGLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(globalCameraIndex + 1) + "GradeLabel");
  TTntLabel *GradeGValueLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(globalCameraIndex + 1) + "GradeValueLabel");

  if(GradeCheckNum[globalCameraIndex] != GGradeCount)
  {
    GradeCheck[globalCameraIndex][GradeCheckNum[globalCameraIndex]] = CheckgreenVal;


    GradeCheckNum[globalCameraIndex]++;
  }
  else  // GradeCheckNum == GGradeCount일 경우
  {
    for(int k = 0; k < GGradeCount; k++)
    {
       avgGGrade += GradeCheck[globalCameraIndex][k];
    }

    avgGGrade = avgGGrade / GGradeCount;

    GradeGValueLabel->Caption = IntToStr(avgGGrade);

    if(avgGGrade > 97 && avgGGrade < 103)
    {
      GradeGLabel->Caption = "O ( " + IntToStr(avgGGrade) + " )";
      NextCount[3][globalCameraIndex] = 1;
      GradeNext[globalCameraIndex] = 1;
    }
    else
    {
      GradeGLabel->Caption = "X ( " + IntToStr(avgGGrade) + " )";
      NextCount[3][globalCameraIndex] = 0;
      GradeNext[globalCameraIndex] = 0;
    }
    GradeCheckNum[globalCameraIndex] = 0;
  }
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::FindAlpa(int ActivCameraNumber)
{
  int x,y;

  byte *ptr;
  int tempAddress ;
  int protoThreshold = 80;
  int startX, endX, startY, endY;
  unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];
  short smallSizeLabelImage[(640 / 4)*(480 / 4)];
  int smallSizeImagWidth;
  int ImageWidth, ImageHeight;
  int maxLabelN;
  int minX,minY,maxX,maxY;
  int L1,R1,B1,U1;
  int SumX,SumY,SumCount;
  int CenterX,CenterY;
  int CameraIndex;


  SumX = SumY = SumCount = 0;
  minX = minY = 100000;
  maxX = maxY = 0;
  startX = 10;
  endX = 640 - 10;
  startY = 10;
  endY = 480 - 10;
  ImageWidth = 640;
  ImageHeight = 480;
  smallSizeImagWidth = ImageWidth / 4;

  memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);
  memset(ColorSourceImage,0, 640*480*3);


  TTntImage *DestImage;
  if (ImageLoadType == FIRSTDISK)DestImage = (TTntImage *) FirstDiskSelectImage;
  else if(ImageLoadType == SECONDDISK)DestImage = (TTntImage *) SecondDiskSelectImage;

  for (y = 0; y < 480; y++)
  {
    ptr = (Byte*)DestImage->Picture->Bitmap->ScanLine[y];
    for (x = 0; x < 640; x++)
    {
      tempAddress = 640 * y + x;
      ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
      ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
      ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];

    }
  }
  //ch

  // calibration에서 사용할때는, 흰색정제를 이용하므로 임계값을 러프하게 설정하여도 배경과 구분이 될 수있을거라 예상.
  for (int y = startY; y < endY; y++)
  {
    for (int x = startX; x < endX; x++)
    {
      if (*(ColorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 0) > protoThreshold)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
    }
  }

  maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);

  minX = minY = 100000;
  maxX = maxY = 0;

  /*
  for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
  {
    for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
    {
      if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
      {
        for (int i = y - 1; i <= y + 1; i++)
        {
          for (int j = x - 1; j <= x + 1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
      }
    }
  }

  minX *= 4;
  minY *= 4;
  maxX *= 4;
  maxY *= 4;
  */

  int tempX, tempY;
  for (int y = startY + 1; y < endY - 1; y++)
  {
    for (int x = startX + 1; x < endX - 1; x++)
    {
      tempX = x / 4;
      tempY = y / 4;

      if (smallSizeLabelImage[(tempY) * smallSizeImagWidth + (tempX)] == maxLabelN)
      {
        for (int i = tempY - 1; i <= tempY + 1; i++)
        {
          for (int j = tempX - 1; j <= tempX + 1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
      }
    }
  }


  startX = minX;
  startY = minY;
  endX = maxX;
  endY = maxY;


  // 라벨링된 영역을 나타내주는 작업
  /*

  DestImage->Canvas->Pen->Color = clYellow;

  DestImage->Canvas->MoveTo(startX,startY);
  DestImage->Canvas->LineTo(endX,startY) ;            // ㅡ
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(startX,startY);
  DestImage->Canvas->LineTo(startX,endY) ;         // ㅣ
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(startX,endY);        // ㅡ
  DestImage->Canvas->LineTo(endX,endY) ;
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(endX,startY);    // ㅣ
  DestImage->Canvas->LineTo(endX,endY) ;
  DestImage->Refresh();

  */

  alpa = CenterPosition[ActiveCameraNumber].CenterX - minX;
  beta = CenterPosition[ActiveCameraNumber].CenterY - minY;

  XD = maxX - minX;
  YD = maxY - minY;


  CenterPosition[ActiveCameraNumber].XD = XD;
  CenterPosition[ActiveCameraNumber].YD = YD;

  CenterPosition[ActiveCameraNumber].Alpa = alpa;
  CenterPosition[ActiveCameraNumber].Beta = beta;




}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::TrackCenterPosition(int ActiveCamerNumaber)
{
  int x,y;

  byte *ptr;
  int tempAddress ;
  int protoThreshold = 80;
  int startX, endX, startY, endY;
  unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];
  short smallSizeLabelImage[(640 / 4)*(480 / 4)];
  int smallSizeImagWidth;
  int ImageWidth, ImageHeight;
  int maxLabelN;
  int minX,minY,maxX,maxY;
  int L1,R1,B1,U1;
  int SumX,SumY,SumCount;
  int CenterX,CenterY;
  int CameraIndex;


  SumX = SumY = SumCount = 0;
  minX = minY = 100000;
  maxX = maxY = 0;
  startX = 10;
  endX = 640 - 10;
  startY = 10;
  endY = 480 - 10;
  ImageWidth = 640;
  ImageHeight = 480;
  smallSizeImagWidth = ImageWidth / 4;

  memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);
  memset(ColorSourceImage,0, 640*480*3);


  TTntImage *DestImage;
  if (ImageLoadType == FIRSTDISK)DestImage = (TTntImage *) FirstDiskSelectImage;
  else if(ImageLoadType == SECONDDISK)DestImage = (TTntImage *) SecondDiskSelectImage;

  for (y = 0; y < 480; y++)
  {
    ptr = (Byte*)DestImage->Picture->Bitmap->ScanLine[y];
    for (x = 0; x < 640; x++)
    {
      tempAddress = 640 * y + x;
      ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
      ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
      ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];
    }
  }
  //ch

  // calibration에서 사용할때는, 흰색정제를 이용하므로 임계값을 러프하게 설정하여도 배경과 구분이 될 수있을거라 예상.
  for (int y = startY; y < endY; y++)
  {
    for (int x = startX; x < endX; x++)
    {
      if (*(ColorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 0) > protoThreshold)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
    }
  }

  maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);

  minX = minY = 100000;
  maxX = maxY = 0;

  // test1 라벨링후 min좌표 찾는과정에서 영역범위 달라짐

  int tempX, tempY;
  for (int y = startY + 1; y < endY - 1; y++)
  {
    for (int x = startX + 1; x < endX - 1; x++)
    {
      tempX = x / 4;
      tempY = y / 4;

      if (smallSizeLabelImage[(tempY) * smallSizeImagWidth + (tempX)] == maxLabelN)
      {
        for (int i = tempY - 1; i <= tempY + 1; i++)
        {
          for (int j = tempX - 1; j <= tempX + 1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
      }
    }
  }

  /*

  for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
        for (int i = y-1; i <= y+1; i++)
        {
          for (int j = x-1; j <= x+1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
			}
		}
	}

  minX *= 4;
  minY *= 4;
  maxX *= 4;
  maxY *= 4;
  */


  startX = minX;
  startY = minY;
  endX = maxX;
  endY = maxY;


  /*
  // test 2 라벨링된 영역을 표시해주는 작업

  DestImage->Canvas->Pen->Color = clYellow;
  DestImage->Canvas->MoveTo(startX,startY);
  DestImage->Canvas->LineTo(endX,startY) ;            // ㅡ
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(startX,startY);
  DestImage->Canvas->LineTo(startX,endY) ;         // ㅣ
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(startX,endY);        // ㅡ
  DestImage->Canvas->LineTo(endX,endY) ;
  DestImage->Refresh();

  DestImage->Canvas->MoveTo(endX,startY);    // ㅣ
  DestImage->Canvas->LineTo(endX,endY) ;
  DestImage->Refresh();

  */


  YD2 = maxY - minY;
  XD2 = maxX - minX;

  CenterPosition[ActiveCameraNumber].YD2 = YD2;
  CenterPosition[ActiveCameraNumber].XD2 = XD2;


  CenterPosition[ActiveCameraNumber].TestAlpa = (CenterPosition[ActiveCameraNumber].Alpa * CenterPosition[ActiveCameraNumber].XD2) / CenterPosition[ActiveCameraNumber].XD;
  CenterPosition[ActiveCameraNumber].TestBeta = (CenterPosition[ActiveCameraNumber].Beta * CenterPosition[ActiveCameraNumber].YD2) / CenterPosition[ActiveCameraNumber].YD;

  CenterPosition[ActiveCameraNumber].CenterX = minX + CenterPosition[ActiveCameraNumber].TestAlpa;
  CenterPosition[ActiveCameraNumber].CenterY = minY + CenterPosition[ActiveCameraNumber].TestBeta;


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::StartButton1Click(TObject *Sender)
{
  // 시작
  memset(L1, 0, sizeof(L1));
  memset(R1, 0, sizeof(R1));
  memset(U1, 0, sizeof(U1));
  memset(B1, 0, sizeof(B1));

  if(stepSW == NoneStart)
  {
    stepSW = FirstDiskStart;

    EPanel->Caption = "1번디스크 카메라의 센터좌표를 지정하여 밝기, 위치, 초점을 조절하여 검증결과표를 완성하십시오." ;

    // 결과표 1번 Disk로 띄우기
    PositionVerifyGroupBox1->BringToFront();
    PositionVerifyGroupBox2->SendToBack();

    // 1번 디스크 카메라 이미지 Sheet
    FirstDiskPanel->BringToFront();
    SecondDiskPanel->SendToBack();
    RGBValueBox->BringToFront();
    UBLREXPanel->BringToFront();

    Disk1SpeedButton->Enabled = true;
    Disk1SpeedButton->Down = true;

    Disk2SpeedButton->Enabled = true;
    Disk2SpeedButton->Down = false;

    ShowGuideLine->Enabled = true;
    CloseButton->Enabled = true;
    // 석션 1 ON
    try
	  {
		  int blowerIndex = 0;
		  int speed1 = MachineControlParams.SuctionDisk1InverterSpeed;
		  int speed2 = MachineControlParams.SuctionDisk2InverterSpeed;

	  	Machine.RingBlowerOn(blowerIndex, speed1, speed2);
	  }
	  catch (Exception &ec)
	  {
		  ShowMessageFA(ec.Message);
	  }


    //1번 디스크 카메라 CaptureStart
    ImageLoadType = FIRSTDISK;
    InitCaptureComponent();  // ImageLoadType에 따라 Init

    if (SendSPBCaptureSetup())
    {
      TCaptureCommandParam_HCB captureCommandParam_HCB;
      captureCommandParam_HCB.Action = 1;
      captureCommandParam_HCB.FrameTime = 100 * 20 + 0.5; //StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.LEDMask[0] = LEDOnMask[0];//0x00FFFFFF;
      captureCommandParam_HCB.LEDOnTime[0] = 13 * 20 + 0.5; //StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.ShutterDelay = 1 * 20 + 0.5; //StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
      if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
        NULL, 0))
      {
       if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) DiskImageLoadTimer->Enabled = true;
        StartButton1->Enabled = false;

      }
    }
  }

  else if (stepSW == FirstDiskValueSet)
  {
    panelCount = 0;
    ProcessingPanel->Visible = true;
    ProcessingPanel->BringToFront();

    // RGB AUTO PROCESSING 에는 DISK 선택 못하도록 막음
    Disk1SpeedButton->Enabled = false;
    Disk2SpeedButton->Enabled = false;
    ShowGuideLine->Enabled = false;
    CloseButton->Enabled = false;

    EPanel->Caption = "카메라별 WhiteBalance 자동 설정중입니다. " ;
    //우선 DiskImageLoadTimer를 통한 Capture를 정지
    TCaptureCommandParam_HCB captureCommandParam_HCB;
    captureCommandParam_HCB.Action = 0;

    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
      }
    }

    if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
      NULL, 0))
    {
    }

    if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) DiskImageLoadTimer->Enabled = false;

    Sleep(3000);


    for(int g = 0; g < 8; g++)
    {
      if(g != 4)
      {
        TTntLabel *GradeGValueLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(g + 1) + "GradeValueLabel");
        GreenValue[g] = StrToInt(GradeGValueLabel->Caption);
      }
    }

    // ValueSetTimer를 통해 Capture 재시작

    InitCaptureComponent();  // ImageLoadType에 따라 Init
    if (SendSPBCaptureSetup())
    {
      TCaptureCommandParam_HCB captureCommandParam_HCB;
      captureCommandParam_HCB.Action = 1;
      captureCommandParam_HCB.FrameTime = 100 * 20 + 0.5; //StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.LEDMask[0] = LEDOnMask[0];//0x00FFFFFF;
      captureCommandParam_HCB.LEDOnTime[0] = 13 * 20 + 0.5; //StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.ShutterDelay = 1 * 20 + 0.5; //StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
      if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
        NULL, 0))
      {

        if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK)
        {
          ValueSetTimer->Enabled = true;
          memset(RVChangeSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          memset(BVChangeSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          memset(RFinalValueSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          memset(BFinalValueSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          StartButton1->Enabled = false;
        }

      }
    }


  }

  else if (stepSW == SecondDiskStart)
  {
    // 다음으로 표시되어있는 버튼을 클릭함 - > 결과표의 OK는 다시 비활성화 되어야함
    //VerifyOkButton->Enabled = false;
    // 결과표 2번 Disk로 띄우기
    ProcessingPanel->Visible = false;
    Label100->Caption = "Processing..";
    for(int x = 5; x<19; x++)
    {
      TTntPanel *PRPanel;
      PRPanel = (TTntPanel *) FindComponent("TntPanel" + IntToStr(x));
      PRPanel->Visible = false;
    }

    Disk1SpeedButton->Enabled = true;
    Disk1SpeedButton->Down = false;

    Disk2SpeedButton->Enabled = true;
    Disk2SpeedButton->Down = true;

    ShowGuideLine->Enabled = true;
    CloseButton->Enabled = true;

    EPanel->Caption = "2번디스크 카메라의 센터좌표를 지정하여 밝기, 위치, 초점을 조절하여 검증결과표를 완성하십시오." ;

    PositionVerifyGroupBox1->SendToBack();
    PositionVerifyGroupBox2->BringToFront();

    // 2번 디스크 카메라 이미지 Sheet
    FirstDiskPanel->SendToBack();
    SecondDiskPanel->BringToFront();
    RGBValueBox->BringToFront();
    UBLREXPanel->BringToFront();

    // 석션 1 OFF
    int blowerIndex = 0;
	  Machine.RingBlowerOff(blowerIndex);

    TCaptureCommandParam_HCB captureCommandParam_HCB;
    captureCommandParam_HCB.Action = 0;

    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
      }
    }

    if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
      NULL, 0))
    {
    }

    if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) ValueSetTimer->Enabled = false;

    Sleep(3000);

    // 석션 2 ON
    try
	  {
		  int blowerIndex = 1;
		  int speed1 = MachineControlParams.SuctionDisk1InverterSpeed;
		  int speed2 = MachineControlParams.SuctionDisk2InverterSpeed;

	  	Machine.RingBlowerOn(blowerIndex, speed1, speed2);
	  }
	  catch (Exception &ec)
	  {
		  ShowMessageFA(ec.Message);
	  }

    //2번 디스크 카메라 CaptureStart
    ImageLoadType = SECONDDISK;
    InitCaptureComponent();  // ImageLoadType에 따라 Init

    if (SendSPBCaptureSetup())
    {
      TCaptureCommandParam_HCB captureCommandParam_HCB;
      captureCommandParam_HCB.Action = 1;
      captureCommandParam_HCB.FrameTime = 100 * 20 + 0.5; //StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.LEDMask[0] = LEDOnMask[8];//0x00FFFFFF;
      captureCommandParam_HCB.LEDOnTime[0] = 13 * 20 + 0.5; //StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.ShutterDelay = 1 * 20 + 0.5; //StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
      if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
        NULL, 0))
      {

        if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) DiskImageLoadTimer->Enabled = true;
        StartButton1->Enabled = false;

      }
    }
    
  }

  else if (stepSW == SecondDiskValueSet)
  {
    EPanel->Caption = "카메라별 WhiteBalance 자동 설정중입니다.";

    panelCount = 0;
    ProcessingPanel->Visible = true;
    ProcessingPanel->BringToFront();


    // RGB AUTO PROCESSING 에는 DISK 선택 못하도록 막음
    Disk1SpeedButton->Enabled = false;
    Disk2SpeedButton->Enabled = false;
    ShowGuideLine->Enabled = false;
    CloseButton->Enabled = false;


    //우선 DiskImageLoadTimer를 통한 Capture를 정지
    TCaptureCommandParam_HCB captureCommandParam_HCB;
    captureCommandParam_HCB.Action = 0;

    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
      }
    }

    if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
      NULL, 0))
    {
    }

    if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) DiskImageLoadTimer->Enabled = false;

    Sleep(3000);

    for(int g = 8; g < 16; g++)
    {
      if(g != 12)
      {
        TTntLabel *GradeGValueLabel = (TTntLabel *) FindComponent("Cam" + IntToStr(g + 1) + "GradeValueLabel");
        GreenValue[g] = StrToInt(GradeGValueLabel->Caption);
      }
    }


    // ValueSetTimer를 통해 Capture 재시작

    InitCaptureComponent();  // ImageLoadType에 따라 Init
    if (SendSPBCaptureSetup())
    {
      TCaptureCommandParam_HCB captureCommandParam_HCB;
      captureCommandParam_HCB.Action = 1;
      captureCommandParam_HCB.FrameTime = 100 * 20 + 0.5; //StrToFloat(FrameTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.LEDMask[0] = LEDOnMask[8];//0x00FFFFFF; 
      captureCommandParam_HCB.LEDOnTime[0] = 13 * 20 + 0.5; //StrToFloat(LedOnTimeEdit->Text) * 20 + 0.5;
      captureCommandParam_HCB.ShutterDelay = 1 * 20 + 0.5; //StrToFloat(ShutterDelayEdit->Text) * 20 + 0.5;
      if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
        NULL, 0))
      {

        if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK)
        {
          ValueSetTimer->Enabled = true;
          memset(RVChangeSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          memset(BVChangeSW, 0, SYSTEM_TOTAL_CAMERA_COUNT);
          StartButton1->Enabled = false;
        }

      }
    }


  }


  else if(stepSW == Final)
  {
    EPanel->Caption = "2D Calibration작업이 완료되었습니다. ";
    StartButton1->Caption = "완료";

    ShowGuideLine->Enabled = true;
    CloseButton->Enabled = true;

    // 2 번석션디스크  OFF
    int blowerIndex = 1;
	  Machine.RingBlowerOff(blowerIndex);
    TCaptureCommandParam_HCB captureCommandParam_HCB;
    captureCommandParam_HCB.Action = 0;

    for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;

      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));
      }
    }

    if (Comm_Request(COMM_HCB, CMD_TABLET_CAPTURE, &captureCommandParam_HCB, sizeof(TCaptureCommandParam_HCB),
      NULL, 0))
    {
    }

    if(ImageLoadType == FIRSTDISK || ImageLoadType == SECONDDISK) DiskImageLoadTimer->Enabled = false;

  }


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::HorizontalVerification(int globalCameraIndex)
{
    // 수평 확인
  int x,y;

  byte *ptr;
  int tempAddress ;
  int protoThreshold = 80;
  int startX, endX, startY, endY;
  unsigned char smallSizeBinaryImage[(640 / 4)*(480 / 4)];
  short smallSizeLabelImage[(640 / 4)*(480 / 4)];
  int smallSizeImagWidth;
  int ImageWidth, ImageHeight;
  int maxLabelN;
  int minX,minY,maxX,maxY;
  int L1,R1,B1,U1;
  int SumX,SumY,SumCount;
  int CenterX,CenterY;
  int CameraIndex;
  int EdgeMinX,EdgeMaxX;
  int EdgeMinXDistance, EdgeMaxXDistance;


  SumX = SumY = SumCount = 0;
  minX = minY = 100000;
  maxX = maxY = 0;
  startX = 10;
  endX = 640 - 10;
  startY = 10;
  endY = 480 - 10;
  ImageWidth = 640;
  ImageHeight = 480;
  smallSizeImagWidth = ImageWidth / 4;


  memset(smallSizeBinaryImage, 0, (ImageWidth / 4)*(ImageHeight / 4));
	memset(smallSizeLabelImage, 0, (ImageWidth / 4)*(ImageHeight / 4) * 2);
  memset(ColorSourceImage,0, 640*480*3);


  TTntImage *DestImage;
  DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));
 // if (ImageLoadType == FIRSTDISK)DestImage = (TTntImage *) FirstDiskSelectImage;
 // else if(ImageLoadType == SECONDDISK)DestImage = (TTntImage *) SecondDiskSelectImage;

  for (y = 0; y < 480; y++)
  {
    ptr = (Byte*)DestImage->Picture->Bitmap->ScanLine[y];
    for (x = 0; x < 640; x++)
    {
      tempAddress = 640 * y + x;
      ColorSourceImage[tempAddress * 3 + 0] = ptr[3 * x + 0];
      ColorSourceImage[tempAddress * 3 + 1] = ptr[3 * x + 1];
      ColorSourceImage[tempAddress * 3 + 2] = ptr[3 * x + 2];
    }
  }
  //ch

  // calibration에서 사용할때는, 흰색정제를 이용하므로 임계값을 러프하게 설정하여도 배경과 구분이 될 수있을거라 예상.
  for (int y = startY; y < endY; y++)
  {
    for (int x = startX; x < endX; x++)
    {
      if (*(ColorSourceImage + (ImageWidth*y + x) * 3 + 1) > protoThreshold && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 2) > protoThreshold
        && *(ColorSourceImage + (ImageWidth*y + x) * 3 + 0) > protoThreshold)
        smallSizeBinaryImage[smallSizeImagWidth*(y / 4) + x / 4] = 1;
    }
  }

  maxLabelN = LabellingForTabletImage(smallSizeLabelImage, smallSizeBinaryImage, startX / 4, endX / 4, startY / 4, endY / 4, ImageWidth / 4, ImageHeight / 4);

  minX = minY = 100000;
  maxX = maxY = 0;


  int tempX, tempY;
  for (int y = startY + 1; y < endY - 1; y++)
  {
    for (int x = startX + 1; x < endX - 1; x++)
    {
      tempX = x / 4;
      tempY = y / 4;
      tempAddress = 640 * y + x;
      if (smallSizeLabelImage[(tempY) * smallSizeImagWidth + (tempX)] == maxLabelN)
      {
        for (int i = tempY - 1; i <= tempY + 1; i++)
        {
          for (int j = tempX - 1; j <= tempX + 1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
            if(smallSizeLabelImage[smallSizeImagWidth*(i)+j] != maxLabelN)
            {
              EdgeArea[tempAddress] = 1;

            }
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
      }
    }
  }

 /*
  for (int y = startY / 4 + 1; y < endY / 4 - 1; y++)
	{
		for (int x = startX / 4 + 1; x < endX / 4 - 1; x++)
		{
      tempAddress = 640 * (y*4) + (x*4);
			if (smallSizeLabelImage[(y)*smallSizeImagWidth + (x)] == maxLabelN)
			{
        for (int i = y-1; i <= y+1; i++)
        {
          for (int j = x-1; j <= x+1; j++)
          {
            smallSizeBinaryImage[smallSizeImagWidth*(i)+j] = 2;
            if(smallSizeLabelImage[smallSizeImagWidth*(i)+j] != maxLabelN)
            {
              EdgeArea[tempAddress] = 1;
            }
          }
        }
        if(minX > x)minX = x;
        if(minY > y)minY = y;
        if(maxX < x)maxX = x;
        if(maxY < y)maxY = y;
			}
		}
	}
  minX *= 4;
  minY *= 4;
  maxX *= 4;
  maxY *= 4;
  */


  startX = minX;
  startY = minY;
  endX = maxX;
  endY = maxY;



  CenterX = (maxX + minX) / 2 ;

  int Incline = 0;
  EdgeMinX = 10000;
  EdgeMaxX = 0;


  for(int y = startY + 1; y < endY - 1; y++)
  {
    for(int x = startX + 1; x < endX - 1; x++)
    {
      tempAddress = MAX_IMAGE_WIDTH * y + x;
      if(EdgeArea[tempAddress]) // (x) for문이 끝나면 ㅡ 수평으로 검사
      {
        if(EdgeMinX > x) EdgeMinX = x;
        if(EdgeMaxX < x) EdgeMaxX = x;
      }
    }

    EdgeMinXDistance = CenterX - EdgeMinX;
    EdgeMaxXDistance = EdgeMaxX - CenterX;

    if(abs(EdgeMinXDistance - EdgeMaxXDistance) > 20) // 5픽셀 이상 차이나면 수평이 안맞는걸로 정의
    {
      Incline++;
    }

  }


  TTntLabel *InclineLabel = (TTntLabel *) FindComponent("InclineLabel" + IntToStr(globalCameraIndex + 1));


  if(Incline > (maxY - minY) * 0.1) // 10%이상 수평이 안맞다면
  {
    InclineLabel->Caption = "X";
    NextCount[4][globalCameraIndex] = 0;
  }

  else
  {
    InclineLabel->Caption = "O";
    NextCount[4][globalCameraIndex] = 1;
    InclineCheck[globalCameraIndex] = 1;
  }




}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::PixelInformation(int X, int Y, int CameraNumber)
{
  TTntImage *DestImage;
  DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(CameraNumber + 1));
  int RedVal;
  int BlueVal;

  RedVal = 0;
  BlueVal = 0;
  for(int i = -1; i <= 1; i++)
  {
    for(int j = -1; j <= 1; j++)
    {
      TColor color = DestImage->Canvas->Pixels[X+i][Y+j];
      RedVal += color & 0xFF;
      BlueVal += (color >> 16) & 0xFF;
    }
  }

  CheckRedVal[CameraNumber] = RedVal / 9;
  CheckBlueVal[CameraNumber] = BlueVal / 9;


  if(CheckRedVal[CameraNumber] >= GreenValue[CameraNumber])
  {
    RDownSW[CameraNumber] = 1;
    RUpSW[CameraNumber] = 0;
    if(!RVChangeSW[CameraNumber])
    {
      RValueChangeSW[CameraNumber] = DOWNSW;
      RVChangeSW[CameraNumber] = 1;
    }
  }
  else
  {
    RDownSW[CameraNumber] = 0;
    RUpSW[CameraNumber] = 1;
    if(!RVChangeSW[CameraNumber])
    {
      RValueChangeSW[CameraNumber] = UPSW;
      RVChangeSW[CameraNumber] = 1;
    }
  }


  if(CheckBlueVal[CameraNumber] >= GreenValue[CameraNumber])
  {
    BDownSW[CameraNumber] = 1;
    BUpSW[CameraNumber] = 0;
    if(!BVChangeSW[CameraNumber])
    {
      BValueChangeSW[CameraNumber] = DOWNSW;
      BVChangeSW[CameraNumber] = 1;
    }
  }
  else
  {
    BDownSW[CameraNumber] = 0;
    BUpSW[CameraNumber] = 1;
    if(!BVChangeSW[CameraNumber])
    {
      BValueChangeSW[CameraNumber] = UPSW;
      BVChangeSW[CameraNumber] = 1;
    }
  }


}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::SetRedValue(int Value, int CamIndex)
{
  int WhiteBalanceValue;
  WhiteBalanceValue = Value;
  WhiteBalanceInfo[CamIndex].RColorInfo = Value;
  SetWhiteBalanceValue(WhiteBalanceValue, 2);
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  WriteCameraWhiteBalanceColorInfo(fileName, CamIndex, 2);
  WhiteBalanceRValueEdit->Text = IntToStr(WhiteBalanceRValue->Position);
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::SetBlueValue(int Value, int CamIndex)
{
  int WhiteBalanceValue;
  WhiteBalanceValue = Value;
  WhiteBalanceInfo[CamIndex].BColorInfo = Value;
  SetWhiteBalanceValue(WhiteBalanceValue, 0);
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  WriteCameraWhiteBalanceColorInfo(fileName, CamIndex, 0);
  WhiteBalanceBValueEdit->Text = IntToStr(WhiteBalanceBValue->Position);
}
//---------------------------------------------------------------------------
void __fastcall TTwoDCalibrationGuideForm::ValueSetTimerTimer(
      TObject *Sender)
{
  bool bCaptureExist;
	unsigned int data[2];
	unsigned int receivedData[2];
  int startCameraIndex, endCameraIndex;
  bool timerEnalbed = ValueSetTimer->Enabled;

  ValueSetTimer->Enabled = false;

  if(ImageLoadType == FIRSTDISK)
  {
    //0~7 = 1~8번 카메라
    startCameraIndex = 0;
    endCameraIndex = 8;
  }
  else if(ImageLoadType == SECONDDISK)
  {
    //8~15 = 9~16 카메라
    startCameraIndex = 8;
    endCameraIndex = 16;
  }

  for(int globalCameraIndex = startCameraIndex; globalCameraIndex < endCameraIndex; globalCameraIndex++)
  {
    if(globalCameraIndex != 4 && globalCameraIndex != 12)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
      data[0] = camIndex;

      try
      {
        if (Comm_IsConnected(COMM_SPB + spbIndex))
        {
          if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
            receivedData, sizeof(unsigned int) * 2))
          {

          }

          if (receivedData[0])
          {
            bCaptureExist = true;
          }

          else
          {
            bCaptureExist = false;
          }

          if (bCaptureExist)
          {
            data[1] = MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT;
            if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
              CaptureData, MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT))
            {

            }
            TTntImage *DestImage;
            DestImage = (TTntImage *) FindComponent("CAMImage" + IntToStr(globalCameraIndex + 1));

            if(RVChangeSW[globalCameraIndex] == 0) // R초기값
            {
              RValue[globalCameraIndex] = 1600;
            }
            if(BVChangeSW[globalCameraIndex] == 0)  // B초기값
            {
              BValue[globalCameraIndex] = 1600;
            }

            //Value값에따라 Write해줌
            if(!RFinalValueSW[globalCameraIndex])    // 결정된 RValue값이 없을때만 다시 Set
            {
              SetRedValue(RValue[globalCameraIndex],globalCameraIndex);
            }
            if(!BFinalValueSW[globalCameraIndex])
            {
              SetBlueValue(BValue[globalCameraIndex],globalCameraIndex);
            }

            AnsiString fileName;
            fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
            ReadCameraWhiteBalanceColorInfo(fileName, globalCameraIndex);

            GetNFACamera2DColorImage(DestImage->Picture->Bitmap, CaptureData, MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT, globalCameraIndex, false, NULL ,0);


            // For SELMA200, 영상 반전 수정 예정
            if (globalCameraIndex == SD2_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                globalCameraIndex == SD2_2D_SIDE_FACE_M45_CAMERA_INDEX - 1)
            {
              byte *pTempLine = new byte[DestImage->Picture->Bitmap->Width * 3];
              for (int y = 0; y < (DestImage->Picture->Bitmap->Height); y++)
              {
                byte *pBitmap = (byte *)DestImage->Picture->Bitmap->ScanLine[y];

                for (int x = 0; x < DestImage->Picture->Bitmap->Width; x++)
                {
                  pTempLine[x * 3 + 0] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 0];
                  pTempLine[x * 3 + 1] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 1];
                  pTempLine[x * 3 + 2] = pBitmap[(DestImage->Picture->Bitmap->Width - 1 - x) * 3 + 2];
                }
                memcpy(pBitmap, pTempLine, DestImage->Picture->Bitmap->Width * 3);
              }
              delete[] pTempLine;
            }
            else if (globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX - 1 ||
                      globalCameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX - 1)
            {
              byte *pTempLineT = new byte[DestImage->Picture->Bitmap->Width * 3];
              byte *pTempLineB = new byte[DestImage->Picture->Bitmap->Width * 3];
              for (int y = 0; y < (DestImage->Picture->Bitmap->Height + 1) / 2; y++)
              {
                byte *pBitmapT = (byte *)DestImage->Picture->Bitmap->ScanLine[y];
                byte *pBitmapB = (byte *)DestImage->Picture->Bitmap->ScanLine[DestImage->Picture->Bitmap->Height - 1 - y];

                memcpy(pTempLineT, pBitmapB, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pTempLineB, pBitmapT, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pBitmapT, pTempLineT, DestImage->Picture->Bitmap->Width * 3);
                memcpy(pBitmapB, pTempLineB, DestImage->Picture->Bitmap->Width * 3);
              }
              delete[] pTempLineT;
              delete[] pTempLineB;
            }
            DestImage->Repaint();


            // 가장 처음, 1600으로 했을때 이미지가 찍혔고, 그때의 RValue값이 GValue이상인지 이하인지 검사
            // 첫 SW값을 ValueChangeSW에 저장,
            // 이상이라면 DownSW =1, 이하라면 UpSW = 1
            // 아래함수에서 RValue에따른 이상,이하 SW 값이 결정
            PixelInformation(CenterPosition[globalCameraIndex].CenterX, CenterPosition[globalCameraIndex].CenterY, globalCameraIndex);

            // 아래의작업은 첫 1600일때의 SW값 ValueChangeSW와 실시간으로 바뀌는 RValue에따른 SW값을 비교한다.
            // 변경된다면 그때의 Value값을 RValueList에 최종값으로 저장한다.
            // 처음 SW값은 DOWN이라서, DOWN을 진행중이였는데, UPSW값이 들어온다면, 그때의 Value + 을 100으로 본다.
            if(RValueChangeSW[globalCameraIndex] == DOWNSW && RUpSW[globalCameraIndex])
            {
              RValueList[globalCameraIndex] = RValue[globalCameraIndex] + 1;
              if(!RFinalValueSW[globalCameraIndex])
              {
                TTntPanel *PRPanel;
                PRPanel = (TTntPanel *) FindComponent("TntPanel" + IntToStr(panelCount + 5));
                PRPanel->Visible = true;
                panelCount++;
              }
              RFinalValueSW[globalCameraIndex] = 1;
            }
            if(RValueChangeSW[globalCameraIndex] == UPSW && RDownSW[globalCameraIndex])
            {
              RValueList[globalCameraIndex] = RValue[globalCameraIndex]-1;

              if(!RFinalValueSW[globalCameraIndex])
              {
                TTntPanel *PRPanel;
                PRPanel = (TTntPanel *) FindComponent("TntPanel" + IntToStr(panelCount + 5));
                PRPanel->Visible = true;
                panelCount++;
              }
              RFinalValueSW[globalCameraIndex] = 1;
            }

            if(!RFinalValueSW[globalCameraIndex]) // 확정된 값이 없으면 계속 Value 변경
            {
              if(RDownSW[globalCameraIndex]==1)  // RValue를 낮춰야함
              {
                RValue[globalCameraIndex]--;
              }
              else if(RUpSW[globalCameraIndex]==1)
              {
                RValue[globalCameraIndex]++;
              }
            }


            if(BValueChangeSW[globalCameraIndex] == DOWNSW && BUpSW[globalCameraIndex])
            {
              BValueList[globalCameraIndex] = BValue[globalCameraIndex]  + 1;

              if(!BFinalValueSW[globalCameraIndex])
              {
                TTntPanel *PRPanel;
                PRPanel = (TTntPanel *) FindComponent("TntPanel" + IntToStr(panelCount + 5));
                PRPanel->Visible = true;
                panelCount++;
              }
              BFinalValueSW[globalCameraIndex] = 1;
            }
            if(BValueChangeSW[globalCameraIndex] == UPSW && BDownSW[globalCameraIndex])
            {
              BValueList[globalCameraIndex] = BValue[globalCameraIndex] - 1;

              if(!BFinalValueSW[globalCameraIndex])
              {
                TTntPanel *PRPanel;
                PRPanel = (TTntPanel *) FindComponent("TntPanel" + IntToStr(panelCount + 5));
                PRPanel->Visible = true;
                panelCount++;
              }
              BFinalValueSW[globalCameraIndex] = 1;
            }

            if(!BFinalValueSW[globalCameraIndex])
            {
              if(BDownSW[globalCameraIndex]==1)
              {
                BValue[globalCameraIndex]--;
              }
              else if(BUpSW[globalCameraIndex]==1)
              {
                BValue[globalCameraIndex]++;
              }
            }


          }
        }
      }
      catch (...)
      {
        DiskImageLoadTimer->Enabled = false;
      }
    }

  }

  int RSW = 0;
  int BSW = 0;

  for(int z = startCameraIndex; z < endCameraIndex; z++)
  {
    if(RFinalValueSW[z])
    {
      RSW++;
    }
    if(BFinalValueSW[z])
    {
      BSW++;
    }
  }

  if(RSW == 7 && BSW == 7) // R값이 모두 설정 됨
  {
    if(stepSW == FirstDiskValueSet)
    {
      Label100->Caption = "OK";
      StartButton1->Enabled = true;
      stepSW = SecondDiskStart;
      EPanel->Caption = "1번디스크 카메라 WhiteBalance 설정이 완료되었습니다.";
    }
    else if (stepSW == SecondDiskValueSet)
    {
      Label100->Caption = "OK";
      StartButton1->Enabled = true;
      stepSW = Final;
      EPanel->Caption = "2번 디스크 카메라 WhiteBalance 설정이 완료되었습니다.";
    }
  }

  ValueSetTimer->Enabled = timerEnalbed;
}
//---------------------------------------------------------------------------



void __fastcall TTwoDCalibrationGuideForm::Disk1SpeedButtonClick(
      TObject *Sender)
{
  FirstDiskPanel->BringToFront();
  SecondDiskPanel->SendToBack();
  RGBValueBox->BringToFront();
  UBLREXPanel->BringToFront();
  PositionVerifyGroupBox1->BringToFront();
  PositionVerifyGroupBox2->SendToBack();


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

void __fastcall TTwoDCalibrationGuideForm::Disk2SpeedButtonClick(
      TObject *Sender)
{
  FirstDiskPanel->SendToBack();
  SecondDiskPanel->BringToFront();
  RGBValueBox->BringToFront();
  UBLREXPanel->BringToFront();
  PositionVerifyGroupBox1->SendToBack();
  PositionVerifyGroupBox2->BringToFront();
}
//---------------------------------------------------------------------------


void __fastcall TTwoDCalibrationGuideForm::TntImage1Click(TObject *Sender)
{
  if(VerifyOkButton->Visible == true)
  {
    VerifyOkButton->Visible = false;
  }
  else
  {
    VerifyOkButton->Visible = true;
  }
}
//---------------------------------------------------------------------------




void __fastcall TTwoDCalibrationGuideForm::FormActivate(TObject *Sender)
{
  SetScreenPosition(this);
}
//---------------------------------------------------------------------------

