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

#include <vcl.h>
#pragma hdrstop

#include <tlhelp32.h>
#include "LaserCalibration_Form.h"
#include "StudySpeedControl_Form.h"
#include "NCControl_Form.h"
#include "Environment.h"
#include "Waiting_Form.h"
#include "Keyboard_Form.h"
#include "MultiLanguage.h"
#include "winuser.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"
TLaserCalibrationForm* LaserCalibrationForm;
//---------------------------------------------------------------------------
__fastcall TLaserCalibrationForm::TLaserCalibrationForm(TComponent* Owner)
	: TForm(Owner)
{
  if(DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
    ComponentSetFontName(this, "SimSun");
  else if(DefaultLCID == 1041)
    ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

  GetDefaultString();
}
//---------------------------------------------------------------------------
void __fastcall TLaserCalibrationForm::Button1Click(TObject* Sender)
{   
	AnsiString filepath = "C:\\Users\\mbc89_000\\Desktop\\NFAImageConverter.exe";
	AnsiString PgmName = "NFAImageConverter.exe";

  //AnsiString filepath = "D:\\Project\\sLaser\\sLaser.exe";
	//AnsiString PgmName = "sLaser.exe";

	HWND hWnd = NULL;
	DWORD dwProcessID = 0;
	if (!IsExistProcess(PgmName))
	{
		ShellExecuteA(NULL, "open", filepath.c_str(), NULL, "D:\\Project\\sLaser", SW_SHOW);

		Sleep(3000);
	}

	dwProcessID = GetProcessIDByName(PgmName);
	if (dwProcessID)
	{
		hWnd = GetWinHandle(dwProcessID);
	}

	if (hWnd)
	{
    ShowWindowAsync(hWnd, SW_SHOWNORMAL);
    SetActiveWindow (hWnd);
		SetForegroundWindow(hWnd);
      
		TRect rc;
		GetWindowRect(hWnd, &rc);
		winHandle = ::SetParent(hWnd, Panel3->Handle);
		prevRc = rc;

		SetWindowPos(hWnd, NULL, 0, 0, rc.Width(), rc.Height(), 0);

		//LONG lStyle = GetWindowLong(hWnd, GWL_STYLE);
		//lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
		//SetWindowLong(hWnd, GWL_STYLE, lStyle);
	}
}
//---------------------------------------------------------------------------

DWORD GetProcessIDByName(AnsiString name)
{
	DWORD pid = 0;

	// Create toolhelp snapshot.
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	PROCESSENTRY32 process;
	ZeroMemory(&process, sizeof(process));
	process.dwSize = sizeof(process);

	// Walkthrough all processes.
	if (Process32First(snapshot, &process))
	{
		do
		{
			// Compare process.szExeFile based on format of name, i.e., trim file path
			// trim .exe if necessary, etc.
			if (AnsiString(process.szExeFile) == name)
			{
				pid = process.th32ProcessID;
				break;
			}
		} while (Process32Next(snapshot, &process));
	}

	CloseHandle(snapshot);

	return pid;
}

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

HANDLE GetWinHandle(ULONG pid) // 프로세스 아이디로 윈도우 핸들 얻기
{
	HANDLE tempHwnd = FindWindow(NULL, NULL); // 최상위 윈도우 핸들 찾기

	ULONG tmpPid;

	while (tempHwnd != NULL)
	{
		if (GetParent(tempHwnd) == NULL) // 최상위 핸들인지 체크, 버튼 등도 핸들을 가질 수 있으므로 무시하기 위해
    {
			GetWindowThreadProcessId(tempHwnd, &tmpPid);

		  if (pid == tmpPid) return tempHwnd;
    }

    tempHwnd = GetWindow(tempHwnd, GW_HWNDNEXT); // 다음 윈도우 핸들 찾기
	}
	return NULL;
}

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

void __fastcall TLaserCalibrationForm::Button2Click(TObject* Sender)
{
	AnsiString filepath = "C:\\Users\\mbc89_000\\Desktop\\NFAImageConverter.exe";
	AnsiString PgmName = "NFAImageConverter.exe";

  //AnsiString filepath = "D:\\Project\\sLaser\\sLaser.exe";
	//AnsiString PgmName = "sLaser.exe";

	HWND hWnd = NULL;
	DWORD dwProcessID = 0;
	if (IsExistProcess(PgmName))
	{
		dwProcessID = GetProcessIDByName(PgmName);
		if (dwProcessID)
		{
			hWnd = GetWinHandle(dwProcessID);
		}

		if (hWnd)
		{
      HWND childHwnd;
      childHwnd = GetWindow(Panel3->Handle, GW_CHILD); // 다른 자식 handle에 대한 예외처리가 진행되지 않음. Panel3에는 기타 컴포넌트가 위치해서는 안됨

      if(childHwnd)
      {
        ::SetParent(childHwnd, winHandle);
        SetWindowPos(childHwnd, NULL, prevRc.left, prevRc.top, prevRc.Width(), prevRc.Height(), 0);

			  //LONG lStyle = GetWindowLong(childHwnd, GWL_STYLE);
			  //lStyle &= (WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
			  //SetWindowLong(childHwnd, GWL_STYLE, lStyle);
      }
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::CloseButtonClick(TObject *Sender)
{
  Comm_Request(COMM_HCB, CMD_MACHINE_CAPTURE_STOP);

  Machine.MachineStop();
  this->Close();
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::NCControlButtonClick(
      TObject *Sender)
{
  NCControlForm->IsMEMode = false;
	NCControlForm->ShowModal();  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::SpeedControlButtonClick(
      TObject *Sender)
{
  TStudySpeedControlForm *studyspeedControlForm = new TStudySpeedControlForm(this);
	studyspeedControlForm->ShowModal();
	delete studyspeedControlForm;  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::CaptureStopButtonClick(
      TObject *Sender)
{
  Comm_Request(COMM_HCB, CMD_MACHINE_CAPTURE_STOP);

  if (Machine.MachineStop())
  {
    WaitingForm->WaitingMachineStop();
  }

  CaptureStartButton->Enabled = true;
  CaptureStopButton->Enabled = false;
  CaptureCheckTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::FormCreate(TObject *Sender)
{
  ImagePanel->DoubleBuffered = true;
  CaptureStartButton->Enabled = true;
  CaptureStopButton->Enabled = false;

  LaserTestProgressBarCamera1->Position = 0;
  LaserTestProgressBarCamera5->Position = 0;

  LaserTestProgressLabelCamera1->Caption = "0";
  LaserTestProgressLabelCamera5->Caption = "0";

  InitImageComponents();
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::CaptureStartButtonClick(
      TObject *Sender)
{
  // check machine interlock
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if (MachineSetupData.InterlockInfo.ACdomesticMode)
    {
      if (!Machine.InterlockCheck())
      {
        ShowMessageFA(Machine.GetInterlockMessage());
        return;
      }
    }
    else
    {
      if (!Machine.InterlockCheck())
      {
        ShowMessageFA(Machine.GetInterlockMessage());
        return;
      }
    }
  }
  else
  {
    if (MachineSetupData.InterlockInfo.DoorInterlockEnabled)
    {
      if (!Machine.InterlockCheck())
      {
        ShowMessageFA(Machine.GetInterlockMessage());
        return;
      }
    }
  }

	if (!Machine.CanCaptureStart(ProductData.LampKind))
	{
		ShowMessageFA(Machine.GetCaptureStartFailMessage(ProductData.LampKind));
		return;
	}

  if (Machine.Status.OperationState != MACHINE_STATE_STOP &&
			Machine.Status.OperationState != MACHINE_STATE_CLEANING &&
			Machine.Status.OperationState != MACHINE_STATE_ATTACHING &&
			Machine.Status.OperationState != MACHINE_STATE_DETACHING)
  {
    Machine.MachineStop();
    ShowMessageFA(INSPECTIONFORM_MSG_23);
    return;
  }

	bool bError = false;

  InitImageComponents();


  unsigned int camMask = 0;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
    if ((CameraMapInfo[globalCameraIndex].CameraInspectPosition < CAMERA_POSITION_DISCONNECT) && (SystemLinkCameraInfo[globalCameraIndex] != 0 ))
    {
      if(globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
          globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
      {
        camMask |= (0x0001 << globalCameraIndex);
      }
    }
  }
  
	try
	{
    float tabletHalfLength = ProductData.TabletLength / 2;

    // Camera Shutter Speed 갱신
    for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	  {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      if (!Comm_IsConnected(COMM_SPB + spbIndex)) continue;

      if (CameraMapInfo[globalCameraIndex].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[globalCameraIndex] != 0)
      {
        if(globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
            globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
        {
          RefreshCameraInfo(globalCameraIndex, 1.0);
          Application->ProcessMessages();
          this->Refresh();
        }
      }
    }

    if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
    {
      if((camMask & (0x0001 << (SD1_3D_FRONT_FACE_CAMERA_INDEX - 1))) == 0)
      {
        Set3DCamera_CaptureParameter(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1, ThreeDCameraDefaultInformation[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].AnalogCameraGain, ThreeDCameraDefaultInformation[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].ExposureTime);
      }

      if((camMask & (0x0001 << (SD2_3D_FRONT_FACE_CAMERA_INDEX - 1))) == 0)
      {
        Set3DCamera_CaptureParameter(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1, ThreeDCameraDefaultInformation[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].AnalogCameraGain, ThreeDCameraDefaultInformation[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].ExposureTime);
      }
    }

    // second capture - object
    SendSPBCaptureSetup_Multi(&ProductData, camMask, tabletHalfLength, ProductData.ShutterSpeed,
			                        ProductData.StudyMotorSpeedList[SD1_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed,
			                        ProductData.StudyMotorSpeedList[SD2_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed,
                              RESOLUTION_NORMAL_QUALITY, false);

    		CaptureCheckTimer->Enabled = true;
		TMachineCaptureSetupData machineCaptureSetupData;
		memcpy(machineCaptureSetupData.IlluminatorMask, MachineSetupData.MachineCaptureInfo.IlluminatorMask, SYSTEM_MACHINE_CAPTURE_COUNT * sizeof(int));
		machineCaptureSetupData.CaptureOption = 0;
		machineCaptureSetupData.TabletLength = ProductData.TabletLength;
		machineCaptureSetupData.TabletSideThick = ProductData.TabletSideThick*10;
		machineCaptureSetupData.SuctionDiskSpeed = ProductData.StudyMotorSpeedList[0][0]; /// studyspeed khs
		machineCaptureSetupData.StudiedTabletSensorLength = ProductData.TabletLength / MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_1 * 20.0 * 1000;

		if (!Comm_Request(COMM_HCB, CMD_MACHINE_CAPTURE, &machineCaptureSetupData, sizeof(TMachineCaptureSetupData),
			NULL, 0))
		{
			throw Exception("");
		}

		int motorSpeedList[MAX_SERVO_MOTOR_COUNT];
		for (int motorIndex = 0; motorIndex < MAX_SERVO_MOTOR_COUNT; motorIndex++)
		{
			motorSpeedList[motorIndex] = ProductData.StudyMotorSpeedList[motorIndex][0]; // studyspeed khs
		}

		if (!Machine.MachineRun(PROCEDURE_MODE_CAPTURE, &ProductData.MachineRunOption,
			ProductData.NCMotorPos, motorSpeedList))
		{
			throw Exception("");
		}

    CaptureStartButton->Enabled = false;
    CaptureStopButton->Enabled = true;

    LaserTestProgressBarCamera1->Position = 0;
    LaserTestProgressBarCamera5->Position = 0;

    LaserTestProgressLabelCamera1->Caption = "0";
    LaserTestProgressLabelCamera5->Caption = "0";
	}
	catch (...)
	{

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


void __fastcall TLaserCalibrationForm::InitImageComponents()
{
  LaserTestImageCamera1->Width = SYSTEM_CAMERA_WIDTH;
	LaserTestImageCamera1->Height = SYSTEM_CAMERA_HEIGHT;
	LaserTestImageCamera1->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
	LaserTestImageCamera1->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
	LaserTestImageCamera1->Picture->Bitmap->PixelFormat = pf24bit;

  LaserTestImageCamera5->Width = SYSTEM_CAMERA_WIDTH;
	LaserTestImageCamera5->Height = SYSTEM_CAMERA_HEIGHT;
	LaserTestImageCamera5->Picture->Bitmap->Width = SYSTEM_CAMERA_WIDTH;
	LaserTestImageCamera5->Picture->Bitmap->Height = SYSTEM_CAMERA_HEIGHT;
	LaserTestImageCamera5->Picture->Bitmap->PixelFormat = pf24bit;

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

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

//---------------------------------------------------------------------------
void __fastcall TLaserCalibrationForm::RefreshCameraInfo(int camIndex, float m)
{ 
	int ShutterSpeed = 0;
	int Threshold = 0;
	int WriteMask = 0;

  int TwoDShutterSpeedVal;
  int TwoDGainVal;

  TwoDShutterSpeedVal = StrToInt(ShutterSpeedTextBox->Text);
  TwoDGainVal = StrToInt(GainTextBox->Text);

	// Shutter 정보
  if(camIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
  {
	  ShutterSpeed = TwoDShutterSpeedVal * m;
  }
  else
  {
    ShutterSpeed = ProductData.ShutterSpeed[camIndex] * m;
  }

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

	// Threshold는 3D 카메라에만 적용
	if (CameraMapInfo[camIndex].CameraInspectPosition == CAMERA_POSITION_3D)
	{
		Threshold = ProductData.ThresholdFor3D[camIndex];
		WriteMask |= CAMERA_WRITE_MASK_TH;
	}

	TROIInfo DefaultROIInfo, ApplyROIInfo;
	AnsiString filePath;
	int DiskBaseHeight;
	int tempStartY, tempEndY, tempRowCount;
	filePath = ProgramPath.Env + "\\NFACameraInformation.ini";
	DefaultROIInfo = ReadCameraInformation(filePath, camIndex);

	if (CameraMapInfo[camIndex].CameraInspectPosition != CAMERA_POSITION_3D)
	{
		memcpy(&ApplyROIInfo, &DefaultROIInfo, sizeof(TROIInfo));
    WriteMask |= CAMERA_WRITE_MASK_2D_ROI;
	}
	else
	{
		ApplyROIInfo = SetThreeDCameraROI(DefaultROIInfo, &ProductData);
    WriteMask |= CAMERA_WRITE_MASK_3D_ROI;
	}

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

  if (CameraMapInfo[camIndex].CameraInspectPosition != CAMERA_POSITION_3D)
  {
    SetCameraInformation(ApplyROIInfo, ShutterSpeed, Threshold, RESOLUTION_NORMAL_QUALITY, camIndex, WriteMask);
    SetCameraGain(camIndex + 1, SYSTEM_DEFAULT_ANLOG_GAIN, TwoDGainVal, 0);
  }
  else
  {
    WriteMask |= CAMERA_WRITE_MASK_3D_SH;

    int ThreedCameraIndex = 0;
    if(camIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX-1) ThreedCameraIndex = 0;
    else ThreedCameraIndex = 1;

    if(ProductData.ExposureTime3D[ThreedCameraIndex] != -1)
    {
      Set3DCamera_CaptureParameter(camIndex,ProductData.AnalogGain3D[ThreedCameraIndex],ProductData.ExposureTime3D[ThreedCameraIndex]);
    }
    else
    {
      Set3DCamera_CaptureParameter(camIndex,ThreeDCameraDefaultInformation[camIndex].AnalogCameraGain,ThreeDCameraDefaultInformation[camIndex].ExposureTime);
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TLaserCalibrationForm::CaptureCheckTimerTimer(
      TObject *Sender)
{
  bool bTimerEnabled;
  
  bTimerEnabled = CaptureCheckTimer->Enabled;

  bool bCaptureExist;

	char cameraIndex;
	unsigned int data[2];
	unsigned int receivedData[2];
  unsigned char CaptureData[SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT];

  int CaptureWidth, CaptureHeight;

  CaptureWidth = SYSTEM_CAMERA_WIDTH;
  CaptureHeight = SYSTEM_CAMERA_HEIGHT;

  for(int allCameraIndex = 0; allCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; allCameraIndex++)
  {
    if(allCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || allCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
    {
      if (CameraMapInfo[allCameraIndex].CameraInspectPosition == CAMERA_POSITION_DISCONNECT) continue;

      int camIndex = CameraMapInfo[allCameraIndex].CamIndex;
      int spbIndex = CameraMapInfo[allCameraIndex].SPBIndex;

      data[0] = camIndex;
      data[1] = CaptureWidth * CaptureHeight;

      TImage *LaserTestImage = (TImage *) FindComponent("LaserTestImageCamera" + IntToStr(allCameraIndex + 1));
      TProgressBar *LaserTestProgressBar = (TProgressBar *) FindComponent("LaserTestProgressBarCamera" + IntToStr(allCameraIndex + 1));
      TLabel *LaserTestProgressLabel = (TLabel *) FindComponent("LaserTestProgressLabelCamera" + IntToStr(allCameraIndex + 1));

      try
      {
        if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
          receivedData, sizeof(unsigned int) * 2))
        {
          throw(0);
        }
    
        if (receivedData[0])
        {
          bCaptureExist = true;
        }
        else
        {
          bCaptureExist = false;
        }
    
        if (bCaptureExist)
        {
          if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
          CaptureData, (CaptureWidth) * CaptureHeight))
          {
            throw(0);
          }

          if(allCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
          {
            LaserTestImage->Picture->Bitmap->Width = CaptureWidth;
            LaserTestImage->Picture->Bitmap->Height = CaptureHeight;
            LaserTestImage->Picture->Bitmap->PixelFormat = pf24bit;
      
            AnsiString fileName;
            fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
            ReadCameraWhiteBalanceColorInfo(fileName, allCameraIndex);

            GetNFACamera2DColorImage(LaserTestImage->Picture->Bitmap, CaptureData, CaptureWidth, CaptureHeight, allCameraIndex,SystemImageOffsetSWCal[allCameraIndex - 1], SystemOffsetImage[allCameraIndex - 1], RESOLUTION_NORMAL_QUALITY);

            // 상하좌우
            byte *pTempLineT = new byte[CaptureWidth * 3];
            byte *pTempLineB = new byte[CaptureWidth * 3];
            for (int y = 0; y < (CaptureHeight + 1) / 2; y++)
            {
              byte *pBitmapT = (byte *)LaserTestImage->Picture->Bitmap->ScanLine[y];
              byte *pBitmapB = (byte *)LaserTestImage->Picture->Bitmap->ScanLine[CaptureHeight - 1 - y];

              for (int x = 0; x < CaptureWidth; x++)
              {
                pTempLineT[x * 3 + 0] = pBitmapB[x * 3 + 0];
                pTempLineB[x * 3 + 0] = pBitmapT[x * 3 + 0];
                pTempLineT[x * 3 + 1] = pBitmapB[x * 3 + 1];
                pTempLineB[x * 3 + 1] = pBitmapT[x * 3 + 1];
                pTempLineT[x * 3 + 2] = pBitmapB[x * 3 + 2];
                pTempLineB[x * 3 + 2] = pBitmapT[x * 3 + 2];
              }
              memcpy(pBitmapT, pTempLineT, CaptureWidth * 3);
              memcpy(pBitmapB, pTempLineB, CaptureWidth * 3);
            }
            delete[] pTempLineT;
            delete[] pTempLineB;
          }
          else
          {
            LaserTestImage->Picture->Bitmap->Width = IMAGE_WIDTH_3D * 2;
            LaserTestImage->Picture->Bitmap->Height = IMAGE_HEIGHT_3D;
            LaserTestImage->Picture->Bitmap->PixelFormat = pf24bit;

            Graphics::TBitmap *tempBitmap = new Graphics::TBitmap;
            tempBitmap->Width = IMAGE_WIDTH_3D;
            tempBitmap->Height = IMAGE_HEIGHT_3D;
            tempBitmap->PixelFormat = pf8bit;

            ImageConversion_3D(tempBitmap, IMAGE_WIDTH_3D, IMAGE_HEIGHT_3D, CaptureData, SYSTEM_CAMERA_WIDTH_3D, SYSTEM_CAMERA_HEIGHT_3D);

            for (int y = 1; y < IMAGE_HEIGHT_3D - 1; y++)
            {
              byte *pBitmap = (byte *)LaserTestImage->Picture->Bitmap->ScanLine[y];
              byte *pSrc = (byte *)tempBitmap->ScanLine[y];

              for (int x = IMAGE_WIDTH_3D * 2 - 1; x >= 0; x--)
              {
                pBitmap[3 * x + 0] = pSrc[x / 2];
                pBitmap[3 * x + 1] = pSrc[x / 2];
                pBitmap[3 * x + 2] = pSrc[x / 2];
              }
            }

            // 상하좌우
            byte *pTempLineT = new byte[CaptureWidth * 3];
            byte *pTempLineB = new byte[CaptureWidth * 3];
            for (int y = 0; y < (CaptureHeight + 1) / 2; y++)
            {
              byte *pBitmapT = (byte *)LaserTestImage->Picture->Bitmap->ScanLine[y];
              byte *pBitmapB = (byte *)LaserTestImage->Picture->Bitmap->ScanLine[CaptureHeight - 1 - y];

              for (int x = 0; x < CaptureWidth; x++)
              {
                pTempLineT[x * 3 + 0] = pBitmapB[x * 3 + 0];
                pTempLineB[x * 3 + 0] = pBitmapT[x * 3 + 0];
                pTempLineT[x * 3 + 1] = pBitmapB[x * 3 + 1];
                pTempLineB[x * 3 + 1] = pBitmapT[x * 3 + 1];
                pTempLineT[x * 3 + 2] = pBitmapB[x * 3 + 2];
                pTempLineB[x * 3 + 2] = pBitmapT[x * 3 + 2];
              }
              memcpy(pBitmapT, pTempLineT, CaptureWidth * 3);
              memcpy(pBitmapB, pTempLineB, CaptureWidth * 3);
            }
            delete[] pTempLineT;
            delete[] pTempLineB;

            delete tempBitmap;
          }

          if(GridSettingCheckBox->Checked)
          {
            float x, y;
            float gridSize;
            gridSize = (float)SYSTEM_CAMERA_WIDTH / StrToFloat(FOVEdit->Text);

            LaserTestImage->Canvas->Pen->Color = clDkGray;
            LaserTestImage->Canvas->Pen->Width = 1;
            LaserTestImage->Canvas->Brush->Style = bsClear;

            int centerX;
            int centerY;

            centerX = SYSTEM_CAMERA_WIDTH / 2;
            centerY = SYSTEM_CAMERA_HEIGHT / 2;

            for(y = centerY; y >= 0; y -= (int)gridSize)
            {
              LaserTestImage->Canvas->MoveTo(0, y);
              LaserTestImage->Canvas->LineTo(SYSTEM_CAMERA_WIDTH, y);
            }

            for(y = centerY + gridSize; y < SYSTEM_CAMERA_HEIGHT; y += (int)gridSize)
            {
              LaserTestImage->Canvas->MoveTo(0, y);
              LaserTestImage->Canvas->LineTo(SYSTEM_CAMERA_WIDTH, y);
            }

            for(x = centerX; x >= 0; x -= (int)gridSize)
            {
              LaserTestImage->Canvas->MoveTo(x, 0);
              LaserTestImage->Canvas->LineTo(x, SYSTEM_CAMERA_HEIGHT);
            }

            for(x = centerX + gridSize; x < SYSTEM_CAMERA_WIDTH; x += (int)gridSize)
            {
              LaserTestImage->Canvas->MoveTo(x, 0);
              LaserTestImage->Canvas->LineTo(x, SYSTEM_CAMERA_HEIGHT);
            }
          }
      
          if(CenterPositionCheckBox->Checked)
          {
            LaserTestImage->Canvas->Pen->Color = clYellow;
            LaserTestImage->Canvas->Pen->Width = 2;
            LaserTestImage->Canvas->Brush->Style = bsClear;

            int centerX, centerY;
            centerX = SYSTEM_CAMERA_WIDTH / 2;
            centerY = SYSTEM_CAMERA_HEIGHT / 2;

            LaserTestImage->Canvas->MoveTo(0,                   centerY);
            LaserTestImage->Canvas->LineTo(SYSTEM_CAMERA_WIDTH, centerY);
            LaserTestImage->Canvas->MoveTo(centerX, 0);
            LaserTestImage->Canvas->LineTo(centerX, SYSTEM_CAMERA_HEIGHT);
          }

          LaserTestProgressBar->Position++;
          if(LaserTestProgressBar->Position == LaserTestProgressBar->Max)
            LaserTestProgressBar->Position = 0;

          LaserTestProgressLabel->Caption = IntToStr(LaserTestProgressBar->Position);

          LaserTestImage->Repaint();
        }
      }
      catch (...)
      {
        bTimerEnabled = false;
      }
    }
  }

  CaptureCheckTimer->Enabled = bTimerEnabled;  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::BitBtn1Click(TObject *Sender)
{
  RefreshCameraInfo(SD1_2D_FRONT_FACE_CAMERA_INDEX - 1, 1.0);
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::FOVEditClick(TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
    try
    {
      float tempValue = StrToFloat(KeyboardForm->Text);
      if(tempValue <= 0)
      {
        throw Exception("");        
      }

      theEdit->Text = KeyboardForm->Text;
    }
    catch(...)
    {
      ShowMessage("The input value is incorrect.");
    }
  }  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::ShutterSpeedTextBoxClick(
      TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
    try
    {
      int tempValue = StrToInt(KeyboardForm->Text);

      theEdit->Text = KeyboardForm->Text;
    }
    catch(...)
    {
      ShowMessage("The input value is incorrect.");
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::GainTextBoxClick(TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
  KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {
    try
    {
      int tempValue = StrToInt(KeyboardForm->Text);

      theEdit->Text = KeyboardForm->Text;
    }
    catch(...)
    {
      ShowMessage("The input value is incorrect.");
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::ShutterSpeedTextBoxKeyPress(
      TObject *Sender, char &Key)
{
  Key = NULL;  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::GainTextBoxKeyPress(TObject *Sender,
      char &Key)
{
  Key = NULL;  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::FOVEditKeyPress(TObject *Sender,
      char &Key)
{
  Key = NULL;  
}
//---------------------------------------------------------------------------

void __fastcall TLaserCalibrationForm::GetDefaultString()
{
  CaptureGroupBox->Caption = LASERCALIBRATION_FORM_TEXT_01;
  CaptureStartButton->Caption = LASERCALIBRATION_FORM_TEXT_02;
  CaptureStopButton->Caption = LASERCALIBRATION_FORM_TEXT_03;
  GridSettingCheckBox->Caption = LASERCALIBRATION_FORM_TEXT_04;
  CenterPositionCheckBox->Caption = LASERCALIBRATION_FORM_TEXT_05;
  Label2->Caption = LASERCALIBRATION_FORM_TEXT_06;
  NCControlButton->Caption = LASERCALIBRATION_FORM_TEXT_07;
  SpeedControlButton->Caption = LASERCALIBRATION_FORM_TEXT_08;
}
//---------------------------------------------------------------------------
void __fastcall TLaserCalibrationForm::sLaserControlBtnClick(
      TObject *Sender)
{
  AnsiString filepath = "D:\\Project\\sLaser\\sLaser.exe";
	AnsiString PgmName = "NFA sLaser";

  if(IsExistProcess("sLaser.exe"))
  {
    HWND hWnd = FindWindowA(NULL, PgmName.c_str());

    ShowWindowAsync(hWnd, SW_SHOWNORMAL);
    SetActiveWindow (hWnd);
    SetForegroundWindow(hWnd);
  }
  else
  {
    ShellExecuteA(NULL, "open", filepath.c_str(), NULL, "D:\\Project\\sLaser\\", SW_SHOW);
  }
}
//---------------------------------------------------------------------------

