//---------------------------------------------------------------------------
#include <vcl.h>
#include <registry.hpp>
#include <inifiles.hpp>
#pragma hdrstop

#include <windows.h>
#include <process.h>
#include <io.h>                                                 
#include <conio.h>

#include "Main_Form.h"
#include "LogIn_Form.h"                                                               
#include "Environment.h"
#include "Message_Form.h"
#include "SetPath_Form.h"                                                                                                                                                                                                                  
#include "SystemSetting_Form.h"
//#include "MachineSetup_Form.h"
#include "MachineSetupMenu_Form.h"                                                                                                                                                                   
#include "Calibration_Form.h"
#include "Inspection_Form.h"                                                                                          
#include "MachineControl_Form.h"                                                                                 
#include "ErrorList_Form.h"                                                                                                                          
#include "Study_Form.h"
#include "TabletCharacterExtract.h"
#include "ProductInput_Form.h"                                                                                             
#include "Alarm_Form.h"
#include "First_Study.h"
#include "UserRegister_Form.h"
#include "MachineTest_Form.h"
#include "InspectionReport_Form.h"
#include "EnvironmentSetting_Form.h"
#include "CameraSetting3D_Form.h"
#include "AuditTrail_Form.h"
#include "InspectionRecover_Form.h"
#include "Keyboard_Form.h"
#include "GradeSetting.h"
#include "MouseHook.h"
#include "NCControl_Form.h"
#include "AdvMachineControl_Form.h"                
#include "CPBStatus_Form.h"
#include "DataMatching_Form.h"
#include "MachineControl.h"
#include "Waiting_Form.h"
#include "QuickStart_Form.h"
#include "MultiLanguage.h"
#include "SystemSimulation_Form.h"
#include "UserAuthoritySetting_Form.h"
#include "ThreeDSensorStatusCheck_Form.h"
#include "VisionSetting_Form.h"

#include <tlhelp32.h>
#include <shellapi.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"
TMainForm *MainForm;
HHOOK hHook;
unsigned int LastUserActiveTime;
unsigned int doorlock_refresh_main = 0;
AnsiString space;
//q사 dll 관련작업
OBJ_INIT obj_init;
OBJ_TERM obj_term;
OBJ_GETPORTTYPE obj_getporttype;
OBJ_SETINPORT obj_setinport;
OBJ_GETOUTPORT obj_getoutport;
OBJ_SETSTATUS obj_setstatus;
OBJ_GETCOMMAND obj_getcommand;
OBJ_SETPRODUCTINFO obj_setproductinfo;
OBJ_SETPARAMINFO obj_setparaminfo;
OBJ_SETALARMINFO obj_setalarminfo;
OBJ_GETOBJSTATUS obj_getobjstatus;
OBJ_ERRORRESET obj_errorreset;
OBJ_SEQCLEAR obj_seqclear;
OBJ_SETEXECOMMAND obj_setexecommand;
HINSTANCE hDllInstance = NULL;
HINSTANCE hNFALaserDll = NULL;

DWORD ThreadDword = 0;
HANDLE DLLLoadThreadHandle;
int last_laser_command;
int Laser_dll_timer_count = 0;
int HCB_DisConnect_count = 0;

TMESProductData MESProductData;
//cjg OPC Test
HINSTANCE hOPC_DLL = NULL;
int (*pSetMachineAlarmState)(TMachineAlarmState *);
int (*pSetMESProductData)(TMESProductData *);

TCheckCamTimeOut CheckCamTimeOut;
//---------------------------------------------------------------------------
LRESULT CALLBACK MouseHook(int code, WPARAM wParam, LPARAM lParam)
{
  if((int)wParam != 0x200) //MouseMove 제외
  {
    LastUserActiveTime = GetTickCount();
  }
  return CallNextHookEx(hHook,code,wParam,lParam);
}

unsigned int WINAPI QDllLoadThread(PVOID pData)
{
  TMainForm * MainForm =  (TMainForm*)pData;
  if (obj_init != NULL)
  {
    if(!obj_init())
    {
      //ShowMessageFA("MCPInit Error!");
    }
    else
    {
      //UVLaser.UVLaserStatus.DLLLoadStatus = true;
    }
  }
  _endthreadex(0);
}

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
	: TTntForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
	else if (DefaultLCID == 1041)
  {
		ComponentSetFontName(this, "Meiryo UI");
    Application->Title = "ACROCIA";
  }
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }
    
	ActiveSubForm = NULL;
	UserInfo.AccessLevel = SYSTEM_ACCESS_LEVEL_ANONYMOUS;
	MachineSetupComplete = false;
	this->Width = Screen->Width;
	this->Height = Screen->Height;

	AlarmForm = new TAlarmForm(Application);
	IP_ConnectCheckTimer = 0;
	BlackOutFlag = 0;
	LastSafetyMode = 0;
	LastHeaveyAlarmState =false;
	MachineOffFlag = false;   
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::GetDefalutString()
{
	StudyButton->Caption = MAINFORM_BUTTON_CAPTION_01;
	LogOutButton->Caption = MAINFORM_BUTTON_CAPTION_02;
	AuditTrailButton->Caption = MAINFORM_BUTTON_CAPTION_03;
	InspectionButton->Caption = MAINFORM_BUTTON_CAPTION_04;
	InspectionReportButton->Caption = MAINFORM_BUTTON_CAPTION_05;
	MachineSetupButton->Caption = MAINFORM_BUTTON_CAPTION_06;
	ReadyButton->Caption = MAINFORM_BUTTON_CAPTION_07;
	SystemSettingButton->Caption = MAINFORM_BUTTON_CAPTION_08;
	CalibrationButton->Caption = MAINFORM_BUTTON_CAPTION_09;
	UserRegisterButton->Caption = MAINFORM_BUTTON_CAPTION_10;
	MachineControlButton->Caption = MAINFORM_BUTTON_CAPTION_11;
	MachineTestButton->Caption = MAINFORM_BUTTON_CAPTION_12;
	TabletInfoButton->Caption = MAINFORM_BUTTON_CAPTION_13;
	CleaningButton->Caption = MAINFORM_BUTTON_CAPTION_14;
	ExtractCharacterButton->Caption = MAINFORM_BUTTON_CAPTION_15;
	FirstStudyButton->Caption = MAINFORM_BUTTON_CAPTION_16;
	EnvironmentSettingButton->Caption = MAINFORM_BUTTON_CAPTION_17;
	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
		Label3->Caption = "Batch";
	else
		Label3->Caption = MAINFORM_LABEL_CAPTION_01;
	Label5->Caption = MAINFORM_LABEL_CAPTION_03;
	ProductNameLabel->Caption = MAINFORM_LABEL_CAPTION_04;

	LOTNameLabel->Caption = MAINFORM_LABEL_CAPTION_04;

	Label1->Caption = MAINFORM_LABEL_CAPTION_08;
	Label11->Caption = MAINFORM_LABEL_CAPTION_09;
  SystemInfoLabel->Caption = MAINFORM_LABEL_CAPTION_10;
  StorageLabel->Caption = MAINFORM_LABEL_CAPTION_11;

  CloseButton->Caption = MAINFORM_LABEL_CAPTION_13;

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CloseButtonClick(TObject *Sender)
{
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectOpen();
	this->Close();
	Machine.MachineCleaning();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RefreshMenu(void)
{
	LastUserActiveTime = GetTickCount();

	MachineSetupButton->Enabled = false;
	CalibrationButton->Enabled = false;
	ExtractCharacterButton->Enabled = false;
	FirstStudyButton->Enabled = false;
	StudyButton->Enabled = false;
	InspectionButton->Enabled = false;
	InspectionReportButton->Enabled = false;

	if (UserInfo.Status == USER_STATUS_LOGIN)
	{
    WideString AuthorityName;

		if (UserInfo.AccessLevel == SYSTEM_ACCESS_LEVEL_ANONYMOUS)
		{
			AuthorityName = "NONE";
		}
		else
		{
			AuthorityName = WideString(ProgramAccessAuthorityData.ProgramAccessAuthorityName[UserInfo.AccessLevel]);
		}
    
		WCHAR TempString[100];
		wsprintfW(TempString, MAINFORM_LABEL_CAPTION_05, WideString(UserInfo.Name), AuthorityName);
		UserInfoLabel->Caption = TempString;

    	if(PCProgramOption.AllAuthorityNotActive == true)
    	{
     		UserInfo.AccessLevel = SYSTEM_HIGHEST_ACCESS_LEVEL;
    	}        

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_PRODUCT_INFO])
			TabletInfoButton->Visible = true;
		else
			TabletInfoButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_MACHINE_SETUP])
			MachineSetupButton->Visible = true;
		else
			MachineSetupButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_CAPTURE])
			CalibrationButton->Visible = true;
		else
			CalibrationButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_FEATURE_EXTRACTION])
			ExtractCharacterButton->Visible = true;
		else
			ExtractCharacterButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_FIRST_STUDY])
			FirstStudyButton->Visible = true;
		else
			FirstStudyButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_SECOND_STUDY])
			StudyButton->Visible = true;
		else
			StudyButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_INSPECTION])
			InspectionButton->Visible = true;
		else
			InspectionButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_INSPECTION_HISTORY])
			InspectionReportButton->Visible = true;
		else
			InspectionReportButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_CLEANING_STANDBY])
			CleaningButton->Visible = true;
		else
			CleaningButton->Visible = false;
      
		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_CLEANING_STANDBY])
		{
			ReadyButton->Visible = true;
			ReadyButton->BiDiMode = true;
		}
		else
		{
			ReadyButton->Visible = false;
			ReadyButton->BiDiMode = false;
		}

    if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_LOG_OUT])
			LogOutButton->Visible = true;
		else
			LogOutButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_EXIT])
			CloseButton->Visible = true;
		else
			CloseButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_DEVICE_CONTROL])
			MachineTestButton->Visible = true;
		else
			MachineTestButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_DEVICE_CONTROL])
			MachineControlButton->Visible = true;
		else
			MachineControlButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_USER_ADMINISTRATION])
			UserRegisterButton->Visible = true;
		else
			UserRegisterButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_SYSTEM_SETUP])
			SystemSettingButton->Visible = true;
		else
			SystemSettingButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_ENV_SETUP])
			EnvironmentSettingButton->Visible = true;
		else
			EnvironmentSettingButton->Visible = false;

		if (ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_AUDIT_TRAIL])
			AuditTrailButton->Visible = true;
		else
			AuditTrailButton->Visible = false;

		LeftMenuPanel->Visible = true;
		RightMenuPanel->Visible = true;
    ShowThreeDSensorStatusBtn->Visible = false;

		if (!ProductData.ProductCode.IsEmpty())
		{
			MachineSetupButton->Enabled = true;
			InspectionReportButton->Enabled = true;
			MachineSetupComplete = true;
		}
		else
		{
			MachineSetupButton->Enabled = false;
			InspectionReportButton->Enabled = false;
		}

		if (MachineSetupComplete)
		{
			if (!ProductData.ProductCode.IsEmpty())
			{
				CalibrationButton->Enabled = true;
			}
			else
			{
				CalibrationButton->Enabled = false;
			}
			if (ProductData.ProcessingStep > TABLET_PROCESSING_STEP_CALIBRATION_REQUIRED)
			{
				ExtractCharacterButton->Enabled = true;
			}
			else
			{
				ExtractCharacterButton->Enabled = false;
			}
			if (ProductData.ProcessingStep > TABLET_PROCESSING_STEP_EXTRACT_CHARACTER_REQUIRED)
			{
				FirstStudyButton->Enabled = true;
			}
			else
			{
				FirstStudyButton->Enabled = false;
			}
			if (ProductData.ProcessingStep > TABLET_PROCESSING_STEP_FIRST_STUDY_REQUIRED)
			{
				StudyButton->Enabled = true;
			}
			else
			{
				StudyButton->Enabled = false;
			}
			if (ProductData.ProcessingStep > TABLET_PROCESSING_STEP_STUDY_REQUIRED)
			{
				InspectionButton->Enabled = true;
			}
			else
			{
				InspectionButton->Enabled = false;
			}
		}

		// PC Option 상태에 따른 장비구동 화면 초기 설정
		if (AdvMachineControlForm)
		{
			if (PCProgramOption.SensorOutputSettingOption)
			{
				AdvMachineControlForm->TntGroupBox1->Visible = true;
			}
			else
			{
				AdvMachineControlForm->TntGroupBox1->Visible = false;
			}
		}
	}
	else
	{
		UserInfoLabel->Caption = MAINFORM_LABEL_CAPTION_06;
	}

	if (UserInfo.AccessLevel == SYSTEM_ACCESS_LEVEL_ANONYMOUS)
	{
		LeftMenuPanel->Visible = false;
		RightMenuPanel->Visible = false;
    ShowThreeDSensorStatusBtn->Visible = false;
	}

	__int64 freeSpace = DiskFree(4);//DiskFree('d' - 'a' + 1);
	int freeSpaceSize = freeSpace / 1024 / 1024;
	DiscSpaceLabel->Caption = FloatToStrF(freeSpaceSize / 1024.0, ffFixed, 5, 2) + " GB";
	// 저장 공간 부족 메세지 띄워야함.
	space = FloatToStrF(freeSpaceSize / 1024.0, ffFixed, 5, 2);

  /*
	TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\DSMInfor.ini");
	if (iniFile)
	{
		bool VisibleCheck = iniFile->ReadBool("Information", "Mainform DiskspaceEnabled", false);
		StorageLabel->Visible = VisibleCheck;
		DiscSpaceLabel->Visible = VisibleCheck;

    delete iniFile;
	}

  2020-12-02 기본적으로 활성화 되도록 변경
  */

  StorageLabel->Visible = true;
  DiscSpaceLabel->Visible = true;

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    Machine.MisejectOpen();
  }
  else
  {
    if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
    {
      if(LaserStatusPanel->Visible == false)
        LaserStatusPanel->Visible = true;


        LaserInactiveBtnPanel->Visible = true;
        LaserActiveBtnPanel->Visible = true;
 
    }
    else
    {
      LaserStatusPanel->Visible = false;
    }
  }

  if(GlobalProgramID == PROGRAM_ID_150P)
  {
    SystemInfo->Caption = "TVM15P";
  }
  else
  {
    SystemInfo->Caption = "TVM20";
  }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::DeleteActiveSubMenu(void)
{
	if (ActiveSubForm)
	{
		delete ActiveSubForm;
		ActiveSubForm = NULL;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
	if (UserInfo.Status == USER_STATUS_LOGIN)
	{
		//		AddCSVEventLog(ECSV_EVENT_LOGOUT, (unsigned char *)(UserInfo.Name.c_str()), UserInfo.Name.Length() + 1);
		AddCSVActionLog(ECSV_ACTION_LOGOUT, UserInfo.Name, "", NULL, 0);
	}
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if(!MachineSetupData.InterlockInfo.ACdomesticMode)
    {
      Comm_Request(COMM_HCB, CMD_SAFETY_REVERT);
    }
  }
	AddCSVEventLog(ECSV_EVENT_APPLICATION_TERMINATED, NULL, 0);
	StatusTimer->Enabled = false;
	AcroCiaDllTimer->Enabled = false;
	AMTecDllTimer->Enabled = false;
	KeyboardStatusCheckTimer->Enabled = false;
	DeleteActiveSubMenu();
	KeyMonitorActive(true);
	remove("PRINT_BITMAP_FILE.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::LogOutButtonClick(TObject *Sender)
{
	DeleteActiveSubMenu();
	int oldStatus = UserInfo.Status;
	UserInfo.Status = USER_STATUS_INQUIRE_LOGOUT;
	if (MessageDlgFA(MAINFORM_MSG_09, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
	{
		//		AddCSVEventLog(ECSV_EVENT_LOGOUT, (unsigned char *)(UserInfo.Name.c_str()), UserInfo.Name.Length() + 1);
		AddCSVActionLog(ECSV_ACTION_LOGOUT, UserInfo.Name, "", NULL, 0);
		UserInfo.Status = USER_STATUS_LOGOUT;
		UserInfo.AccessLevel = SYSTEM_ACCESS_LEVEL_ANONYMOUS;
		ProductData.ProductCode = "";
		ProductData.ProductName = "";
		ProductData.LOTName = "";
		ProductData.ProcessingStep = TABLET_PROCESSING_STEP_NONE;
		RefreshProductInfo();
		//        LogOutButton->Caption = "LOG IN";
		MachineSetupComplete = false;
    KeyMonitorActive();
		RefreshMenu();
		RequestLogIn();
	}
	else
	{
		UserInfo.Status = oldStatus;
	}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::TabletInfoButtonClick(TObject *Sender)
{
	int oldGuideSize, newGuideSize;
  
	AnsiString oldProductName, newProductName;
	TLaserInfo* temp_info;
  
	oldProductName = ProductData.ProductName;
	oldGuideSize = ProductData.RotatingGuideKind;

	if (MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable==1)
	{	
		if(NFALaserinfo.LaserStatus == LaserStatus_None)
		{
			ShowMessageFA("Laser Program Not Start!!  Plase Start Laser Program.");
		}
		else
		{	
			temp_info = Laser_obj_GetLaserInfo();
			memcpy(&RecipeInfo,temp_info,sizeof(TLaserInfo));
		}
	}

	WaitingForm->SetMessage(MAINFORM_MSG_13);
	WaitingForm->Show();
	Application->ProcessMessages();

	ProductInputForm = new TProductInputForm(this);

	WaitingForm->Hide();

	ActiveSubForm = ProductInputForm;
	if (ProductInputForm->ShowModal() == mrOk)
	{
		if (ProductData.ProcessingStep == TABLET_PROCESSING_STEP_STUDY_COMPLETE)
		{
			bool bOldSetupData = false;
			bool dataExist = true;

			AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
			if (FileExists(setupDataFileName))
			{
				TFileStream *fileStream = new TFileStream(setupDataFileName, fmOpenRead);
				if (fileStream)
				{
					if (fileStream->Size != sizeof(TTabletSetupData))
					{
						bOldSetupData = true;
					}

					delete fileStream;
				}
				else
				{
					bOldSetupData = true;
				}
			}
			else
			{
				bOldSetupData = true;
				dataExist = false;
			}

			if (bOldSetupData)
			{
        if (dataExist)
          ProductData.ProcessingStep = TABLET_PROCESSING_STEP_EXTRACT_CHARACTER_REQUIRED;
        else
          ProductData.ProcessingStep = TABLET_PROCESSING_STEP_CALIBRATION_REQUIRED;

        AnsiString fileName;
        fileName = ProgramPath.Product + "\\" + ProductData.ProductCode;

        int iAttributes = faAnyFile;
        TSearchRec sr;
        if (dataExist)
        {
          try
          {
            if (FindFirst(fileName + "\\" + ProductData.ProductCode + ".*", iAttributes, sr) == 0)
            {
              do
              {
                AnsiString oldFileName = sr.Name;
                char file_ext[50];
                _splitpath(sr.Name.c_str(),NULL,NULL,NULL,file_ext);
                AnsiString AnsiExt = AnsiString(file_ext);

                AnsiString fileExtension = AnsiExt;

                if (fileExtension != ".dat" && fileExtension != ".grd")
                {
                  AnsiString newFileName = fileName + "\\" + ProductData.ProductCode + "_old" + fileExtension;

                  if (FileExists(newFileName))
                  {
                    DeleteFileA(newFileName.c_str());
                  }

                  RenameFile(fileName + "\\" + oldFileName, newFileName);
                }
              } while (FindNext(sr) == 0);
              FindClose(sr);
            }
          }
          catch (...)
          {

          }
        }
        fileName = GetProductDataFileName(ProductData.ProductCode);
        WriteProductData(fileName, ProductData);
			}
		}

		MachineSetupComplete = false;
		RefreshProductInfo();
		RefreshMenu();
		CPBSetupInfo.StudySetupDataValid = false;
		CPBSetupInfo.InspectionSetupDataValid = false;
		CPBSetupInfo.GradeDataValid = false;

		WaitingForm->SetMessage(MAINFORM_MSG_13);
		WaitingForm->Show();
		Application->ProcessMessages();

		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
			Comm_Request(COMM_SPB + spbIndex, CMD_CIS_PARTIAL_CAPTURE_MODE);
		}

		AdvMachineControlForm->ApplyProductInfo();

		if (MachineSetupData.CompanyID != INTERNATIONAL_MACHINE2)
		{
			if (PCProgramOption.QuickStartEnabled)
			{
				TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
				if (iniFile)
				{
					iniFile->WriteString("Quick Start", "Recent Product", ProductData.ProductName);
					iniFile->WriteString("Quick Start", "Recent Lot", "");
					delete iniFile;
				}
			}
		}

		newProductName = ProductData.ProductName;
		newGuideSize = ProductData.RotatingGuideKind;

		if (oldProductName == "") // 장비를 처음 켠 상태. NEW, EDIT 등등에 상관없이 Cleaning 상태로 대기함
		{
			Machine.MachineCleaning();
		}
		else if (oldProductName != newProductName)
		{
			// 장비 운용중에 제품레시피를 변경

			if (oldGuideSize != newGuideSize)
			{
				// 제품 레시피를 변경했는데 가이드의 크기가 다름
				// 신규던 아니던 무조건 클리닝으로 보냄
				Machine.MachineCleaning();
			}
			else
			{
				// 제품 레시피를 변경했는데 가이드의 크기가 같음
				if (ProductInputForm->ProductSettingMode == PIM_NEW)
				{
					Machine.MachineCleaning();
				}
				else
				{
					Machine.MachineCleaning();
					Sleep(1500);
					Machine.MachineReady();
				}
			}
		}
		else
		{
			// 제품 레시피가 같음
			Machine.MachineReady();
		}

		WaitingForm->Hide();
	}

   TVisionSettingForm *visionSettingForm = new TVisionSettingForm(this);
   visionSettingForm->SetCaptureInfo(MachineSetupData.MachineCaptureInfo);
   visionSettingForm->GetCaptureInfo(MachineSetupData.MachineCaptureInfo);
  ReadSystemCameraOffsetImage(ProductData.DigitalGainV);
  RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormCreate(TObject *Sender)
{
	if (!SetProgramPath(ProgramPath))
	{
		SetPathForm = new TSetPathForm(this);
		if (SetPathForm->ShowModal() == mrOk)
		{
			SetProgramPath(ProgramPath);
		}
		delete SetPathForm;
	}
	Environment_Init();

	Comm_ConnectAll();

	// Check Board Connection
	AnsiString deviceName;

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		//deviceName = "\\\\.\\USBFAE_SPB_" + IntToStr(spbIndex + 1);
		//SPBConnection[spbIndex].Connect(deviceName);
		TTntLabel *connectLabel = (TTntLabel *)FindComponent("SPBConnectLabel" + IntToStr(spbIndex + 1));
		if (connectLabel)
		{
			if (Comm_IsConnected(COMM_SPB + spbIndex))
			{
				connectLabel->Font->Color = clBlue;
				connectLabel->Caption = "Connected";
			}
			else
			{
				connectLabel->Font->Color = clRed;
				connectLabel->Caption = "Not Connected";
			}
		}
	}

	RefreshMenu();

	bool bHCBSystemValid = false;                                                       
	bool bDataMatched = false;

  memset(bSPBSystemValid, false, sizeof(bool) * SYSTEM_SPB_MAX_COUNT);

	// check firmware information
	try
	{
		bool bProgramRevMatched = false;                                        
		if (Comm_IsConnected(COMM_HCB))
		{
			// read system header
			THCBProgramHeader hcbProgramHeader;
			THCBDBHeader hcbDBHeader;
			if (!Comm_Request(COMM_HCB, CMD_READ_PROGRAM_HEADER, NULL, 0, &hcbProgramHeader, sizeof(THCBProgramHeader)))
			{
				throw Exception("HCB Communication Fail");
			}
			if (!Comm_Request(COMM_HCB, CMD_READ_DB_HEADER, NULL, 0, &hcbDBHeader, sizeof(THCBDBHeader)))
			{
				throw Exception("HCB Communication Fail");
			}
			if (hcbProgramHeader.ProjectID == PROJECT_ID_ELMA_100)
			{
				bHCBSystemValid = true;
				if (hcbProgramHeader.ProgramRev == TARGET_HCB_PROGRAM_REV)
				{
					bProgramRevMatched = true;
					if (!CommSimulationMode)
					{
						CheckHCBDataMatching(&hcbProgramHeader, &hcbDBHeader);
					}
				}
				else
				{
					bProgramRevMatched = false;
				}
			}
			else
			{
				bProgramRevMatched = false;
			}
			if (!bProgramRevMatched)
			{
				ShowMessageFA(MAINFORM_MSG_07);
				bHCBSystemValid = false;
			}
		}
	}
	catch (...)
	{
		bHCBSystemValid = false;
	}

	WCHAR TempString[100];
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		try
		{
			bool bProgramRevMatched = false;
			if (Comm_IsConnected(COMM_SPB + spbIndex))
			{
				// read system header
				TSPBProgramHeader spbProgramHeader;
				TSPBDBHeader spbDBHeader;
				if (!Comm_Request(COMM_SPB + spbIndex, CMD_READ_PROGRAM_HEADER, NULL, 0, &spbProgramHeader, sizeof(TSPBProgramHeader)))
				{
					wsprintfW(TempString, MAINFORM_MSG_01, spbIndex + 1);
					throw Exception("IPB Communication Fail");
				}
				if (!Comm_Request(COMM_SPB + spbIndex, CMD_READ_DB_HEADER, NULL, 0, &spbDBHeader, sizeof(TSPBDBHeader)))
				{
					wsprintfW(TempString, MAINFORM_MSG_01, spbIndex + 1);
					throw Exception("IPB Communication Fail");
				}
				if (spbProgramHeader.ProjectID == PROJECT_ID_ELMA_100)
				{
					bSPBSystemValid[spbIndex] = true;
					if (spbProgramHeader.ProgramRev == TARGET_SPB_PROGRAM_REV)
					{
						bProgramRevMatched = true;
						if (!CommSimulationMode)
						{
							CheckSPBDataMatching(&spbProgramHeader, &spbDBHeader, spbIndex);
						}
					}
					else
					{
						bProgramRevMatched = false;
					}
				}
				else
				{
					bProgramRevMatched = false;
				}
				if (!bProgramRevMatched)
				{
					WCHAR TempString[100];
					wsprintfW(TempString, MAINFORM_MSG_02, spbIndex + 1);
					ShowMessageFA(TempString);
					bSPBSystemValid[spbIndex] = false;
				}
			}
		}
		catch (...)
		{
			bSPBSystemValid[spbIndex] = false;
		}
	}

	if (ComputerSystemInfo.InactivityLogoutEnabled)
	{
		hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHook, NULL, GetCurrentThreadId());
    LastUserActiveTime = GetTickCount();
    ActivityCheckTimer->Enabled = true;
	}
	else
	{
		ActivityCheckTimer->Enabled = false;
	}

	this->Left = Screen->Monitors[0]->Left;
	this->Top = Screen->Monitors[0]->Top;
	this->Width = Screen->Monitors[0]->Width;
	this->Height = Screen->Monitors[0]->Height;

	CPBStatusForm = new TCPBStatusForm(Application);
	bool bAllSPBSystemValid = true;
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (!bSPBSystemValid[spbIndex])
		{
			bAllSPBSystemValid = false;
			break;
		}
	}
	if (bAllSPBSystemValid)
	{
		CheckCPBBootStatus(true);
	}
	else
	{
		//Machine.DisableBlackOut();
	}
	KeyboardStatusCheckTimer->Enabled = true;

	if (bHCBSystemValid && bAllSPBSystemValid)
	{
    CheckSystemCompatibility();
	}
	AddCSVEventLog(ECSV_EVENT_APPLICATION_STARTED, NULL, 0);

  memset(GlobalEnabledCameraStatus, true, sizeof(bool) * SYSTEM_TOTAL_CAMERA_COUNT);


 	GetDefalutString();
  	//Q사 dll 관련 작업
  memset(&UVLaser, 0, sizeof(UVLaser));
	memset(&MESUpDate_Param, 0 , sizeof(MESUpDate_Param));
	memset(&MESUpDate_Product, 0 , sizeof(MESUpDate_Product));

  if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
  {
    PcUiFlag.APPActive = 1;
		Machine.SetUIFlagData();
  }


   if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
	{
		UVLaser.SELMAStatus.APPActive = 1;
//		Machine.SetUVLaserStatus();
    if(hDllInstance == NULL)
    {
      hDllInstance = ::LoadLibrary(TEXT("QJPObj.dll"));
      if (hDllInstance)
      {
        // initalize control obj
        obj_init			= (OBJ_INIT)GetProcAddress(hDllInstance, "Obj_Init");
        obj_term			= (OBJ_TERM)GetProcAddress(hDllInstance, "Obj_Termnate");
        obj_getporttype			= (OBJ_GETPORTTYPE)GetProcAddress(hDllInstance, "Obj_GetPortType");
        obj_setinport		= (OBJ_SETINPORT)GetProcAddress(hDllInstance, "Obj_SetInport");
        obj_getoutport		= (OBJ_GETOUTPORT)GetProcAddress(hDllInstance, "Obj_GetOutport");
        obj_setstatus		= (OBJ_SETSTATUS)GetProcAddress(hDllInstance, "Obj_SetStatus");
        obj_getcommand		= (OBJ_GETCOMMAND)GetProcAddress(hDllInstance, "Obj_GetCommand");
        obj_setproductinfo	= (OBJ_SETPRODUCTINFO)GetProcAddress(hDllInstance, "Obj_SetProductInfo");
        obj_setparaminfo		= (OBJ_SETPARAMINFO)GetProcAddress(hDllInstance, "Obj_SetParamInfo");
        obj_setalarminfo =	 (OBJ_SETALARMINFO)GetProcAddress(hDllInstance, "Obj_SetAlarmInfo");
        obj_getobjstatus	= (OBJ_GETOBJSTATUS)GetProcAddress(hDllInstance, "Obj_GetObjStatus");
        obj_errorreset		= (OBJ_ERRORRESET)GetProcAddress(hDllInstance, "Obj_ErrorReset");
        obj_seqclear		= (OBJ_SEQCLEAR)GetProcAddress(hDllInstance, "Obj_SeqClear");
        obj_setexecommand = (OBJ_SETEXECOMMAND)GetProcAddress(hDllInstance,"Obj_SetExeCommand");
        AcroCiaDllTimer->Enabled = true;
        /*if (obj_init != NULL)
        {
          if(!obj_init())
          {
            ShowMessageFA("MCPInit Error!");
          }
          else
          {
            UVLaser.UVLaserStatus.DLLLoadStatus = true;
          }
  //				else
  //				{
  //					ShowMessageFA("MCPInit OK!!");
  //				}
        }*/

      }
      DLLLoadThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, QDllLoadThread, this, 0, (unsigned int*)&ThreadDword);
    }
	}
  else if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
  {
    AcroCiaDllTimer->Enabled = true;
  }
  

  
 	if (bHCBSystemValid)
	{
		StatusTimer->Enabled = true;
	}
	RecipeInfo.RecipeCount = 0;

	if(hNFALaserDll == NULL)
	{
		 hNFALaserDll = ::LoadLibrary(TEXT("LaserDllObj.dll"));
		if (hNFALaserDll)
		{
			// initalize control obj
			Laser_obj_Init = (LASER_OBJ_INIT)GetProcAddress(hNFALaserDll, "Obj_Init");
			Laser_obj_Termnate = (LASER_OBJ_TERM)GetProcAddress(hNFALaserDll, "Obj_Termnate");
			Laser_obj_Reset = (LASER_OBJ_RESET)GetProcAddress(hNFALaserDll, "Obj_Reset");
			Laser_obj_ResetCount = (LASER_Obj_RESETCOUNT)GetProcAddress(hNFALaserDll, "Obj_ResetCount");
			Laser_obj_GetObjStatus = (LASER_OBJ_GETOBJSTATUS)GetProcAddress(hNFALaserDll, "Obj_GetObjStatus");

			Laser_obj_SetObjCommand = (LASER_OBJ_SETOBJCOMMAND)GetProcAddress(hNFALaserDll, "Obj_SetObjCommand");
			Laser_obj_GetObjCommand = (LASER_OBJ_GETOBJCOMMAND)GetProcAddress(hNFALaserDll, "Obj_GetObjCommand");


			Laser_obj_SetLaserStatus = (LASER_OBJ_SETLASERSTATUS)GetProcAddress(hNFALaserDll, "Obj_SetLaserStatus");
			Laser_obj_GetLaserStatus = (LASER_OBJ_GETLASERSTATUS)GetProcAddress(hNFALaserDll, "Obj_GetLaserStatus");
			Laser_obj_SetLaserCount = (LASER_OBJ_SETLASERCOUNT)GetProcAddress(hNFALaserDll, "Obj_SetLaserCount");
			Laser_obj_GetLaserCount = (LASER_OBJ_GETLASERCOUNT)GetProcAddress(hNFALaserDll, "Obj_GetLaserCount");
			Laser_obj_SetProductName = (LASER_OBJ_SETPRODUCTNAME)GetProcAddress(hNFALaserDll, "Obj_SetProductName");
			Laser_obj_SetLaserRecipeName = (LASER_OBJ_SETLASERRECIPENAME)GetProcAddress(hNFALaserDll, "Obj_SetLaserRecipeName");
			Laser_obj_GetLaserRecipeName = (LASER_OBJ_GETLASERRECIPENAME)GetProcAddress(hNFALaserDll, "Obj_GetLaserRecipeName");			

			Laser_obj_SetLaserInfo = (LASER_OBJ_SETLASERINFO)GetProcAddress(hNFALaserDll, "Obj_SetLaserInfo");
			Laser_obj_GetLaserInfo = (LASER_OBJ_GETLASERINFO)GetProcAddress(hNFALaserDll, "Obj_GetLaserInfo");
			Laser_obj_SetLaserError = (LASER_OBJ_SETLASERERROR)GetProcAddress(hNFALaserDll, "Obj_SetLaserError");
			Laser_obj_GetLaserError = (LASER_OBJ_GETLASERERROR)GetProcAddress(hNFALaserDll, "Obj_GetLaserError");

			Laser_obj_SetMachineStatus = (LASER_OBJ_SETMACHINESTATUS)GetProcAddress(hNFALaserDll, "Obj_SetMachineStatus");
			Laser_obj_GetMachineStatus = (LASER_OBJ_GETMACHINESTATUS)GetProcAddress(hNFALaserDll, "Obj_GetMachineStatus");
			Laser_obj_SetMachineCount = (LASER_OBJ_SETMACHINECOUNT)GetProcAddress(hNFALaserDll, "Obj_SetMachineCount");
			Laser_obj_GetMachineCount = (LASER_OBJ_GETMACHINECOUNT)GetProcAddress(hNFALaserDll, "Obj_GetMachineCount");
			Laser_obj_GetProductName = (LASER_OBJ_GETPRODUCTNAME)GetProcAddress(hNFALaserDll, "Obj_GetProductName");

			Laser_obj_SetMachineUIStatus = (LASER_OBJ_SETMACHINEUISTATUS)GetProcAddress(hNFALaserDll, "Obj_SetMachineUIStatus");
			Laser_obj_GetMachineUIStatus = (LASER_OBJ_GETMACHINEUISTATUS)GetProcAddress(hNFALaserDll, "Obj_GetMachineUIStatus");
			Laser_obj_SetMachineDiskSpeed = (LASER_OBJ_SETMACHINEDISKSPEED)GetProcAddress(hNFALaserDll, "Obj_SetMachineDiskSpeed");
			Laser_obj_GetMachineDiskSpeed = (LASER_OBJ_GETMACHINEDISKSPEED)GetProcAddress(hNFALaserDll, "Obj_GetMachineDiskSpeed");			

			Laser_obj_SetLaserMachineStatus = (LASER_OBJ_SETLASERMACHINESTATUS)GetProcAddress(hNFALaserDll, "Obj_SetLaserMachineStatus");

			Laser_obj_GetLaserMarkTime = (LASER_OBJ_GETMACHINESTATUS)GetProcAddress(hNFALaserDll, "Obj_GetLaserMarkTime");
			Laser_obj_GetLaserMachineStatus = (LASER_OBJ_GETLASERMACHINESTATUS)GetProcAddress(hNFALaserDll, "Obj_GetLaserMachineStatus");			
			AMTecDllTimer->Enabled = true;
			memset(&RecipeInfo,0,sizeof(TLaserInfo));
			if (!Laser_obj_Init())
			{
				ShowMessageFA("AMTec DLL LOAD Error!");
				AMTecDllTimer->Enabled = false;
			}
		}
	}
	memset(&NFALaserinfo,0,sizeof(NFALaserinfo));
	memset(GlobalSD1LSFTable, 0, sizeof(int) * MAX_MOTOR_SPEED);
	memset(GlobalSD2LSFTable, 0, sizeof(int) * MAX_MOTOR_SPEED);

	AnsiString fileName = ProgramPath.Env + "\\LSFStudyResultTable.lsf";
	ReadGlobalLSFTable(fileName);
	int laser_shutter_onoff = 1;
	if (MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable==1)
	{  
		// 임시
		if (Comm_IsConnected(COMM_HCB))
		{
			if (!Comm_Request(COMM_HCB, CMD_LASER_SHUTTER_ONOFF, &laser_shutter_onoff, sizeof(int)));
		}
	}
/* 윈도우 시간 변경 코드
	SYSTEMTIME st;
	time_t now = time(NULL);
	struct tm *t;
	t = localtime(&now);
	st.wSecond=t->tm_sec;
	st.wMinute= t->tm_min;
	st.wHour =t->tm_hour;
	st.wDay =t->tm_mday;
	st.wMonth = t->tm_mon +1;
	st.wYear = t->tm_year +1900;
	SetLocalTime(&st);
*/

//cjg OPC Test    
    AnsiString pstrSrc = ProgramPath.Root + "\\Lib\\SELMA_MES.dll";
    int nLen = strlen(pstrSrc.c_str())+1;

    wchar_t* pwstr = (LPWSTR)malloc(sizeof(wchar_t)*nLen);
    mbstowcs(pwstr,pstrSrc.c_str(),nLen);

	if(hOPC_DLL == NULL)
	{
//                hOPC_DLL = ::LoadLibrary(TEXT("SELMA_MES.dll"));
		hOPC_DLL = ::LoadLibrary(pwstr);
	}
        free(pwstr);

	if(hOPC_DLL)
	{
		pSetMachineAlarmState 	= (int(*)(TMachineAlarmState *))GetProcAddress(hOPC_DLL, "SetMachineAlarmState");
		pSetMESProductData		= (int(*)(TMESProductData *))GetProcAddress(hOPC_DLL, "SetMESProductData");
	}

	WideString msgCamTimOut[8] = {" ",};
	WideString msgCamTimeOutTotal = "";
	int tmpCamTimOut[8] = {0,};
	int tmpSPB_index = 0;

	for(int tmpSpbIndex = 0; tmpSpbIndex<MachineSetupData.IPB_BoardCount; tmpSpbIndex++)
	{
		Comm_SetMaxWaitingTime(COMM_SPB + tmpSpbIndex, 5000);
		if (!Comm_Request(COMM_SPB + tmpSpbIndex, CMD_CHK_CAM_TIME_OUT, NULL, 0, &CheckCamTimeOut, sizeof(TCheckCamTimeOut)))
		{
			//ShowMessage("Communication Error #" + IntToStr(tmpSpbIndex + 1) + " SPB");
		}
		else
		{
			if(	CheckCamTimeOut.CamTimeOutStauts == 0)
			{
				tmpCamTimOut[tmpSpbIndex] = 0;
			}
			else
			{
				tmpCamTimOut[tmpSpbIndex] = 1;
			}
		}
		Comm_SetDefaultMaxWaitingTime(COMM_SPB + tmpSpbIndex);
	}

	for(int tmpSpbIndex = 0; tmpSpbIndex<MachineSetupData.IPB_BoardCount; tmpSpbIndex++)
	{
		if(tmpCamTimOut[tmpSpbIndex] == 0)
		{
			msgCamTimOut[tmpSpbIndex] = IntToStr(tmpSpbIndex + 1) ;
      msgCamTimeOutTotal += (" " + msgCamTimOut[tmpSpbIndex]);      
			//ShowMessage("CAM TIME OUT " + IntToStr(tmpSpbIndex + 1) + " SPB");
		}
	}

	for(int tmpSpbIndex = 0; tmpSpbIndex<MachineSetupData.IPB_BoardCount; tmpSpbIndex++)
	{
		if(tmpCamTimOut[tmpSpbIndex] == 0)
		{
			ShowMessageW(msgCamTimeOutTotal + " " + MAINFORM_LABEL_CAPTION_12);
			break;
		}
	}
	TVisionSettingForm *visionSettingForm = new TVisionSettingForm(this);
	visionSettingForm->SetCaptureInfo(MachineSetupData.MachineCaptureInfo);
	visionSettingForm->GetCaptureInfo(MachineSetupData.MachineCaptureInfo);	
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RequestLogIn(void)
{
	quickStartActivated = false;
	quickStartOption = 0;
	alarmActivated = 0;
	WideString lastProductName, lastInspectionLot;
	LogInForm = new TLogInForm(this);

  if (bInitProgramAuthority)
	{
		// 장비를 이미 가동중인 업체에 프로그램 배포시 권한정보는 존재하지 않으며 업체 상황에 따라 사용자 ID를 생성해서 사용될 수 있음
		// 이때는 System 계정을 로그인해서 최초의 권한정보를 변경할 수 있도록 조치
		bool bUserExist = false;

		TStringList *userIDList = new TStringList;
		TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\user.ini");

		if (iniFile)
		{
			iniFile->ReadSections(userIDList);

			if (userIDList->Count > 0)
			{
				bUserExist = true;
			}
		}

		delete iniFile;
		delete userIDList;

		if (bUserExist)
		{
      LogInForm->bRequestSystemIDLogIn = true;

      MessageDlgFA(SYSTEM_AUTHORITY_LOGIN_ERROR_MSG_01, mtConfirmation, TMsgDlgButtons() << mbOK);
		}
	}
  
	Image1->Visible = false;

	if (LogInForm->ShowModal() == mrOk)
	{
    if(LogInForm->bRequestSystemIDLogIn)
    {
      if(UserInfo.Name == "system")
      {
        TUserAuthoritySettingForm *UserAuthoritySettingForm = new TUserAuthoritySettingForm(this);
        UserAuthoritySettingForm->tempProgramAccessAuthorityData.SystemAuthorityCount = ProgramAccessAuthorityData.SystemAuthorityCount;

        for (int AuthorityID = 0; AuthorityID < ProgramAccessAuthorityData.SystemAuthorityCount; AuthorityID++)
        {
          UserAuthoritySettingForm->tempProgramAccessAuthorityData.ProgramAccessAuthorityName[AuthorityID] = ProgramAccessAuthorityData.ProgramAccessAuthorityName[AuthorityID];
        }

        for (int EventID = 0; EventID < MAX_UI_ACCESS_EVENT; EventID++)
        {
          UserAuthoritySettingForm->tempProgramAccessAuthorityData.ProgramAccessEventSerialNumber[EventID] = ProgramAccessAuthorityData.ProgramAccessEventSerialNumber[EventID];
        }

        for (int EventID = 0; EventID < MAX_UI_ACCESS_EVENT; EventID++)
        {
          UserAuthoritySettingForm->tempProgramAccessAuthorityData.ProgramAccessEventDescription[EventID] = ProgramAccessAuthorityData.ProgramAccessEventDescription[EventID];
        }

        for (int AuthorityID = 0; AuthorityID < ProgramAccessAuthorityData.SystemAuthorityCount; AuthorityID++)
        {
          for (int EventID = 0; EventID < MAX_UI_ACCESS_EVENT; EventID++)
          {
            UserAuthoritySettingForm->tempProgramAccessAuthorityData.ProgramAccessAuthorityTable[AuthorityID][EventID] = ProgramAccessAuthorityData.ProgramAccessAuthorityTable[AuthorityID][EventID];
          }
        }

        if (UserAuthoritySettingForm->ShowModal() == mrOk)
        {
          bInitProgramAuthority = false;
          LogInForm->bRequestSystemIDLogIn = false;

          TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\SystemAuthorityInformation.ini");
          if (iniFile)
          {
            iniFile->WriteBool("Initial Authority Complete", "State", true);
          }
          delete iniFile;
          
          ShowMessageFA(SYSTEM_AUTHORITY_REVISION_SUCCESS_MSG);
        }
        else
        {
          ShowMessageFA(SYSTEM_AUTHORITY_REVISION_FAIL_MSG);
        }

        delete UserAuthoritySettingForm;
      }
    }
    
		Image1->Visible = true;

		AddCSVActionLog(ECSV_ACTION_LOGIN, UserInfo.Name, "", NULL, 0);
		UserInfo.Status = USER_STATUS_LOGIN;

		if (PCProgramOption.QuickStartEnabled)
		{
			TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
			if (iniFile)
			{
				lastProductName = iniFile->ReadString("Quick Start", "Recent Product", "");
				lastInspectionLot = iniFile->ReadString("Quick Start", "Recent Lot", "");
				delete iniFile;
				if (!lastProductName.IsEmpty() && ProductData.ProductCode.IsEmpty())
				{
					TQuickStartForm *quickStartForm = new TQuickStartForm(this);
					quickStartForm->SetInfo(lastProductName, lastInspectionLot);
					if (quickStartForm->ShowModal() == mrOk)
					{
						quickStartActivated = true;
						quickStartOption = quickStartForm->QuickStartOption;
					}
					delete quickStartForm;
				}
			}
		}
	}
	delete LogInForm;
	LogInForm = NULL;
	RefreshMenu();

	if (quickStartActivated)
	{    
		TProductData tempProductData;
		AnsiString productFileName = GetProductDataFileName(lastProductName);
		if (ReadProductData(productFileName, tempProductData, MachineParams, MachineSetupData))
		{
			CopyProductData(ProductData, tempProductData); 

      bool bOldSetupData = false;
			if (ProductData.ProcessingStep == TABLET_PROCESSING_STEP_STUDY_COMPLETE)
			{
			  bool dataExist = true;

        AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
        if (FileExists(setupDataFileName))
        {
          TFileStream *fileStream = new TFileStream(setupDataFileName, fmOpenRead);
          if (fileStream)
          {
            if (fileStream->Size != sizeof(TTabletSetupData))
            {
              bOldSetupData = true;
            }

            delete fileStream;
          }
          else
          {
            bOldSetupData = true;
          }
        }
        else
        {
          bOldSetupData = true;
          dataExist = false;
        }

        if (bOldSetupData)
        {
          if (dataExist)
            ProductData.ProcessingStep = TABLET_PROCESSING_STEP_EXTRACT_CHARACTER_REQUIRED;
          else
            ProductData.ProcessingStep = TABLET_PROCESSING_STEP_CALIBRATION_REQUIRED;

          AnsiString fileName;
          fileName = ProgramPath.Product + "\\" + ProductData.ProductCode;

          int iAttributes = faAnyFile;
          TSearchRec sr;
          if (dataExist)
          {
            try
            {
              if (FindFirst(fileName + "\\" + ProductData.ProductCode + ".*", iAttributes, sr) == 0)
              {
                do
                {
                  AnsiString oldFileName = sr.Name;
                  char file_ext[50];
                  _splitpath(sr.Name.c_str(),NULL,NULL,NULL,file_ext);
                  AnsiString AnsiExt = AnsiString(file_ext);

                  AnsiString fileExtension = AnsiExt;

                  if (fileExtension != ".dat" && fileExtension != ".grd")
                  {
                    AnsiString newFileName = fileName + "\\" + ProductData.ProductCode + "_old" + fileExtension;

                    if (FileExists(newFileName))
                    {
                      DeleteFileA(newFileName.c_str());
                    }

                    RenameFile(fileName + "\\" + oldFileName, newFileName);
                  }
                } while (FindNext(sr) == 0);
                FindClose(sr);
              }
            }
            catch (...)
            {

            }
          }

          fileName = GetProductDataFileName(ProductData.ProductCode);
          WriteProductData(fileName, ProductData);
        }
      }

			MachineSetupComplete = true;
			RefreshProductInfo();
			RefreshMenu();

			CPBSetupInfo.StudySetupDataValid = false;
			CPBSetupInfo.InspectionSetupDataValid = false;
			CPBSetupInfo.GradeDataValid = false;
			WaitingForm->SetMessage(MAINFORM_MSG_13);
			WaitingForm->Show();
			Application->ProcessMessages();

			for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
			{
				Comm_Request(COMM_SPB + spbIndex, CMD_CIS_PARTIAL_CAPTURE_MODE);
			}

			AdvMachineControlForm->ApplyProductInfo();

			WaitingForm->Hide();

			if (!bOldSetupData)
			{
				if (quickStartOption == EQUICK_START_INSPECTION)
				{
					ProductData.LOTName = lastInspectionLot;
					InspectionButton->Click();
				}
			}
      else
      {
        quickStartOption = EQUICK_START_SELECT_PRODUCT;
        quickStartActivated = false;
      }
		}
	}

  // With Mouse Active Check
  if(ActiveSubForm != NULL && InspectionForm == ActiveSubForm)
  {
    if(!ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MAINFORM_INSPECTION])
    {
      // 검사 폼에대한 접근 권한이 없는 레벨의 경우 버튼은 로그인시 일시적으로 막을 수 있으나 검사 종료나 알람 발생 상태에따라 버튼들이 활성화 될 수 있으므로
      // 검사 폼은 유지한 상태로 재 로그인 알람을 띄운다.
      ShowMessageFA(NEW_ADD_STRING_89);
      RequestLogIn();
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormDestroy(TObject *Sender)
{
	
	int laser_shutter_onoff = 0;
	if (MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable==1)
	{
		// 임시
		if (Comm_IsConnected(COMM_HCB))
		{
			if (!Comm_Request(COMM_HCB, CMD_LASER_SHUTTER_ONOFF, &laser_shutter_onoff, sizeof(int)));
		}
		Sleep(1000);
	}
	


	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
	{
		UVLaser.SELMAStatus.APPActive = 0;
	}
	else if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
		PcUiFlag.APPActive = 0;
		Machine.SetUIFlagData();
	}
 	DeleteActiveSubMenu();
	Comm_DisconnectAll();
	Environment_Destroy();

	if (hHook != NULL)
	{
		UnhookWindowsHookEx(hHook);
	}
	if(hDllInstance!=NULL)
	{
		obj_term();
		FreeLibrary(hDllInstance);
	}
	if(hNFALaserDll!=NULL)
	{
		Laser_obj_Termnate();
		FreeLibrary(hNFALaserDll);
	}	 
	
}

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

void __fastcall TMainForm::StatusTimerTimer(TObject *Sender)
{
	if (!bSystemStatusCheckSW) return;

	bool timerEnabled;
	bool bAlarm = false;
	bool bWarning = false;
	int BoardIndex = 0;

	timerEnabled = StatusTimer->Enabled;
	StatusTimer->Enabled = false;
	TimeLabel->Caption = Now().DateTimeString();
	
	if (!Comm_IsConnected(COMM_HCB))
	{
//		Machine.ClearMachineStatus();
		HCB_DisConnect_count++;
		if(HCB_DisConnect_count > 20)
		{
			Machine.Status.AlarmExist = true;	
			bAlarm = true;
		}
	}
	else
	{
		HCB_DisConnect_count = 0;
		Machine.ReadMachineStatus();
   		Machine.ReadPortStatus();

    	if (Machine.Status.BlackOut)
		{
			if (BlackOutFlag == 0)
			{
				//bSystemStatusCheckSW = false;
				ActivityCheckTimer->Enabled = false;
				BlackOutFlag = 1;
				unsigned int alarmCode;
				alarmCode = CSV_ALARM_CODE_BLACKOUT;
				AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
			}
	  }

		if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
		{
			if(Machine.Status.MachineOff)
			{
				if(MachineOffFlag == false)
				{
					MachineOffFlag = true;
					AddCSVEventLog(ECSV_EVENT_MACHINE_OFF, NULL, 0);
				}
			}	  
		}

		if (Machine.Status.AlarmExist)
		{
			bAlarm = true;
		}

		if (Machine.Status.WarningExist)
		{
			bWarning = true;
		}
	}

	if (bAlarm)
	{
		MachineStatusLabel->Caption = MAINFORM_LABEL_CAPTION_02;
		if (MachineStatusLabel->Font->Color == clRed)
		{
			MachineStatusLabel->Font->Color = clBlack;
			MachineStatusLabel->Color = clRed;
		}
		else
		{
			MachineStatusLabel->Font->Color = clRed;
			MachineStatusLabel->Color = clBlack;
		}
		//if (UserInfo.Status == USER_STATUS_LOGIN && UserInfo.Grade > USER_GRADE_MACHINE_ENGINEER)
		if (!AlarmForm->SleepMode)
		{
			if (!alarmActivated)
			{
				StatusTimer->Enabled = timerEnabled;
				alarmActivated = true;
				AlarmForm->ShowAlarm();
				alarmActivated = false;
				timerEnabled = StatusTimer->Enabled;
			}
		}
	}
	else if (Machine.WarningStatus.VBFeederEmpty)
	{
		if (DefaultLCID == 1028)
			MachineStatusLabel->Caption = "주의";
		else
			MachineStatusLabel->Caption = "Caution";
		if (MachineStatusLabel->Font->Color == clYellow)
		{
			MachineStatusLabel->Font->Color = clBlack;
			MachineStatusLabel->Color = clYellow;
		}
		else
		{
			MachineStatusLabel->Font->Color = clYellow;
			MachineStatusLabel->Color = clBlack;
		}
		if (!AlarmForm->WarningSleep)
		{
			if (!alarmActivated)
			{
				StatusTimer->Enabled = timerEnabled;
				alarmActivated = true;
				AlarmForm->ShowAlarm();
				alarmActivated = false;
				timerEnabled = StatusTimer->Enabled;
			}
		}
	}
	else
	{
		MachineStatusLabel->Caption = MAINFORM_LABEL_CAPTION_07;
		MachineStatusLabel->Font->Color = clLime;
		MachineStatusLabel->Color = clBlack;
	}

	TPCAlarmState newAlarmState;
	memset(&newAlarmState, 0, sizeof(TPCAlarmState));

  if (!Comm_IsConnected(COMM_HCB))
  {
    newAlarmState.HCBNotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_1))
  {
    newAlarmState.SPB1NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_2))
  {
    newAlarmState.SPB2NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_3))
  {
    newAlarmState.SPB3NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_4))
  {
    newAlarmState.SPB4NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_5))
  {
    newAlarmState.SPB5NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_6))
  {
    newAlarmState.SPB6NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_7))
  {
    newAlarmState.SPB7NotConnected = true;
  }
  if (!Comm_IsConnected(COMM_SPB_8))
  {
    newAlarmState.SPB8NotConnected = true;
  }  

	if (bAlarm)
	{
		unsigned int alarmCode;


		if (Machine.AlarmStatus.RegulatorError)
		{
			newAlarmState.RegulatorError = true;
		}
    if (Machine.AlarmStatus.TemperatureOver[0])
    {
      newAlarmState.TemperatureOver[0] = true;
    }
    if (Machine.AlarmStatus.TemperatureOver[1])
    {
      newAlarmState.TemperatureOver[1] = true;
    }
    if (Machine.AlarmStatus.TemperatureOver[2])
    {
      newAlarmState.TemperatureOver[2] = true;
    }
		if (Machine.AlarmStatus.EmergencyOn)
		{
			newAlarmState.EmergencyOn = true;
		}
		if (Machine.AlarmStatus.Inverter1Trip)
		{
			newAlarmState.Inverter1Trip = true;
		}
		if (Machine.AlarmStatus.Inverter2Trip)
		{
			newAlarmState.Inverter2Trip = true;
		}
		if (Machine.AlarmStatus.Inverter3Trip)
		{
			newAlarmState.Inverter3Trip = true;
		}
		if (Machine.AlarmStatus.Disk1SuctionLow)
		{
			newAlarmState.Disk1SuctionLow = true;
		}
		if (Machine.AlarmStatus.Disk2SuctionLow)
		{
			newAlarmState.Disk2SuctionLow = true;
		}
		if (Machine.AlarmStatus.ServoAlarm)
		{
			newAlarmState.ServoAlarm = true;
		}
		if (Machine.AlarmStatus.Interlock)
		{
			newAlarmState.Interlock = true;
		}
		if (Machine.AlarmStatus.Disk1Stall)
		{
			newAlarmState.Disk1Stall = true;
		}
		if (Machine.AlarmStatus.Disk2Stall)
		{
			newAlarmState.Disk2Stall = true;
		}
		if (Machine.AlarmStatus.TotalFull)
		{
			newAlarmState.TotalFull = true;
		}
		if (Machine.AlarmStatus.GPFull)
		{
			newAlarmState.GPFull = true;
		}
		if (Machine.AlarmStatus.DPFull)
		{
			newAlarmState.DPFull = true;
		}
		if (Machine.AlarmStatus.UPFull)
		{
			newAlarmState.UPFull = true;
		}
		if (Machine.AlarmStatus.DPRatioOver)
		{
			newAlarmState.DPRatioOver = true;
		}
		if (Machine.AlarmStatus.UPRatioOver)
		{
			newAlarmState.UPRatioOver = true;
		}
    if (Machine.AlarmStatus.CritDPRatioOver)
		{
			newAlarmState.CritDPRatioOver = true;
		}
		if (Machine.AlarmStatus.CritUPRatioOver)
		{
			newAlarmState.CritUPRatioOver = true;
		}
		if (Machine.AlarmStatus.Sensor1Error)
		{
			newAlarmState.Sensor1Error = true;
		}
		if (Machine.AlarmStatus.Sensor2Error)
		{
			newAlarmState.Sensor2Error = true;
		}
		if (Machine.AlarmStatus.BrightnessDown)
		{
			newAlarmState.BrightnessDown = true;
		}
		if (Machine.AlarmStatus.StepMotorStall[0])
		{
			newAlarmState.StepMotorStall[0] = true;
		}
		if (Machine.AlarmStatus.StepMotorStall[1])
		{
			newAlarmState.StepMotorStall[1] = true;
		}
		if (Machine.AlarmStatus.StepMotorStall[2])
		{
			newAlarmState.StepMotorStall[2] = true;
		}
		if (Machine.AlarmStatus.StepMotorStall[3])
		{
			newAlarmState.StepMotorStall[3] = true;
		}
		if (Machine.AlarmStatus.StepMotorStall[4])
		{
			newAlarmState.StepMotorStall[4] = true;
		}
    if (Machine.AlarmStatus.CheckMisEjector)
		{
			newAlarmState.CheckMisEjector = true;
		}
    if (Machine.AlarmStatus.MisEjectFull)
		{
			newAlarmState.MisEjectFull = true;
		}

		if (Machine.AlarmStatus.mes_status)
		{
			newAlarmState.mes_status= true;
		}
      if (Machine.AlarmStatus.Qjp_object_status)
		{
        newAlarmState.Qjp_object_status= true;
		}
		if (Machine.AlarmStatus.upstream_status)
		{
			newAlarmState.upstream_status= true;
		}
		if (Machine.AlarmStatus.downstream_status)
		{
			newAlarmState.downstream_status = true;
		}
		if (Machine.AlarmStatus.laser_emergency)
		{
			newAlarmState.laser_emergency = true;
		}
    if (Machine.AlarmStatus.EmissionSensorOn)
		{
			newAlarmState.EmissionSensorOn = true;
		}
	
	}

	unsigned int alarmCode;
	if (newAlarmState.HCBNotConnected)
	{
		if (!OldAlarmState.HCBNotConnected)
		{
			alarmCode = CSV_ALARM_CODE_HCB_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.HCBNotConnected)
		{
			alarmCode = CSV_ALARM_CODE_HCB_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.SPB1NotConnected)
	{
		if (!OldAlarmState.SPB1NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_1_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB1NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_1_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.SPB2NotConnected)
	{
		if (!OldAlarmState.SPB2NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_2_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB2NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_2_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.SPB3NotConnected)
	{
		if (!OldAlarmState.SPB3NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_3_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB3NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_3_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.SPB4NotConnected)
	{
		if (!OldAlarmState.SPB4NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_4_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB4NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_4_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.SPB5NotConnected)
	{
		if (!OldAlarmState.SPB5NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_5_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB5NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_5_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.SPB6NotConnected)
	{
		if (!OldAlarmState.SPB6NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_6_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.SPB6NotConnected)
		{
			alarmCode = CSV_ALARM_CODE_SPB_6_NC;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.RegulatorError)
	{
		if (!OldAlarmState.RegulatorError)
		{
			alarmCode = CSV_ALARM_CODE_COMPRESSED_AIR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.RegulatorError)
		{
			alarmCode = CSV_ALARM_CODE_COMPRESSED_AIR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.TemperatureOver[0])
	{
		if (!OldAlarmState.TemperatureOver[0])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_1_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.TemperatureOver[0])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_1_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.TemperatureOver[1])
	{
		if (!OldAlarmState.TemperatureOver[1])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_2_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.TemperatureOver[1])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_2_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.TemperatureOver[2])
	{
		if (!OldAlarmState.TemperatureOver[2])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_3_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.TemperatureOver[2])
		{
			alarmCode = CSV_ALARM_CODE_TEMPERATURE_3_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.EmergencyOn)
	{
		if (!OldAlarmState.EmergencyOn)
		{
			alarmCode = CSV_ALARM_CODE_EMERGENCY_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.EmergencyOn)
		{
			alarmCode = CSV_ALARM_CODE_EMERGENCY_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Inverter1Trip)
	{
		if (!OldAlarmState.Inverter1Trip)
		{
			alarmCode = CSV_ALARM_CODE_INVERTER_1_TRIP;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Inverter1Trip)
		{
			alarmCode = CSV_ALARM_CODE_INVERTER_1_TRIP;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	if (newAlarmState.Inverter2Trip)
	{
		if (!OldAlarmState.Inverter2Trip)
		{
			alarmCode = CSV_ALARM_CODE_INVERTER_2_TRIP;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Inverter2Trip)
		{
			alarmCode = CSV_ALARM_CODE_INVERTER_2_TRIP;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.Inverter3Trip)
	{
		if (!OldAlarmState.Inverter3Trip)
		{
      if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
      {
			  alarmCode = CSV_ALARM_CODE_INVERTER_3_TRIP;
      }
      else
      {
        alarmCode = CSV_ALARM_CODE_RING_BLOWER_3_OL;
      }
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Inverter3Trip)
		{
			if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
      {
			  alarmCode = CSV_ALARM_CODE_INVERTER_3_TRIP;
      }
      else
      {
        alarmCode = CSV_ALARM_CODE_RING_BLOWER_3_OL;
      }
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Disk1SuctionLow)
	{
		if (!OldAlarmState.Disk1SuctionLow)
		{
			alarmCode = CSV_ALARM_CODE_DISK_1_SUCTION_LOW;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Disk1SuctionLow)
		{
			alarmCode = CSV_ALARM_CODE_DISK_1_SUCTION_LOW;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Disk2SuctionLow)
	{
		if (!OldAlarmState.Disk2SuctionLow)
		{
			alarmCode = CSV_ALARM_CODE_DISK_2_SUCTION_LOW;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Disk2SuctionLow)
		{
			alarmCode = CSV_ALARM_CODE_DISK_2_SUCTION_LOW;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.ServoAlarm)
	{
		if (!OldAlarmState.ServoAlarm)
		{
			alarmCode = CSV_ALARM_CODE_SERVO_ALARM;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.ServoAlarm)
		{
			alarmCode = CSV_ALARM_CODE_SERVO_ALARM;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Interlock)
	{
		if (!OldAlarmState.Interlock)
		{
			alarmCode = CSV_ALARM_CODE_INTERLOCK;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Interlock)
		{
			alarmCode = CSV_ALARM_CODE_INTERLOCK;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Disk1Stall)
	{
		if (!OldAlarmState.Disk1Stall)
		{
			alarmCode = CSV_ALARM_CODE_DISK_1_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Disk1Stall)
		{
			alarmCode = CSV_ALARM_CODE_DISK_1_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Disk2Stall)
	{
		if (!OldAlarmState.Disk2Stall)
		{
			alarmCode = CSV_ALARM_CODE_DISK_2_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Disk2Stall)
		{
			alarmCode = CSV_ALARM_CODE_DISK_2_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.TotalFull)
	{
		if (!OldAlarmState.TotalFull)
		{
			alarmCode = CSV_ALARM_CODE_TOTAL_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.TotalFull)
		{
			alarmCode = CSV_ALARM_CODE_TOTAL_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.GPFull)
	{
		if (!OldAlarmState.GPFull)
		{
			alarmCode = CSV_ALARM_CODE_GP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.GPFull)
		{
			alarmCode = CSV_ALARM_CODE_GP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.DPFull)
	{
		if (!OldAlarmState.DPFull)
		{
			alarmCode = CSV_ALARM_CODE_DP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.DPFull)
		{
			alarmCode = CSV_ALARM_CODE_DP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.UPFull)
	{
		if (!OldAlarmState.UPFull)
		{
			alarmCode = CSV_ALARM_CODE_UP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.UPFull)
		{
			alarmCode = CSV_ALARM_CODE_UP_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.DPRatioOver)
	{
		if (!OldAlarmState.DPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_DP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.DPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_DP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.CritDPRatioOver)
	{
		if (!OldAlarmState.CritDPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_CRIT_DP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.CritDPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_CRIT_DP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.UPRatioOver)
	{
		if (!OldAlarmState.UPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_UP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.UPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_UP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.CritUPRatioOver)
	{
		if (!OldAlarmState.CritUPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_CRIT_UP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.CritUPRatioOver)
		{
			alarmCode = CSV_ALARM_CODE_CRIT_UP_RATIO_OVER;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Sensor1Error)
	{
		if (!OldAlarmState.Sensor1Error)
		{
			alarmCode = CSV_ALARM_CODE_SENSOR_1_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Sensor1Error)
		{
			alarmCode = CSV_ALARM_CODE_SENSOR_1_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.Sensor2Error)
	{
		if (!OldAlarmState.Sensor2Error)
		{
			alarmCode = CSV_ALARM_CODE_SENSOR_2_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Sensor2Error)
		{
			alarmCode = CSV_ALARM_CODE_SENSOR_2_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.BrightnessDown)
	{
		if (!OldAlarmState.BrightnessDown)
		{
			alarmCode = CSV_ALARM_CODE_BRIGHTNESS_DOWN;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.BrightnessDown)
		{
			alarmCode = CSV_ALARM_CODE_BRIGHTNESS_DOWN;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.StepMotorStall[0])
	{
		if (!OldAlarmState.StepMotorStall[0])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_1_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.StepMotorStall[0])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_1_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.StepMotorStall[1])
	{
		if (!OldAlarmState.StepMotorStall[1])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_2_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.StepMotorStall[1])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_2_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	if (newAlarmState.StepMotorStall[2])
	{
		if (!OldAlarmState.StepMotorStall[2])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_3_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.StepMotorStall[2])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_3_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.StepMotorStall[3])
	{
		if (!OldAlarmState.StepMotorStall[3])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_4_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.StepMotorStall[3])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_4_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

	if (newAlarmState.StepMotorStall[4])
	{
		if (!OldAlarmState.StepMotorStall[4])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_5_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.StepMotorStall[4])
		{
			alarmCode = CSV_ALARM_CODE_STEPMOTOR_5_STALL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.CheckMisEjector)
	{
		if (!OldAlarmState.CheckMisEjector)
		{
			alarmCode = CSV_ALARM_CODE_MISEJECTOR_CHECK;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.CheckMisEjector)
		{
			alarmCode = CSV_ALARM_CODE_MISEJECTOR_CHECK;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.MisEjectFull)
	{
		if (!OldAlarmState.MisEjectFull)
		{
			alarmCode = CSV_ALARM_CODE_MISEJECTOR_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.MisEjectFull)
		{
			alarmCode = CSV_ALARM_CODE_MISEJECTOR_FULL;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.mes_status)
	{
		if (!OldAlarmState.mes_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_MES_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.mes_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_MES_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.Qjp_object_status)
	{
		if (!OldAlarmState.Qjp_object_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_DLL_OBJECT_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.Qjp_object_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_DLL_OBJECT_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.upstream_status)
	{
		if (!OldAlarmState.upstream_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_UPSTREAM_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.upstream_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_UPSTREAM_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.downstream_status)
	{
		if (!OldAlarmState.downstream_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_DOWNSTREAM_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.downstream_status)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_DOWNSTREAM_STATUS_ERROR;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.laser_emergency)
	{
		if (!OldAlarmState.laser_emergency)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_LASER_EMERGENCY_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.laser_emergency)
		{
			alarmCode = CSV_ALARM_CODE_ACROCIA_LASER_EMERGENCY_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}

  if (newAlarmState.EmissionSensorOn)
	{
		if (!OldAlarmState.EmissionSensorOn)
		{
			alarmCode = CSV_ALARM_CODE_EMISSIONSENSOR_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}
	else
	{
		if (OldAlarmState.EmissionSensorOn)
		{
			alarmCode = CSV_ALARM_CODE_EMISSIONSENSOR_ON;
			AddCSVEventLog(ECSV_EVENT_ALARM_CLEAR, (unsigned char *)&alarmCode, sizeof(unsigned int));
		}
	}


	OldAlarmState = newAlarmState;

	//    StatusTimer->Enabled = false;

	if (NCControlForm)
	{
		if (Machine.Status.MEStatus.Connected && Machine.Status.MEStatus.Enabled)
		{
			NCControlForm->ShowModal();
		}
		else if (NCControlForm->IsMEMode)
		{
			NCControlForm->Close();
		}
	}

	if (quickStartOption == EQUICK_START_INSPECTION)
	{
		quickStartOption++;
	}
	else if (quickStartOption > EQUICK_START_INSPECTION)
	{
		quickStartOption = 0;
		quickStartActivated = false;
		StatusTimer->Enabled = timerEnabled;
		InspectionButton->Click();
	}

	StatusTimer->Enabled = timerEnabled;

//cjg OPC Test
	if(hOPC_DLL)	(*pSetMachineAlarmState)(&Machine.AlarmStatus);

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::RefreshProductInfo(void)
{
	if (ProductData.ProductName.IsEmpty())
	{
		ProductNameLabel->Caption = MAINFORM_LABEL_CAPTION_04;
	}
	else
	{
		ProductNameLabel->Caption = ProductData.ProductName;
	}
	if (ProductData.LOTName.IsEmpty())
	{
		LOTNameLabel->Caption = MAINFORM_LABEL_CAPTION_04;
	}
	else
	{
		LOTNameLabel->Caption = ProductData.LOTName;
	}

	// set motor params
	int tabletType = 0, tabletShape = 0;

	if (ProductData.TabletType < TABLET_TYPE_COUNT)
	{
		tabletType = ProductData.TabletType;
	}
	else
	{
		tabletType = 0;
	}

	if (ProductData.TabletShape < TABLET_SHAPE_COUNT)
	{
		tabletShape = ProductData.TabletShape;
	}
	else if (ProductData.TabletShape == TABLET_SHAPE_TRIANGLE)
	{
		tabletShape = TABLET_SHAPE_CIRCLE;
	}
	else
	{
		tabletShape = 0;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SystemSettingButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;
  
	TSystemSettingForm *systemSettingForm = new TSystemSettingForm(this);
	ActiveSubForm = systemSettingForm;
	systemSettingForm->ShowModal();
  RefreshMenu();
  DeleteActiveSubMenu();
  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::MachineSetupButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;

	MachineSetupMenuForm = new TMachineSetupMenuForm(this);
	ActiveSubForm = MachineSetupMenuForm;

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();
    
	if (MachineSetupMenuForm->ShowModal() == mrOk)
	{
		MachineSetupComplete = true;
	}
	else
	{
		//MachineSetupComplete = false;
	}

	RefreshMenu();
  DeleteActiveSubMenu();

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    SendThreeDCameraSensorOnOffSignal(0, NULL, NULL);
  }
  
  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CalibrationButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;

	CalibrationForm = new TCalibrationForm(this);
	ActiveSubForm = CalibrationForm;
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();
	CalibrationForm->ShowModal();
	RefreshMenu();
 	DeleteActiveSubMenu();

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    SendThreeDCameraSensorOnOffSignal(0, NULL, NULL);
  }
  
  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::InspectionButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;

	bool bError = false;
	// Release 시 Comment 풀어야 함.
	//*************************************************************
	WideString VerWStr;
	VerWStr.SetLength(100);  //sjm add
	WideString  FpgaVer;
	FpgaVer = "220";
	VerWStr = "111";
	/************************************************************/

	if (PCProgramOption.FPGAVersionEnabled == 1)
	{
		//* sjm  (Add) 여기도 풀어야 한다.
		//************************************************************
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
			if (Comm_IsConnected(COMM_SPB + spbIndex))
			{
				Comm_Request(COMM_SPB + spbIndex, CMD_FPGA_VERSION_INFO, NULL, 0, &MSPBFPGAVersion[spbIndex], sizeof(TSPBFPGAVersion));
				wsprintfW(VerWStr, L"%d%d%d", MSPBFPGAVersion[spbIndex].VersionH & 0x0F, (MSPBFPGAVersion[spbIndex].VersionL & 0xF0) >> 4, MSPBFPGAVersion[spbIndex].VersionL & 0x0F);
				//ShowMessageFA(VerWStr);
				if (FpgaVer == VerWStr)
				{
					//ShowMessageFA("EQURE===");
				}
				else
				{
					//ShowMessageFA("NOT_EQURE !!!!!");
					return;
				}
				VerWStr = "111";
			}
		}
		//*************************************************************
		//*************************************************************
		// sjm (end) */
	}
	// load study data
	AnsiString studyFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".stu";
	if (!LoadStudyData(studyFileName, TabletStudyResultData_PC))
	{
		ShowMessageFA(MAINFORM_MSG_14);
		bError = true;
	}

	if (!bError)
	{
		// load grade data
		AnsiString gradeFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".grd";
		if (!LoadGradeData(gradeFileName, TabletGradeData_PC))
		{
			ShowMessageFA(MAINFORM_MSG_11);
			SetDefaultGradeData(TabletGradeData_PC);
			SaveGradeData(gradeFileName, TabletGradeData_PC);
		}

		WaitingForm->SetMessage(MAINFORM_MSG_13);
		WaitingForm->Show();
		Application->ProcessMessages();

		MainMenuBtnLockControl(true);

		// 검사 데이터 생성으로 인해 상당시간 소요된다.
		InspectionForm = new TInspectionForm(this);

		WaitingForm->Hide();
    InspectFormStatus = true;
		MainMenuBtnLockControl(false);

		ActiveSubForm = InspectionForm;
		InspectionForm->ShowModal();

	}
  InspectFormStatus = false;
  RefreshMenu();
  DeleteActiveSubMenu();

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    SendThreeDCameraSensorOnOffSignal(0, NULL, NULL);
  }
  
  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MachineTestButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;

	MachineTestForm = new TMachineTestForm(this);

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();

	ActiveSubForm = MachineTestForm;
	MachineTestForm->ShowModal();
  RefreshMenu();
  DeleteActiveSubMenu();

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    SendThreeDCameraSensorOnOffSignal(0, NULL, NULL);
  }
  
  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ErrorMenuItemClick(TObject *Sender)
{
	ErrorListForm->Show();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::StudyButtonClick(TObject *Sender)
{
  ThreeDSensorControlTimer->Enabled = false; // Machine Run & Camera Setup을 하는 경우 중복 Command가 전송되는 것을 방지하기 위함

  DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
  DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

  ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

  RecentDisk1ThreeDCameraLSFValue = -1;
  RecentDisk2ThreeDCameraLSFValue = -1;
  
	TStudyForm *studyForm = new TStudyForm(this);
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();
	ActiveSubForm = studyForm;
	studyForm->ShowModal();
	RefreshMenu();
  DeleteActiveSubMenu();

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    SendThreeDCameraSensorOnOffSignal(0, NULL, NULL);
  }

  ThreeDSensorControlTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ExtractCharacterButtonClick(TObject *Sender)
{
	TTabletCharacterExtractForm *tabletCharacterExtractForm = new TTabletCharacterExtractForm(this);
  tabletCharacterExtractForm->SetupMode = TABLET_SETUP_MODE_NORMAL;
  
	ActiveSubForm = tabletCharacterExtractForm;
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();
	if (tabletCharacterExtractForm->ShowModal() == mrOk)
	{
		CPBSetupInfo.StudySetupDataValid = false;
		CPBSetupInfo.InspectionSetupDataValid = false;
		CPBSetupInfo.GradeDataValid = false;
	}
	RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormActivate(TObject *Sender)
{
  SetScreenPosition(this);
	RefreshMenu();

	if (UserInfo.Status == USER_STATUS_LOGOUT)
	{
		// check recent inspection
		if (Comm_IsConnected(COMM_HCB))
		{
			TTerminationInfo terminationInfo;
			if (Comm_Request(COMM_HCB, CMD_TERMINATION_INFO, NULL, 0, &terminationInfo, sizeof(TTerminationInfo)))
			{
				if (terminationInfo.DataValid)
				{
					int inspectionID;
					AnsiString recentProductName, recentLot, userName;
					double inspectionTime;
					TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
					if (iniFile)
					{
						inspectionID = iniFile->ReadInteger("Recent Inspection", "Inspection ID", 0);
						userName = iniFile->ReadString("Recent Inspection", "User Name", "Unknown");
						inspectionTime = iniFile->ReadFloat("Recent Inspection", "Inspection Start Time", 0);
						recentProductName = iniFile->ReadString("Recent Inspection", "Product Name", "Unknown");
						recentLot = iniFile->ReadString("Recent Inspection", "Lot Name", "Unknown");
						delete iniFile;

						if (terminationInfo.InspectionID == inspectionID)
						{
							// 2019-05-27 report file의 문제 발생 원인으로 예상되는 지점, Log 추가 후 장비에 적용하여 나중에 확인해보자
							WritePCProgramErrorLog(this->Name, __LINE__);
							TInspectionRecoverForm *inspectionRecoverForm = new TInspectionRecoverForm(this);
							inspectionRecoverForm->SetProcessingReport(userName, inspectionTime, recentProductName, recentLot, &terminationInfo);
							inspectionRecoverForm->ExecuteRecover();
							delete inspectionRecoverForm;
						}
					}

					Comm_Request(COMM_HCB, CMD_INVALIDATE_TERMINATION_INFO);
				}
			}
		}
		/*
		TTerminationInfo terminationInfo;
		AnsiString recentProductName, recentLot, userName;
		double inspectionTime;
		TInspectionRecoverForm *inspectionRecoverForm = new TInspectionRecoverForm(this);
		inspectionRecoverForm->SetProcessingReport(userName, inspectionTime, recentProductName, recentLot, &terminationInfo);
		inspectionRecoverForm->ShowModal();
		delete inspectionRecoverForm;
		*/

		RequestLogIn();
	}
  	BackupIniFiles();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::CleaningButtonClick(TObject *Sender)
{
	Machine.MachineCleaning();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ReadyButtonClick(TObject *Sender)
{
	if (ProductData.ProductCode.IsEmpty())
	{
		ShowMessageFA(MAINFORM_MSG_12);
		return;
	}

	Machine.MachineReady();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::AlarmPanelClick(TObject *Sender)
{
	AlarmForm->SleepMode = false;
	AlarmForm->WarningSleep = false;
	AlarmForm->Show();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FirstStudyButtonClick(TObject *Sender)
{
	TFirstStudy *firstStudyForm = new TFirstStudy(this);
	ActiveSubForm = firstStudyForm;

	if (firstStudyForm->ShowModal() == mrOk)
	{
		CPBSetupInfo.StudySetupDataValid = false;
		CPBSetupInfo.InspectionSetupDataValid = false;
		CPBSetupInfo.GradeDataValid = false;
	}
	RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::UserRegisterButtonClick(TObject *Sender)
{
	bool currentUserRemoved;
	//	TUserRegisterForm *userRegisterForm = new TUserRegisterForm(this);
	UserRegisterForm = new TUserRegisterForm(this);
	ActiveSubForm = UserRegisterForm;
	UserRegisterForm->ShowModal();
	currentUserRemoved = UserRegisterForm->CurrentUserRemoved;
	if (currentUserRemoved)
	{
		UserInfo.Status = USER_STATUS_LOGOUT;
		UserInfo.AccessLevel = SYSTEM_ACCESS_LEVEL_ANONYMOUS;
		ProductData.ProductCode = "";
		ProductData.ProcessingStep = TABLET_PROCESSING_STEP_NONE;
		MachineSetupComplete = false;
		RefreshMenu();
		RequestLogIn();
	}
	RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::MachineControlButtonClick(TObject *Sender)
{
	//	TMachineControlForm *machineControlForm = new TMachineControlForm(this);
	MachineControlForm = new TMachineControlForm(this);
	ActiveSubForm = MachineControlForm;
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    Machine.MisejectClose();
	MachineControlForm->ShowModal();
  RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::ClientPanelDblClick(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 TMainForm::InspectionReportButtonClick(TObject *Sender)
{
	//TInspectionReportForm *inspectionReportForm = new TInspectionReportForm(this);
  InspectionReportForm =new TInspectionReportForm(this);
	ActiveSubForm = InspectionReportForm;//inspectionReportForm;
  InspectionReportForm->ShowModal();
	//inspectionReportForm->ShowModal();
  RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::EnvironmentSettingButtonClick(TObject *Sender)
{
	EnvironmentSettingForm = new TEnvironmentSettingForm(this);
	ActiveSubForm = EnvironmentSettingForm;
	EnvironmentSettingForm->ShowModal();

  if(EnvironmentSettingForm->bNeedLogOut)
  {
    UserInfo.Status = USER_STATUS_LOGOUT;
    UserInfo.AccessLevel = SYSTEM_ACCESS_LEVEL_ANONYMOUS;
    ProductData.ProductCode = "";
    ProductData.ProcessingStep = TABLET_PROCESSING_STEP_NONE;
    MachineSetupComplete = false;
    RefreshMenu();
    RequestLogIn();
  }

  RefreshMenu();

	if (ComputerSystemInfo.InactivityLogoutEnabled)
	{
		if (hHook == NULL)
		{
        hHook = SetWindowsHookEx(WH_MOUSE, (HOOKPROC)MouseHook, NULL, GetCurrentThreadId());
       LastUserActiveTime = GetTickCount();
       ActivityCheckTimer->Enabled = true;
		}
		else
		{
			LastUserActiveTime = GetTickCount();
			ActivityCheckTimer->Enabled = true;
		}
	}
	else
	{
		ActivityCheckTimer->Enabled = false;
	}
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::AuditTrailButtonClick(TObject *Sender)
{
	//TAuditTrailForm *auditTrailForm = new TAuditTrailForm(this);
	AuditTrailForm = new TAuditTrailForm(this);
	ActiveSubForm = AuditTrailForm;
	AuditTrailForm->ShowModal();
  RefreshMenu();
  DeleteActiveSubMenu();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ActivityCheckTimerTimer(TObject *Sender)
{
	if (GetTickCount() - LastUserActiveTime > ComputerSystemInfo.InactivityTimeout * 60 * 1000)
	{
		if (UserInfo.Status != USER_STATUS_LOGOUT)
		{
			AddCSVActionLog(ECSV_ACTION_LOGOUT, UserInfo.Name, "", NULL, 0);
			UserInfo.Status = USER_STATUS_LOGOUT;
			UserInfo.AccessLevel = SYSTEM_ACCESS_LEVEL_ANONYMOUS;

      RequestLogIn();


			if (ActiveSubForm == NULL)
			{

			}
			else if (ProductInputForm == ActiveSubForm)
			{
				ProductInputForm->OnUserChange();
			}
			else if (MachineSetupMenuForm == ActiveSubForm)
			{
				MachineSetupMenuForm->OnUserChange();
			}
			else if (CalibrationForm == ActiveSubForm)
			{
				CalibrationForm->OnUserChange();
			}
			else if (InspectionForm == ActiveSubForm)
			{
				InspectionForm->OnUserChange();
			}
			else if (MachineTestForm == ActiveSubForm)
			{
				MachineTestForm->OnUserChange();
			}
			else if (UserRegisterForm == ActiveSubForm)
			{
				UserRegisterForm->OnUserChange();
			}
			else if (AuditTrailForm == ActiveSubForm)
			{
				AuditTrailForm->OnUserChange();
			}
			else if (EnvironmentSettingForm == ActiveSubForm)
			{
				EnvironmentSettingForm->OnUserChange();
			}
			else if (MachineControlForm == ActiveSubForm)
			{
				// 구현 안됨
			}
			else if (SystemSettingForm == ActiveSubForm)
			{
				SystemSettingForm->OnUserChange();
			}
      else if(InspectionReportForm == ActiveSubForm)
      {
        InspectionReportForm->OnUserChange();
      }
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::KeyboardStatusCheckTimerTimer(TObject *Sender)
{

	// LogInForm에서 생성되는 KeyboardForm은 실시간 상태확인대상에서 제외한다.
	bool timerEnabled;

	timerEnabled = KeyboardStatusCheckTimer->Enabled;
	KeyboardStatusCheckTimer->Enabled = false;

	int WindowsOSLanID = GetUserDefaultUILanguage();

	if (KeyboardForm != NULL)
	{
		//System(Windows 한영상태 Check)
		unsigned long Conversion, Sentence;
		HIMC Mode = ImmGetContext(Application->Handle);
		ImmGetConversionStatus(Mode, &Conversion, &Sentence);

		if (DefaultLCID == LANGUAGE_ID_KOREAN && WindowsOSLanID == LANGUAGE_ID_KOREAN)
		{
			if (Conversion == IME_CMODE_HANGEUL)
			{
				if (KeyboardForm->IsHangulMode == false)
				{
					KeyboardForm->IsHangulMode = !KeyboardForm->IsHangulMode;
					KeyboardForm->CompBufSize = 0;
					KeyboardForm->CompStr[0] = '\0';
				}
			}
			else
			{
				if (KeyboardForm->IsHangulMode == true)
				{
					KeyboardForm->IsHangulMode = !KeyboardForm->IsHangulMode;
					KeyboardForm->CompBufSize = 0;
					KeyboardForm->CompStr[0] = '\0';
				}
			}
		}
		else if (DefaultLCID != LANGUAGE_ID_KOREAN && WindowsOSLanID == LANGUAGE_ID_KOREAN)
		{
			if (Conversion == IME_CMODE_HANGEUL)
			{
				ImmSetConversionStatus(Mode, IME_CMODE_ALPHANUMERIC, Sentence);
			}

			KeyboardForm->IsHangulMode = false;
			KeyboardForm->CompBufSize = 0;
			KeyboardForm->CompStr[0] = '\0';
		}
		else
		{
			KeyboardForm->IsHangulMode = false;
			KeyboardForm->CompBufSize = 0;
			KeyboardForm->CompStr[0] = '\0';
		}

		//System CapslockCheck

		if ((GetKeyState(VK_CAPITAL) & 0x0001) == 1) // 1 = CapsLock On, 0 = CapsLock Off
		{
			if (KeyboardForm->CapsLock == false)
			{
				KeyboardForm->CapsLock = true;
				KeyboardForm->SetKeyValues();
			}
		}
		else
		{
			if (KeyboardForm->CapsLock == true)
			{
				KeyboardForm->CapsLock = false;
				KeyboardForm->SetKeyValues();
			}
		}
	}

	KeyboardStatusCheckTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SimulationButtonDblClick(TObject *Sender)
{
	if (!ProductData.ProductName.IsEmpty())
	{
		ErrorListForm->ErrorReadTimer->Enabled = false;

		TSystemSimulationForm *pSystemSimulationForm;
		pSystemSimulationForm = new TSystemSimulationForm(this);

		pSystemSimulationForm->ShowModal();

		delete pSystemSimulationForm;

		ErrorListForm->ErrorReadTimer->Enabled = true;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::SetDefaultCameraGain()
{
 	 // 시스템 기본 카메라 밝기 설정
	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		int spbIndex = CameraMapInfo[cameraIndex - 1].SPBIndex;
		int camIndex = CameraMapInfo[cameraIndex - 1].CamIndex;

		if (Comm_IsConnected(COMM_SPB + spbIndex) && bSPBSystemValid[spbIndex])
		{
			if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[cameraIndex - 1] != 0)
			{
				if (cameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX && cameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX) // 3D Camera
				{
					SetCameraGain(cameraIndex, SYSTEM_DEFAULT_ANLOG_GAIN, 1, 0);
				}
			}
		}
	}



  /*
  // UI 실행될 때 ipb에 연결된 2D카메라의 캡쳐를 한번씩 진행
  TCaptureCommandParam captureCommandParam;
	captureCommandParam.CaptureMode = CAPTURE_MODE_CONTINUOUS;

  unsigned int data[2];
	unsigned int receivedData[2];
  unsigned long captureStartTime;
  unsigned long currentTime;
  AnsiString errorMsg;

  for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
  {
    int spbIndex = CameraMapInfo[cameraIndex - 1].SPBIndex;
    int camIndex = CameraMapInfo[cameraIndex - 1].CamIndex;

    if (Comm_IsConnected(COMM_SPB + spbIndex) && bSPBSystemValid[spbIndex])
		{
			if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition != CAMERA_POSITION_DISCONNECT)
      {
				if (cameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX && cameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX) // 3D Camera
        {
          if (!GlobalEnabledCameraStatus[cameraIndex - 1]) continue;

          captureCommandParam.CameraMask = 0x01 << camIndex;
          captureCommandParam.ShutterSpeed[camIndex] = 17;
          captureCommandParam.SubsamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
          RefreshCameraInfo(cameraIndex - 1);

          captureCommandParam.FrameBufferCount = 3;
          captureCommandParam.CaptureKind = CAPTURE_KIND_FRAME;

          captureStartTime = GetTickCount();

          if (Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_START, &captureCommandParam, sizeof(TCaptureCommandParam)))
          {
            data[0] = camIndex;
            data[1] = SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT;

            while(1)
            {
              Application->ProcessMessages();

              Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int), receivedData, sizeof(unsigned int) * 2);

              if (receivedData[0]) // capture exist
              {
                Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));


                break;
              }
              else
              {
                currentTime = GetTickCount();

                if(currentTime - captureStartTime > CAPTURE_WAITING_TIME)
                {
                  Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_STOP, &camIndex, sizeof(int));

                  errorMsg = "Camera capture timeout [#" + IntToStr(cameraIndex) + "]";
                  ShowMessage(errorMsg);

                  break;
                }
              }
            }
          }
        }
      }
		}
  }
  */
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::MainMenuBtnLockControl(bool bLock)
{
	if (bLock)
	{
		prevMainMenuBtnState[0] = TabletInfoButton->Enabled;
		prevMainMenuBtnState[1] = MachineSetupButton->Enabled;
		prevMainMenuBtnState[2] = CalibrationButton->Enabled;
		prevMainMenuBtnState[3] = ExtractCharacterButton->Enabled;
		prevMainMenuBtnState[4] = FirstStudyButton->Enabled;
		prevMainMenuBtnState[5] = StudyButton->Enabled;

		prevMainMenuBtnState[6] = InspectionButton->Enabled;
		prevMainMenuBtnState[7] = InspectionReportButton->Enabled;
		prevMainMenuBtnState[8] = CleaningButton->Enabled;
		prevMainMenuBtnState[9] = ReadyButton->Enabled;
		prevMainMenuBtnState[10] = LogOutButton->Enabled;
		prevMainMenuBtnState[11] = CloseButton->Enabled;

		prevMainMenuBtnState[12] = MachineTestButton->Enabled;
		prevMainMenuBtnState[13] = MachineControlButton->Enabled;
		prevMainMenuBtnState[14] = UserRegisterButton->Enabled;
		prevMainMenuBtnState[15] = SystemSettingButton->Enabled;
		prevMainMenuBtnState[16] = EnvironmentSettingButton->Enabled;
		prevMainMenuBtnState[17] = AuditTrailButton->Enabled;

		TabletInfoButton->Enabled = false;
		MachineSetupButton->Enabled = false;
		CalibrationButton->Enabled = false;
		ExtractCharacterButton->Enabled = false;
		FirstStudyButton->Enabled = false;
		StudyButton->Enabled = false;

		InspectionButton->Enabled = false;
		InspectionReportButton->Enabled = false;
		CleaningButton->Enabled = false;
		ReadyButton->Enabled = false;
		LogOutButton->Enabled = false;
		CloseButton->Enabled = false;

		MachineTestButton->Enabled = false;
		MachineControlButton->Enabled = false;
		UserRegisterButton->Enabled = false;
		SystemSettingButton->Enabled = false;
		EnvironmentSettingButton->Enabled = false;
		AuditTrailButton->Enabled = false;
	}
	else
	{
		TabletInfoButton->Enabled = prevMainMenuBtnState[0];
		MachineSetupButton->Enabled = prevMainMenuBtnState[1];
		CalibrationButton->Enabled = prevMainMenuBtnState[2];
		ExtractCharacterButton->Enabled = prevMainMenuBtnState[3];
		FirstStudyButton->Enabled = prevMainMenuBtnState[4];
		StudyButton->Enabled = prevMainMenuBtnState[5];

		InspectionButton->Enabled = prevMainMenuBtnState[6];
		InspectionReportButton->Enabled = prevMainMenuBtnState[7];
		CleaningButton->Enabled = prevMainMenuBtnState[8];
		ReadyButton->Enabled = prevMainMenuBtnState[9];
		LogOutButton->Enabled = prevMainMenuBtnState[10];
		CloseButton->Enabled = prevMainMenuBtnState[11];

		MachineTestButton->Enabled = prevMainMenuBtnState[12];
		MachineControlButton->Enabled = prevMainMenuBtnState[13];
		UserRegisterButton->Enabled = prevMainMenuBtnState[14];
		SystemSettingButton->Enabled = prevMainMenuBtnState[15];
		EnvironmentSettingButton->Enabled = prevMainMenuBtnState[16];
		AuditTrailButton->Enabled = prevMainMenuBtnState[17];
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::Panel1DblClick(TObject *Sender)
{
  SimulationButton->Visible = !SimulationButton->Visible;
  DllInitButton->Visible = !DllInitButton->Visible;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::BackupIniFiles()
{


  AnsiString CopyPath =  ProgramPath.Root + "\\INI_BACKUP";
  AnsiString InIPath =  ProgramPath.Env ;
  int FloderAliveCount = 0;
  try
  {
    // 아무것도 없을때
    if (!DirectoryExists(CopyPath))
    {
      ForceDirectories(CopyPath);

      AnsiString Date;
      DateTimeToString(Date,"yyyy/mm/dd",Now());//  Now().DateString();
      int length = Date.Length();
      int Temp;
      for(int i = 0; i < length; ++i)
      {
        if(!TryStrToInt(Date.c_str()[i],Temp))
        {
          Date.c_str()[i]=0x2D;
        }
      }

      ForceDirectories(CopyPath+ "\\" +Date );

      TSearchRec sr;
      int iAttributes = faAnyFile;
      if (FindFirst(InIPath + "\\*.ini", iAttributes, sr) == 0)
      {
        do
        {
          if (sr.Name == "." || sr.Name == "..") continue;
          {
            AnsiString Nowpath =  InIPath + "\\"+sr.Name;
            AnsiString Targetpath = CopyPath+ "\\" +Date+"\\"+sr.Name;
            CopyFileA(Nowpath.c_str(),Targetpath.c_str(),false);
          }
        } while (FindNext(sr) == 0);
        FindClose(sr);
      }
    }
    else
    {
      bool NewWrite = true;
      TSearchRec sr;
      AnsiString SaveFileName;
      int iAttributes = faAnyFile;
      if (FindFirst(CopyPath + "\\*.*", iAttributes, sr) == 0)
      {
        do
        {
          if (sr.Name == "." || sr.Name == ".." || sr.Attr != 16) continue;

          FloderAliveCount ++;
          AnsiString dt = sr.Name;
          int length = dt.Length();
          int count = 0;
          char SplitChange;
          AnsiString NDate = Now().DateString();
          int eCount =NDate.Length();
          int Temp;
          for(int i = 0; i < eCount; ++i)
          {
            if(!TryStrToInt(NDate.c_str()[i],Temp))
            {
              SplitChange = NDate.c_str()[i];
              break;
            }
          }
          DateTimeToString(NDate,"yyyy/mm/dd",Now());
          SaveFileName =NDate;
          while(length--)
          {
            if(!TryStrToInt(dt.c_str()[count],Temp))
            {
              dt.c_str()[count] = SplitChange;// SplitChange  //0x2D
              //break;
            }
            count++;
          }

          for(int i = 0; i < eCount; ++i)
          {
            if(!TryStrToInt(SaveFileName.c_str()[i],Temp))
            {
              SaveFileName.c_str()[i]=  0x2D;
            }
          }


          TDateTime SearchDT;

          TryEncodeDate(StrToInt(dt.SubString(0,4)) ,StrToInt(dt.SubString(6,2)),StrToInt(dt.SubString(9,2)),SearchDT);
          //SearchDT.Val =  StrToDate(dt).Val;


          if(14 > Now().Val - SearchDT.Val)
          {
            NewWrite = false;
            return;
          }

        } while (FindNext(sr) == 0);
        FindClose(sr);
      }

      if(FloderAliveCount == 0)
      {
        AnsiString NDate;
          DateTimeToString(NDate,"yyyy/mm/dd",Now());//  Now().DateString();
          //AnsiString NDate = Now().DateString();
          int eCount = NDate.Length();
          SaveFileName = NDate;
          int Temp;

          for(int i = 0; i < eCount; ++i)
          {
            if(!TryStrToInt(SaveFileName.c_str()[i],Temp))
            {
              SaveFileName.c_str()[i]=  0x2D;
            }
          }

         NewWrite = true;
      }
      
      if(NewWrite)
      {
        ForceDirectories(CopyPath+ "\\" + SaveFileName );

        TSearchRec sr;
        int iAttributes = faAnyFile;
        if (FindFirst(InIPath + "\\*.ini", iAttributes, sr) == 0)
        {
          do
          {
            if (sr.Name == "." || sr.Name == "..") continue;
            {
              AnsiString Nowpath =  InIPath + "\\"+sr.Name;
              AnsiString Targetpath = CopyPath+ "\\" +SaveFileName+"\\"+sr.Name;
              CopyFileA(Nowpath.c_str(),Targetpath.c_str(),false);
            }
          } while (FindNext(sr) == 0);
          FindClose(sr);
        }
      }
    }
  }
  catch(...)
  {
  }

}
void __fastcall TMainForm::PIO05PortStatusCheck()
{
	unsigned short inport,outport;
	unsigned short Laser_port = 0;
	unsigned short bit = 0x0001;
	unsigned short SelmaSts;
	unsigned short dllSts;
  unsigned short CommandApplySts = 0;
	unsigned short command;
	int i;
	PortStatusInfo PIO05_status;

	PIO05_status.IPMask = 0;
	PIO05_status.OPMask = 0;
	SelmaSts = STATUS_Undefine;


  if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
  {


    int M_StatusFlag[4] = {0};

    if(PcUiFlag.InsReady)
       M_StatusFlag[0] = 1;
    else
       M_StatusFlag[0] = 0;
    if(PcUiFlag.EMR)
       M_StatusFlag[1] = 1;
    else
       M_StatusFlag[1] = 0;
    if(PcUiFlag.InsActive)
       M_StatusFlag[2] = 1;
    else
       M_StatusFlag[2] = 0;

    if(PcUiFlag.APPActive)
       M_StatusFlag[3] = 1;
    else
       M_StatusFlag[3] = 0;

    unsigned short BitT = 0;
    for(i = 0 ; i < 4; i++)
    {
      if(M_StatusFlag[i])
        BitT |= bit<<i;
      else
        BitT &= ~(bit<<i);
    }
    PIO05_status.OPMask = BitT;

    Comm_Request(COMM_HCB, CMD_PIO05_PORT_ONOFF,&PIO05_status, sizeof(PortStatusInfo));
  }
  else
  {
    for(i = 0 ; i < MAX_PIO5_PORT_NUM; i++)
    {
      if(Machine.PortStatus.IPStatus[MAX_PIO5_PORT_OFFSET+i])
        PIO05_status.IPMask |= bit<<i;
      else
        PIO05_status.IPMask &= ~(bit<<i);
    }
    obj_setinport(PIO05_status.IPMask);
    PIO05_status.OPMask = obj_getoutport();
    Comm_Request(COMM_HCB, CMD_PIO05_PORT_ONOFF,&PIO05_status, sizeof(PortStatusInfo));



/*
	if(UVLaser.SELMAStatus.APPActive)
	{
		Laser_port |= bit<<(IP_LINK_APPACTION-MAX_PIO5_PORT_OFFSET);
	}
	else
	{
		Laser_port &= ~(bit<<(IP_LINK_APPACTION-MAX_PIO5_PORT_OFFSET));
	}
	if(UVLaser.SELMAStatus.Ready)
	{
//		UVLaser.SELMAStatus.Active = 0;
		Laser_port |= bit<<(IP_LINK_READY-MAX_PIO5_PORT_OFFSET);
	}
	else
	{
		Laser_port &= ~(bit<<(IP_LINK_READY-MAX_PIO5_PORT_OFFSET));
	}
	if(UVLaser.SELMAStatus.Active)
	{
//		UVLaser.SELMAStatus.Ready = 0;
		Laser_port |= bit<<(IP_LINK_ACTION-MAX_PIO5_PORT_OFFSET);
	}
	else
	{
		Laser_port &= ~(bit<<(IP_LINK_ACTION-MAX_PIO5_PORT_OFFSET));
	}
	if(UVLaser.SELMAStatus.EMR)
	{
		Laser_port |= bit<<(IP_LINK_EMR-MAX_PIO5_PORT_OFFSET);
	}
	else
	{
		Laser_port &= ~(bit<<(IP_LINK_EMR-MAX_PIO5_PORT_OFFSET));
	}
*/
	//PIO05_status.OPMask = obj_getoutport();
//	PIO05_status.OPMask |= Laser_port;

//	if(PIO05_status.OPMask> 0)

		//Comm_Request(COMM_HCB, CMD_PIO05_PORT_ONOFF,&PIO05_status, sizeof(PortStatusInfo));  //n
//	}

  if (Machine.Status.AlarmExist)
	{
		SelmaSts |= STATUS_HeavyAlarm;
    LastHeaveyAlarmState = true;
	}
	else
	{
		SelmaSts &= ~STATUS_HeavyAlarm;
    if(Machine.Status.OperationState == MACHINE_STATE_STOP)
      LastHeaveyAlarmState = false;
	}

	switch (Machine.Status.OperationState)
	{
		case MACHINE_STATE_STOP:
				if(UVLaser.SELMAStatus.Ready)
				{
					SelmaSts |= STATUS_WaitStop;
					SelmaSts &= ~STATUS_Run;
				}

        if(UVLaser.UVLaserStatus.InsForm_Active)
        {
          if (!Machine.Status.AlarmExist) // 알람이 없을때 //if (!Machine.WarningStatus.VBFeederEmpty && !Machine.Status.AlarmExist) // 알람이 없을때
          {
				    SelmaSts |= STATUS_Ready;
          }
          else // 알람이 있을때
          {
            SelmaSts &= ~STATUS_Ready;
            SelmaSts &= ~STATUS_WaitStop;
          }
        }
        else
        {
          UVLaser.UVLaserStatus.InsRestart_ActiveStatus = 0;
          SelmaSts &= ~STATUS_Ready;
        }

			break;
		case MACHINE_STATE_RUN:
				SelmaSts |= STATUS_Run;
			break;
		case MACHINE_STATE_CLEANING:
				SelmaSts |= STATUS_Undefine;
				SelmaSts &= ~STATUS_WaitStop;
				SelmaSts &= ~STATUS_Ready;
			break;

		case MACHINE_STATE_STARTING:
				SelmaSts |= STATUS_Run;
				SelmaSts &= ~STATUS_Ready;
				SelmaSts &= ~STATUS_WaitStop;
			break;
		case MACHINE_STATE_STOPPING:
        if(LastHeaveyAlarmState == true)
        {
          SelmaSts &= STATUS_Run;
        }
        else
        {
          SelmaSts |= STATUS_Run;
        }

				SelmaSts &= ~STATUS_WaitStop;
			break;
		case MACHINE_STATE_EMERGENCY_STOP:
				//SelmaSts |= STATUS_HeavyAlarm;
        SelmaSts |= STATUS_Emergency;
				SelmaSts &= ~STATUS_WaitStop;
				SelmaSts &= ~STATUS_Ready;
				SelmaSts &= ~STATUS_Run;   // Emergency는 들어왔다가 바로Stop으로 빠지는것 같음.
			break;

		default:
			break;
	}

  if (Machine.AlarmStatus.EmergencyOn)
  {
    SelmaSts |= STATUS_Emergency;
    SelmaSts &= ~STATUS_WaitStop;
    SelmaSts &= ~STATUS_Ready;
		SelmaSts &= ~STATUS_Run;
  }
  else
  {
    SelmaSts &= ~STATUS_Emergency;
  }

  if (Machine.WarningStatus.VBFeederEmpty)
  {
    if(UVLaser.SELMAStatus.Ready)  // WaitStop
    {
      SelmaSts |= STATUS_Warning;
      //SelmaSts &= ~STATUS_Run;
    }
    else
    {
      SelmaSts |= STATUS_Warning;
      SelmaSts |= STATUS_Run;
    }
  }
  else
  {
    SelmaSts &= ~ STATUS_Warning;
  }

	if (PCProgramOption.UVLaserUpstreamEnabled)
	{
		SelmaSts |= STATUS_UsInterlockMode;
	}
  else
  {
		SelmaSts &= ~ STATUS_UsInterlockMode;
  }

  if (PCProgramOption.UVLaserDownstreamEnabled)
  {
		SelmaSts |= STATUS_DsInterlockMode;
  }
  else
  {
		SelmaSts &= ~ STATUS_DsInterlockMode;
  }

  if(UVLaser.UVLaserStatus.InsForm_Active)
  {
    if (UVLaser.SELMAStatus.InsRestart_ActiveStatus)
  {
      SelmaSts |= STATUS_ReStartRedy;
  }
  else
  {
      SelmaSts &= ~ STATUS_ReStartRedy;
    }
  }

	obj_setstatus(SelmaSts);

  if(UVLaser.UVLaserStatus.StartCommandApply)
  {
    UVLaser.UVLaserStatus.StartCommandApply = 0;
    CommandApplySts |= COMMAND_Start;
  }
  if(UVLaser.UVLaserStatus.RestartCommandApply)
  {
    UVLaser.UVLaserStatus.RestartCommandApply = 0;
    CommandApplySts |= COMMAND_ReStart;
  }
  if(UVLaser.UVLaserStatus.ResumeCommandApply)
  {
    UVLaser.UVLaserStatus.ResumeCommandApply = 0;
    CommandApplySts |= COMMAND_Resume;
  }
  if(UVLaser.UVLaserStatus.EMStopCommandApply)
  {
    UVLaser.UVLaserStatus.EMStopCommandApply = 0;
    CommandApplySts |= COMMAND_EmergencyStop;
  }
  if(UVLaser.UVLaserStatus.StopCommandApply)
  {
    UVLaser.UVLaserStatus.StopCommandApply = 0;
    CommandApplySts |= COMMAND_Stop;
  }
  if(UVLaser.UVLaserStatus.WaitStop1CommandApply)
  {
    UVLaser.UVLaserStatus.WaitStop1CommandApply = 0;
    CommandApplySts |= COMMAND_WaitStop1;
  }
  if(UVLaser.UVLaserStatus.WaitStop2CommandApply)
  {
    UVLaser.UVLaserStatus.WaitStop2CommandApply = 0;
    CommandApplySts |= COMMAND_WaitStop2;
  }
  if(UVLaser.UVLaserStatus.DischargeResetCommandApply)
  {
    UVLaser.UVLaserStatus.DischargeResetCommandApply = 0;
    CommandApplySts |= COMMAND_DischargeCountReset;
  }
  if(UVLaser.UVLaserStatus.AjustTimeCommandApply)
  {
    UVLaser.UVLaserStatus.AjustTimeCommandApply = 0;
    CommandApplySts |= COMMAND_AjustTime;
  }
  if(UVLaser.UVLaserStatus.ProductDataClearApply)
  {
    UVLaser.UVLaserStatus.ProductDataClearApply = 0;
    CommandApplySts |= COMMAND_ProductDataClear;
  }
  obj_setexecommand(CommandApplySts);

  dllSts = obj_getobjstatus();
  int OBJ_RESET = 0;

  if(dllSts & OBJ_STATUS_NotRun)
	{
    UVLaser.UVLaserStatus.NotRunFlag = 1;
	}
	else
	{
    UVLaser.UVLaserStatus.NotRunFlag = 0;
	}

  if(dllSts & OBJ_STATUS_NotChangeRecipe)
	{
    UVLaser.UVLaserStatus.NotChangeRecipeFlag = 1;
	}
	else
	{
    UVLaser.UVLaserStatus.NotChangeRecipeFlag = 0;
	}

  if(dllSts & OBJ_STATUS_UpStreamNotReady || dllSts & OBJ_STATUS_DownStreamNotReady)
  {
    UVLaser.UVLaserStatus.Ready = 0;
  }
  else
  {
    UVLaser.UVLaserStatus.Ready = 1;
  }

  if(alarm_reset_button_on || Machine.PortStatus.IPStatus[IP_ALARM_RESET])//alarm_reset_button_on)
	{
    OBJ_RESET = 1;
    
		if(dllSts & OBJ_STATUS_MesError)
		{
			Machine.Acrocia_Set_AlarmStatus(10);
			obj_errorreset(OBJ_STATUS_MesError);
			obj_seqclear(SEQ_Mes);
		}
		if(dllSts & OBJ_STATUS_UpstreamError)
		{
			Machine.Acrocia_Set_AlarmStatus(20);
			obj_errorreset(OBJ_STATUS_UpstreamError);
			obj_seqclear(SEQ_UpStreem);
		}
		if(dllSts & OBJ_STATUS_DownstreamError)
		{
			Machine.Acrocia_Set_AlarmStatus(30);
			//ProductData.DischargeCount = 0;
			obj_errorreset(OBJ_STATUS_DownstreamError);
			obj_seqclear(SEQ_DownStreem);
		}
    if(dllSts & OBJ_STATUS_QjpobjectError)
		{
			Machine.Acrocia_Set_AlarmStatus(40);
			obj_errorreset(OBJ_STATUS_QjpobjectError);
		}
    alarm_reset_button_on = 0;
	}

  if(!OBJ_RESET)
  {
    if(dllSts & OBJ_STATUS_MesError)
    {
      if(Machine.AlarmStatus.mes_status == 0)
      {
        Machine.Acrocia_Set_AlarmStatus(1);
      }
    }

    if((dllSts & OBJ_STATUS_UpstreamError)&&PCProgramOption.UVLaserUpstreamEnabled)
    {
      if(Machine.AlarmStatus.upstream_status == 0)
      {
        Machine.Acrocia_Set_AlarmStatus(2);
      }
    }
    if((dllSts & OBJ_STATUS_DownstreamError)&&PCProgramOption.UVLaserDownstreamEnabled)
    {
      if(Machine.AlarmStatus.downstream_status == 0)
      {
        Machine.Acrocia_Set_AlarmStatus(3);
      }
    }
    if((dllSts & OBJ_STATUS_QjpobjectError))
    {
      if(Machine.AlarmStatus.Qjp_object_status == 0)
      {
        Machine.Acrocia_Set_AlarmStatus(4);
      }
    }
  }


	UVLaser.DLL_Command = obj_getcommand();

  switch (UVLaser.DLL_Command)
  {
    case COMMAND_AjustTime:				// time adjustment
    UVLaser.UVLaserStatus.AjustTimeCommandApply =1;
    AddCSVEventLog(ECSV_EVENT_APPLICATION_TIMECHANGEED,NULL,0);
    break;
  }

  }

}

void __fastcall TMainForm::MakeMESUpdateData()
{
  char Temp[128]={0,};
  char Temp2[128]={0,};
  char Temp3[128]={0,};
  WideCharToMultiByte(CP_ACP,0,ProductData.ProductCode.c_bstr(),-1,Temp,128,NULL,NULL);
  WideCharToMultiByte(CP_ACP,0,ProductData.ProductName.c_bstr(),-1,Temp2,128,NULL,NULL);
  WideCharToMultiByte(CP_ACP,0,ProductData.LOTName.c_bstr(),-1,Temp3,128,NULL,NULL);
	strncpy(MESUpDate_Product.TProductData.ProductCode, Temp, 128);
	strncpy(MESUpDate_Product.TProductData.ProductName, Temp2, 128);
	strncpy(MESUpDate_Product.TProductData.LOTName, Temp3, 128);
	strncpy(MESUpDate_Product.TProductData.TabletColorCode, ProductData.TabletColorCode.c_str(), 128);
	strncpy(MESUpDate_Product.TProductData.PrintColorCode, ProductData.PrintColorCode.c_str(), 128);
	
	MESUpDate_Product.TProductData.TabletType = ProductData.TabletType;
	MESUpDate_Product.TProductData.TabletShape = ProductData.TabletShape;
	MESUpDate_Product.TProductData.StudyStep = ProductData.StudyStep ;
	MESUpDate_Product.TProductData.TabletLength = ProductData.TabletLength;
	MESUpDate_Product.TProductData.TabletWidth = ProductData.TabletWidth;
	MESUpDate_Product.TProductData.TabletThick = ProductData.TabletThick;
	MESUpDate_Product.TProductData.TabletSideThick = ProductData.TabletSideThick;
	MESUpDate_Product.TProductData.EngraveType = ProductData.EngraveType;
	MESUpDate_Product.TProductData.EngravePos = ProductData.EngravePos;
	MESUpDate_Product.TProductData.PrintBrightness = ProductData.PrintBrightness;
	
	for(int i = 0; i <SYSTEM_TOTAL_CAMERA_COUNT;i++)
	{	
		MESUpDate_Product.TProductData.BoundaryLeft[i] = ProductData.BoundaryLeft[i];
		MESUpDate_Product.TProductData.BoundaryTop[i] = ProductData.BoundaryTop[i];
		MESUpDate_Product.TProductData.BoundaryRight[i] = ProductData.BoundaryRight[i];
		MESUpDate_Product.TProductData.BoundaryBottom[i] = ProductData.BoundaryBottom[i];
		MESUpDate_Product.TProductData.ShutterSpeed[i] = ProductData.ShutterSpeed[i];
		MESUpDate_Product.TProductData.DigitalGainV[i] = ProductData.DigitalGainV[i];
		MESUpDate_Product.TProductData.LineScanFrequency[i] = 0;
	}

	MESUpDate_Product.TProductData.ProcessingStep = ProductData.ProcessingStep;
	memcpy(MESUpDate_Product.TProductData.MotorSpeedList, ProductData.MotorSpeedList , sizeof(ProductData.MotorSpeedList));
	MESUpDate_Product.TProductData.ProductionCount = ProductData.ProductionCount;
	MESUpDate_Product.TProductData.PlateTablet = ProductData.PlateTablet;
	MESUpDate_Product.TProductData.TabletLayerCount = ProductData.TabletLayerCount;

	MESUpDate_Product.TProductData.StudiedSensor1Length = ProductData.StudiedSensor1Length;
	MESUpDate_Product.TProductData.StudiedSensor2Length = ProductData.StudiedSensor2Length;
	MESUpDate_Product.TProductData.StudiedSensorIntervalA = ProductData.StudiedSensorIntervalA;
	MESUpDate_Product.TProductData.StudiedSensorIntervalB = ProductData.StudiedSensorIntervalB;

	MESUpDate_Product.TProductData.NCMotorPos[0] = ProductData.NCMotorPos[0];
	MESUpDate_Product.TProductData.NCMotorPos[1] = ProductData.NCMotorPos[1];
	MESUpDate_Product.TProductData.NCMotorPos[2] = ProductData.NCMotorPos[2];
	MESUpDate_Product.TProductData.NCMotorPos[3] = ProductData.NCMotorPos[3];
	MESUpDate_Product.TProductData.NCMotorPos[4] = ProductData.NCMotorPos[4];
	
	MESUpDate_Product.TProductData.RotatingGuideKind = ProductData.RotatingGuideKind;
	MESUpDate_Product.TProductData.FixedGuideKind = ProductData.FixedGuideKind;
	MESUpDate_Product.TProductData.VerticalGate2Kind = ProductData.VerticalGate2Kind;
	MESUpDate_Product.TProductData.Arrange = ProductData.Arrange;
	MESUpDate_Product.TProductData.SymmetricLineCount = ProductData.SymmetricLineCount;
	MESUpDate_Product.TProductData.LampKind = ProductData.LampKind;
	MESUpDate_Product.TProductData.SpecialInsCount[0] = ProductData.SpecialInsCount[0];
	MESUpDate_Product.TProductData.SpecialInsCount[1] = ProductData.SpecialInsCount[1];
	MESUpDate_Product.TProductData.SpecialInsCount[2] = ProductData.SpecialInsCount[2];
	MESUpDate_Product.TProductData.SpecialInsCount[3] = ProductData.SpecialInsCount[3];
	MESUpDate_Product.TProductData.SpecialInsCount[4] = ProductData.SpecialInsCount[4];
	MESUpDate_Product.TProductData.SpecialInsCount[5] = ProductData.SpecialInsCount[5];
	MESUpDate_Product.TProductData.SpecialInsCheckbox= ProductData.SpecialInsCheckbox;

	MESUpDate_Product.TProductData.MarvelingTabletSW = ProductData.MarvelingTabletSW;
	//sjm add
	MESUpDate_Product.TProductData.StudiedSensor3Length = ProductData.StudiedSensor3Length;
	MESUpDate_Product.TProductData.DivisionLineInfo = ProductData.DivisionLineInfo;
	MESUpDate_Product.TProductData.SubSamplingMode = ProductData.SubSamplingMode;

	MESUpDate_Product.TProductData.ExposureTime3D[0] = ProductData.ExposureTime3D[0];
	MESUpDate_Product.TProductData.AnalogGain3D[0] = ProductData.AnalogGain3D[0];
	MESUpDate_Product.TProductData.ExposureTime3D[1] = ProductData.ExposureTime3D[1];
	MESUpDate_Product.TProductData.AnalogGain3D[1] = ProductData.AnalogGain3D[1];

	MESUpDate_Product.TProductData.DischargeCountSetValue = ProductData.DischargeCountSetValue;
	MESUpDate_Product.TProductData.DischargeCount = ProductData.DischargeCount;
	
	memcpy(&MESUpDate_Alarm.TAlarmInfo_Machine, &Machine.AlarmStatus, sizeof(TMachineAlarmState));
	memcpy(&MESUpDate_Product.TMachineOption ,&ProductData.MachineRunOption, sizeof(TMachineRunOption));


	obj_setproductinfo(&MESUpDate_Product);
  if( MESUpDate_Param.TInspectOption.QMachineDischargeActiveCount == -1)
  {
      MESUpDate_Param.TInspectOption.QMachineDischargeActiveCount = 0;
  }
	obj_setparaminfo(&MESUpDate_Param);
	obj_setalarminfo(&MESUpDate_Alarm);
	if(UVLaser.DLL_Command==COMMAND_AjustTime)
	{
		//to do		
	}
	
}
//---------------------------------------------------------------------------



void __fastcall TMainForm::DllInitButtonClick(TObject *Sender)
{
	AnsiString fileName;
    	obj_seqclear(SEQ_All);
	ProductData.DischargeCount = 0;	
	Machine.AlarmStatus.laser_emergency= false;
	Machine.AlarmStatus.mes_status = 0;
	Machine.AlarmStatus.upstream_status= 0;
	Machine.AlarmStatus.downstream_status= 0;
  Machine.AlarmStatus.Qjp_object_status = 0;
	obj_errorreset(OBJ_STATUS_MesError);
	obj_errorreset(OBJ_STATUS_UpstreamError);
	obj_errorreset(OBJ_STATUS_DownstreamError);	
	fileName = GetProductDataFileName(ProductData.ProductCode);
	WriteProductData(fileName, ProductData);
  memset(&UVLaser, 0, sizeof(UVLaser));
	memset(&MESUpDate_Param, 0 , sizeof(MESUpDate_Param));
	memset(&MESUpDate_Product, 0 , sizeof(MESUpDate_Product));	
}
//---------------------------------------------------------------------------
int __fastcall TMainForm::GetLastSafetyMode()
{
  return LastSafetyMode;
}
void __fastcall TMainForm::SetLastSafetyMode(int newSafeMode)
{
  LastSafetyMode =newSafeMode;
}
void __fastcall TMainForm::RefreshCameraInfo(int cameraIndex)
{
  // 사용자가 설정한 ShutterSpeed, Threshold, ROI(는 사실 Default) 를 반영
  int ShutterSpeed = 0;
  int Threshold = 0;
  int WriteMask = 0;
  int cameraGain = 1;

  // 기본 밝기
  ShutterSpeed = 5;
  cameraGain = 1;

  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;
  }

  if(!SetCameraInformation(ApplyROIInfo, ShutterSpeed, Threshold, RESOLUTION_NORMAL_QUALITY, cameraIndex, WriteMask))
  {
    GlobalEnabledCameraStatus[cameraIndex] = false;
  }

  SetCameraGain(cameraIndex + 1, SYSTEM_DEFAULT_ANLOG_GAIN, cameraGain, 0);
}


void __fastcall TMainForm::AcroCiaDllTimerTimer(TObject *Sender)
{
   bool timerEnabled;
	timerEnabled = AcroCiaDllTimer->Enabled;
	AcroCiaDllTimer->Enabled = false;
  if (Comm_IsConnected(COMM_HCB))
	{
    if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
      if (hDllInstance)
      {
        //if(UVLaser.UVLaserStatus.APPActive == 0)
          //UVLaser.UVLaserStatus.APPActive = 1; // dll 연결에 성공했는지를 테스트 한다.
        UVLaser.UVLaserStatus.DLLLoadStatus = true;
        PIO05PortStatusCheck();
        MakeMESUpdateData();
      }
      /*if(Machine.PortStatus.OPStatus[OP_INTERLOCK_SOLENOID] != doorlock_refresh_main)
      {
        RefreshMenu();
        doorlock_refresh_main = Machine.PortStatus.OPStatus[OP_INTERLOCK_SOLENOID];
      }*/
    }
    else if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
    {
      PIO05PortStatusCheck();
    }
    AcroCiaDllTimer->Enabled =  timerEnabled;
  }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::AMTecDllTimerTimer(TObject *Sender)
{
	bool timerEnabled;
	char Temp_name[255]={0,};
/*
	WideCharToMultiByte(CP_ACP,0,ProductData.RecipeName.c_bstr(),-1,Temp_name,255,NULL,NULL);
	Laser_obj_SetLaserRecipeName(Temp_name);
*/
	if (MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable==1)
	{
		switch (Machine.Status.OperationState)
		{
			case MACHINE_STATE_STOP:
				Laser_obj_SetMachineStatus(MachineStatus_Stop);
				if(NFALaserinfo.LaserStatus != LaserStatus_Stop && NFALaserinfo.LaserStatus != LaserStatus_Ready)
				{
					if(NFALaserinfo.SendDLLCommand==CMD_MACHINE_NONE)
					{
					 	NFALaserinfo.SendDLLCommand = CMD_MACHINE_STOP;
				  	}
				}
				break;
			case MACHINE_STATE_RUN:
				Laser_obj_SetMachineStatus(MachineStatus_Run);
				
				break;
			case MACHINE_STATE_CLEANING:
				Laser_obj_SetMachineStatus(MachineStatus_Stop);
				break;
			case MACHINE_STATE_STARTING:
				Laser_obj_SetMachineStatus(MachineStatus_Starting);
				if(NFALaserinfo.LaserStatus != LaserStatus_Run)
				{
					if(NFALaserinfo.SendDLLCommand==CMD_MACHINE_NONE)
					{
						NFALaserinfo.SendDLLCommand = CMD_MACHINE_START;
				  	}
				}				
				break;
			case MACHINE_STATE_STOPPING:
				Laser_obj_SetMachineStatus(MachineStatus_Stoping);
				break;
			case MACHINE_STATE_EMERGENCY_STOP:
				Laser_obj_SetMachineStatus(MachineStatus_Stop);
				break;
			case MACHINE_STATE_TERMINATE:
				NFALaserinfo.SendDLLCommand = CMD_LASER_STOP;
				break;
			default:
				break;
		}
		
		switch (NFALaserinfo.SendDLLCommand)
		{
			case CMD_MACHINE_STOP:
				if(NFALaserinfo.LaserStatus == LaserStatus_Run)
				{
					Laser_obj_SetObjCommand(CMD_MACHINE_STOP);
					NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
					Laser_dll_timer_count = 0;
				}
				else
				{
					Laser_dll_timer_count++;
					if(Laser_dll_timer_count > 100)
					{
            					Laser_obj_SetObjCommand(CMD_MACHINE_STOP);
						NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
						Laser_dll_timer_count = 0;
					}
				}
				break;			
			case CMD_MACHINE_START:
				if(NFALaserinfo.LaserStatus == LaserStatus_Ready)
				{
					Laser_obj_SetObjCommand(CMD_MACHINE_START);
					NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
					Laser_dll_timer_count = 0;
				}
				else
				{
					Laser_dll_timer_count++;
					if(Laser_dll_timer_count > 100)
					{
						NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
						Laser_dll_timer_count = 0;
					}
				}
				break;
			case CMD_LASER_COUNT_RESET:
				Laser_obj_SetObjCommand(CMD_LASER_COUNT_RESET);
				NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
				Laser_dll_timer_count = 0;
				break;		
			case CMD_LASER_RECIPE_SELECT:
				WideCharToMultiByte(CP_ACP,0,ProductData.RecipeName.c_bstr(),-1,Temp_name,255,NULL,NULL);	
				Laser_obj_SetLaserRecipeName(Temp_name);
				if(NFALaserinfo.LaserStatus != LaserStatus_Run){
					Laser_obj_SetObjCommand(CMD_LASER_RECIPE_SELECT);
					NFALaserinfo.LaserStatus = Laser_obj_GetLaserStatus();
				}

				if(NFALaserinfo.LaserStatus == LaserStatus_Ready)
				{
					NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
					Laser_dll_timer_count = 0;
				}
				else
				{
					Laser_dll_timer_count++;
					if(Laser_dll_timer_count > 100)
					{
						NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
						Laser_dll_timer_count = 0;
					}				
				}
				break;
			case CMD_LASER_STOP:
				Laser_obj_SetObjCommand(CMD_LASER_STOP);
				Laser_dll_timer_count++;
				if(NFALaserinfo.LaserMachineStatus == LaserMachineStatus_Stop)
				{
					NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
					Laser_dll_timer_count = 0;
				}				
				break;	
			case CMD_LASER_START:
				Laser_obj_SetObjCommand(CMD_LASER_START);
				Laser_dll_timer_count++;
				if(NFALaserinfo.LaserMachineStatus == LaserMachineStatus_Run)
				{
					NFALaserinfo.SendDLLCommand = CMD_MACHINE_NONE;
					Laser_dll_timer_count = 0;
				}
				break;					
			default: 
				break;					
		}
		
		NFALaserinfo.LaserStatus = Laser_obj_GetLaserStatus();
		NFALaserinfo.LaserMachineStatus = Laser_obj_GetLaserMachineStatus();
		NFALaserinfo.LaserMackingTime = Laser_obj_GetLaserMarkTime();
		
		if(NFALaserinfo.LaserMachineStatus == LaserMachineStatus_None || NFALaserinfo.LaserMachineStatus == LaserMachineStatus_WarmUp)
    {
      LaserPreparingStatusPanel->Font->Color = clWhite;
      LaserPreparingStatusPanel->Color = clRed;
      LaserPauseStatusPanel->Font->Color = clWhite;
      LaserPauseStatusPanel->Color = clBlack;
      LaserReadyStatusPanel->Font->Color = clWhite;
      LaserReadyStatusPanel->Color = clBlack;
    }
		else if(NFALaserinfo.LaserMachineStatus ==LaserMachineStatus_Stop)
    {
      LaserPreparingStatusPanel->Font->Color = clWhite;
      LaserPreparingStatusPanel->Color = clBlack;
      LaserPauseStatusPanel->Font->Color = clBlack;
      LaserPauseStatusPanel->Color = clYellow;
      LaserReadyStatusPanel->Font->Color = clWhite;
      LaserReadyStatusPanel->Color = clBlack;
    }
		else if(NFALaserinfo.LaserMachineStatus ==LaserMachineStatus_Run)
    {
      LaserPreparingStatusPanel->Font->Color = clWhite;
      LaserPreparingStatusPanel->Color = clBlack;
      LaserPauseStatusPanel->Font->Color = clWhite;
      LaserPauseStatusPanel->Color = clBlack;
      LaserReadyStatusPanel->Font->Color = clBlack;
      LaserReadyStatusPanel->Color = clLime;
    }
	}		                                                           
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::CheckSystemCompatibility(void)
{                                                                                                 
  TProgramVersion HCBVersion;
  TProgramVersion SPBVersion[SYSTEM_SPB_MAX_COUNT];
  
  THCBCompatibility HCBCompatibility;
  TSPBCompatibility SPBCompatibility[SYSTEM_SPB_MAX_COUNT];

  if (Comm_IsConnected(COMM_HCB))
  {
    Comm_Request(COMM_HCB, CMD_VERSION_INFO, NULL, 0, &HCBVersion, sizeof(TProgramVersion));
    Comm_Request(COMM_HCB, CMD_READ_COMPATIBILITY, NULL, 0, &HCBCompatibility, sizeof(THCBCompatibility));
  }

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (Comm_IsConnected(COMM_SPB + spbIndex))
		{
			Comm_Request(COMM_SPB + spbIndex, CMD_VERSION_INFO, NULL, 0, &SPBVersion[spbIndex], sizeof(TProgramVersion));
      Comm_Request(COMM_SPB + spbIndex, CMD_READ_COMPATIBILITY, NULL, 0, &SPBCompatibility[spbIndex], sizeof(TSPBCompatibility));
		}
	}
    
  // 호환성 체크
  WCHAR TempString[100];
  AnsiString result;
  try
  {
    // PC-HCB
    if (Comm_IsConnected(COMM_HCB)) 
    {
      if((ProgramVersion.MajorVersion != HCBVersion.MajorVersion) ||
          (ProgramVersion.MinorVersion != HCBVersion.MinorVersion) ||
          (ProgramVersion.Date != HCBVersion.Date) ||
          (ProgramVersion.Type != HCBVersion.Type))
      {
        result = "PC - HCB";
        if(DefaultLCID != 1028)
        {
        	wsprintfW(TempString, L"Programs are not compatible between %s. Please check board type and update the latest program.", WideString(result));
        }
        else
        {
        	//wsprintfW(TempString, MAINFORM_MSG_15, WideString(result));
            wsprintf(TempString, MAINFORM_MSG_15, WideString(result));
        }
        throw Exception(TempString);
      }
    }

    // PC-SPB
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        if((ProgramVersion.MajorVersion
         != SPBVersion[spbIndex].MajorVersion) ||
            (ProgramVersion.MinorVersion != SPBVersion[spbIndex].MinorVersion) ||
            (ProgramVersion.Date != SPBVersion[spbIndex].Date) ||
            (ProgramVersion.Type != SPBVersion[spbIndex].Type))
        {
          result = "PC - IPB" + IntToStr(spbIndex + 1);
          if(DefaultLCID != 1028)
          {
          	wsprintfW(TempString, L"Programs are not compatible between %s. Please check board type and update the latest program.", WideString(result));
          }
          else
          {
          	//wsprintfW(TempString, MAINFORM_MSG_15, WideString(result));
          	wsprintf(TempString, MAINFORM_MSG_15, WideString(result));
          }
          throw Exception(TempString);
        }
      }
    }

    // PC-CPB
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        if((ProgramVersion.MajorVersion != SPBCompatibility[spbIndex].CPBAlgMajorVersion) ||
            (ProgramVersion.MinorVersion != SPBCompatibility[spbIndex].CPBAlgMinorVersion) ||
            (ProgramVersion.Date != SPBCompatibility[spbIndex].CPBAlgReleaseDate) ||
            (ProgramVersion.Type != SPBCompatibility[spbIndex].CPBAlgTargetSystem))
        {
          result = "PC - CPB(IPB" + IntToStr(spbIndex + 1) + ")";
          if(DefaultLCID != 1028)
          {
          	wsprintfW(TempString, L"Programs are not compatible between %s. Please check board type and update the latest program.", WideString(result));
          }
          else
          {
          	//wsprintfW(TempString, MAINFORM_MSG_15, WideString(result));
          	wsprintf(TempString, MAINFORM_MSG_15, WideString(result));
          }
          throw Exception(TempString);
        }
      }
    }

    // HCB-SPB
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      if (Comm_IsConnected(COMM_SPB + spbIndex) && Comm_IsConnected(COMM_HCB))
      {
        if((HCBVersion.MajorVersion != SPBVersion[spbIndex].MajorVersion) ||
            (HCBVersion.MinorVersion != SPBVersion[spbIndex].MinorVersion) ||
            (HCBVersion.Date != SPBVersion[spbIndex].Date) ||
            (HCBVersion.Type != SPBVersion[spbIndex].Type))
        {
          result = "HCB - IPB" + IntToStr(spbIndex + 1);
          if(DefaultLCID != 1028)
          {
          	wsprintfW(TempString, L"Programs are not compatible between %s. Please check board type and update the latest program.", WideString(result));
          }
          else
          {
          	//wsprintfW(TempString, MAINFORM_MSG_15, WideString(result));
          	wsprintf(TempString, MAINFORM_MSG_15, WideString(result));
          }
          throw Exception(TempString);
        }
      }
    }
                                                                                                                  
    // SPB-CPB                                                                                        
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {                                                                                                                
      if (Comm_IsConnected(COMM_SPB + spbIndex))
      {
        if((SPBVersion[spbIndex].MajorVersion != SPBCompatibility[spbIndex].CPBAlgMajorVersion) ||
            (SPBVersion[spbIndex].MinorVersion != SPBCompatibility[spbIndex].CPBAlgMinorVersion) ||
            (SPBVersion[spbIndex].Date != SPBCompatibility[spbIndex].CPBAlgReleaseDate) ||
            (SPBVersion[spbIndex].Type != SPBCompatibility[spbIndex].CPBAlgTargetSystem))
        {
          result = "IPB" + IntToStr(spbIndex + 1) + "- CPB";
          if(DefaultLCID != 1028)
          {
          	wsprintfW(TempString, L"Programs are not compatible between %s. Please check board type and update the latest program.", WideString(result));
          }
          else
          {
          	//wsprintfW(TempString, MAINFORM_MSG_15, WideString(result));
          	wsprintf(TempString, MAINFORM_MSG_15, WideString(result));
          }
          throw Exception(TempString);
        }
      }
    }
  }
  catch (Exception &ec)
  {
    ShowMessageFA(ec.Message);
  }
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::LaserInactiveBtnPanelClick(TObject *Sender)
{
	TTntPanel *thePanel = (TTntPanel *) Sender;
	AnsiString filepath = "D:\\Project\\sLaser\\sLaser.exe";
	AnsiString PgmName = "NFA sLaser";
	if(thePanel->Tag == 0)
	{
		// Inactive
		LaserActiveBtnPanel->Font->Color = clWhite;
		LaserActiveBtnPanel->Color = clBlack;
		LaserInactiveBtnPanel->Font->Color = clBlack;
		LaserInactiveBtnPanel->Color = clYellow;
		if(IsExistProcess("sLaser.exe"))
		{		
			HWND hWnd = FindWindowA(NULL, PgmName.c_str());
			ShowWindow (hWnd, SW_HIDE);
		}
	}
	else
	{
		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);
		}
		LaserActiveBtnPanel->Font->Color = clBlack;
		LaserActiveBtnPanel->Color = clLime;
		LaserInactiveBtnPanel->Font->Color = clWhite;
		LaserInactiveBtnPanel->Color = clBlack;
	}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ThreeDSensorControlTimerTimer(TObject *Sender)
{
  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    // 기계 동작 시 (이미지 촬영 X)에만 아래 로직이 적용되어야함
    bool bError;

    int SD1ThreeDCameraSPBIndex, SD2ThreeDCameraSPBIndex;
    SD1ThreeDCameraSPBIndex = CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].SPBIndex;
    SD2ThreeDCameraSPBIndex = CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].SPBIndex;

    Disk1ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_GOOD;
    Disk2ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_GOOD;

    bError = false;

    if (!Comm_IsConnected(COMM_SPB + SD1ThreeDCameraSPBIndex))
    {
      bError = false;
      Disk1ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_BRD_DISCONNECTED;
    }
    else if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D)
    {
      bError = true;
      Disk1ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_INVALID_MAPPING;
    }
    else if (CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_DISCONNECT || SystemLinkCameraInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] == 0)
    {
      bError = true;
      Disk1ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_CAMERA_DISCONNECTED;
    }

    if (!Comm_IsConnected(COMM_SPB + SD2ThreeDCameraSPBIndex))
    {
      bError = true;
      Disk2ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_BRD_DISCONNECTED;
    }
    else if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition != CAMERA_POSITION_3D)
    {
      bError = true;
      Disk2ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_INVALID_MAPPING;
    }
    else if (CameraMapInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1].CameraInspectPosition == CAMERA_POSITION_DISCONNECT || SystemLinkCameraInfo[SD2_3D_FRONT_FACE_CAMERA_INDEX] == 0)
    {
      bError = true;
      Disk2ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_CAMERA_DISCONNECTED;
    }

    if(!bError)
    {
      if(Machine.Status.OperationState == MACHINE_STATE_RUN ||
          Machine.Status.OperationState == MACHINE_STATE_STARTING)
      {
        if(ThreeDSensorActiveStatus == THREED_SENSOR_OFF)
        {
          if(!bError)
          {
            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);
            EnabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1, RANGER_3D_BASE_SHUTTER_SPEED, THREED_SENSOR_NONE_MODE);

            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);
            EnabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1, RANGER_3D_BASE_SHUTTER_SPEED2, THREED_SENSOR_NONE_MODE);

            ThreeDSensorActiveStatus = THREED_SENSOR_ON;
          }
        }
      }
      else if(Machine.Status.OperationState == MACHINE_STATE_STOP ||
              Machine.Status.OperationState == MACHINE_STATE_EMERGENCY_STOP ||
              Machine.Status.OperationState == MACHINE_STATE_CLEANING ||
              Machine.Status.OperationState == MACHINE_STATE_DETACHING ||
              Machine.Status.OperationState == MACHINE_STATE_ATTACHING ||
              Machine.Status.OperationState == MACHINE_STATE_STOPPING)
      {
        if(ThreeDSensorActiveStatus == THREED_SENSOR_ON)
        {
          DisabledThreeDLaserSensor(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
          DisabledThreeDLaserSensor(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);

          ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

          Disk1ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_GOOD;
          Disk2ThreeDSensorErrorCode = THREED_SENSOR_ERROR_CODE_GOOD;

          RecentDisk1ThreeDCameraLSFValue = -1;
          RecentDisk2ThreeDCameraLSFValue = -1;
        }
      }
    }
    else
    {
      ThreeDSensorActiveStatus = THREED_SENSOR_OFF;

      RecentDisk1ThreeDCameraLSFValue = -1;
      RecentDisk2ThreeDCameraLSFValue = -1;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::ShowThreeDSensorStatusBtnClick(TObject *Sender)
{
  ThreeDSensorStatusCheckForm->Show();
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::TntFormShow(TObject *Sender)
{
  SetDefaultCameraGain();
	gThreeDCameraSetup(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1);
	gThreeDCameraSetup(SD2_3D_FRONT_FACE_CAMERA_INDEX - 1);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::makePID15BtnClick(TObject *Sender)
{
  char pidBuff[PROGRAM_ID_FILE_SIZE];
  memset(pidBuff, 0, sizeof(char) * PROGRAM_ID_FILE_SIZE);

  for(int m = 0; m < PROGRAM_ID_FILE_SIZE; m++)
  {
    pidBuff[m] = rand() & 0xFF;
  }

  pidBuff[PROGRAM_ID_ADDRESS_A] = 'F';
  pidBuff[PROGRAM_ID_ADDRESS_B] = '1';
  pidBuff[PROGRAM_ID_ADDRESS_C] = '5';
  pidBuff[PROGRAM_ID_ADDRESS_D] = '+';
  pidBuff[PROGRAM_ID_ADDRESS_E] = 'A';

  AnsiString RootPath, fileName;
  RootPath = ExtractFileDir(Application->ExeName);
  fileName = RootPath + "\\tvmsm15p.dat";

  TFileStream *fileStream = new TFileStream(fileName, fmCreate);
  fileStream->Write(pidBuff, PROGRAM_ID_FILE_SIZE);
	delete fileStream;
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::makePID20BtnClick(TObject *Sender)
{
  char pidBuff[PROGRAM_ID_FILE_SIZE];
  memset(pidBuff, 0, sizeof(char) * PROGRAM_ID_FILE_SIZE);

  for(int m = 0; m < PROGRAM_ID_FILE_SIZE; m++)
  {
    pidBuff[m] = rand() & 0xFF;
  }

  pidBuff[PROGRAM_ID_ADDRESS_A] = '2';
  pidBuff[PROGRAM_ID_ADDRESS_B] = 'A';
  pidBuff[PROGRAM_ID_ADDRESS_C] = '0';
  pidBuff[PROGRAM_ID_ADDRESS_D] = '0';
  pidBuff[PROGRAM_ID_ADDRESS_E] = 'F';

  AnsiString RootPath, fileName;
  RootPath = ExtractFileDir(Application->ExeName);
  fileName = RootPath + "\\tvmsm20.dat";

  TFileStream *fileStream = new TFileStream(fileName, fmCreate);
  fileStream->Write(pidBuff, PROGRAM_ID_FILE_SIZE);
	delete fileStream;
}
//---------------------------------------------------------------------------
