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

#include "main.h"
#include "TcpComm.h"
#include "OptionSetting_Form.h"
#include <stdio.h>
#include <io.h>
#include "inifiles.hpp"
#include <tlhelp32.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma resource "*.dfm"
TMain_form *Main_form;

bool MachineResetFlag;

SHELLEXECUTEINFO sInfo;
int StartOptionBoardCount = 0;

unsigned int TCP_Check_flag = 1;
unsigned int TCPOn_Time = 0;
unsigned int TCPOn_Board = 0;
unsigned int TCP_Check_Progress = 0;

//---------------------------------------------------------------------------
__fastcall TMain_form::TMain_form(TComponent* Owner)
	: TForm(Owner)
{
  bPgmClose = PRG_CLOSE_OPTION_NONE;

  for(int commIndex = 0; commIndex < MAX_COMM_COUNT; commIndex++)
  {
	  DownCode[commIndex] = -1;
  }

	MachineResetFlag = 0;
	ProgramPathSetup();
	CreateProgramFolder();
	SetCommParameter();
	SetCommTypeLabel();

  AnsiString SystemOptionInfoFileName;
	SystemOptionInfoFileName = ProgramPath.Env_Root + "\\SystemInfo.ini";

	if (!FileExists(SystemOptionInfoFileName))
	{
		ShowMessageFA("The setting value does not exist.");

		TOptionSettingForm *OptionSettingForm = new TOptionSettingForm(this);
    OptionSettingForm->bDefault = true;
    OptionSettingForm->bChangeParams = false;

		if(OptionSettingForm->ShowModal() == mrOk)
    {
      bPgmClose = PRG_CLOSE_OPTION_SAVE_AND_EXIT;
    }
    else
    {
      bPgmClose = PRG_CLOSE_OPTION_INVALID_DATA;
    }
		delete OptionSettingForm;
	}
	else
	{
		ReadApplicationOption(SystemOptionInfoFileName, &ApplicationStartOption);
	}
  StartOptionBoardCount = ApplicationStartOption.comm_brdCount;
	Panel5->Visible = false;

	//해상도 보정
	const int design_Width = this->Width;
	const int design_Height = this->Height;
	if (Screen->Width < design_Width)
	{
		Scaled = true;
		Height = Height * Screen->Height / design_Height;
		Width = Width * Screen->Width / design_Width;

		ScaleBy(Screen->Width, design_Width);
	}

	bProgramExecution = false;

  Panel1->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::ProgramPathSetup()
{
	//인스톨할때 폴더가 이미 생성된 상태라고 가정
	ProgramPath.Root = ExtractFileDir(Application->ExeName);

	ProgramPath.Tablet = ProgramPath.Root + "\\Tablet5.0";
	ProgramPath.Capsule = ProgramPath.Root + "\\Capsule5.0";
	ProgramPath.Env_Root = ProgramPath.Root + "\\Env";
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::ProgramExecution(AnsiString ProgramName)
{
	AnsiString IDPARAMS;
	IDPARAMS = IntToStr(ApplicationStartOption.SelectedCommType) + " -LocaleID " + IntToStr(ApplicationStartOption.SelectedLCID);
	if (FileExists(ProgramName))
	{
		ShellExecute(NULL, "open", ProgramName.c_str(), IDPARAMS.c_str(), NULL, SW_SHOW);
	}
	else
	{
		ShowMessageFA("Application does not exist.");
	}
}
//---------------------------------------------------------------------------
AnsiString __fastcall TMain_form::ApplicationProgramName(int ProgramType)
{
  switch (ProgramType)
  {
  case PROGRAM_TABLET_APPLICATION:
    return ProgramPath.Tablet + "\\" + tvmExename;

  case PROGRAM_CAPSULE_APPLICATION:
    return ProgramPath.Capsule + "\\" + cvmExename;
  }
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::FirmWareReset(int ProgramType)
{
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::HCB_ProgramReset(int ProgramType)
{
	unsigned int programID;
	unsigned int brData[2];
	int HCB_Version;
	TBootRecord br;

	switch (ProgramType)
	{
	case PROGRAM_TABLET_APPLICATION:
		programID = PID_HCB_APPLICATION_TABLET_5;
		HCB_Version = FW_VERSION_HCB_TABLET;
		MachineResetFlag = 0;
		break;

	case PROGRAM_CAPSULE_APPLICATION:
		programID = PID_HCB_APPLICATION_CAPSULE_5;
		HCB_Version = FW_VERSION_HCB_CAPSULE;
		MachineResetFlag = 1;
		break;

	default:
		programID = PID_HCB_APPLICATION_CAPSULE_5;
		HCB_Version = FW_VERSION_HCB_CAPSULE;
		MachineResetFlag = 1;
		break;
	}

	if (Comm_IsConnected(COMM_HCB)) // HCB 연결
	{
		DownloadFirmwareReport(ProgramType, HCB_Version);
		int time = Now().FileDate();
		br.BREnabled = 1;
		br.ProgramID = programID;
		programID = PID_BOOT_RECORD;

		memcpy(&brData[0], &programID, sizeof(unsigned int));
		memcpy(&brData[1], &time, sizeof(int));

		if (Comm_RequestEx(COMM_HCB, CMD_DOWNLOAD, brData, 2 * sizeof(unsigned int),
			&br, sizeof(TBootRecord))) // HCB에 br코드를 내려보냄
		{
			if ((DownCode[COMM_HCB] == -1 || MachineResetFlag == DownCode[COMM_HCB]) && BoardShutDown == false)
			{
				//Comm_Request(COMM_HCB, CMD_RESET);
				//Comm_Disconnect(COMM_HCB);
			}
			else if (MachineResetFlag != DownCode[0] || BoardShutDown == true)
			{
				SystemBootingCheckTimer->Enabled = false;
				Panel5->Visible = false;
				Panel8->Visible = true;
        Panel8->BringToFront();
        Panel1->Visible = false;
				BoardShutDown = true;
				//내려보낸 후에 reset
				SystemBootingCheckTimer->Enabled = false;
				Comm_Request(COMM_HCB, CMD_MACHINE_POWER_OFF);
			}
		}
	}
	else
	{
		ShowMessageFA("HCB is not connected");

	}
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::SPB_ProgramReset(int ProgramType)
{
	unsigned int programID;
	unsigned int brData[2];
	TBootRecord br;
	int SPB_Version;
	int downloadCount = 0;
	bool downloadBoard[SYSTEM_SPB_COUNT] = { false, };

	for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
	{
		if (Comm_IsConnected(COMM_SPB + spbIndex)) // spb 연결시도
		{
			DownloadFirmwareReport(ProgramType, SPB_Version);
			switch (ProgramType)
			{
			case PROGRAM_TABLET_APPLICATION:
				programID = PID_SPB_TABLET_5;
				SPB_Version = FW_VERSION_SPB_TABLET;
				MachineResetFlag = 0;
				break;

			case PROGRAM_CAPSULE_APPLICATION:
				programID = PID_SPB_CAPSULE_5;
				SPB_Version = FW_VERSION_SPB_CAPSULE;
				MachineResetFlag = 1;
				break;

			default:
				programID = PID_SPB_CAPSULE_5;
				SPB_Version = FW_VERSION_SPB_CAPSULE;
				MachineResetFlag = 1;
				break;
			}

			br.BREnabled = 1;
			br.ProgramID = programID;
			programID = PID_BOOT_RECORD;
			int time = Now().FileDate();

			memcpy(&brData[0], &programID, sizeof(unsigned int));
			memcpy(&brData[1], &time, sizeof(int));

			if (Comm_RequestEx(COMM_SPB + spbIndex, CMD_DOWNLOAD, brData, 2 * sizeof(unsigned int),
				&br, sizeof(TBootRecord))) // spb 연결되면 br을 내려보냄
			{
				if (DownCode[COMM_SPB + spbIndex] == -1 || DownCode[COMM_SPB + spbIndex] == MachineResetFlag)
				{
					// 내려보낸후 해당 보드 run
					/*if(Comm_Request(COMM_SPB + spbIndex, CMD_RESET))
					{
					Comm_Disconnect(COMM_SPB + spbIndex);
					downloadCount++;
					downloadBoard[spbIndex] = true;
					}*/
				}
				else
				{
					BoardShutDown = true;
				}
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::TPB_ProgramReset(int ProgramType)
{
	unsigned int programID;
	unsigned int brData[2];
	TBootRecord br;
	int TPB_Version;
	int downloadCount = 0;
	bool downloadBoard = false;

	if (Comm_IsConnected(COMM_TPB))
	{
		DownloadFirmwareReport(ProgramType, TPB_Version);
		switch (ProgramType)
		{
		case PROGRAM_TABLET_APPLICATION:
			programID = PID_TPB_TABLET;
			TPB_Version = FW_VERSION_TPB_TABLET;
			MachineResetFlag = 0;
			break;

		case PROGRAM_CAPSULE_APPLICATION:
			programID = PID_TPB_CAPSULE;
			TPB_Version = FW_VERSION_TPB_CAPSULE;
			MachineResetFlag = 1;
			break;

		default:
			programID = PID_TPB_CAPSULE;
			TPB_Version = FW_VERSION_TPB_CAPSULE;
			MachineResetFlag = 1;
			break;
		}

		br.BREnabled = 1;
		br.ProgramID = programID;
		programID = PID_BOOT_RECORD;
		int time = Now().FileDate();

		memcpy(&brData[0], &programID, sizeof(unsigned int));
		memcpy(&brData[1], &time, sizeof(int));

		if (Comm_RequestEx(COMM_TPB, CMD_DOWNLOAD, brData, 2 * sizeof(unsigned int),
			&br, sizeof(TBootRecord))) // spb 연결되면 br을 내려보냄
		{
			if (DownCode[COMM_TPB] == -1 || DownCode[COMM_TPB] == MachineResetFlag)
			{
				// 내려보낸후 해당 보드 run
				/*if(Comm_Request(COMM_SPB + spbIndex, CMD_RESET))
				{
				Comm_Disconnect(COMM_SPB + spbIndex);
				downloadCount++;
				downloadBoard[spbIndex] = true;
				}*/
			}
			else
			{
				BoardShutDown = true;
			}
		}
	}

}
//---------------------------------------------------------------------------
void __fastcall TMain_form::CreateProgramFolder()
{
	if (!DirectoryExists(ProgramPath.Capsule))
	{
		CreateDir(ProgramPath.Capsule);
	}

	if (!DirectoryExists(ProgramPath.Tablet))
	{

		CreateDir(ProgramPath.Tablet);
	}

	if (!DirectoryExists(ProgramPath.Env_Root))
	{
		CreateDir(ProgramPath.Env_Root);
	}
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::PastFirmwareConfirm(int programType)
{
	TIniFile *iniFile;
	iniFile = new TIniFile(ProgramPath.Env_Root + "\\FWVersion.ini");

	if (iniFile)
	{
		PastFW_HCB = iniFile->ReadInteger("HCB", "DownLoad File", FW_VERSION_NOT_DOWNLOAD);
		PastFW_SPB = iniFile->ReadInteger("SPB", "DownLoad File", FW_VERSION_NOT_DOWNLOAD);
		PastFW_TPB = iniFile->ReadInteger("TPB", "DownLoad File", FW_VERSION_NOT_DOWNLOAD);
	}

	delete iniFile;
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::DownloadFirmwareReport(int programType, int FW_Version)
{
	TIniFile *iniFile;
	iniFile = new TIniFile(ProgramPath.Env_Root + "\\FWVersion.ini");

	if (iniFile)
	{
		switch (FW_Version)
		{
		case FW_VERSION_HCB_TABLET:
		case FW_VERSION_HCB_CAPSULE:
			iniFile->WriteInteger("HCB", "DownLoad File", FW_Version);
			break;

		case FW_VERSION_SPB_TABLET:
		case FW_VERSION_SPB_CAPSULE:
			iniFile->WriteInteger("SPB", "DownLoad File", FW_Version);
			break;

		case FW_VERSION_TPB_TABLET:
		case FW_VERSION_TPB_CAPSULE:
			iniFile->WriteInteger("TPB", "DownLoad File", FW_Version);
			break;

		default:
			iniFile->WriteInteger("HCB", "DownLoad File", FW_Version);
			iniFile->WriteInteger("SPB", "DownLoad File", FW_Version);
			iniFile->WriteInteger("TPB", "DownLoad File", FW_Version);
			break;
		}
	}

	delete iniFile;
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::HCBSystemSetup(int programType)
{
}
//---------------------------------------------------------------------------
bool __fastcall TMain_form::ReadUserMachineEnvData(AnsiString fileName, TUserMachineEnv &userMachineEnv)
{
}
//---------------------------------------------------------------------------
bool __fastcall TMain_form::MakePortMapInfo(AnsiString FileName, TPortMapInfo &PortMapInfo, unsigned int machineRev)
{
}
//---------------------------------------------------------------------------
bool __fastcall TMain_form::ReadMachineSetupData(AnsiString fileName, TMachineSetupData &machineSetupData)
{
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::SPBSystemSetup(int spbIndex, int programType)
{
}
//---------------------------------------------------------------------------
bool __fastcall TMain_form::ReadSPBSystemSetupData(AnsiString fileName, TSPBSystemSetupData *spbSystemSetupData,
	TCameraMapInfo *cameraMapInfo)
{
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::executionBtn2Click(TObject *Sender)
{
	BoardShutDown = false;

  // license check
  if(!ApplicationStartOption.noLicenseApplication)
  {
    AnsiString licensename = "";
    AnsiString sysTypeName = "";
    if(ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150T || ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150H)
    {
      licensename = ProgramPath.Capsule + "\\" + cvm15LicenseName;
      sysTypeName = "150C";
    }
    else
    {
      licensename = ProgramPath.Capsule + "\\" + cvm20LicenseName;
      sysTypeName = "200C";
    }

    if(!FileExists(licensename))
    {
      ShowMessageFA("License does not exist [" + sysTypeName + "]");
      return;
    }
  }
  // end

  // board comm check
  if(ApplicationStartOption.CommCheckSW)
  {
    for(int commIndex = 0; commIndex <= ApplicationStartOption.comm_brdCount; commIndex++)
    {
      if (!Comm_IsConnected(commIndex))
      {
        ShowMessageFA("Boards not ready. Please wait a moment.");
        return;
      }
    }
  }
  // end

  // pgm run check
	bool bProgramIsRunning = false;

	if (IsExistProcess(tvmExename))
	{
		bProgramIsRunning = true;
	}
	else if (IsExistProcess(cvmExename))
	{
		bProgramIsRunning = true;
	}

	if (bProgramIsRunning)
	{
		ShowMessageFA("Program is running.");
		return;
	}
  // end

	GroupBox2->Visible = false;
	GroupBox3->Visible = false;

  for(int spbIndex = 0; spbIndex < SYSTEM_SPB_COUNT; spbIndex++)
  {
    checkedSPB[spbIndex] = 0;
  }

  checkedTPB = 0;

	BootingStopButton = 0;

	SystemBootingCommand = BOOT_PROCESS_BOARD_CONNECTION;
	WaitngBar->Position = 0;

	bAllConnected = false;
	ConnectedCount = 0;

	StatusCheckTimer->Enabled = false;
	SystemBootingCheckTimer->Enabled = true;

	bProgramExecution = true;

	executionBtn1->Enabled = false;
	executionBtn2->Enabled = false;

	CurrentFW_HCB = FW_VERSION_HCB_CAPSULE;
	CurrentFW_SPB = FW_VERSION_SPB_CAPSULE;
	CurrentFW_TPB = FW_VERSION_TPB_CAPSULE;
	ProgramType = PROGRAM_CAPSULE_APPLICATION;

  if (ApplicationStartOption.sLaserPath != "" && ApplicationStartOption.LaserComplexer)
  {
    AnsiString ProgramName;
    ProgramName = ApplicationStartOption.sLaserPath + "\\sLaser\\sLaser.exe";
    if (FileExists(ProgramName))
    {
      PROCESS_INFORMATION pinfo;
      STARTUPINFO start;
      memset(&start, 0, sizeof(STARTUPINFO));
      start.cb = sizeof(start);
      start.wShowWindow = SW_SHOWMINNOACTIVE;
      SECURITY_ATTRIBUTES sec;
      sec.nLength = sizeof(sec);
      sec.lpSecurityDescriptor = NULL;
      sec.bInheritHandle = TRUE;

      if(CreateProcess(ProgramName.c_str(), NULL, &sec, &sec, TRUE,
        0, NULL, NULL,  &start, &pinfo) != TRUE)
      {
          //ShowMessage(AnsiString("CreateProcess() failed: ") + GetLastError());
          return;
      }
      else
      {
        Sleep(5000);
        TerminateProcess(pinfo.hProcess,0);//또는 ExitProcess 사용해서 죽임..
      }
    }
  }

	PastFirmwareConfirm(ProgramType);

	Panel5->Visible = true;
	Panel5->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::Panel4DblClick(TObject *Sender)
{
	FWResetBtn->Visible = !FWResetBtn->Visible;
	OptionSettingBtn->Visible = !OptionSettingBtn->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::executionBtn1Click(TObject *Sender)
{
	BoardShutDown = false;

  // license check
  if(!ApplicationStartOption.noLicenseApplication)
  {
    AnsiString licensename = "";
    AnsiString sysTypeName = "";
    if(ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150T || ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150H)
    {
      licensename = ProgramPath.Tablet + "\\" + tvm15LicenseName;
      sysTypeName = "150T";
    }
    else
    {
      licensename = ProgramPath.Tablet + "\\" + tvm20LicenseName;
      sysTypeName = "200T";
    }

    if(!FileExists(licensename))
    {
      ShowMessageFA("License does not exist [" + sysTypeName + "]");
      return;
    }
  }
  // end

  // board comm check
  if(ApplicationStartOption.CommCheckSW)
  {
    for(int commIndex = 0; commIndex <= ApplicationStartOption.comm_brdCount; commIndex++)
    {
      if (!Comm_IsConnected(commIndex))
      {
        ShowMessageFA("Boards not Ready. Please wait a moment.");
        return;
      }
    }
  }
  // end

  // prg run check
  bool bProgramIsRunning = false;

	if (IsExistProcess(tvmExename))
	{
		bProgramIsRunning = true;
	}
	else if (IsExistProcess(cvmExename))
	{
		bProgramIsRunning = true;
	}

	if (bProgramIsRunning)
	{
		ShowMessageFA("Program is running.");
		return;
	}
  // end

	GroupBox2->Visible = false;
	GroupBox3->Visible = false;

  for(int spbIndex = 0; spbIndex < SYSTEM_SPB_COUNT; spbIndex++)
  {
    checkedSPB[spbIndex] = 0;
  }

  checkedTPB = 0;

	BootingStopButton = 0;

	SystemBootingCommand = BOOT_PROCESS_BOARD_CONNECTION;
	WaitngBar->Position = 0;

	bAllConnected = false;
	ConnectedCount = 0;

	StatusCheckTimer->Enabled = false;
	SystemBootingCheckTimer->Enabled = true;

	bProgramExecution = true;

	executionBtn1->Enabled = false;
	executionBtn2->Enabled = false;

	CurrentFW_HCB = FW_VERSION_HCB_TABLET;
	CurrentFW_SPB = FW_VERSION_SPB_TABLET;
	CurrentFW_TPB = FW_VERSION_TPB_TABLET;

	ProgramType = PROGRAM_TABLET_APPLICATION;

	PastFirmwareConfirm(ProgramType);

	Panel5->Visible = true;
	Panel5->Refresh();
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::FormCreate(TObject *Sender)
{
	// 키 모니터 프로그램
	HWND hWndt = FindWindow(NULL, "NFAKeyMonitor");
	if (!hWndt)
	{
		if (FileExists("NFAKEYMONITOR.exe"))
		{
			_SetKeyHookReg("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
				"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer", false);
		}
		ShellExecuteA(NULL, "open", "NFAKeyMonitor.exe", NULL, NULL, SW_SHOW);
	}

	bProgramExecution = false;
}

//---------------------------------------------------------------------------
void __fastcall TMain_form::_SetKeyHookReg(const char* First_PATH, const char* Second_PATH, bool AccessState)
{
	LONG lResult;
	char buffer[100];
	HKEY hKey;
	DWORD dwDesc;
	int LengthSize = 0;
	String data = "";
	// 레지스트리 폴더 확인 후 생성 
	lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
		First_PATH,
		0, KEY_ALL_ACCESS, &hKey);

	if (lResult == ERROR_SUCCESS)
	{
		lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
			First_PATH,
			0, buffer,
			REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
			&hKey, &dwDesc);
		RegCloseKey(hKey);
	}

	lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
		Second_PATH,
		0, KEY_ALL_ACCESS, &hKey);

	if (lResult == ERROR_SUCCESS)
	{
		lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
			Second_PATH,
			0, buffer,
			REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
			&hKey, &dwDesc);
		RegCloseKey(hKey);
	}

	lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
		First_PATH,
		0, KEY_ALL_ACCESS, &hKey);

	if (lResult == ERROR_SUCCESS)
	{
		DWORD Val = 1;

		if (AccessState)
			Val = 0;

		RegSetValueEx(hKey, "DisableChangePassword", 0, REG_DWORD, (LPBYTE)&Val, sizeof(Val));   //(BYTE*)(Tempword.c_str())
		RegSetValueEx(hKey, "DisableLockWorkstation", 0, REG_DWORD, (LPBYTE)&Val, sizeof(Val));   //(BYTE*)(Tempword.c_str())
		RegSetValueEx(hKey, "DisableTaskMgr", 0, REG_DWORD, (LPBYTE)&Val, sizeof(Val));   //(BYTE*)(Tempword.c_str())

		RegCloseKey(hKey);
	}

	lResult = RegOpenKeyEx(HKEY_CURRENT_USER,
		Second_PATH,
		0, KEY_ALL_ACCESS, &hKey);

	if (lResult == ERROR_SUCCESS)
	{
		lResult = RegCreateKeyEx(HKEY_CURRENT_USER,
			Second_PATH,
			0, buffer,
			REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
			&hKey, &dwDesc);
		DWORD Val = 1;

		if (AccessState)
			Val = 0;

		if (lResult == ERROR_SUCCESS)
		{
			lResult = RegSetValueEx(hKey, "NoLogoff", 0, REG_DWORD, (LPBYTE)&Val, sizeof(Val));   //(BYTE*)(Tempword.c_str())
		}
		RegCloseKey(hKey);
	}
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::FormActivate(TObject *Sender)
{
	if(bPgmClose)
  {
    if(bPgmClose == PRG_CLOSE_OPTION_SAVE_AND_EXIT)
    {
      // 파라미터 저장 후 종료
      ShowMessageFA("Restart the program to load the settings.");
    }
    else if(bPgmClose == PRG_CLOSE_OPTION_INVALID_DATA)
    {
      // 기본값 설정하지 않은 상태로 강제 종료
      ShowMessageFA("The program ends because there is no default setting.");
    }

    this->Close();
  }

  if(ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150T ||
      ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_200T)
  {
    executionBtn2->Visible = false;
  }

  tvmExename = ApplicationStartOption.tmsAppName + ".exe";
  cvmExename = ApplicationStartOption.cmsAppName + ".exe";

  tvm15LicenseName = "tvmsm15p.dat";
  tvm20LicenseName = "tvmsm20.dat";
  cvm15LicenseName = "cvmsm15p.dat";
  cvm20LicenseName = "cvmsm20.dat";

  RefreshBoardCountComponents();

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

void __fastcall TMain_form::SetCommParameter()
{
	AnsiString fileName = ProgramPath.Env_Root + "\\CommParams.ini";

	if (FileExists(fileName))
	{
		ReadCommunicationParams(fileName);
	}
	else
	{
		WriteDefaultCommunicationParams(fileName);
		ReadCommunicationParams(fileName);
	}
}

//---------------------------------------------------------------------------
void __fastcall TMain_form::Panel1DblClick(TObject *Sender)
{
	if (Screen->MonitorCount < 2) return;
	this->Align = alCustom;
	if (Screen->MonitorCount < 3)
	{
		if (this->Left == Screen->Monitors[0]->Left)
		{
			this->Top = Screen->Monitors[1]->Top;
			this->Left = Screen->Monitors[1]->Left;
			this->Width = Screen->Monitors[1]->Width;
			this->Height = Screen->Monitors[1]->Height;
		}
		else
		{
			this->Left = Screen->Monitors[0]->Left;
			this->Top = Screen->Monitors[0]->Top;
			this->Width = Screen->Monitors[0]->Width;
			this->Height = Screen->Monitors[0]->Height;
		}
	}
	else if (Screen->MonitorCount < 4)
	{
		if (this->Left == Screen->Monitors[0]->Left)
		{
			this->Top = Screen->Monitors[1]->Top;
			this->Left = Screen->Monitors[1]->Left;
			this->Width = Screen->Monitors[1]->Width;
			this->Height = Screen->Monitors[1]->Height;
		}
		else if (this->Left == Screen->Monitors[1]->Left)
		{
			this->Left = Screen->Monitors[2]->Left;
			this->Top = Screen->Monitors[2]->Top;
			this->Width = Screen->Monitors[2]->Width;
			this->Height = Screen->Monitors[2]->Height;
		}
		else
		{
			this->Left = Screen->Monitors[0]->Left;
			this->Top = Screen->Monitors[0]->Top;
			this->Width = Screen->Monitors[0]->Width;
			this->Height = Screen->Monitors[0]->Height;
		}
	}
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::SetCommTypeLabel()
{
	//1-usb all 2-hcb-usb/tcp-spb  3-tcp all

	for (int commIndex = 1; commIndex <= MAX_COMM_COUNT; commIndex++)
	{
		TLabel *tempLabel = (TLabel *)FindComponent("CommTypeLabel" + IntToStr(commIndex));

		if (tempLabel)
		{
			if (ApplicationStartOption.SelectedCommType == SYSTEM_INFO_COMM_TYPE_USB)
			{
				tempLabel->Caption = "USB";
			}
			else if (ApplicationStartOption.SelectedCommType == SYSTEM_INFO_COMM_TYPE_HYBRID)
			{
				if (commIndex - 1 == COMM_HCB)
				{
					tempLabel->Caption = "USB";
				}
				else
				{
					tempLabel->Caption = "TCP/IP";
				}
			}
			else if (ApplicationStartOption.SelectedCommType == SYSTEM_INFO_COMM_TYPE_TCP_IP)
			{
				tempLabel->Caption = "TCP/IP";
			}
		}

	}
}
//---------------------------------------------------------------------------
void __fastcall TMain_form::StatusCheckTimerTimer(TObject *Sender)
{
	if (!InitDlayTimer) return;
	else Timer1->Enabled = false;
	// 프로그램 실행상태 확인
	int ProgramIsRunning = 0;

	SetCommTypeLabel();

	if (IsExistProcess(tvmExename))
	{
		ProgramIsRunning = 1;
	}
	else if (IsExistProcess(cvmExename))
	{
		ProgramIsRunning = 2;
	}

	if (ProgramIsRunning == 1)
	{
    if(ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150T || ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150H)
    {
		  Label4->Caption = "Tablet 150 Inspection Program";
    }
    else
    {
      Label4->Caption = "Tablet 200 Inspection Program";
    }

    Label4->Font->Color = clLime;

		TntShape1->Pen->Color = clLime;
		TntShape1->Brush->Color = clLime;
	}
	else if (ProgramIsRunning == 2)
	{
    if(ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150T || ApplicationStartOption.MachineType == SYSTEM_INFO_MACHINE_TYPE_150H)
    {
		  Label4->Caption = "Capsule 150 Inspection Program";
    }
    else
    {
      Label4->Caption = "Capsule 200 Inspection Program";
    }

		Label4->Font->Color = clLime;

		TntShape1->Pen->Color = clLime;
		TntShape1->Brush->Color = clLime;
	}
	else
	{
		Label4->Caption = "Program is not running.";
		Label4->Font->Color = clRed;

		TntShape1->Pen->Color = clRed;
		TntShape1->Brush->Color = clRed;
	}

	if (!bProgramExecution)
	{
		//double starttime, endtime;
		StatusCheckTimer->Enabled = false;

		Application->ProcessMessages();
		// 보드 연결상태 확인
		if (!ProgramIsRunning)
		{
			//starttime = GetTickCount();
			VersionCheckProcess();
			//endtime = GetTickCount();
			//int diff = endtime - starttime;

			bStatusCheckTimerSw = false;
			if (HCBVersionLabel->Caption != "DISCONNECTED")
			{
				if (HCBVersionLabel->Caption.SubString(HCBVersionLabel->Caption.Length(), 1) == "T")
				{
					if (DownCode[0] != 0)
					{
						DownCode[0] = 0;
						executionBtn1->Left = 260;//260
						executionBtn1->Top = 525;
						executionBtn1->Height = 530;
						executionBtn1->Width = 578;

						executionBtn2->Left = 28; //28
						executionBtn2->Top = 1059; //TPB added  //1131 orignal;
						executionBtn2->Height = 300;
						executionBtn2->Width = 300;
					}
				}
				else if (HCBVersionLabel->Caption.SubString(HCBVersionLabel->Caption.Length(), 1) == "C")
				{
					if (DownCode[0] != 1)
					{
						DownCode[0] = 1;
						executionBtn2->Left = 260;
						executionBtn2->Top = 525;
						executionBtn2->Height = 530;
						executionBtn2->Width = 578;

						executionBtn1->Left = 28;
						executionBtn1->Top = 1059; //TPB added 1131;
						executionBtn1->Height = 300;
						executionBtn1->Width = 300;
					}
				}
				else
				{
					DownCode[0] = -1;

					if (PastFW_HCB == 1)
					{
						executionBtn1->Left = 500;//260
						executionBtn1->Top = 1059; //TPB added 1131;
						executionBtn1->Height = 300;
						executionBtn1->Width = 300;

						executionBtn2->Left = 28; //28
						executionBtn2->Top = 1059; //TPB added 1131;
						executionBtn2->Height = 300;
						executionBtn2->Width = 300;
					}
					else if (PastFW_HCB == 2)
					{
						executionBtn2->Left = 500;//260
						executionBtn2->Top = 1059; //TPB added 1131;
						executionBtn2->Height = 300;
						executionBtn2->Width = 300;

						executionBtn1->Left = 28; //28
						executionBtn1->Top = 1059; //TPB added 1131;
						executionBtn1->Height = 300;
						executionBtn1->Width = 300;
					}
					else
					{
						executionBtn1->Left = 500;//260
						executionBtn1->Top = 1059; //TPB added 1131;
						executionBtn1->Height = 300;
						executionBtn1->Width = 300;

						executionBtn2->Left = 28; //28
						executionBtn2->Top = 1059; //TPB added 1131;
						executionBtn2->Height = 300;
						executionBtn2->Width = 300;
					}
				}
			}
		}

		StatusCheckTimer->Enabled = true;
	}
}
//---------------------------------------------------------------------------

bool __fastcall TMain_form::IsExistProcess(AnsiString ProcessName)
{
	bool           ret = false;
	HANDLE         hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (hProcess != NULL) {
		PROCESSENTRY32 pe32 = { 0 };
		pe32.dwSize = sizeof(PROCESSENTRY32);

		if (Process32First(hProcess, &pe32)) {
			do {
				if (AnsiString(pe32.szExeFile) == ProcessName) {
					ret = true;
					break;
				}
			} while (Process32Next(hProcess, &pe32));
		}
		CloseHandle(hProcess);
	}

	return ret;
}
//---------------------------------------------------------------------------


void __fastcall TMain_form::SystemBootingCheckTimerTimer(TObject *Sender)
{
	bBootingCheckTimerEnabled = SystemBootingCheckTimer->Enabled;
	SystemBootingCheckTimer->Enabled = false;

	SystemBootingProcess();

	WaitngBar->Position++;
	if (WaitngBar->Position == WaitngBar->Max)
	{
		WaitngBar->Position = WaitngBar->Min;
	}

	WaitingTimeCount++;

	SystemBootingCheckTimer->Enabled = bBootingCheckTimerEnabled;
}
//---------------------------------------------------------------------------

bool __fastcall TMain_form::KillProcess(AnsiString ProcessName)
{
	HANDLE         hProcessSnap = NULL;
	DWORD          Return = FALSE;
	PROCESSENTRY32 pe32 = { 0 };

	ProcessName.LowerCase();

	hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return (DWORD)INVALID_HANDLE_VALUE;

	pe32.dwSize = sizeof(PROCESSENTRY32);

	if (Process32First(hProcessSnap, &pe32))
	{
		DWORD Code = 0;
		DWORD dwPriorityClass;

		do {
			HANDLE hProcess;
			hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
			dwPriorityClass = GetPriorityClass(hProcess);

			AnsiString Temp = pe32.szExeFile;
			Temp.LowerCase();

			if (Temp == ProcessName)
			{
				if (TerminateProcess(hProcess, 0))
					GetExitCodeProcess(hProcess, &Code);
				else
					return GetLastError();
			}

			CloseHandle(hProcess);
		}

		while (Process32Next(hProcessSnap, &pe32));
		Return = TRUE;
	}
	else
		Return = FALSE;

	CloseHandle(hProcessSnap);

	return Return;
}

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

bool __fastcall TMain_form::BoardBootingCheckProcess(int BoardType)
{
	bool returnValue;
	if (BoardType == BOARD_TYPE_SPB)
	{
		// 카메라 부팅 및 Tcp/Ip 연결상태 확인
		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
		{
			if (!Comm_IsConnected(spbIndex + 1) && !checkedSPB[spbIndex])
			{
				Comm_Connect(COMM_SPB + spbIndex);
			}
		}

		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
		{
			if (Comm_IsConnected(spbIndex + 1))
			{
				checkedSPB[spbIndex] = 1;
				Comm_Disconnect(COMM_SPB + spbIndex);
			}
		}

		int spbBootCount = 0;
		int ConnectedBoardCount = 0;

		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
		{
			if (bConnectedBoard[COMM_SPB + spbIndex])
			{
				ConnectedBoardCount++;
			}
		}

		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
		{
			if (checkedSPB[spbIndex])
			{
				spbBootCount++;
			}
		}

		if (spbBootCount == ConnectedBoardCount)
		{
			returnValue = true;
		}
		else
		{
			returnValue = false;
		}
	}
	else if (BoardType == BOARD_TYPE_HCB)
	{
		//Tcp/Ip(USB) 연결상태 확인

		if (bConnectedBoard[COMM_HCB])
		{
			if (!Comm_IsConnected(COMM_HCB))
			{
				Comm_Connect(COMM_HCB);
			}

			if (Comm_IsConnected(COMM_HCB))
			{
				Comm_Disconnect(COMM_HCB);

				returnValue = true;
			}
			else
			{
				returnValue = false;
			}
		}
		else
		{
			returnValue = true;
		}
	}
	else if (BoardType == BOARD_TYPE_TPB)
	{
	
		if (bConnectedBoard[COMM_TPB])
		{
			if (!Comm_IsConnected(COMM_TPB))
			{
				Comm_Connect(COMM_TPB);
			}

			if (Comm_IsConnected(COMM_TPB))
			{
				Comm_Disconnect(COMM_TPB);

				returnValue = true;			
			}
			else
			{
				returnValue = false;	
			}
		}
		else
		{
			returnValue = true;
		}

	}

	return returnValue;
}

//---------------------------------------------------------------------------
void __fastcall TMain_form::SystemBootingProcess()
{
	HWND hWnd;
	AnsiString ProgramName;

	switch (SystemBootingCommand)
	{
	case BOOT_PROCESS_BOARD_CONNECTION:

		Comm_Connect(COMM_HCB);
		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
		{
			Comm_Connect(COMM_SPB + spbIndex);
		}

		if(ApplicationStartOption.TPB_OperationMode)	Comm_Connect(COMM_TPB);
		
		SystemBootingCommand = BOOT_PROCESS_STABLE_WAITING1;
		timeCheck = WaitingTimeCount;
		break;

	case BOOT_PROCESS_STABLE_WAITING1:

		for (int commIndex = 0; commIndex < MAX_COMM_COUNT; commIndex++)
		{
			bConnectedBoard[commIndex] = false;
			if (Comm_IsConnected(commIndex))
			{
				ConnectedCount++;
				bConnectedBoard[commIndex] = true;
			}
		}

		if (ConnectedCount == MAX_COMM_COUNT)
		{
			bAllConnected = true;
		}

		if (bAllConnected)
		{
			SystemBootingCommand = BOOT_PROCESS_CHECK_SPB_VERSION;
		}
		else if (WaitingTimeCount - timeCheck > 150) // 1500ms
		{
			SystemBootingCommand = BOOT_PROCESS_CHECK_SPB_VERSION;
		}

		break;

	case BOOT_PROCESS_CHECK_SPB_VERSION:

		if (PastFW_SPB != CurrentFW_SPB)
		{
			SystemBootingCommand = BOOT_PROCESS_SPB_BOOTING;
		}
		else
		{
			SystemBootingCommand = BOOT_PROCESS_CHECK_HCB_VERSION;
		}
		break;

	case BOOT_PROCESS_SPB_BOOTING:

		SPB_ProgramReset(ProgramType);
		if (BoardShutDown == true)
		{
			SystemBootingCommand = BOOT_PROCESS_HCB_BOOTING;
		}
		else
		{
			SystemBootingCommand = BOOT_PROCESS_LOAD_SPB;
			timeCheck = WaitingTimeCount;
		}

		break;

		/*
		case BOOT_PROCESS_STABLE_WAITING2:

		if(WaitingTimeCount - timeCheck > 500) // 5000ms
		SystemBootingCommand = BOOT_PROCESS_LOAD_SPB;
		break;
		*/

	case BOOT_PROCESS_LOAD_SPB:

		Application->ProcessMessages();
		if (BoardBootingCheckProcess(BOARD_TYPE_SPB))
		{
			SystemBootingCommand = BOOT_PROCESS_CHECK_HCB_VERSION;
		}
		else if (WaitingTimeCount - timeCheck > 2000) // 20000ms
		{
			SystemBootingCommand = BOOT_PROCESS_CHECK_HCB_VERSION;
		}
		break;

	case BOOT_PROCESS_CHECK_HCB_VERSION:

		if (PastFW_HCB != CurrentFW_HCB)
		{
			SystemBootingCommand = BOOT_PROCESS_HCB_BOOTING;
		}		
		/*
		else
		{
			//SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
			SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
		}
		*/
		else
		{
			if(ApplicationStartOption.TPB_OperationMode == 0)
			{
				SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;							
			}
			else
			{
				SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
			}
		}

		
		break;

	case BOOT_PROCESS_HCB_BOOTING:

		HCB_ProgramReset(ProgramType);
		/*
		if (BoardShutDown == true)
		{
			SystemBootingCommand = BOOT_PROCESS_TPB_BOOTING;
			//SystemBootingCommand = BOOT_PROCESS_VARIABLE_INITIAL;
		}
		*/
		if (BoardShutDown == true)
		{
			if(ApplicationStartOption.TPB_OperationMode == 0)
			{
				SystemBootingCommand = BOOT_PROCESS_VARIABLE_INITIAL;
			}
			else
			{
				SystemBootingCommand = BOOT_PROCESS_TPB_BOOTING;
			}
		}	
		else
		{
			SystemBootingCommand = BOOT_PROCESS_LOAD_HCB;
			timeCheck = WaitingTimeCount;
		}

		break;

		/*
		case BOOT_PROCESS_STABLE_WAITING3:

		if(WaitingTimeCount - timeCheck > 400) // 4000ms
		SystemBootingCommand = BOOT_PROCESS_LOAD_HCB;
		break;
		*/

	case BOOT_PROCESS_LOAD_HCB:

		Application->ProcessMessages();
		/*
		if (BoardBootingCheckProcess(BOARD_TYPE_HCB))
		{
			//SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
			SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
		}
		else if (WaitingTimeCount - timeCheck > 2000) // 20000ms
		{
			//SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
			SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
		}
		*/
		if(ApplicationStartOption.TPB_OperationMode == 0)
		{
			if (BoardBootingCheckProcess(BOARD_TYPE_HCB))
			{
				SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
			}
			else if (WaitingTimeCount - timeCheck > 2000) // 20000ms
			{
				SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
			}
		}
		else
		{
			if (BoardBootingCheckProcess(BOARD_TYPE_HCB))
			{
				SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
			}
			else if (WaitingTimeCount - timeCheck > 2000) // 20000ms
			{
				SystemBootingCommand = BOOT_PROCESS_CHECK_TPB_VERSION;
			}
		}
		break;
		
	case BOOT_PROCESS_CHECK_TPB_VERSION:

		if (PastFW_TPB != CurrentFW_TPB)
		{
			SystemBootingCommand = BOOT_PROCESS_TPB_BOOTING;
		}
		else
		{
			SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
		}
		break;

	case BOOT_PROCESS_TPB_BOOTING:

		TPB_ProgramReset(ProgramType);
		if (BoardShutDown == true)
		{
			SystemBootingCommand = BOOT_PROCESS_VARIABLE_INITIAL;
		}
		else
		{
			SystemBootingCommand = BOOT_PROCESS_LOAD_TPB;
			timeCheck = WaitingTimeCount;
		}
    break;

	case BOOT_PROCESS_LOAD_TPB:

		Application->ProcessMessages();
		if (BoardBootingCheckProcess(BOARD_TYPE_TPB))
		{
			SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;
		}
		else if (WaitingTimeCount - timeCheck > 2000) // 20000ms
		{
			SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;			
		}
		break;

	case BOOT_PROCESS_BOARD_DISCONNECTION:

		for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
			Comm_Disconnect(COMM_SPB + spbIndex);

		Application->ProcessMessages();
		Sleep(500);

		Comm_Disconnect(COMM_TPB);

		Application->ProcessMessages();
		Sleep(500);

		Comm_Disconnect(COMM_HCB);

		if (!BootingStopButton)
		{
			SystemBootingCommand = BOOT_PROCESS_STABLE_WAITING4;
			timeCheck = WaitingTimeCount;
		}
		else
		{
			SystemBootingCommand = BOOT_PROCESS_VARIABLE_INITIAL;
		}
		break;

	case BOOT_PROCESS_STABLE_WAITING4:

		if (WaitingTimeCount - timeCheck > 300) // 3000ms
			SystemBootingCommand = BOOT_PROCESS_EXECUTION_UI;
		break;

	case BOOT_PROCESS_EXECUTION_UI:

    if(ApplicationStartOption.LaserComplexer)
    {
      RunsLaser();
    }

		hWnd = ::GetActiveWindow();
		SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);//| SWP_SHOWWINDOW
		ProgramName = ApplicationProgramName(ProgramType);
		ProgramExecution(ProgramName);
		SystemBootingCommand = BOOT_PROCESS_VARIABLE_INITIAL;
		break;

	case BOOT_PROCESS_VARIABLE_INITIAL:

		Panel5->Visible = false;
		executionBtn1->Enabled = true;
		executionBtn2->Enabled = true;
		bProgramExecution = false;
		bBootingCheckTimerEnabled = false;
		StatusCheckTimer->Enabled = true;
		GroupBox3->Visible = true;
		GroupBox2->Visible = true;
		break;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::Panel7Click(TObject *Sender)
{
	BootingStopButton = 1;
	SystemBootingCommand = BOOT_PROCESS_BOARD_DISCONNECTION;

	PastFW_SPB = 10; // Default set
	PastFW_HCB = 10; // Default set
	PastFW_TPB = 10; // Default set

	DownloadFirmwareReport(ProgramType, PastFW_SPB);
	DownloadFirmwareReport(ProgramType, PastFW_HCB);
	if(ApplicationStartOption.TPB_OperationMode) DownloadFirmwareReport(ProgramType, PastFW_TPB);
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::Panel7MouseDown(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	Panel7->Color = clBlue;
	Panel7->Font->Color = clWhite;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::Panel7MouseUp(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	Panel7->Color = clGray;
	Panel7->Font->Color = clBlack;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::VersionCheckProcess()
{
	TCPOn_Board = 0;
	if(!Comm_IsConnected(COMM_HCB))
	{
		Comm_Connect(COMM_HCB);
	}
	
	for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
	{
		if(!Comm_IsConnected(COMM_SPB + spbIndex))
		{	
		   	Application->ProcessMessages();
			Comm_Connect(COMM_SPB + spbIndex);
		}
	}
	
	if(ApplicationStartOption.TPB_OperationMode) 
	{
		if(!Comm_IsConnected(COMM_TPB))
		{
			Comm_Connect(COMM_TPB);
		}

	}
	bStatusCheckTimerSw = true;

	if (Comm_IsConnected(COMM_HCB))
	{
		BoardCommStatusShape1->Pen->Color = clLime;
		BoardCommStatusShape1->Brush->Color = clLime;
	}
	else
	{
		BoardCommStatusShape1->Pen->Color = clRed;
		BoardCommStatusShape1->Brush->Color = clRed;
	}

	for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
	{
		TTntShape *tempShape = (TTntShape *)FindComponent("BoardCommStatusShape" + IntToStr(spbIndex + 2));

		if (tempShape)
		{
			if (Comm_IsConnected(spbIndex + 1))
			{
				tempShape->Pen->Color = clLime;
				tempShape->Brush->Color = clLime;
				TCPOn_Board ++;
			}
			else
			{
				tempShape->Pen->Color = clRed;
				tempShape->Brush->Color = clRed;
			}
		}
	}
	if(TCPOn_Board > 1 && TCPOn_Board != ApplicationStartOption.comm_brdCount)
	{
		TCPOn_Time++;
		if(TCPOn_Time > 4)
		{
			if(TCP_Check_Progress ==0)
			{
        WaitngBar->Max = 20;
				Panel5->Visible = true;
				Panel5->Refresh();		
				TCP_Check_Progress =1;
			}
			
			WaitngBar->Position++;
			if (WaitngBar->Position <= WaitngBar->Max)
			{
				WaitngBar->Position = WaitngBar->Min;
			}
		}
	}
	else
	{
		TCPOn_Time = 0;
    WaitngBar->Max = 250;
		TCP_Check_Progress = 0;
		WaitngBar->Position = 0;
		Panel5->Visible = false;
	}

	if (Comm_IsConnected(COMM_TPB))
	{
		BoardCommStatusShape10->Pen->Color = clLime;
		BoardCommStatusShape10->Brush->Color = clLime;
	}
	else
	{
		BoardCommStatusShape10->Pen->Color = clRed;
		BoardCommStatusShape10->Brush->Color = clRed;
	}

	bool validHCBVersion = false;
	bool validSPBVersion[SYSTEM_SPB_COUNT] = {false, };
	bool validTPBVersion = false;

	memset(&HCBVersion, 0, sizeof(TProgramVersion));
	memset(&SPBVersion, 0, sizeof(TProgramVersion) * SYSTEM_SPB_COUNT);
	memset(&TPBVersion, 0, sizeof(TProgramVersion));

	if (Comm_IsConnected(COMM_HCB))
	{
		if (Comm_Request(COMM_HCB, CMD_VERSION_INFO, NULL, 0, &HCBVersion, sizeof(TProgramVersion)))
		{
			validHCBVersion = true;
		}
		else
		{
			//Comm_Disconnect(COMM_HCB);
		}
	}

	for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
	{
		if (Comm_IsConnected(COMM_SPB + spbIndex))
		{
			if (Comm_Request(COMM_SPB + spbIndex, CMD_VERSION_INFO, NULL, 0, &SPBVersion[spbIndex], sizeof(TProgramVersion)))
			{
				validSPBVersion[spbIndex] = true;
			}
			else
			{
				//Comm_Disconnect(COMM_SPB + spbIndex);
			}
		}
	}

	if(ApplicationStartOption.TPB_OperationMode)
	{
		if (Comm_IsConnected(COMM_TPB))
		{
			if (Comm_Request(COMM_TPB, CMD_VERSION_INFO, NULL, 0, &TPBVersion, sizeof(TProgramVersion)))
			{
				validTPBVersion = true;
			}
			else
			{
				//Comm_Disconnect(COMM_TPB);
			}
		}
	}

	WideString tmpWStr;
	tmpWStr.SetLength(100);

	if (validHCBVersion)
	{
		HCBVersionLabel->Font->Color = clLime;
		wsprintfW(tmpWStr, L"%d.%d.%d.%c", HCBVersion.MajorVersion, HCBVersion.MinorVersion, HCBVersion.Date, HCBVersion.Type & 0xFF);
		HCBVersionLabel->Caption = tmpWStr;
	}
	else
	{
		HCBVersionLabel->Font->Color = clRed;
		HCBVersionLabel->Caption = "DISCONNECTED";
	}

	for (int spbIndex = 0; spbIndex < ApplicationStartOption.comm_brdCount; spbIndex++)
	{
		TLabel *versionLabel = (TLabel *)FindComponent("SPBVersionLabel" + IntToStr(spbIndex + 1));
		if (versionLabel)
		{
			if (validSPBVersion[spbIndex])
			{
				versionLabel->Font->Color = clLime;
				wsprintfW(tmpWStr, L"%d.%d.%d.%c", SPBVersion[spbIndex].MajorVersion, SPBVersion[spbIndex].MinorVersion, SPBVersion[spbIndex].Date, SPBVersion[spbIndex].Type & 0xFF);
				versionLabel->Caption = tmpWStr;

				if (versionLabel->Caption.SubString(versionLabel->Caption.Length(), 1) == "T")
				{
					DownCode[spbIndex + 1] = 0;
				}
				else if (versionLabel->Caption.SubString(versionLabel->Caption.Length(), 1) == "C")
				{
					DownCode[spbIndex + 1] = 1;
				}
				else
				{
					DownCode[spbIndex + 1] = -1;
				}
			}
			else
			{
				versionLabel->Font->Color = clRed;
				versionLabel->Caption = "DISCONNECTED";
				InitDlayTimer = false;
			}
		}
	}

	if (validTPBVersion)
	{
		TPBVersionLabel->Font->Color = clLime;
		wsprintfW(tmpWStr, L"%d.%d.%d.%c", TPBVersion.MajorVersion, TPBVersion.MinorVersion, TPBVersion.Date, TPBVersion.Type & 0xFF);
		TPBVersionLabel->Caption = tmpWStr;

		if (TPBVersionLabel->Caption.SubString(TPBVersionLabel->Caption.Length(), 1) == "T")
		{
			DownCode[COMM_TPB] = 0;
		}
		else if (TPBVersionLabel->Caption.SubString(TPBVersionLabel->Caption.Length(), 1) == "C")
		{
			DownCode[COMM_TPB] = 1;
		}
		else
		{
			DownCode[COMM_TPB] = -1;
		}
	}
	else
	{
		TPBVersionLabel->Font->Color = clRed;
		TPBVersionLabel->Caption = "DISCONNECTED";
	}
	
  RefreshBoardCountComponents();
  
	if (InitDlayTimer == false)
	{
		Timer1->Enabled = true;
	}
}

//---------------------------------------------------------------------------
void __fastcall TMain_form::Timer1Timer(TObject *Sender)
{
	InitDlayTimer = true;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::FWResetBtnClick(TObject *Sender)
{
	PastFW_SPB = 10; // Default set
	PastFW_HCB = 10; // Default set
	PastFW_TPB = 10; // Default set

	DownloadFirmwareReport(ProgramType, PastFW_SPB);
	DownloadFirmwareReport(ProgramType, PastFW_HCB);
	if(ApplicationStartOption.TPB_OperationMode)	DownloadFirmwareReport(ProgramType, PastFW_TPB);

	StatusCheckTimer->Enabled = false;
	bProgramExecution = false;
	for (int commIndex = 0; commIndex <= ApplicationStartOption.comm_brdCount; commIndex++)
	{
		Comm_Connect(commIndex);
		if (!Comm_IsConnected(commIndex))
    {
      Comm_Recover(commIndex);
    }
	}

	ShowMessageFA("Complete!");
	StatusCheckTimer->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::OptionSettingBtnClick(TObject *Sender)
{
  StatusCheckTimer->Enabled = false;

  bool bClose = false;
  TOptionSettingForm *OptionSettingForm = new TOptionSettingForm(this);
  OptionSettingForm->bDefault = false;
  OptionSettingForm->bChangeParams = false;

  if(OptionSettingForm->ShowModal() == mrOk)
  {
    if(OptionSettingForm->bChangeParams)
    {
      // 파라미터 저장 후 종료
      ShowMessageFA("Restart the program to load the settings.");
      bClose = true;
    }
  }

  delete OptionSettingForm;

  if(bClose)
  {
    this->Close();
  }

  StatusCheckTimer->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TMain_form::RefreshBoardCountComponents()
{
  int componentHeight = 34;// designed
  int unVisibleCount = 0;

  int BoardCount  = ApplicationStartOption.comm_brdCount;

  if (HCBVersionLabel->Caption.SubString(HCBVersionLabel->Caption.Length(), 1) == "C")
  {
  	if(ApplicationStartOption.TPB_OperationMode == 0)
  	{
	    if(BoardCount > 6)
	      BoardCount = 6;
  	}
  }
  

  for (int spbIndex = 0; spbIndex < SYSTEM_SPB_COUNT; spbIndex++)
  {
    TLabel *IPBNumberLabel = (TLabel *)FindComponent("IPBNumberLabel" + IntToStr(spbIndex + 1));
    TLabel *CommTypeLabel = (TLabel *)FindComponent("CommTypeLabel" + IntToStr(spbIndex + 2));
    TLabel *SPBVersionLabel = (TLabel *)FindComponent("SPBVersionLabel" + IntToStr(spbIndex + 1));
    TTntShape *tempShape = (TTntShape *)FindComponent("BoardCommStatusShape" + IntToStr(spbIndex + 2));

    if(spbIndex < BoardCount)
    {
      if(IPBNumberLabel)
      {
        IPBNumberLabel->Visible = true;
      }

      if(CommTypeLabel)
      {
        CommTypeLabel->Visible = true;
      }

      if(SPBVersionLabel)
      {
        SPBVersionLabel->Visible = true;
      }

      if(tempShape)
      {
        tempShape->Visible = true;
      }
    }
    else
    {
      if(IPBNumberLabel)
      {
        IPBNumberLabel->Visible = false;
      }

      if(CommTypeLabel)
      {
        CommTypeLabel->Visible = false;
      }

      if(SPBVersionLabel)
      {
        SPBVersionLabel->Visible = false;
      }

      if(tempShape)
      {
        tempShape->Visible = false;
      }

      unVisibleCount++;
    }
  }

 	if(ApplicationStartOption.TPB_OperationMode == 0)
 	{
 		TPBNumberLabel->Visible = false;
 		CommTypeLabel10->Visible = false;
 		TPBVersionLabel->Visible = false;
 		BoardCommStatusShape10->Visible = false;
 	}
 	else
 	{
 		TPBNumberLabel->Visible = true;
 		CommTypeLabel10->Visible = true;
 		TPBVersionLabel->Visible = true;
 		BoardCommStatusShape10->Visible = true;
 	}

	if(ApplicationStartOption.TPB_OperationMode == 0)	GroupBox3->Height = 362 - componentHeight * unVisibleCount;
	else GroupBox3->Height = 394; //TPB added

	if(BoardCount== 6)
	{
    if(ApplicationStartOption.TPB_OperationMode == 0)
    {
		//executionBtn2->Top = 1131;
		GroupBox2->Top = 1356;//1284;
 		GroupBox3->Height = 294;
    GroupBox3->Top = 1447;
    }
    else
    {
		//executionBtn2->Top = 1131;
		GroupBox2->Top = 1356;//1284;
 		TPBNumberLabel->Top = 280;
 		CommTypeLabel10->Top = 280;
 		TPBVersionLabel->Top = 280;
 		BoardCommStatusShape10->Top = 280;
 		GroupBox3->Height = 324;
    GroupBox3->Top = 1447;
    }
	}
	else
	{
    if(ApplicationStartOption.TPB_OperationMode == 0)
    {
		//executionBtn2->Top = 1131;
		GroupBox2->Top = 1356;//1284;
 		GroupBox3->Height = 364;
    GroupBox3->Top = 1447;
    }
    else
    {
		//executionBtn2->Top = 1131;//1059;
		GroupBox2->Top = 1356;//1356;
 		TPBNumberLabel->Top = 350;
 		CommTypeLabel10->Top = 350;
 		TPBVersionLabel->Top = 350;
 		BoardCommStatusShape10->Top = 353;
 		GroupBox3->Height = 394;
    GroupBox3->Top = 1447;
    }  
	}
	
}

//---------------------------------------------------------------------------
void __fastcall TMain_form::RunsLaser()
{
  if (HCBVersionLabel->Caption.SubString(HCBVersionLabel->Caption.Length(), 1) == "T")
  {
    AnsiString ProgramName;
    ProgramName = ApplicationStartOption.sLaserPath + "\\sLaser\\sLaser.exe";
    if (FileExists(ProgramName))
    {
      ShellExecute(NULL, "open", ProgramName.c_str(), NULL, NULL, SW_SHOW);
    }
    else
    {
      ShowMessageFA("[sLaser.exe] does not exist.");
    }
  }
}
//---------------------------------------------------------------------------

