//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 완료
// CameraIndex 관련 수정 완료
//---------------------------------------------------------------------------
// 수정버전
#include <vcl.h>
#include <inifiles.hpp>
#include <algorithm>
#pragma hdrstop

#include "Inspection_Form.h"
#include "Message_Form.h"
#include "Bayer.h"
#include "GradeSetting.h"
#include "Waiting_Form.h"
#include "MachineControl_Form.h"
#include "SpeedControl_Form.h"
#include "Progress_Form.h"
#include "Keyboard_Form.h"
#include "Setup_Form.h"
#include "AbstractDB.h"
#include "NCControl_Form.h"
#include "MachineControl.h"
#include "CPBStatus_Form.h"
#include "SystemProcessInfo_Form.h"
#include "UnmanedOperation_Form.h"
#include "ThreeDImageViewer_Form.h"
#include "Graph_Check_Form.h"
#include "MultiLanguage.h"
#include "LogViewer_Form.h"
#include "Alarm_Form.h"
#include "math.h"
#include "InspectionStatus_Form.h"
#include "common.h"
#include "LaserInspectionMarkingInfo_Form.h"
#include "HCBMonitoring_Form.h"
#include "CameraTest_Form.h"
#include "TPBCameraSetting_Form.h"
#include "ComputerSystemSetting_Form.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma link "TntComCtrls"
#pragma link "TntExtCtrls"
#pragma link "TntGrids"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"

#define AUTO_SAVE_INTERVAL      100

#define OPTION_DISPLAY_KIND_GRADE				    0
#define OPTION_DISPLAY_KIND_MACHINE				  1
#define OPTION_DISPLAY_KIND_TABLET_INFO			2
#define OPTION_DISPLAY_KIND_LASER_INFO			3

#define VFSPEEDMODE_ON                      1
#define VFSPEEDMODE_OFF						2

#define DEFECT_UPLOAD_WAITING_TABLET_COUNT		100

TInspectionForm *InspectionForm;
int AppOnOffFlag = false;
int BtnOnOffFlag = false;
int DHStartFlag = false;
int InspectionStartStep;
//sjm Chg Time
double ChgInspectionEndTime;
// UV
int last_inspection_good_count=0;
int last_vb_sensor_value = 0;
char LastUVLaserStatus[4] = { 0,0,0,0 };
int wait_stop_step = 0;
int CommandWaitAction = 0; // 0 Clear 1 Q Command Wait 3 NFA CommandWait nt
bool SkipDischargeQuestion = 0;
int SD2CaptureSensor_UITimer = 0;
bool Using_CaptuerSensorTimer;
bool InspectionStop_flag = false;
int InspectionStop_count = 0;

extern TMESProductData MESProductData;

//cjg OPC Test
HINSTANCE hOPC_DLL = NULL;
int (*pSetTabletGradeData)(TTabletGradeData *);
int (*pSetTabletInspectInfo)(TTabletInspectInfo *);
int (*pSetInspectionOption)(TInspectionOption *);
int (*pSetMachineRunOption)(TMachineRunOption*);
int (*pSetMESProductData)(TMESProductData*);
//---------------------------------------------------------------------------
__fastcall TInspectionForm::TInspectionForm(TComponent* Owner)
	: TTntForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
	else if (DefaultLCID == 1041)
		ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

  	memset(LastUVLaserStatus, 0, sizeof(LastUVLaserStatus));
  	memset(&InspectInfo_Additional,0,sizeof(TInspectionAdditionalInfo));
	GetDefaultString();

	InspectionStartStep = 0;
  NewInsepctionDataSetFlag = 0;

  if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    APP->Visible = true;
  }
  else
  {
    APP->Visible = false;
  }

  LaserMonitoringStringGrid->Cells[0][0] = "#Data";
  LaserMonitoringStringGrid->Cells[1][0] = "#Unit";
  LaserMonitoringStringGrid->Cells[2][0] = "Prt Br(MR)"; // Marking Result
  LaserMonitoringStringGrid->Cells[3][0] = "Theta(MR)";
  LaserMonitoringStringGrid->Cells[4][0] = "X (MR)";
  LaserMonitoringStringGrid->Cells[5][0] = "Y (MR)";
  LaserMonitoringStringGrid->Cells[6][0] = "Theta(CR)"; // Calculted Result
  LaserMonitoringStringGrid->Cells[7][0] = "X (CR)";
  LaserMonitoringStringGrid->Cells[8][0] = "Y (CR)";

  int lmGridCellWidth = (LaserMonitoringStringGrid->Width / LaserMonitoringStringGrid->ColCount) - 2;
  for(int m = 0; m < LaserMonitoringStringGrid->ColCount; m++)
  {
    LaserMonitoringStringGrid->ColWidths[m] = lmGridCellWidth;
  } 

	APP->Font->Color = clBlack;
	AppOnOffFlag = false;
	BtnOnOffFlag = false;
  ExternalWriteInspectionResult = false;

	CurrentDefectImage->Picture->Bitmap->PixelFormat = pf24bit;

	InspectState = INSPECTION_STATE_STOP;
	InspectionStopOption = INSPECTION_STOP_OPTION_NONE;

	InspectionStopButton->Enabled = false;
	StopInfoPanel->Visible = false;
	InspectionRestartButton->Enabled = false;
	SubDefectInfoForm = new TDefectInfoForm(this);
	SubDefectInfoForm->Parent = ClientPanel;
	IsChartView = true;
	ClearDefectInfoList();
	RefreshDefectsInfo();

  DefectDataStringGrid->ColWidths[0] = 155;
	DefectDataStringGrid->Cells[0][0] = INSPECTIONFORM_LABEL_CAPTION_42;
	DefectDataStringGrid->Cells[0][1] = INSPECTIONFORM_STRGRID_CELL_19;
	DefectDataStringGrid->Cells[0][2] = INSPECTIONFORM_BUTTON_CAPTION_07;
	DefectDataStringGrid->Cells[0][3] = INSPECTIONFORM_STRGRID_CELL_08;

	AutoSaveInterval = 0;

	OptionalDisplayKind = OPTION_DISPLAY_KIND_GRADE;
	GradeInfoPanel->BringToFront();
  TntPanel4->BringToFront();

	ThroughputChartList = NULL;
	ThroughputChartCount = 0;
	InspectionRatioChartCount = 0;
	ThroughputChartAutoScroll = true;

	Current3DBitmap = new Graphics::TBitmap;
	VFSpeedMode = VFSPEEDMODE_ON;


  if (PCProgramOption.UVLaserEnabled && MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
  {
    InspectionStartButton->Caption = INSPECTIONFORM_LABEL_CAPTION_77;
  }
  else
    InspectionStartButton->Caption = INSPECTIONFORM_LABEL_CAPTION_78;


	AlarmStringList = new TTntStringList;

	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
	{
    int RecentEndFlag = 0;
     AnsiString RecentLot = "";
     AnsiString RecentProduct = "";

     TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
     RecentLot = iniFile->ReadString("Quick Start", "Recent Lot", "");
     RecentProduct = iniFile->ReadString("Quick Start", "Recent Product", "");
     RecentEndFlag = iniFile->ReadInteger("Quick Start", "Batch End", 1);
     delete iniFile;

     //AnsiString resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result";
		 //AnsiString FileName = resultDir + "\\" + ProductData.LOTName + ".dat";

     if(RecentEndFlag == 0)
     {
      if(ProductData.ProductCode == RecentProduct) // prodcut 가 같으면 Lot 도 같다고 본다
      {
        InspectionStartButton->Visible = false;
        InspectionRestartButton->Enabled = true;
      }
     }

     /*if(FILE*file = fopen(FileName.c_str(),"r"))
     {
      fclose(file); // 검사를 돌렸던 적이 있음
      InspectionStartButton->Visible = false;
     }
     else
     {
      InspectionStartButton->Visible = true;
     }*/

     /*if(RecentEndFlag == 0)
     {
        ShowMessageFA("There is an inspection that has not been terminated.[" + RecentProduct +" , " + RecentLot +" , " "]"); // Lot 랑 배치 이름 출력 해야됨  // Batch End 하지 않은 Batch가 존재한다.
     }    */

		Panel23->Caption = "BATCH";

	}
  else if (MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
		if (PCProgramOption.UVLaserEnabled)
		{
			UVLinkTimer->Enabled = true;
			InspectionRestartButton->Visible = false;
		}
		else
			InspectionStartStep = false;
	}
  else if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if(MachineSetupData.EjectorInfo.MisejectActive)
    {
      MisejectActiveTimeLabel->Visible = true;
      MisejectTimeEdit->Visible = true;
    }
    EjectorMode2RB->Visible = false;
    EjectorLabel6->Visible = false;
    TntLabel8->Visible = true;

    DumperUsalActiveTimeEdit->Visible = true;
    QDischargeCountMainPanel->Visible = true;
    QMisejectCountMainPanel->Visible = true;
    QDischargeCountNamePanel->Caption = INSPECTIONFORM_PANEL_CAPTION_46;
    QMisejectCountNamePanel->Caption = INSPECTIONFORM_PANEL_CAPTION_47;

    UVLinkTimer->Enabled = true;
  }

	//한국콜마
	if (PCProgramOption.TwoSplitterEnable)
	{
		DistributorTntPanel->Visible = true;
		GroupBox10->Visible = true;
	}
	else
	{
		DistributorTntPanel->Visible = false;
		GroupBox10->Visible = false;
	}

	TestMode = 0; // Ajanta
	LaserLinkIntervalTime = 0;
	StartOperName = "";
	EndOperName = "";

  if(MachineSetupData.SimpleSpeedControlOption)
  {
    TSpeedControlForm *speedControlForm = new TSpeedControlForm(this);
    speedControlForm->ApplyMachineSpeedButton->Click();
    delete speedControlForm;
  }
  ClearInspectionRatioChart = false;

  if(MachineSetupData.EjectorInfo.TPB_MisejectActive == 1)
    TPBActiveCheckBox->Checked = true;
  else
    TPBActiveCheckBox->Checked = false;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::GetDefaultString()
{
	CloseBitBtn->Caption = INSPECTIONFORM_BITBTN_CAPTION_01;
	//InspectionStartButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_01;
	InspectionRestartButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_02;
	InspectionStopButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_03;
	GradeSettingButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_05;
	UnmanedOperationButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_06;
	SpeedControlButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_08;
	NCControlButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_09;
	InspectionResultSpeedButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_10;
	ShowImageButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_11;
	VibratorInfoLabel->Caption = INSPECTIONFORM_BUTTON_CAPTION_12;
	VibrationStopButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_13;
	CleaningButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_16;
	this->Caption = INSPECTIONFORM_FORM_CAPTION_01;
	GroupBox8->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_01;
	Panel142->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_02;
	CountCheckLabel->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_03;
	UnInsCountCheckingBtn->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_04;
	Panel113->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_05;
	Panel139->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_06;
	Panel134->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_07;
	Panel137->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_08;
	Label8->Caption = INSPECTIONFORM_GROUPBOX_CAPTION_09;
	Label20->Caption = INSPECTIONFORM_LABEL_CAPTION_08;
	Label57->Caption = INSPECTIONFORM_LABEL_CAPTION_09;
	Label43->Caption = INSPECTIONFORM_LABEL_CAPTION_10;
	Label21->Caption = INSPECTIONFORM_LABEL_CAPTION_11;
	Label50->Caption = INSPECTIONFORM_LABEL_CAPTION_12;
	Label16->Caption = "Miseject 작동 수";//INSPECTIONFORM_LABEL_CAPTION_13;
	Label14->Caption = INSPECTIONFORM_LABEL_CAPTION_14;
	ThroughPutChartLabel->Caption = INSPECTIONFORM_LABEL_CAPTION_15;
	Label32->Caption = INSPECTIONFORM_LABEL_CAPTION_17;
	Label40->Caption = INSPECTIONFORM_LABEL_CAPTION_18;
	Label48->Caption = INSPECTIONFORM_LABEL_CAPTION_19;
	Label17->Caption = INSPECTIONREPORTFORM_LABEL_CAPTION_06;
	Label51->Caption = "미검 정제 수"; //INSPECTIONFORM_LABEL_CAPTION_22;
	Label12->Caption = INSPECTIONFORM_LABEL_CAPTION_23;
	Label34->Caption = INSPECTIONFORM_LABEL_CAPTION_24;
	Label44->Caption = INSPECTIONFORM_LABEL_CAPTION_25;
	Label56->Caption = "불량 정제 수";//INSPECTIONFORM_LABEL_CAPTION_26;
	Label10->Caption = INSPECTIONFORM_LABEL_CAPTION_27;
	Label71->Caption = INSPECTIONFORM_LABEL_CAPTION_28;
	Label49->Caption = INSPECTIONFORM_LABEL_CAPTION_29;
	Label41->Caption = INSPECTIONFORM_LABEL_CAPTION_30;
	Label27->Caption = INSPECTIONFORM_LABEL_CAPTION_31;
	Label31->Caption = INSPECTIONFORM_LABEL_CAPTION_32;
	Label36->Caption = INSPECTIONFORM_LABEL_CAPTION_33;
	Label18->Caption = INSPECTIONFORM_LABEL_CAPTION_34;
	Label60->Caption = "양품 수"; //INSPECTIONFORM_LABEL_CAPTION_35;
	Label47->Caption = INSPECTIONFORM_LABEL_CAPTION_36;
	Label15->Caption = INSPECTIONREPORTFORM_LABEL_CAPTION_15;
	Label53->Caption = INSPECTIONFORM_LABEL_CAPTION_38;
	Label4->Caption = INSPECTIONFORM_LABEL_CAPTION_39;
	Panel148->Caption = INSPECTIONFORM_LABEL_CAPTION_40;
	Label54->Caption = INSPECTIONFORM_LABEL_CAPTION_43;
	Label28->Caption = INSPECTIONFORM_LABEL_CAPTION_44;
	Label13->Caption = INSPECTIONFORM_LABEL_CAPTION_45;
	Label11->Caption = INSPECTIONFORM_LABEL_CAPTION_46;
	Panel132->Caption = INSPECTIONFORM_LABEL_CAPTION_47;
	ChartSelectionLabel->Caption = INSPECTIONFORM_LABEL_CAPTION_48;
	Panel4->Caption = INSPECTIONFORM_LABEL_CAPTION_49;
	Label58->Caption = INSPECTIONFORM_LABEL_CAPTION_51;
	Label42->Caption = INSPECTIONFORM_LABEL_CAPTION_52;
	Label46->Caption = INSPECTIONFORM_LABEL_CAPTION_53;
	Label29->Caption = INSPECTIONFORM_LABEL_CAPTION_54;
	Panel73->Caption = INSPECTIONFORM_PANEL_CAPTION_01;
	Panel144->Caption = INSPECTIONFORM_PANEL_CAPTION_02;
	Panel158->Caption = INSPECTIONFORM_PANEL_CAPTION_03;
	Panel147->Caption = INSPECTIONFORM_PANEL_CAPTION_04;
	Panel31->Caption = INSPECTIONFORM_PANEL_CAPTION_05;
	OptionalInfoPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_06;
	Panel25->Caption = INSPECTIONFORM_PANEL_CAPTION_08;
	Panel34->Caption = INSPECTIONFORM_PANEL_CAPTION_09;
	Panel70->Caption = INSPECTIONFORM_PANEL_CAPTION_10;
	Panel80->Caption = INSPECTIONFORM_PANEL_CAPTION_12;
	Panel90->Caption = INSPECTIONFORM_PANEL_CAPTION_13;
	Panel122->Caption = INSPECTIONFORM_PANEL_CAPTION_14;
	Panel131->Caption = INSPECTIONFORM_PANEL_CAPTION_15;
	Panel12->Caption = INSPECTIONFORM_PANEL_CAPTION_16;
	Panel85->Caption = INSPECTIONFORM_PANEL_CAPTION_17;
	Panel47->Caption = INSPECTIONFORM_PANEL_CAPTION_18;
	Panel36->Caption = INSPECTIONFORM_PANEL_CAPTION_19;
	Panel54->Caption = INSPECTIONFORM_PANEL_CAPTION_20;
	Panel3->Caption = INSPECTIONFORM_PANEL_CAPTION_21;
	Panel83->Caption = INSPECTIONFORM_PANEL_CAPTION_22;
	Panel48->Caption = INSPECTIONFORM_PANEL_CAPTION_23;
	Panel37->Caption = INSPECTIONFORM_PANEL_CAPTION_24;
	Panel45->Caption = INSPECTIONFORM_PANEL_CAPTION_25;
  MachineStopTotalCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	MachineStopGPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	MachineStopUPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
	MachineStopDPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
  QDischargeCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
  QMisejectCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
  MachineStopDefectRatioPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
	MachineStopUnInsRatioPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;
	Panel41->Caption = INSPECTIONFORM_LABEL_CAPTION_15;
	Panel39->Caption = INSPECTIONFORM_PANEL_CAPTION_28;
	Panel28->Caption = INSPECTIONFORM_PANEL_CAPTION_29;
	DefectRatioChartLabel->Caption = INSPECTIONFORM_PANEL_CAPTION_30;
	Panel33->Caption = INSPECTIONFORM_PANEL_CAPTION_31;
	Panel75->Caption = INSPECTIONFORM_PANEL_CAPTION_32;
	Panel26->Caption = INSPECTIONFORM_PANEL_CAPTION_33;
	Panel66->Caption = INSPECTIONFORM_PANEL_CAPTION_34;
	Panel103->Caption = INSPECTIONFORM_PANEL_CAPTION_35;
	Panel107->Caption = INSPECTIONFORM_PANEL_CAPTION_38;
	Panel60->Caption = INSPECTIONFORM_PANEL_CAPTION_39;
	Panel60->Caption = INSPECTIONFORM_PANEL_CAPTION_40;
	Panel61->Caption = INSPECTIONFORM_PANEL_CAPTION_41;
	Panel116->Caption = INSPECTIONFORM_PANEL_CAPTION_42;
	Panel128->Caption = INSPECTIONFORM_PANEL_CAPTION_43;
	Panel19->Caption = INSPECTIONFORM_PANEL_CAPTION_44;
	Panel78->Caption = INSPECTIONFORM_PANEL_CAPTION_45;
	Label1->Caption = AUDITTRAILFORM_BUTTON_CAPTION_03;
	Label2->Caption = INSPECTIONFORM_PANEL_CAPTION_31;
	Label5->Caption = INSPECTIONFORM_PANEL_CAPTION_19;
	Label35->Caption = GRAPHCHECKFORM_LABEL_CAPTION_02;
	Label39->Caption = GRAPHCHECKFORM_LABEL_CAPTION_04;
	Label50->Caption = INSPECTIONREPORTFORM_LABEL_CAPTION_01;
	Label7->Caption = INSPECTIONFORM_PANEL_CAPTION_18;
	Label52->Caption = INSPECTIONREPORTFORM_LABEL_CAPTION_11;
  InspectChartLabel->Caption = PRINTINSPECTIONRESULTFORM_UNKNOWN_04;
	DefectCountCheckingBtn->Caption = DEFECTINFOFORM_GROUPBOX_CAPTION_01;
  HCBDefectCountTitlePanel->Caption = NEW_ADD_STRING_13;
  CPBDefectCountTitlePanel->Caption = INSPECTIONFORM_LABEL_CAPTION_07;
  Panel97->Caption = INSPECTIONFORM_LABEL_CAPTION_79;

	WCHAR TempString[10];
	wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_05, 0);
	TPHLabel->Caption = TempString;

	Panel110->Caption = INSPECTIONFORM_PANEL_CAPTION_38;
	Panel84->Caption = INSPECTIONFORM_PANEL_CAPTION_36;


	Panel89->Caption = INSPECTIONSETUPFORM_LABEL_CAPTION_08;
	//Panel86->Caption = MACHINESETUPPROCESSFORM_GROUPBOX_CAPTION_06;
	//Panel82->Caption = MACHINESETUPPROCESSFORM_GROUPBOX_CAPTION_05;

	Panel115->Caption = MACHINEPARAMSETTINGFORM_LABEL_CAPTION_01;
	Panel112->Caption = MACHINEPARAMSETTINGFORM_LABEL_CAPTION_02;

	TntPanel3->Caption = MACHINECONTROLFORM_LABEL_CAPTION_14;
	Panel109->Caption = MACHINECONTROLFORM_LABEL_CAPTION_01;
	Panel106->Caption = ADVMACHINECONTROLFORM_LABEL_CAPTION_43;

	Panel124->Caption = ADVMACHINECONTROLFORM_LABEL_CAPTION_26;
	Panel121->Caption = MACHINEPARAMSETTINGFORM_LABEL_CAPTION_04;
	Panel118->Caption = MACHINEPARAMSETTINGFORM_LABEL_CAPTION_06;
	Panel94->Caption = MACHINEPARAMSETTINGFORM_LABEL_CAPTION_05;

	UnPrintDefectLabel->Caption = NEW_ADD_STRING_12;

	Panel56->Caption = NEW_ADD_STRING_26;
	Panel91->Caption = NEW_ADD_STRING_27;
	Panel126->Caption = NEW_ADD_STRING_28;
	Panel92->Caption = NEW_ADD_STRING_29;

	Panel99->Caption = NEW_ADD_STRING_45;
	Panel96->Caption = NEW_ADD_STRING_46;
	Panel102->Caption = NEW_ADD_STRING_47;

	TntPanel1->Caption = INSPECTIONFORM_LABEL_CAPTION_55;

	EjectorSettingLabel->Caption = V6_INSPECTION_FORM_EJECT_STR_01;
	GroupBox9->Caption = V6_INSPECTION_FORM_EJECT_STR_02;
	EjectorMode1RB->Caption = V6_INSPECTION_FORM_EJECT_STR_03;
	EjectorMode2RB->Caption = V6_INSPECTION_FORM_EJECT_STR_04;
	EjectorLabel5->Caption = V6_INSPECTION_FORM_EJECT_STR_05;
	EjectorLabel6->Caption = V6_INSPECTION_FORM_EJECT_STR_06;
	EjectorLabel1->Caption = V6_INSPECTION_FORM_EJECT_STR_07;
	EjectorCB1->Caption = V6_INSPECTION_FORM_EJECT_STR_11;
	ApplyDefaultEjectInfoBtn->Caption = V6_INSPECTION_FORM_EJECT_STR_12; 
	EjectorLabel7->Caption = V6_INSPECTION_FORM_EJECT_STR_13;
	TntLabel1->Caption = V6_INSPECTION_FORM_EJECT_STR_16;
	TntLabel2->Caption = V6_INSPECTION_FORM_EJECT_STR_17;

	//한국콜마, language file 추가 해야 함.
	Label23->Caption = V6_INSPECTION_FORM_EJECT_STR_18;     //양품 배출부 최대 수거량.
	Label30->Caption = V6_INSPECTION_FORM_EJECT_STR_21;	  //수거 1
	Label37->Caption = V6_INSPECTION_FORM_EJECT_STR_22;     //수거 2

	TntLabel3->Caption = V6_INSPECTION_FORM_EJECT_STR_19;   //분배기 수거량
	TntLabel4->Caption = V6_INSPECTION_FORM_EJECT_STR_21;   //수거 1
	TntLabel5->Caption = V6_INSPECTION_FORM_EJECT_STR_22;   //수거 2
	TntLabel6->Caption = V6_INSPECTION_FORM_EJECT_STR_23;   //수거 3

	GroupBox10->Caption = V6_INSPECTION_FORM_EJECT_STR_20;  //양품 배출부 활성화 상태.
	TntLabel1->Caption = V6_INSPECTION_FORM_EJECT_STR_24;   //# 1. (수거 1)
	TntLabel2->Caption = V6_INSPECTION_FORM_EJECT_STR_25;   //# 2. (수거 2)
	TntLabel7->Caption = V6_INSPECTION_FORM_EJECT_STR_26;   //# 3. (수거 3)

	StopInfoPanel->Caption = WAITINGFORM_MSG_02;
	FRMismatchDefectLabel->Caption = INSPECTIONFORM_LABEL_CAPTION_57;

    TntPanel13->Caption = INSPECTIONFORM_LABEL_CAPTION_58;
  InspectionRatioChart->Title->Text->Strings[0] = INSPECTIONFORM_LABEL_CAPTION_59;
  InspectionRatioChart->LeftAxis->Title->Caption = INSPECTIONFORM_LABEL_CAPTION_60;
  InspectionRatioChart->BottomAxis->Title->Caption = INSPECTIONFORM_LABEL_CAPTION_61;

  if (DefaultLCID == 1041)
  {
        InspectionRatioChart->Title->Font->Name = "Meiryo UI";
        InspectionRatioChart->LeftAxis->LabelsFont->Name = "Meiryo UI";
        InspectionRatioChart->BottomAxis->LabelsFont->Name = "Meiryo UI";
        InspectionRatioChart->LeftAxis->Title->Font->Name = "Meiryo UI";
        InspectionRatioChart->BottomAxis->Title->Font->Name = "Meiryo UI";

        VibratorInfoChart->Title->Font->Name = "Meiryo UI";
        VibratorInfoChart->BottomAxis->LabelsFont->Name = "Meiryo UI";
        VibratorInfoChart->LeftAxis->LabelsFont->Name = "Meiryo UI";
        VibratorInfoChart->BottomAxis->Title->Font->Name = "Meiryo UI";
        VibratorInfoChart->LeftAxis->Title->Font->Name = "Meiryo UI";

        ThroughputChart->Title->Font->Name = "Meiryo UI";
        ThroughputChart->BottomAxis->LabelsFont->Name = "Meiryo UI";
        ThroughputChart->LeftAxis->LabelsFont->Name = "Meiryo UI";
        ThroughputChart->BottomAxis->Title->Font->Name = "Meiryo UI";
        ThroughputChart->LeftAxis->Title->Font->Name = "Meiryo UI";

        DefectChart->Title->Font->Name = "Meiryo UI";
        DefectChart->BottomAxis->LabelsFont->Name = "Meiryo UI";
        DefectChart->LeftAxis->LabelsFont->Name = "Meiryo UI";
        DefectChart->BottomAxis->Title->Font->Name = "Meiryo UI";
        DefectChart->LeftAxis->Title->Font->Name = "Meiryo UI";
  }

  Series6->Title = INSPECTIONFORM_LABEL_CAPTION_62;
  LineSeries1->Title = INSPECTIONFORM_LABEL_CAPTION_63;
  Series7->Title = INSPECTIONFORM_LABEL_CAPTION_64;

  VibratorInfoChart->Title->Text->Strings[0] = INSPECTIONFORM_LABEL_CAPTION_65;
  VibratorInfoChart->BottomAxis->Title->Caption = INSPECTIONFORM_LABEL_CAPTION_61;

  LineSeries2->Title	= INSPECTIONFORM_LABEL_CAPTION_85;// operating speed
  Series4->Title		= INSPECTIONFORM_LABEL_CAPTION_86;// sensor Average Ratio
  Series2->Title		= INSPECTIONFORM_LABEL_CAPTION_87;// Mesured Sensor Ratio
  Series9->Title		= INSPECTIONFORM_LABEL_CAPTION_88;// Setting Ratio
  Series5->Title  		= INSPECTIONFORM_LABEL_CAPTION_89;// Average speed

  ThroughputChart->Title->Text->Strings[0] = INSPECTIONFORM_LABEL_CAPTION_66;
  ThroughputChart->BottomAxis->Title->Caption = INSPECTIONFORM_LABEL_CAPTION_67;
  ThroughputChart->LeftAxis->Title->Caption = INSPECTIONFORM_LABEL_CAPTION_68;
  ThroughputChart->BottomAxis->AxisValuesFormat = INSPECTIONFORM_LABEL_CAPTION_69;

  DefectChart->Title->Text->Strings[0] = INSPECTIONFORM_LABEL_CAPTION_70;

  InspectionChart->Title->Text->Strings[0] = INSPECTIONFORM_LABEL_CAPTION_71;

  Label25->Caption = INSPECTIONFORM_LABEL_CAPTION_72;
  Label26->Caption = INSPECTIONFORM_LABEL_CAPTION_73;
  Label19->Caption = INSPECTIONFORM_LABEL_CAPTION_74;
  Label33->Caption = INSPECTIONFORM_LABEL_CAPTION_75;
  Label59->Caption = INSPECTIONFORM_LABEL_CAPTION_76;

  CameraTestButton->Caption = CAMERATEST_FORM_TEXT_34;
  Panel23->Caption	= QUICKSTARTFORM_LABEL_CAPTION_03;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionStartButtonClick(
	TObject *Sender)
{
	// 이미지 영역 확인
  WideString LastLotName = LOTNamePanel->Caption;
	bool bErrorCamera[SYSTEM_TOTAL_CAMERA_COUNT];
	ClearInspectionRatioChart = false;
	InspectionStop_flag = false;
	InspectionStop_count = 0;    

	TInspectionSetupForm *inspectionSetupForm = new TInspectionSetupForm(this);    
	
	if (checkCameraArea(&ProductData, bErrorCamera))
	{
		AnsiString ErrorString;
		AnsiString nextString;
		ErrorString = "Incorrect Camera Area (CAM No.";

		int errorCameraCount = 0;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (bErrorCamera[globalCameraIndex]) errorCameraCount++;
		}

		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (bErrorCamera[globalCameraIndex])
			{
				errorCameraCount--;
				if (errorCameraCount)
				{
					ErrorString += IntToStr(globalCameraIndex + 1) + ", ";
				}
				else
				{
					ErrorString += IntToStr(globalCameraIndex + 1) + ")";
				}
			}
		}

		ShowMessageFA(ErrorString);
		LinkSignalInit();
		return;
	}
	//// end

	if (!SimulationInspectionCheckBox->Checked)
	{
		float tabletHalfLength = ProductData.TabletLength / 2;
		if (Machine.Status.OperationState != MACHINE_STATE_STOP &&
			Machine.Status.OperationState != MACHINE_STATE_CLEANING &&
			Machine.Status.OperationState != MACHINE_STATE_ATTACHING &&
			Machine.Status.OperationState != MACHINE_STATE_DETACHING)
		{
			Machine.MachineStop();
			ShowMessageFA(INSPECTIONFORM_MSG_23);
			LinkSignalInit();
			return;
		}

		if (!CheckCPBBootStatus(false,false,true))
		{
			LinkSignalInit();
			return;
		}

    if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
      if(MachineSetupData.InterlockInfo.ACdomesticMode)
      {
        if (MachineSetupData.InterlockInfo.DoorInterlockEnabled)
        {
          if (!Machine.InterlockCheck())
          {
            ShowMessageFA(Machine.GetInterlockMessage());
            LinkSignalInit();
            return;
          }
        }
      }
      else
      {
        if(!Machine.PortStatus.IPStatus[OP_SAFETY_CIRCUIT_SELECT])
        {
          if (!Machine.InterlockCheck())
          {
            ShowMessageFA(Machine.GetInterlockMessage());
            return;
          }
        }
      }
    }
    else
    {
      if (MachineSetupData.InterlockInfo.DoorInterlockEnabled)
      {
        if (!Machine.InterlockCheck())
        {
          ShowMessageFA(Machine.GetInterlockMessage());
          LinkSignalInit();
          return;
        }
      }
    }


		if (!Machine.CanInspectionStart(ProductData.LampKind))
		{
			ShowMessageFA(Machine.GetInspectionStartFailMessage(ProductData.LampKind));
			LinkSignalInit();
			return;
		}

		if (PCProgramOption.HIprogram)
		{
			if (!TabletGradeData_PC.EngravePositionDefectCheckSW && ProductData.EngraveType != ENGRAVE_TYPE_EMPTY)
			{
				ShowMessageFA(INSPECTIONFORM_MSG_26); // For SELMA200, 다국어 수정 필요
				LinkSignalInit();
				return;
			}
		}
	}

	// inspection setting
	
	if (PCProgramOption.UVLaserEnabled && (InspectionStartStep == 2 || InspectionStartStep == 3) && MachineSetupData.CompanyID == DOMESTIC_MACHINE2) // each Ready
	{
		goto secondstep;
	}

  inspectionSetupForm->SetInspectionOption(tempInspectionOption);
  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if(AcrociaStartCommandFlag)
    {
      AcrociaStartCommandFlag = true;
      inspectionSetupForm->SetAcrociaStartCommandStatus(AcrociaStartCommandFlag);
      inspectionSetupForm->OkBitBtn->Click();
      if(inspectionSetupForm->ModalResult == mrOk)
      {
        LOTNamePanel->Caption = ProductData.LOTName;
        inspectionSetupForm->GetInspectionOption(InspectionOption);
        memcpy(&tempInspectionOption, &InspectionOption, sizeof(TInspectionOption));
      }
      else
      {
        
        delete inspectionSetupForm;
        return;
      }
    }
    else
    {
      if (inspectionSetupForm->ShowModal() == mrOk)
      {
        LOTNamePanel->Caption = ProductData.LOTName;
        inspectionSetupForm->GetInspectionOption(InspectionOption);
        if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
        {
          TestMode = inspectionSetupForm->GetTestModeOption();
        }
        memcpy(&tempInspectionOption, &InspectionOption, sizeof(TInspectionOption));
      }
      else
      {
        delete inspectionSetupForm;
        return;
      }
    }
  }
  else if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2 &&(InspectionStartButton->Visible == false || AjantaFormInitCheck == true))
  {
    inspectionSetupForm->OkBitBtn->Click();

    if(inspectionSetupForm->GetReturnCode() == false)
    {
      LOTNamePanel->Caption = ProductData.LOTName;
      inspectionSetupForm->GetInspectionOption(InspectionOption);
      if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
      {
        TestMode = inspectionSetupForm->GetTestModeOption();
      }

      memcpy(&tempInspectionOption, &InspectionOption, sizeof(TInspectionOption));
    }
    else
    {
      delete inspectionSetupForm;
      return;
    }
  }
  else
  {
    if (inspectionSetupForm->ShowModal() == mrOk)
    {
      LOTNamePanel->Caption = ProductData.LOTName;
      inspectionSetupForm->GetInspectionOption(InspectionOption);
      if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
      {
        TestMode = inspectionSetupForm->GetTestModeOption();
      }
      memcpy(&tempInspectionOption, &InspectionOption, sizeof(TInspectionOption));
    }
    else
    {
      delete inspectionSetupForm;
      return;
    }

  }

	if((PCProgramOption.DHprogram == true) && (PCProgramOption.DistributorType4 == 1) && (InspectionOption.SpecialInsCheckbox == 1))
	{
		int checkDistributor = 0;

		if(Comm_Request(COMM_HCB, CMD_READ_DISTRIBUTOR_SIGNAL, NULL, 0, &checkDistributor, sizeof(int)))
		{

		}
		else
		{
			checkDistributor = 1;
		}

		if(checkDistributor == 1)
		{
			return;
		}
	}  	  

	this->Repaint();

	///// Daehwa /////   검사 시작
	DHStartFlag = true;

	MakeHCBInspectionOption(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][MachineOperationInfo.SpeedIndex]);
	// show inspection option
	DisplayInspectionOption();

	//한국콜마
	//공압2분배기 For 뉴트리제약.
	if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_NEW)
	{
		HCBInspectionOption.StartType = 0;
	}
	else if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_CONTINUE)
	{
		HCBInspectionOption.StartType = 1;
	}

	DefectDataDB.ConnectTable(ProductData.ProductCode, ProductData.LOTName);

	if (InspectionOption.IsReInspection)
	{
		if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_NEW)
		{
			memset(&TabletInspectInfo, 0, sizeof(TTabletInspectInfo));

      ProductData.DischargeCount = 0;
			DeleteInspectResult(false);
			ClearDefectInfoList();
      NewInsepctionDataSetFlag = 1;
			InspectionStartTime = Now();
			LastCheckedTime = Now().Val;
      prevtimeForUninsCheck = Now().Val;
			ElapsedTime = 0;
      bSetPrevCount = false;
      bUninsMachineStopSW = false;
			last_inspection_good_count = 0;			
			memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
			DefectTabletNumIndex = 0;
      TPHCheckTabletCount = 0;
      ClearInspectionRatioChart = true;
      ThroughputChart->BottomAxis->SetMinMax(0,100);
      ThroughputChart->BottomAxis->Scroll(0,100);
		}
		else
		{
      if(LastLotName != NULL)
      {
        int SrcStrLen  = wcslen(LastLotName);
        int DstStrLen  = wcslen(ProductData.LOTName);
        int SearchSize = 0;
        if(SrcStrLen >= DstStrLen)
          SearchSize = SrcStrLen;
        else
          SearchSize = DstStrLen;

        int DifResult = wcsncmpi(LastLotName,ProductData.LOTName,SearchSize);
        if(DifResult != 0)
        {
          if (ThroughputChartList) delete[] ThroughputChartList;
          ThroughputChartList = new double[THROUGHPUT_CHART_DEFAULT_SIZE];
          ThroughputChartListSize = THROUGHPUT_CHART_DEFAULT_SIZE;
          ThroughputChartCount = 0;
          ClearInspectionRatioChart = true;
          ThroughputChart->BottomAxis->SetMinMax(0,100);
          ThroughputChart->BottomAxis->Scroll(0,100);
          HCBInspectionOption.StartType = 0;
        }
      }

      NewInsepctionDataSetFlag = 0;
			LoadInspectResult();

			if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_REINS1) // 미선별 재검사
			{
				ClearUninspectedTabletCount();

				memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
				DefectTabletNumIndex = 0;
			}
			else if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_REINS2) // 불량 +미선별 재검사
			{
				// clear defect tablet count
				ClearDefectTabletCount();
				ClearUninspectedTabletCount();

				DeleteInspectResult(true);
				ClearDefectInfoList();

				memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
				DefectTabletNumIndex = 0;
			}
      
			LastCheckedTime = Now().Val;
      prevtimeForUninsCheck = Now().Val;

      bSetPrevCount = false;
      bUninsMachineStopSW = false;

       if(!InspectionOption.QMachineDischargeActive)
       {
        	ProductData.DischargeCount = 0;
        }

      	if(!InspectionOption.QMachineMisejectActive)
      	{
        	Comm_Request(COMM_HCB, CMD_ACROCIA_INSPECTION_INFO_RESET);
        	TabletInspectInfo.MisejectActiveCount = 0;
      	}

      last_inspection_good_count = TabletInspectInfo.GoodTabletCount - ProductData.DischargeCount;
		}
	}
	else	// new inspection
	{
    StartOperName = UserInfo.Name;

		memset(&TabletInspectInfo, 0, sizeof(TTabletInspectInfo));

    NewInsepctionDataSetFlag = 1;
		InspectionStartTime = Now();
		LastCheckedTime = Now().Val;
    prevtimeForUninsCheck = Now().Val;
    bSetPrevCount = false;
    bUninsMachineStopSW = false;

		ElapsedTime = 0;

		ClearDefectInfoList();

		// clear throughput list
    ThroughputChart->Series[0]->Clear();
		if (ThroughputChartList) delete[] ThroughputChartList;
		ThroughputChartList = new double[THROUGHPUT_CHART_DEFAULT_SIZE];
		ThroughputChartListSize = THROUGHPUT_CHART_DEFAULT_SIZE;
		ThroughputChartCount = 0;
    ClearInspectionRatioChart = true;
    ThroughputChart->BottomAxis->SetMinMax(0,100);
    ThroughputChart->BottomAxis->Scroll(0,100);
    //ClearInspectionStatistics();
		memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
		DefectTabletNumIndex = 0;
    ProductData.DischargeCount = 0;
	}

  ClearInspectionStatistics(ClearInspectionRatioChart);

	if (!IsChartView)
	{
		SubDefectInfoForm->InitDefectInfo(ProductData.ProductCode, ProductData.LOTName);
	}

	// Q Laser goto
secondstep:

  if(NewInsepctionDataSetFlag)
  {
    InspectionStartTime = Now();
    LastCheckedTime = Now().Val;
    prevtimeForUninsCheck = Now().Val;
    bSetPrevCount = false;
    bUninsMachineStopSW = false;
    NewInsepctionDataSetFlag = 0;
  }

	// spb setup 후 hcb setup 하여야 한다.
	SPBInspectionSetup();
	HCBInspectionSetup();

  TPBActiveCheckBox->Enabled = false;
  if(TPBActiveCheckBox->Checked)
  {
    bExecuteTPB = true;
    TPBCameraSettingForm->CaptureTrigger = true;
  }

	if (PCProgramOption.UVLaserEnabled && (InspectionStartStep == 0) &&  MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
		InspectionStartButton->Enabled = false;
		InspectionRestartButton->Enabled = false;
		InspectionStopButton->Enabled = true;
		GradeSettingButton->Enabled = false;
		SpeedControlButton->Enabled = false;
		NCControlButton->Enabled = false;
		CloseBitBtn->Enabled = false;
    CameraTestButton->Enabled = false;

		delete inspectionSetupForm;

		InspectionStartStep = 1;
		PcUiFlag.InsReady = 1;
		Machine.SetUIFlagData();

		return;
	}

	int speedControlIndex = MachineOperationInfo.SpeedIndex;

	// write recent inspection information
	TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
	if (iniFile)
	{
		iniFile->WriteInteger("Recent Inspection", "Inspection ID", HCBInspectionOption.InspectionID);
		iniFile->WriteString("Recent Inspection", "User Name", UserInfo.Name);
		iniFile->WriteFloat("Recent Inspection", "Inspection Start Time", Now().Val);
		iniFile->WriteString("Recent Inspection", "Product Code", ProductData.ProductCode);
		iniFile->WriteString("Recent Inspection", "Product Name", ProductData.ProductName);
		iniFile->WriteString("Recent Inspection", "Lot Name", ProductData.LOTName);
		delete iniFile;
	}

	// run machine
	try
	{
		int motorSpeedList[MAX_SERVO_MOTOR_COUNT];
		for (int motorIndex = 0; motorIndex < MAX_SERVO_MOTOR_COUNT; motorIndex++)
		{
			motorSpeedList[motorIndex] = ProductData.MotorSpeedList[motorIndex][speedControlIndex];
		}

		if (!Machine.MachineRun(PROCEDURE_MODE_INSPECTION, &ProductData.MachineRunOption,
			ProductData.NCMotorPos, motorSpeedList))
		{
			throw Exception("Machine Run Failure");
		}
	}
	catch (Exception &ec)
	{

	}

	RatioCheckTimerCount = 0;

	TabletInspectInfo_Begin = TabletInspectInfo;

	TCSVInspectionStartActionLogData csvInspectionStartActionLogData;
	csvInspectionStartActionLogData.IsReInspection = InspectionOption.IsReInspection ? 1 : 0;
	csvInspectionStartActionLogData.DesiredInspectionCount = InspectionOption.DesiredInspectionCount;
	csvInspectionStartActionLogData.ReInspectionType = InspectionOption.ReInspectionType;
	csvInspectionStartActionLogData.ReInspectionTabletCount = TabletInspectInfo.TotalTabletCount;

	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		csvInspectionStartActionLogData.CameraEnabled[globalCameraIndex] = InspectionOption.CameraEnabled[globalCameraIndex] ? 1 : 0;
	}

	csvInspectionStartActionLogData.MachineStopActivated = InspectionOption.MachineStopActivated ? 1 : 0;
	csvInspectionStartActionLogData.MachineStopDefectRatio = InspectionOption.MachineStopDefectRatio;
	csvInspectionStartActionLogData.MachineStopUnInsRatio = InspectionOption.MachineStopUnInsRatio;
	csvInspectionStartActionLogData.NCAsDefect = InspectionOption.NCAsDefect ? 1 : 0;
	csvInspectionStartActionLogData.MotorSpeed[0] = (float)MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed / ProductData.MotorSpeedList[SD1_MOTOR_INDEX][speedControlIndex];
	csvInspectionStartActionLogData.MotorSpeed[1] = (float)MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed / ProductData.MotorSpeedList[SD2_MOTOR_INDEX][speedControlIndex];
	csvInspectionStartActionLogData.MotorSpeed[2] = (float)MachineSetupData.ServoMotorData[BF_ID_MOTOR_INDEX].BaseSpeed / ProductData.MotorSpeedList[BF_ID_MOTOR_INDEX][speedControlIndex];
	csvInspectionStartActionLogData.MotorSpeed[3] = (float)MachineSetupData.ServoMotorData[BF_OD_IN_MOTOR_INDEX].BaseSpeed / ProductData.MotorSpeedList[BF_OD_IN_MOTOR_INDEX][speedControlIndex];

        char Temp[64] = {0,};
        WideCharToMultiByte(CP_ACP,0,ProductData.LOTName.c_bstr(),-1,Temp,64,NULL,NULL);
	strncpy(csvInspectionStartActionLogData.LotName, Temp, 64);

	AddCSVActionLog(ECSV_ACTION_INSPECTION_START, UserInfo.Name, ProductData.ProductName, (unsigned char *)&csvInspectionStartActionLogData, sizeof(TCSVInspectionStartActionLogData));
	
	DefectedTabletList.clear();
	LastCheckedTabletNumber = 0;
	LastDefectSeriesCheckedTabletNumber = 0;
	ClearDefectInfoHeap();

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
  {
    if(TestMode == false)
    {
      TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
      if (iniFile)
      {
        iniFile->WriteString("Quick Start", "Recent Product", ProductData.ProductName);
        iniFile->WriteString("Quick Start", "Recent Lot", ProductData.LOTName);
        iniFile->WriteInteger("Quick Start", "Batch End", 0);
        InspectionStartButton->Visible =false;
        AjantaFormInitCheck = true;
        delete iniFile;
      }
    }

  }
  else
  {
    if (PCProgramOption.QuickStartEnabled)
    {
      TIniFile *iniFile = new TIniFile(ProgramPath.Env + "\\UserSetting.ini");
      if (iniFile)
      {
        iniFile->WriteString("Quick Start", "Recent Lot", ProductData.LOTName);
        delete iniFile;
      }
    }
  }

  bool AdditionalInfo = false;
	InspectState = INSPECTION_STATE_START;
	if (ProductData.EngraveType != ENGRAVE_TYPE_EMPTY && ProductData.EngraveType != ENGRAVE_TYPE_UNKNOWN && InspectionOption.CheckUnPrint && !MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
	{
		UnPrintDefectLabel->Visible = true;
		UnPrintTabletCountLabel->Visible = true;
    AdditionalInfo = true;
	}
	else
	{
		UnPrintDefectLabel->Visible = false;
		UnPrintTabletCountLabel->Visible = false;
	}

	if (ProductData.TabletLayerCount > 1 &&
		(ProductData.MultiLayeredTabletColor[0] != ProductData.MultiLayeredTabletColor[ProductData.TabletLayerCount - 1]))	// two color
	{
		FRMismatchDefectLabel->Visible = true;
		FRMismatchTabletCountLabel->Visible = true;
    AdditionalInfo = true;
	}
	else
	{
		FRMismatchDefectLabel->Visible = false;
		FRMismatchTabletCountLabel->Visible = false;
	}

  StandbyHCBMonitoring();
  
	InspectionStartButton->Enabled = false;
	InspectionRestartButton->Enabled = false;
	InspectionStopButton->Enabled = true;
	InspectionResultTimer->Enabled = true;
	DefectCheckTimer->Enabled = true;
	InspectionInfoTimer->Enabled = true;
	StopInfoPanel->Visible = false;
	AlarmForm->WarningSleep = false;
	bSuspendCheck = false;
	InspectionCompleteTime.Val = 0;

  CameraTestButton->Enabled = false;
	CloseBitBtn->Enabled = false;
	TcpSndTimer1->Enabled = true;

  ClearLaserMonitoringData();
  for(int i = LaserMonitoringStringGrid->FixedRows; i < LaserMonitoringStringGrid->RowCount; ++i)
  {
    LaserMonitoringStringGrid->Rows[i]->Clear();
  }
  LaserMonitoringStringGrid->RowCount = 2;
 
  MarkingInfoPagePanel->Visible = false;
  if (UserInfo.AccessLevel == SYSTEM_HIGHEST_ACCESS_LEVEL)
  {
	UploadRealtimeCapturedImageTimer->Enabled = true;
	HCBMonitoringTimer->Enabled = true;
  }
  else
  {
	UploadRealtimeCapturedImageTimer->Enabled = false;
	HCBMonitoringTimer->Enabled = false;
  }

  RTTabletMinNumber = 0xF0000000;
  RTTabletMaxNumber = 0;
  
	if (!IsChartView)
		ShowImageButton->Click();

	if (VFSpeedMode == VFSPEEDMODE_ON)
	{
		Machine.VFStartSpeedMode(ProductData.MachineRunOption.StartSpeed);
		VFSpeedMode = VFSPEEDMODE_OFF;
	}
	else
	{
		Machine.VFStartSpeedMode(BeforeSpeed);
	}

	if (SimulationInspectionCheckBox->Checked)
	{
		SetSPBVirtualInspectionImage();

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

		int buff;

		buff = StrToInt(Edit2->Text);

		Comm_Request(COMM_HCB, CMD_ALARM_RESET);
		Comm_Request(COMM_HCB, CMD_VIRTUAL_INSPECTION_START, &buff, sizeof(int));
	}

	if (PCProgramOption.UVLaserEnabled && (InspectionStartStep == 2 || InspectionStartStep == 3) &&  MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
                PcUiFlag.InsActive = 1;
		InspectionStartStep = 3;
		Machine.SetUIFlagData();
		LastUVLaserStatus[1] = 1;

		SuccessRun = true;

		GradeSettingButton->Enabled = true;
		SpeedControlButton->Enabled = true;
		NCControlButton->Enabled = true;
	}
  else if(MachineSetupData.CompanyID ==INTERNATIONAL_MACHINE1)
  {
    if(InspectionOption.QMachineDischargeActive)
      QDischargeResetBtn->Enabled = true;
    if(InspectionOption.QMachineMisejectActive)
      QMisejectResetbtn->Enabled = true;

    last_vb_sensor_value = Machine.PortStatus.IPStatus[IP_VB_SENSOR];
    Using_CaptuerSensorTimer = false;
    SD2CaptureSensor_UITimer = 0;
    UVLaser.SELMAStatus.Active = 1;
		UVLaser.SELMAStatus.Ready = 0;
  }
//cjg OPC Test

	if(hOPC_DLL)
	{
		(*pSetTabletGradeData)(&TabletGradeData_PC);
		(*pSetInspectionOption)(&InspectionOption);
		(*pSetMachineRunOption)(&ProductData.MachineRunOption);
		(*pSetMESProductData)(&MESProductData);
	}

	delete inspectionSetupForm;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionInfoTimerTimer(TObject *Sender)
{
	bool timerEnabled = InspectionInfoTimer->Enabled;

	try
	{
		InspectionInfoTimer->Enabled = false;

		int requestNum = 1;
		TTabletInspectInfo tempTabletInspectInfo;
		if (!Comm_Request(COMM_HCB, CMD_TABLET_INSPECT_INFO, &requestNum, sizeof(int),
			&tempTabletInspectInfo, sizeof(TTabletInspectInfo)))
		{
			throw Exception("");
		}
		else
		{
      if((Now().Val - prevtimeForUninsCheck) * 24 * 3600 >= 5) // HCB는 10초 기준인데 HCB타이머랑 PC타이머랑 정확히 일치하지는 않을까 싶어 5초를 적용
      {
        prevtimeForUninsCheck = Now().Val;
        memcpy(&prevTabletInspectInfo, &TabletInspectInfo, sizeof(TTabletInspectInfo));

        bSetPrevCount = true;
      }
      memcpy(&TabletInspectInfo, &tempTabletInspectInfo, sizeof(TTabletInspectInfo));
		}

		double currentTime = Now().Val;
		ElapsedTime += (currentTime - LastCheckedTime);
		LastCheckedTime = currentTime;
		double PassingTime = (currentTime - LastTPHCheckedTime) * 24 * 3600;
		if (PassingTime >= 10)
		{
			// calculate throughput
			CurrentTPH = (TabletInspectInfo.TotalTabletCount - TPHCheckTabletCount) / ((currentTime - LastTPHCheckedTime) * 24);
			TPHCheckTabletCount = TabletInspectInfo.TotalTabletCount;
			UpdateThroughputChart();
			LastTPHCheckedTime = currentTime;
      RatioCheckTimerCount++;
		}

    if(RatioCheckTimerCount >= 6)
    {
      UpdateInspectionRatioChart();
      RatioCheckTimerCount = 0;
    }

		DisplayTabletInspectionInfo();

    if(InspectionOption.QMachineDischargeActiveCount == -1)
      ProductData.DischargeCount = 0 ;
    else
      ProductData.DischargeCount = TabletInspectInfo.GoodTabletCount - last_inspection_good_count;

		// SELMA 200 노즐 추가
		if (TabletInspectInfo.SPGoodTabletDropIndex == 0)
		{
			if (TabletInspectInfo.SPGoodTabletDropIndex != SPGoodTabletDropIndex)
			{
				TntDistributorPanel1->Color = clRed;
				TntDistributorPanel2->Color = clNone;
				TntDistributorPanel3->Color = clNone;
				SPGoodTabletDropIndex = TabletInspectInfo.SPGoodTabletDropIndex;
			}
		}
		else if (TabletInspectInfo.SPGoodTabletDropIndex == 1)
		{
			if (TabletInspectInfo.SPGoodTabletDropIndex != SPGoodTabletDropIndex)
			{
				TntDistributorPanel1->Color = clNone;
				TntDistributorPanel2->Color = clRed;
				TntDistributorPanel3->Color = clNone;
				SPGoodTabletDropIndex = TabletInspectInfo.SPGoodTabletDropIndex;
			}

		}
		else if (TabletInspectInfo.SPGoodTabletDropIndex == 2)
		{
			if (TabletInspectInfo.SPGoodTabletDropIndex != SPGoodTabletDropIndex)
			{
				TntDistributorPanel1->Color = clNone;
				TntDistributorPanel2->Color = clNone;
				TntDistributorPanel3->Color = clRed;
				SPGoodTabletDropIndex = TabletInspectInfo.SPGoodTabletDropIndex;
			}
		}

		TotalRatioChartLabel->Caption = FloatToStrF((double)TabletInspectInfo.GoodTabletCount / (TabletInspectInfo.GoodTabletCount + TabletInspectInfo.DefectTabletCount) * 100, ffGeneral, 4, 2) + " %";

		CheckMachineSuspend();

		if (!SimulationInspectionCheckBox->Checked)
		{
			CheckMachineAlarmStatus();
		}

		if (AutoSaveInterval >= AUTO_SAVE_INTERVAL)
		{
			if (!bCalledWriteFunc)
			{
				/*if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
				{
				if(!TestMode)
				{
				SaveInspectResult();
				}
				}
				else  */
				SaveInspectResult();
			}

			AutoSaveInterval = 0;
		}
		else
		{
			AutoSaveInterval++;
		}

		bool bMachineFinished = false;

		unsigned char machineState = Machine.Status.OperationState;
		if (InspectState == INSPECTION_STATE_STOPPING && (machineState == MACHINE_STATE_STOP || machineState == MACHINE_STATE_CLEANING))
		{
			bMachineFinished = true;
		}
		else if (InspectState == INSPECTION_STATE_STOP || InspectState == INSPECTION_STATE_MACHINE_STOP)
		{
			bMachineFinished = true;
		}

		if (bMachineFinished)
		{
			timerEnabled = false;
			InspectionCompleteTime.Val = Now().Val;
		}
	}
	catch (...)
	{

	}

	InspectionInfoTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::GradeSettingButtonClick(TObject *Sender)
{
	TGradeSettingForm *gradeSettingForm = new TGradeSettingForm(this);
	TTabletGradeData OldTabletGradeData = TabletGradeData_PC;
	gradeSettingForm->SetGradeData(&TabletGradeData_PC);
  gradeSettingForm->bUserMakingGradeData = false;
	if (gradeSettingForm->ShowModal() == mrOk)
	{
		gradeSettingForm->GetGradeData(&TabletGradeData_PC);
//cjg OPC Test
	if(hOPC_DLL)
	{
		(*pSetTabletGradeData)(&TabletGradeData_PC);
	}

		AnsiString gradeFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".grd";
		SaveGradeData(gradeFileName, TabletGradeData_PC);
		DisplayGradeInfo();

		TCSVGradeChangeActionLogData csvGradeChangeActionLogData;
		csvGradeChangeActionLogData.Count = 0;
		int changeIndex = 0;
		if (TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type1 != OldTabletGradeData.option_front_edgeBreaking_Intensity_Type1)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 1;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_front_edgeBreaking_Intensity_Type1;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type1;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_stain_Intensity != OldTabletGradeData.front_stain_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 2;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_stain_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_stain_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_stain_Size != OldTabletGradeData.front_stain_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 3;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_stain_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_stain_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_edge_Intensity != OldTabletGradeData.front_edge_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 4;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_edge_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_edge_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_edge_Size != OldTabletGradeData.front_edge_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 5;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_edge_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_edge_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_edge_dirty_Intensity != OldTabletGradeData.front_edge_dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 6;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_edge_dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_edge_dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_edge_dirty_Size != OldTabletGradeData.front_edge_dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 7;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_edge_dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_edge_dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_dirty_Intensity != OldTabletGradeData.front_dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 8;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_dirty_Size != OldTabletGradeData.front_dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 9;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_color_Intensity != OldTabletGradeData.front_color_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 10;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_color_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_color_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.frontShapeEdgeNeighborRange != OldTabletGradeData.frontShapeEdgeNeighborRange)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 11;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.frontShapeEdgeNeighborRange;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.frontShapeEdgeNeighborRange;
			changeIndex++;
		}
		if (TabletGradeData_PC.frontBorderIsSW != OldTabletGradeData.frontBorderIsSW)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 12;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.frontBorderIsSW;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.frontBorderIsSW;
			changeIndex++;
		}
		if (TabletGradeData_PC.frontSmallSizeGrade != OldTabletGradeData.frontSmallSizeGrade)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 13;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.frontSmallSizeGrade;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.frontSmallSizeGrade;
			changeIndex++;
		}
		if (TabletGradeData_PC.option_Breaking_Intensity != OldTabletGradeData.option_Breaking_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 14;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_Breaking_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_Breaking_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.option_PrintMark_Intensity != OldTabletGradeData.option_PrintMark_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 15;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_PrintMark_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_PrintMark_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.option_Breaking_Size != OldTabletGradeData.option_Breaking_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 16;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_Breaking_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_Breaking_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_stain_Intensity != OldTabletGradeData.side_stain_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 17;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_stain_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_stain_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_stain_Size != OldTabletGradeData.side_stain_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 18;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_stain_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_stain_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_dirty_Intensity != OldTabletGradeData.side_dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 19;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_dirty_Size != OldTabletGradeData.side_dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 20;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_Edge_Top_Neighbor_Intensity != OldTabletGradeData.side_Edge_Top_Neighbor_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 21;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_Edge_Top_Neighbor_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_Edge_Top_Neighbor_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.sideShapeEdgeMaskRange != OldTabletGradeData.sideShapeEdgeMaskRange)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 22;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.sideShapeEdgeMaskRange;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.sideShapeEdgeMaskRange;
			changeIndex++;
		}
		if (TabletGradeData_PC.FrontEdgeAreaExtendSW != OldTabletGradeData.FrontEdgeAreaExtendSW)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 23;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.FrontEdgeAreaExtendSW;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.FrontEdgeAreaExtendSW;
			changeIndex++;
		}
		if (TabletGradeData_PC.frontShaepEdgeSaturationEraseSW != OldTabletGradeData.frontShaepEdgeSaturationEraseSW)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 24;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.frontShaepEdgeSaturationEraseSW;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.frontShaepEdgeSaturationEraseSW;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_print_dirty_Inetensity != OldTabletGradeData.front_print_dirty_Inetensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 25;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_print_dirty_Inetensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_print_dirty_Inetensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.option_front_edgeBreaking_Size_Type1 != OldTabletGradeData.option_front_edgeBreaking_Size_Type1)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 26;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_front_edgeBreaking_Size_Type1;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_front_edgeBreaking_Size_Type1;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_print_erase_Intensity != OldTabletGradeData.front_print_erase_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 27;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_print_erase_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_print_erase_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_print_spread_Intensity != OldTabletGradeData.front_print_spread_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 28;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_print_spread_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_print_spread_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_Color_Dirty_Intensity != OldTabletGradeData.front_Color_Dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 29;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_Color_Dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_Color_Dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_Color_Dirty_Size != OldTabletGradeData.front_Color_Dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 30;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_Color_Dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_Color_Dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_unInspectionIntensity_ForPrint != OldTabletGradeData.front_unInspectionIntensity_ForPrint)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 31;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_unInspectionIntensity_ForPrint;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_unInspectionIntensity_ForPrint;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_unInspectionIntensity_ForEdge != OldTabletGradeData.front_unInspectionIntensity_ForEdge)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 32;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_unInspectionIntensity_ForEdge;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_unInspectionIntensity_ForEdge;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_unInspectionIntensity_ForOptionPrint != OldTabletGradeData.front_unInspectionIntensity_ForOptionPrint)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 33;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_unInspectionIntensity_ForOptionPrint;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_unInspectionIntensity_ForOptionPrint;
			changeIndex++;
		}
		if (TabletGradeData_PC.front_unInspectionIntensity_ForOptionEdge != OldTabletGradeData.front_unInspectionIntensity_ForOptionEdge)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 34;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.front_unInspectionIntensity_ForOptionEdge;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.front_unInspectionIntensity_ForOptionEdge;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_stain_Intensity != OldTabletGradeData.rear_stain_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 35;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_stain_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_stain_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_stain_Size != OldTabletGradeData.rear_stain_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 36;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_stain_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_stain_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_edge_Intensity != OldTabletGradeData.rear_edge_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 37;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_edge_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_edge_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_edge_Size != OldTabletGradeData.rear_edge_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 38;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_edge_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_edge_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_edge_dirty_Intensity != OldTabletGradeData.rear_edge_dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 39;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_edge_dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_edge_dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_edge_dirty_Size != OldTabletGradeData.rear_edge_dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 40;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_edge_dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_edge_dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_dirty_Intensity != OldTabletGradeData.rear_dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 41;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_dirty_Size != OldTabletGradeData.rear_dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 42;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_print_dirty_Inetensity != OldTabletGradeData.rear_print_dirty_Inetensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 43;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_print_dirty_Inetensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_print_dirty_Inetensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_Color_Dirty_Intensity != OldTabletGradeData.rear_Color_Dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 44;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_Color_Dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_Color_Dirty_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.rear_Color_Dirty_Size != OldTabletGradeData.rear_Color_Dirty_Size)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 45;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.rear_Color_Dirty_Size;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.rear_Color_Dirty_Size;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_height_Intensity != OldTabletGradeData.side_height_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 46;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_height_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_height_Intensity;
			changeIndex++;
		}
		if (TabletGradeData_PC.side_Color_Dirty_Intensity != OldTabletGradeData.side_Color_Dirty_Intensity)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 47;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.side_Color_Dirty_Intensity;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.side_Color_Dirty_Intensity;
			changeIndex++;
		}
    if (TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type2 != OldTabletGradeData.option_front_edgeBreaking_Intensity_Type2)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 48;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_front_edgeBreaking_Intensity_Type2;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type2;
			changeIndex++;
		}
    if (TabletGradeData_PC.option_front_edgeBreaking_Size_Type2 != OldTabletGradeData.option_front_edgeBreaking_Size_Type2)
		{
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].GradeID = 49;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].OldValue = OldTabletGradeData.option_front_edgeBreaking_Size_Type2;
			csvGradeChangeActionLogData.GradeChangeData[changeIndex].NewValue = TabletGradeData_PC.option_front_edgeBreaking_Size_Type2;
			changeIndex++;
		}

		// ID 최대 50개 부여

		csvGradeChangeActionLogData.Count = changeIndex;
		if (csvGradeChangeActionLogData.Count > 0)
		{
			AddCSVActionLog(ECSV_ACTION_GRADE_CHANGE, UserInfo.Name, ProductData.ProductName, (unsigned char *)&csvGradeChangeActionLogData, sizeof(int) + csvGradeChangeActionLogData.Count * sizeof(TGradeChangeData));
		}
		CPBSetupInfo.GradeDataValid = false;

		if (CPBSetupInfo.InspectionSetupDataValid == false)
		{
			WaitingForm->SetMessage(MAINFORM_MSG_13);
			WaitingForm->Show();
      Application->ProcessMessages();
			SubDefectInfoForm->RefreshInspectionSetupData();

			WaitingForm->Hide();
		}
	}
	delete gradeSettingForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::SpeedControlButtonClick(
	TObject *Sender)
{
	TSpeedControlForm *speedControlForm = new TSpeedControlForm(this);
	speedControlForm->ShowModal();
	delete speedControlForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::FormCreate(TObject *Sender)
{
//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)
	{
		pSetTabletGradeData =	(int(*)(TTabletGradeData *))	GetProcAddress(hOPC_DLL, "SetTabletGradeData");
		pSetTabletInspectInfo = (int(*)(TTabletInspectInfo*)) 	GetProcAddress(hOPC_DLL, "SetTabletInspectInfo");
		pSetInspectionOption = 	(int(*)(TInspectionOption*)) 	GetProcAddress(hOPC_DLL, "SetInspectionOption");
		pSetMachineRunOption = 	(int(*)(TMachineRunOption*)) 	GetProcAddress(hOPC_DLL, "SetMachineRunOption");
		pSetMESProductData 	=	(int(*)(TMESProductData*))		GetProcAddress(hOPC_DLL, "SetMESProductData");
	}

	if (UserInfo.AccessLevel == SYSTEM_HIGHEST_ACCESS_LEVEL)
	{
    InspectionCountInfoPanel->Visible = true;
		DefectRatioPanel->Visible = false;
		MisejectSpeedButton->Visible = false;
		InspectionResultSpeedButton->Visible = false;
		HCBMonitoringButton->Visible = false;
		VibratorInfoSpeedButton->Visible = true;
    VibratorInfoLabel->Visible = true;
    SimulationButton->Visible = false;
	}
	else
	{
		InspectionCountInfoPanel->Visible = false;
		DefectRatioPanel->Visible = true;
		MisejectSpeedButton->Visible = false;
		InspectionResultSpeedButton->Visible = false;
		HCBMonitoringButton->Visible = false;
//		VibratorInfoSpeedButton->Visible = false;
//    VibratorInfoLabel->Visible = false;
    SimulationButton->Visible = false;
	}

  OnUserChange();

	InitInspectionOption(InspectionOption);
	InitInspectionOption(tempInspectionOption);

	GradePanel->Visible = true;
	ThroughputPanel->Visible = true;
	DefectRatioPanel->Visible = false;

  UnInsCountCheckingBtn->Font->Color = clBlack;
	DefectCountCheckingBtn->Font->Color = clBlue;
  
  UnInsCountPanel->Visible = false;
  DefectCountPanel->Visible = true;

  DefectCountPanel->BringToFront();

  SimulationPanel->Visible = false;
	InspectionCountInfoPanel->Visible = false;
	InspectChartPanel->Visible = true;
	MisejectInfoPanel->Visible = false;
	EjectorSettingPanel->Visible = false;

  ProductNameLabel->Caption = ProductData.ProductName;
	LOTNamePanel->Caption = ProductData.LOTName;

	VFSpeedControlEdit->Text = IntToStr(ProductData.MachineRunOption.ManualMaxSpeed);
	VFSpeedControlUpDown->Position = ProductData.MachineRunOption.ManualMaxSpeed;

	TabletKindPanel->Caption = TabletKindStr(ProductData.TabletType);
	TabletShapePanel->Caption = TabletShapeStr(ProductData.TabletShape);

	TabletLengthPanel->Caption = FloatToStr(ProductData.TabletLength) + "mm";
	TabletWidthPanel->Caption = FloatToStr(ProductData.TabletWidth) + "mm";
	TabletThickPanel->Caption = FloatToStr(ProductData.TabletThick) + "mm";
	TabletSideThickPanel->Caption = FloatToStr(ProductData.TabletSideThick) + "mm";

	TabletEngraveKindPanel->Caption = TabletEngraveKindStr(ProductData.EngraveType);
	TabletEngravePosPanel->Caption = TabletEngravePosStr(ProductData.EngravePos);
	DisplayGradeInfo();
	CheckMachineState();
	setEjectInformation();

	DateTimeLabel->DoubleBuffered = true;
	Panel20->DoubleBuffered = true;
  LaserStatusInfoPanel->DoubleBuffered = true;
  CPBStatusGroupBox->DoubleBuffered = true;

	bCalledWriteFunc = false;
  bExecuteTPB = false;
	SPGoodTabletDropIndex = -1;
	
	LinkSignalInit(false);

	if (ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
	{
		SourceImageWidth[0] = SYSTEM_CAMERA_HD_WIDTH;
		SourceImageHeight[0] = SYSTEM_CAMERA_HD_HEIGHT;

		SourceImageWidth[1] = SYSTEM_CAMERA_WIDTH;
		SourceImageHeight[1] = SYSTEM_CAMERA_HEIGHT;

		rate[0] = 2;
		rate[1] = 1;
	}
	else
	{
		SourceImageWidth[0] = SYSTEM_CAMERA_WIDTH;
		SourceImageHeight[0] = SYSTEM_CAMERA_HEIGHT;

		SourceImageWidth[1] = SYSTEM_CAMERA_WIDTH;
		SourceImageHeight[1] = SYSTEM_CAMERA_HEIGHT;

		rate[0] = 1;
		rate[1] = 1;
	}

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    Machine.MisejectOpen();
    SkipDischargeQuestion = 0;
  }

  if(PCProgramOption.UVLaserEnabled)
  {
    // 2020-08-21
    // 레이저 장비에서 배출부 기능 변경 불가
    EjectorSettingSpeedButton->Visible = false;
  }

	if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
	{
		APP->Caption = "Show sLaser";
		APP->Font->Color = clBlue;
		BtnOnOffFlag = false;
	}

  ClearLaserMonitoringData();
  for(int i = LaserMonitoringStringGrid->FixedRows; i < LaserMonitoringStringGrid->RowCount; ++i)
  {
    LaserMonitoringStringGrid->Rows[i]->Clear();
  }
  LaserMonitoringStringGrid->RowCount = 2;
 
  MarkingInfoPagePanel->Visible = false;
  UploadRealtimeCapturedImageTimer->Enabled = false;
  HCBMonitoringTimer->Enabled = false;
  RTTabletMinNumber = 0xF0000000;
  RTTabletMaxNumber = 0;

  RT2DBuffering->Position = 0;
  RT2DBuffering->Max = MAX_RT_IMAGE_BUFFER_SIZE - 1;

  RT3DBuffering->Position = 0;
  RT3DBuffering->Max = MAX_RT_IMAGE_BUFFER_SIZE - 1;

  TTabletSetupData *pTabletSetupData = new TTabletSetupData;
  if(ReadSetupData(pTabletSetupData))
  {
    meanTabletColor = (pTabletSetupData->protoStudyColorB + pTabletSetupData->protoStudyColorG + pTabletSetupData->protoStudyColorR) / 3;
  }
  else
  {
    meanTabletColor = 255;
  }

  PrintMinColor = max(30, pTabletSetupData->PrintThreshold * 90 / 100);

  delete pTabletSetupData;

  TTabletStudyData *pTabletStudyData = new TTabletStudyData;
  ReadStudyData(pTabletStudyData);
  int CurrentTabletColor = (pTabletStudyData->tabletColorR_ForCamera1 + pTabletStudyData->tabletColorG_ForCamera1 + pTabletStudyData->tabletColorB_ForCamera1) / 3;

  float VectorBrightness = CurrentTabletColor / (float)meanTabletColor;

  meanTabletColor = VectorBrightness * meanTabletColor;
  PrintMinColor = VectorBrightness * PrintMinColor;

  if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    UnPrintPanel->Visible = true;
  }
  else
  {
    UnPrintPanel->Visible = false;
  }
  InspectionStop_flag = false;
  InspectionStop_count = 0;
  delete pTabletStudyData;
}
//---------------------------------------------------------------------------
int __fastcall TInspectionForm::SaveDefectInfo(void)
{
	AnsiString saveDir = GetDefectDataPath(ProductData.ProductCode, ProductData.LOTName);
	ForceDirectories(saveDir);

	int dbDataIndex = DefectDataDB.AddDefectData(&CurrentDefectData);
	return dbDataIndex;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionPause(void)
{
	//sjm Chg Time
	//TTabletInspectReport tabletInspectReport;
	Machine.MachineStop();
	InspectionStopOption = INSPECTION_STOP_OPTION_MACHINE_STOP;
	InspectState = INSPECTION_STATE_STOPPING;

	//sjm Chg Time
	/*tabletInspectReport.InspectionEndTime = Now().Val;
	ChgInspectionEndTime = tabletInspectReport.InspectionEndTime;*/
  ChgInspectionEndTime = Now().Val;

	EndOperName = UserInfo.Name;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::SaveInspectResult(void)
{
	bCalledWriteFunc = true;
	int ErrorLineNum;
	TFileStream *fileStream;
	int currentLine = __LINE__;

	try
	{
		AnsiString resultDir;
		AnsiString resultDir_Backup;
		AnsiString resultFileName;
		AnsiString throughputFileName;
		unsigned int thorughputFileVerion;

    NFA_INSPECTION_REPORT_STRUCT Prev_Report;
    NFA_INSPECTION_REPORT_STRUCT New_Report;

    memset(&New_Report,0,sizeof(NFA_INSPECTION_REPORT_STRUCT));
    memset(&Prev_Report,0,sizeof(NFA_INSPECTION_REPORT_STRUCT));

		resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result";
		ForceDirectories(resultDir);
		resultFileName = resultDir + "\\" + ProductData.LOTName + ".dat";

    if(FileExists(resultFileName))
    {
      Read_InspectionReportData(resultFileName,Prev_Report);
      DeleteFile(resultFileName.c_str());

      if(PCProgramOption.PrintInsResUserDisplayOpt == START_LOT_USER)
      {
      	StartOperName = AnsiString(Prev_Report.Data.OperatorName);
      }
      else
      {
	  	StartOperName = UserInfo.Name;
      }

      strncpy(New_Report.Data.OperatorName, StartOperName.c_str(), strlen(StartOperName.c_str()));
    }
    else
    {
      int sourceStrLength = strlen(StartOperName.c_str());
      if(sourceStrLength > 31)
        strncpy(New_Report.Data.OperatorName, StartOperName.c_str(), 31);
      else
        strncpy(New_Report.Data.OperatorName, StartOperName.c_str(), strlen(StartOperName.c_str()));
    }

		New_Report.Data.ProductionCount = ProductData.ProductionCount;
		New_Report.Data.TotalTabletCount = TabletInspectInfo.TotalTabletCount;
		New_Report.Data.GoodTabletCount = TabletInspectInfo.GoodTabletCount;
		New_Report.Data.DefectTabletCount = TabletInspectInfo.DefectTabletCount;
		New_Report.Data.UnInsTabletCount = TabletInspectInfo.UnInsTabletCount;
		New_Report.Data.SPBProcessingNCTabletCount = TabletInspectInfo.SPBProcessingNCTabletCount;
		New_Report.Data.SPBTOTabletCount = TabletInspectInfo.SPBTOTabletCount;
		New_Report.Data.SPBUnInsTabletCount = TabletInspectInfo.SPBUnInsTabletCount;
		New_Report.Data.DisappearedTabletCount = TabletInspectInfo.DisappearedTabletCount;
		New_Report.Data.InsertedTabletCount = TabletInspectInfo.InsertedTabletCount;
		New_Report.Data.ClosedTabletDefectCount = TabletInspectInfo.ClosedTabletDefectCount;
		New_Report.Data.ClosedTabletUninsCount = TabletInspectInfo.ClosedTabletUninsCount;
		New_Report.Data.ClosedTabletCount = TabletInspectInfo.ClosedTabletCount;
		New_Report.Data.ElapsedTime = ElapsedTime * 24 * 3600;
		New_Report.Data.InspectionStartTime = InspectionStartTime.Val;
		New_Report.Data.InspectionEndTime = ChgInspectionEndTime == 0 ? Now().Val : ChgInspectionEndTime;

		New_Report.Data.UnPrintTabletCount = TabletInspectInfo.UnPrintTabletCount;
		New_Report.Data.PrintMisMatchCount = TabletInspectInfo.PrintMisMatchCount;
		New_Report.Data.WrongNumberTabletCount = TabletInspectInfo.WrongNumberTabletCount;
		New_Report.Data.NumberUndefTabletCount = TabletInspectInfo.NumberUndefTabletCount;
		New_Report.Data.CaptureNotReadyTabletCount = TabletInspectInfo.CaptureNotReadyTabletCount;
		New_Report.Data.BufferFullTabletCount = TabletInspectInfo.BufferFullTabletCount;
		New_Report.Data.CaptureTimoutTabletCount = TabletInspectInfo.CaptureTimoutTabletCount;
		New_Report.Data.ProcessingTimoutTabletCount = TabletInspectInfo.ProcessingTimoutTabletCount;
		New_Report.Data.CPBFullTabletCount = TabletInspectInfo.CPBFullTabletCount;
		New_Report.Data.ProcessingErrorTabletCount = TabletInspectInfo.ProcessingErrorTabletCount;

		New_Report.Data.UnInsTabletPositionCount = TabletInspectInfo.UnInsTabletPositionCount;
		New_Report.Data.UnInsBrightnessDropCount = TabletInspectInfo.UnInsBrightnessDropCount;
		New_Report.Data.UnInsBrightnessChaseCount = TabletInspectInfo.UnInsBrightnessChaseCount;

		New_Report.Data.Sensor1MisFeedingTabletCount = TabletInspectInfo.Sensor1MisFeedingTabletCount;
		New_Report.Data.Sensor2MisFeedingTabletCount = TabletInspectInfo.Sensor2MisFeedingTabletCount;
		New_Report.Data.Sensor1MultiTabletCount = TabletInspectInfo.Sensor1MultiTabletCount;
		New_Report.Data.Sensor2MultiTabletCount = TabletInspectInfo.Sensor2MultiTabletCount;
		New_Report.Data.NozzErrorUnInsTabletCount = TabletInspectInfo.NozzErrorUnInsTabletCount;
		New_Report.Data.NozzErrorDefectTabletCount = TabletInspectInfo.NozzErrorDefectTabletCount;
		New_Report.Data.CounterSensorTabletCount = TabletInspectInfo.CounterSensorTabletCount;
		New_Report.Data.MisejectActiveCount = TabletInspectInfo.MisejectActiveCount;
		New_Report.Data.GoodTabletLostCount = TabletInspectInfo.GoodTabletLostCount;
		New_Report.Data.MisejectTabletInsertCount = TabletInspectInfo.MisejectTabletInsertCount;
		New_Report.Data.MisejectTabletInsertCount = TabletInspectInfo.MisejectTabletInsertCount;
		New_Report.Data.MisejectUnInsTabletCount = TabletInspectInfo.MisejectUnInsTabletCount;
		New_Report.Data.FRMisMatchTabletCount = TabletInspectInfo.FRMismatchTabletCount;
		New_Report.Data.LastDisStep= TabletInspectInfo.LastDisStep;

    char Temp[64]={0,};
    WideCharToMultiByte(CP_ACP,0,ProductData.ProductName.c_bstr(),-1,Temp,64,NULL,NULL);

		strncpy(New_Report.Data.ProductName, Temp, 64);

		if (InspectionOption.IsReInspection && InspectionOption.ReInspectionType != RE_INSPECTION_TYPE_NEW)
		{
			New_Report.Data.IsReIns = 1;
		}
		else
		{
			New_Report.Data.IsReIns = 0;
		}


    // GRADE
		New_Report.GradeData.ColorGrade = TabletGradeData_PC.front_color_Intensity;
		New_Report.GradeData.FrontNormalDirtyGrade = TabletGradeData_PC.front_dirty_Intensity;
		New_Report.GradeData.FrontPrintDirtyGrade = TabletGradeData_PC.front_print_dirty_Inetensity;
		New_Report.GradeData.FrontEdgeDirtyGrade = TabletGradeData_PC.front_edge_dirty_Intensity;
		New_Report.GradeData.FrontStainGrade = TabletGradeData_PC.front_stain_Intensity;
		New_Report.GradeData.FrontEdgeGrade = TabletGradeData_PC.front_edge_Intensity;
		New_Report.GradeData.FrontColorDirtyGrade = TabletGradeData_PC.front_Color_Dirty_Intensity;
		New_Report.GradeData.OptionBreakingGrade = TabletGradeData_PC.option_Breaking_Intensity;
		New_Report.GradeData.OptionFrontStickingGrade_Type1 = TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type1;
		New_Report.GradeData.OptionPrintMarkGrade = TabletGradeData_PC.option_PrintMark_Intensity;
		New_Report.GradeData.SideDirtyGrade = TabletGradeData_PC.side_dirty_Intensity;
		New_Report.GradeData.SideStainGrade = TabletGradeData_PC.side_stain_Intensity;
		New_Report.GradeData.SideHeightGrade = TabletGradeData_PC.side_height_Intensity;
		New_Report.GradeData.PrintEraseGrade = TabletGradeData_PC.front_print_erase_Intensity;
		New_Report.GradeData.PrintSpreadGrade = TabletGradeData_PC.front_print_spread_Intensity;
		New_Report.GradeData.SideColorDirtyGrade = TabletGradeData_PC.side_Color_Dirty_Intensity;
		New_Report.GradeData.ThreeDHeightMinusLimit = TabletGradeData_PC.threeD_Height_Minus_Limit;
		New_Report.GradeData.ThreeDHeightPlusLimit = TabletGradeData_PC.threeD_Height_Plus_Limit;
		New_Report.GradeData.FrontNormalDirtySize = TabletGradeData_PC.front_dirty_Size;
		New_Report.GradeData.FrontEdgeDirtySize = TabletGradeData_PC.front_edge_dirty_Size;
		New_Report.GradeData.FrontStainSize = TabletGradeData_PC.front_stain_Size;
		New_Report.GradeData.FrontEdgeSize = TabletGradeData_PC.front_edge_Size;
		New_Report.GradeData.FrontColorDirtySize = TabletGradeData_PC.front_Color_Dirty_Size;
		New_Report.GradeData.SideDirtySize = TabletGradeData_PC.side_dirty_Size;
		New_Report.GradeData.SideStainSize = TabletGradeData_PC.side_stain_Size;
		New_Report.GradeData.SideHeightSize = TabletGradeData_PC.threeD_Height_Minus_Limit;
		New_Report.GradeData.OptionBreakingSize = TabletGradeData_PC.option_Breaking_Size;
		New_Report.GradeData.OptionFrontStickingSize_Type1 = TabletGradeData_PC.option_front_edgeBreaking_Size_Type1;
		New_Report.GradeData.SideColorDirtySize = TabletGradeData_PC.side_Color_Dirty_Size;
		New_Report.GradeData.EngraveDistinguishGradeFor3D = TabletGradeData_PC.EngraveDistinguishGradeFor3D;
		New_Report.GradeData.Side_Edge_Neighbor_Intensity = TabletGradeData_PC.Side_Edge_Neighbor_Intensity;
		New_Report.GradeData.Side_Edge_Neighbor_Defect_Size = TabletGradeData_PC.Side_Edge_Neighbor_Defect_Size;
		New_Report.GradeData.Side_Edge_Dark_Intensity = TabletGradeData_PC.Side_Edge_Dark_Intensity;
		New_Report.GradeData.Side_Edge_Dark_Defect_Size = TabletGradeData_PC.Side_Edge_Dark_Defect_Size;
		New_Report.GradeData.Side_Edge_Bright_Intensity = TabletGradeData_PC.Side_Edge_Bright_Intensity;
		New_Report.GradeData.Side_Edge_Bright_Defect_Size = TabletGradeData_PC.Side_Edge_Bright_Defect_Size;
		New_Report.GradeData.Side_Edge_Neighbor_Break_Intensity = TabletGradeData_PC.Side_Edge_Neighbor_Break_Intensity;
		New_Report.GradeData.Side_Edge_Neighbor_Break_Size = TabletGradeData_PC.Side_Edge_Neighbor_Break_Size;
		New_Report.GradeData.EngraveDistinguishGradeFor2D = TabletGradeData_PC.EngraveDistinguishGrade;
		New_Report.GradeData.EngravePositionDefectCheckSW = TabletGradeData_PC.EngravePositionDefectCheckSW;
    New_Report.GradeData.OptionFrontStickingGrade_Type2 = TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type2;
    New_Report.GradeData.OptionFrontStickingSize_Type2 = TabletGradeData_PC.option_front_edgeBreaking_Size_Type2;

    // DEFECT SERIES COUNT
    memcpy(New_Report.DefectSeriesCount.DefectSeriesCount,DefectSeriesCount,(MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int));
    // SUB
    New_Report.SubData.BatchEndFlag[0] = Prev_Report.SubData.BatchEndFlag[0];
		strncpy(New_Report.SubData.EndOperatorName, EndOperName.c_str(), 32);

		int speedControlIndex = MachineOperationInfo.SpeedIndex;
		New_Report.SubData.InDiskSpeed = MachineSetupData.ServoMotorData[BF_ID_MOTOR_INDEX].BaseSpeed * 60 / ProductData.MotorSpeedList[BF_ID_MOTOR_INDEX][speedControlIndex];
		New_Report.SubData.RotateGuideSpeed = MachineSetupData.ServoMotorData[BF_OD_IN_MOTOR_INDEX].BaseSpeed * 36 / ProductData.MotorSpeedList[BF_OD_IN_MOTOR_INDEX][speedControlIndex];
		New_Report.SubData.SucktionDiskSpeed = (int)(MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed * SUCTION_DISK_100P_RPM / ProductData.MotorSpeedList[SD1_MOTOR_INDEX][speedControlIndex]);


		// Backup 용 데이터 생성

		resultDir_Backup = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result_Backup";
		ForceDirectories(resultDir_Backup);
		resultFileName = resultDir_Backup + "\\" + ProductData.LOTName + ".dat";
		fileStream = NULL;
		currentLine = __LINE__;

    Create_Report_Data(New_Report,resultFileName);

		// 원본 데이터 생성
		resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result";
		ForceDirectories(resultDir);
		resultFileName = resultDir + "\\" + ProductData.LOTName + ".dat";
		fileStream = NULL;
		currentLine = __LINE__;

		Create_Report_Data(New_Report,resultFileName);

		// write throughput data
		throughputFileName = resultDir + "\\" + ProductData.LOTName + ".trp";
		fileStream = NULL;
		currentLine = __LINE__;
		fileStream = new TFileStream(throughputFileName, fmCreate);
		thorughputFileVerion = THROUGHPUT_FILE_VERSION;
		fileStream->Write(&thorughputFileVerion, sizeof(unsigned int));
		fileStream->Write(&ThroughputChartCount, sizeof(int));
		fileStream->Write(ThroughputChartList, ThroughputChartCount * sizeof(double));
		delete fileStream;

		ProductData.LastInspectionTime = Now();
		AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
		WriteProductData(fileName, ProductData);

		AnsiString tableFileName = ProgramPath.Product + "\\LookupTable.dat";
		TIniFile *iniFile = new TIniFile(tableFileName);
		if (iniFile)
		{
			iniFile->WriteFloat(ProductData.ProductName, "Last Inspection Time", ProductData.LastInspectionTime);
			delete iniFile;
		}

		bCalledWriteFunc = false;
	}
	catch (...)
	{
		bCalledWriteFunc = false;
		WritePCProgramErrorLog(this->Name, currentLine);

		if (fileStream) delete fileStream;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::LoadInspectResult(void)
{
  TFileStream *fileStream;
	AnsiString resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result";
	AnsiString resultFileName = resultDir + "\\" + ProductData.LOTName + ".dat";

  /*TTabletInspectReport tabletInspectReport;
  memset(&tabletInspectReport, 0, sizeof(TTabletInspectReport));*/

  memset(DefectSeriesCount, 0, (MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int));

  NFA_INSPECTION_REPORT_STRUCT Report;

  bool Result = Read_InspectionReportData(resultFileName,Report);

	//TFileStream *fileStream = new TFileStream(resultFileName, fmOpenRead);
  // DATA
	//fileStream->Read(&tabletInspectReport, sizeof(TTabletInspectReport));
  if(Result)
  {
    TabletInspectInfo.TotalTabletCount = Report.Data.TotalTabletCount;
    TabletInspectInfo.GoodTabletCount = Report.Data.GoodTabletCount;
    TabletInspectInfo.DefectTabletCount = Report.Data.DefectTabletCount;
    TabletInspectInfo.UnInsTabletCount = Report.Data.UnInsTabletCount;
    TabletInspectInfo.SPBProcessingNCTabletCount = Report.Data.SPBProcessingNCTabletCount;
    TabletInspectInfo.SPBTOTabletCount = Report.Data.SPBTOTabletCount;
    TabletInspectInfo.SPBUnInsTabletCount = Report.Data.SPBUnInsTabletCount;
    TabletInspectInfo.DisappearedTabletCount = Report.Data.DisappearedTabletCount;
    TabletInspectInfo.InsertedTabletCount = Report.Data.InsertedTabletCount;
    TabletInspectInfo.ClosedTabletUninsCount = Report.Data.ClosedTabletUninsCount;
    TabletInspectInfo.ClosedTabletDefectCount = Report.Data.ClosedTabletDefectCount;
    TabletInspectInfo.ClosedTabletCount = Report.Data.ClosedTabletCount;
    ElapsedTime = Report.Data.ElapsedTime / 24.0 / 3600.0;
    InspectionStartTime.Val = Report.Data.InspectionStartTime;

    TabletInspectInfo.UnPrintTabletCount = Report.Data.UnPrintTabletCount;
    TabletInspectInfo.PrintMisMatchCount = Report.Data.PrintMisMatchCount;
    TabletInspectInfo.WrongNumberTabletCount = Report.Data.WrongNumberTabletCount;
    TabletInspectInfo.NumberUndefTabletCount = Report.Data.NumberUndefTabletCount;
    TabletInspectInfo.CaptureNotReadyTabletCount = Report.Data.CaptureNotReadyTabletCount;
    TabletInspectInfo.BufferFullTabletCount = Report.Data.BufferFullTabletCount;
    TabletInspectInfo.CaptureTimoutTabletCount = Report.Data.CaptureTimoutTabletCount;
    TabletInspectInfo.ProcessingTimoutTabletCount = Report.Data.ProcessingTimoutTabletCount;
    TabletInspectInfo.CPBFullTabletCount = Report.Data.CPBFullTabletCount;
    TabletInspectInfo.ProcessingErrorTabletCount = Report.Data.ProcessingErrorTabletCount;

    TabletInspectInfo.UnInsTabletPositionCount = Report.Data.UnInsTabletPositionCount;
    TabletInspectInfo.UnInsBrightnessDropCount = Report.Data.UnInsBrightnessDropCount;
    TabletInspectInfo.UnInsBrightnessChaseCount = Report.Data.UnInsBrightnessChaseCount;

    TabletInspectInfo.Sensor1MisFeedingTabletCount = Report.Data.Sensor1MisFeedingTabletCount;
    TabletInspectInfo.Sensor2MisFeedingTabletCount = Report.Data.Sensor2MisFeedingTabletCount;
    TabletInspectInfo.Sensor1MultiTabletCount = Report.Data.Sensor1MultiTabletCount;
    TabletInspectInfo.Sensor2MultiTabletCount = Report.Data.Sensor2MultiTabletCount;
    TabletInspectInfo.NozzErrorDefectTabletCount = Report.Data.NozzErrorDefectTabletCount;
    TabletInspectInfo.NozzErrorUnInsTabletCount = Report.Data.NozzErrorUnInsTabletCount;
    TabletInspectInfo.CounterSensorTabletCount = Report.Data.CounterSensorTabletCount;
    TabletInspectInfo.MisejectActiveCount = Report.Data.MisejectActiveCount;
    TabletInspectInfo.GoodTabletLostCount = Report.Data.GoodTabletLostCount;
    TabletInspectInfo.MisejectTabletInsertCount = Report.Data.MisejectTabletInsertCount;
    TabletInspectInfo.MisejectTabletInsertCount = Report.Data.MisejectTabletInsertCount;
    TabletInspectInfo.MisejectUnInsTabletCount = Report.Data.MisejectUnInsTabletCount;
    TabletInspectInfo.FRMismatchTabletCount = Report.Data.FRMisMatchTabletCount;
    TabletInspectInfo.LastDisStep = Report.Data.LastDisStep;
    memcpy(DefectSeriesCount,Report.DefectSeriesCount.DefectSeriesCount,(MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int));
  }
  else
  {
    throw ("Report file data can't read");
  }


  // GRADE
	//TTabletInspectGradeData tabletInspectGradeData;
	//fileStream->Read(&tabletInspectGradeData, sizeof(TTabletInspectGradeData));

  /*int readingSize = fileStream->Size - (fileStream->Position + sizeof(TTabletInspectReportSub));
  int dataSize = sizeof(TTabletInspectReport) + sizeof(TTabletInspectGradeData) + (MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int) + sizeof(TTabletInspectReportSub);

  memset(DefectSeriesCount, 0, (MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int));
  if(fileStream->Size != dataSize)
  {
    fileStream->Read(DefectSeriesCount, readingSize);
  }
  else
  {
    fileStream->Read(DefectSeriesCount, (MAX_DEFECT_SERIES_COUNT + 1) * sizeof(int));
  }*/

  // SUB
	//TTabletInspectReportSub tabletInspectReportSub;
	//memset(&tabletInspectReportSub, 0, sizeof(TTabletInspectReportSub));
	//fileStream->Read(&tabletInspectReportSub, sizeof(TTabletInspectReportSub));

	//delete fileStream;
	fileStream = NULL;
	try
	{
		AnsiString throughputFileName = resultDir + "\\" + ProductData.LOTName + ".trp";
		if (!FileExists(throughputFileName)) throw Exception("Throughput File does not exist");
		fileStream = new TFileStream(throughputFileName, fmOpenRead);
		unsigned int thorughputFileVerion;
		fileStream->Read(&thorughputFileVerion, sizeof(unsigned int));
		if (thorughputFileVerion != THROUGHPUT_FILE_VERSION) throw Exception("Throughput File version is not matched");
		fileStream->Read(&ThroughputChartCount, sizeof(int));
		if (ThroughputChartCount <= 0) throw Exception("Wrong throughtput data count");
		if (ThroughputChartListSize == 0) ThroughputChartListSize = THROUGHPUT_CHART_DEFAULT_SIZE;
		while (ThroughputChartListSize <= ThroughputChartCount)
		{
			ThroughputChartListSize *= 2;
		}
		if (ThroughputChartList) delete[] ThroughputChartList;
		ThroughputChartList = new double[ThroughputChartListSize];
		fileStream->Read(ThroughputChartList, ThroughputChartCount * sizeof(double));
		delete fileStream;
	}
	catch (...)
	{
		if (fileStream) delete fileStream;

		if (ThroughputChartList) delete[] ThroughputChartList;
		ThroughputChartList = new double[THROUGHPUT_CHART_DEFAULT_SIZE];
		ThroughputChartListSize = THROUGHPUT_CHART_DEFAULT_SIZE;
		ThroughputChartCount = 0;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ConfirmSuspendStatus(void)
{
	// Inspection Info Timer Event
	Machine.ConfirmSuspend();

	InspectionStopOption = INSPECTION_STOP_OPTION_MACHINE_STOP;
	InspectState = INSPECTION_STATE_STOPPING;

	if (PCProgramOption.UVLaserEnabled && MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
		PcUiFlag.InsReady = 0;
		PcUiFlag.InsActive = 0;
		Machine.SetUIFlagData();
	}

  InspectionStopButton->Enabled = false;

	if (!bSuspendCheck)
	{
		StopInfoPanel->Visible = true;
		bSuspendCheck = true;

		if (SimulationInspectionCheckBox->Checked)
		{
			Comm_Request(COMM_HCB, CMD_VIRTUAL_INSPECTION_END, NULL, 0);

			for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
			{
				Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_DEBUGGING_DATA5);
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionMachineStop(void)
{
	// 해당사항 없음
	Machine.MachineStop();
	InspectionStopOption = INSPECTION_STOP_OPTION_MACHINE_STOP;
	InspectState = INSPECTION_STATE_STOPPING;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionStop(void)
{
	// CLOSE 버튼, Form destroy Event
	Machine.MachineStop();
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (!Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_END))
		{
			//ShowMessageW(SPBConnection[spbIndex].GetLastErrorMessage());
		}
	}

	if (!Comm_Request(COMM_HCB, CMD_INSPECTION_END))
	{
		//ShowMessageFA(HCBConnection.GetLastErrorMessage());
	}
	UploadRealtimeCapturedImageTimer->Enabled = false;
	HCBMonitoringTimer->Enabled = false;
	InspectionStopOption = INSPECTION_STOP_OPTION_INSPECTION_STOP;
	InspectState = INSPECTION_STATE_STOPPING;

	// save inspect info
	if (!bCalledWriteFunc)
	{
		/*if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
		{
		if(!TestMode)
		SaveInspectResult();
		}
		else */
		SaveInspectResult();
	}
	InspectionStop_count = 0;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionRestart(void)
{
	InspectState = INSPECTION_STATE_START;
	InspectionStartButton->Enabled = false;
	InspectionRestartButton->Enabled = false;
	InspectionStopButton->Enabled = true;
	CloseBitBtn->Enabled = false;
  CameraTestButton->Enabled = false;
	StopInfoPanel->Visible = false;
	InspectionCompleteTime.Val = 0;
	
	LoadInspectResult();

	MakeHCBInspectionOption(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][MachineOperationInfo.SpeedIndex]);
  HCBInspectionOption.StartType = 1;
	//한국콜마 공압2분배기 For 뉴트리제약.
	/*if(MachineSetupData.CompanyID== INTERNATIONAL_MACHINE1 &&  (PCProgramOption.UVLaserDownstreamEnabled||PCProgramOption.UVLaserUpstreamEnabled))
	{
		HCBInspectionOption.StartType = 1;
		LoadInspectResult();
		if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_REINS1) // 미선별 재검사
		{
			ClearUninspectedTabletCount();

			memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
			DefectTabletNumIndex = 0;
		}
		else if (InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_REINS2) // 불량 +미선별 재검사
		{
			// clear defect tablet count
			ClearDefectTabletCount();
			ClearUninspectedTabletCount();

			DeleteInspectResult();
			ClearDefectInfoList();

			memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
			DefectTabletNumIndex = 0;
		}
		LastCheckedTime = Now().Val;
		prevtimeForUninsCheck = Now().Val;

		bSetPrevCount = false;
		bUninsMachineStopSW = false;
	}
	else 
	{
		HCBInspectionOption.StartType = 0;
	}*/

	struct
	{
		THCBInspectionOption InspectionOption;
		TTabletInspectInfo TabletInspectInfo;
	} hcbInspectionData;

	memcpy(&hcbInspectionData.InspectionOption, &HCBInspectionOption, sizeof(THCBInspectionOption));
	memcpy(&hcbInspectionData.TabletInspectInfo, &TabletInspectInfo, sizeof(TTabletInspectInfo));

	if (!Comm_Request(COMM_HCB, CMD_INSPECTION_READY, &hcbInspectionData, sizeof(hcbInspectionData)))
	{
		//ShowMessageFA(HCBConnection.GetLastErrorMessage());
	}

	int speedControlIndex = MachineOperationInfo.SpeedIndex;
	SendInspectionReadyCommand(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][speedControlIndex], MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed,
		ProductData.MotorSpeedList[SD2_MOTOR_INDEX][speedControlIndex], MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed, InspectionOption.CameraEnabled);

	int motorSpeedList[MAX_SERVO_MOTOR_COUNT];
	for (int motorIndex = 0; motorIndex < MAX_SERVO_MOTOR_COUNT; motorIndex++)
	{
		motorSpeedList[motorIndex] = ProductData.MotorSpeedList[motorIndex][speedControlIndex];
	}

	Machine.MachineRun(PROCEDURE_MODE_INSPECTION, &ProductData.MachineRunOption, ProductData.NCMotorPos, motorSpeedList);

	//	TimerCount = 0;
	TabletInspectInfo_Begin = TabletInspectInfo;

  /*char ProductName_Temp[128] = {0,};
  char LotName_Temp[128] = {0,};

  WideCharToMultiByte(CP_ACP,0,ProductData.ProductName.c_bstr(),-1,ProductName_Temp,128,NULL,NULL);
  WideCharToMultiByte(CP_ACP,0,ProductData.LOTName.c_bstr(),-1,LotName_Temp,128,NULL,NULL);*/

	AddCSVActionLog(ECSV_ACTION_INSPECTION_RESTART, UserInfo.Name,  ProductData.ProductName, AnsiString(ProductData.LOTName).c_str(),AnsiString(ProductData.LOTName).Length()+1);
	//AddCSVActionLog(ECSV_ACTION_INSPECTION_RESTART, UserInfo.Name,  ProductData.ProductName, (unsigned char*)&T_LotName,sizeof(T_LotName));

	LastCheckedTime = Now().Val;
  prevtimeForUninsCheck = Now().Val;
  bSetPrevCount = false;
  bUninsMachineStopSW = false;

  StandbyHCBMonitoring();

	DefectedTabletList.clear();
	LastCheckedTabletNumber = 0;
	LastDefectSeriesCheckedTabletNumber = 0;
	ClearDefectInfoHeap();
	InspectionResultTimer->Enabled = true;
	DefectCheckTimer->Enabled = true;
	InspectionInfoTimer->Enabled = true;
	if (UserInfo.AccessLevel == SYSTEM_HIGHEST_ACCESS_LEVEL)
	{
		UploadRealtimeCapturedImageTimer->Enabled = true;
		HCBMonitoringTimer->Enabled = true;
	}
	else
	{
		UploadRealtimeCapturedImageTimer->Enabled = false;
		HCBMonitoringTimer->Enabled = false;
	}
	RTTabletMinNumber = 0xF0000000;
	RTTabletMaxNumber = 0;
	
	AlarmForm->WarningSleep = false;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionResume(void)
{

}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionStopButtonClick(TObject *Sender)
{
	//InspectionMachineStop();
  wait_stop_step = 0;
	StopInfoPanel->Visible = true;
	InspectionPause();
	InspectionStop_flag = true;
	InspectionStop_count = 0;

	//sjm TCPIP
	if (TcpSndFlag == True)
	{
		//MODUS_HEAD.transaction_id1 	= 0;
		//MODUS_HEAD.transaction_id2 	= 0;
		MODUS_HEAD.protocol_id1 = 0;
		MODUS_HEAD.protocol_id2 = 0;
		MODUS_HEAD.length1 = 0;
		MODUS_HEAD.unit_id = 0;
		MODUS_HEAD.function_code = "R";
		if (CurrentTPH < 0) CurrentTPH = 0;

		MODUS_HEAD.length2 = CommControlForm->TxDatalength(MODUS_HEAD.function_code
			+ "G" + GoodTabletCountLabel->Caption
			+ "D" + DefectTabletCountLabel->Caption
			+ "U" + UnInsTabletCountLabel->Caption
			+ "S" + IntToStr(CurrentTPH)
			+ "E") + 1;
		CommControlForm->TxDataToTcp(IntToStr(MODUS_HEAD.transaction_id1)
			+ IntToStr(MODUS_HEAD.transaction_id2)
			+ IntToStr(MODUS_HEAD.protocol_id1)
			+ IntToStr(MODUS_HEAD.protocol_id2)
			+ IntToStr(MODUS_HEAD.length1)
			+ IntToStr(MODUS_HEAD.length2)
			+ IntToStr(MODUS_HEAD.unit_id)
			+ MODUS_HEAD.function_code
			+ "G" + GoodTabletCountLabel->Caption
			+ "D" + DefectTabletCountLabel->Caption
			+ "U" + UnInsTabletCountLabel->Caption
			+ "S" + IntToStr(CurrentTPH)
			+ "E");
	}
	//TcpSndFlag = false;		//sjm TCPIP
	TcpSndTimer1->Enabled = false; //TCPIP
	if (SimulationInspectionCheckBox->Checked)
	{
		if (InspectState == INSPECTION_STATE_STOPPING)// && Machine.Status.OperationState == MACHINE_STATE_STOP)
		{
			// 불량이미지가 모두 올라오지 않은상태에서 이쪽으로 빠지는 경우 불량이미지를 모두 폐기함
			// Machine이 Stop 상태인데 InspectState가 STOPPING 상태라는 것은 DefectCheckTimer 에서 정상적으로 State 처리가 되지 않았다는 것을 의미함
			// < 검사 중지 프로세스 >
			// 피더 안에 약이 없는 경우 InspectionInfoTimer에서 검사 중지 처리하게 됨
			// 이때 InspectState은 INSPECTION_STATE_STOPPING으로 세팅 됨
			// DefectInfoTimer에서 불량 이미지가 모두 올라온 경우 InspectState가 STOP으로 세팅하면서 버튼을 Enable 시키고 타이머가 false 상태가 되어야함
			// (검사 중지 버튼을 누른 경우 InspectState은 INSPECTION_STATE_MACHINE_STOP으로 세팅 됨)

			InspectionResultTimer->Enabled = false;
			DefectCheckTimer->Enabled = false;
			InspectionInfoTimer->Enabled = false;

			InspectState = INSPECTION_STATE_STOP;

			if (!bCalledWriteFunc)
			{
				/*if(MachineSetupData.CompanyID== INTERNATIONAL_MACHINE2)
				{
				if(!TestMode)
				SaveInspectResult();
				}
				else */
				SaveInspectResult();
			}

			int inspectionCount[4];
			inspectionCount[0] = TabletInspectInfo.TotalTabletCount - TabletInspectInfo_Begin.TotalTabletCount;
			inspectionCount[1] = TabletInspectInfo.GoodTabletCount - TabletInspectInfo_Begin.GoodTabletCount;
			inspectionCount[2] = TabletInspectInfo.DefectTabletCount - TabletInspectInfo_Begin.DefectTabletCount;
			inspectionCount[3] = TabletInspectInfo.UnInsTabletCount - TabletInspectInfo_Begin.UnInsTabletCount;

			AddCSVActionLog(ECSV_ACTION_INSPECTION_PAUSE, UserInfo.Name, ProductData.ProductName, (unsigned char *)inspectionCount, 4 * sizeof(unsigned int));

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

			InspectionStartButton->Enabled = true;
			SpeedControlButton->Enabled = true;

      InspectionStartButton->Enabled = true;
      SpeedControlButton->Enabled = true;
      InspectionStopButton->Enabled = false;
      StopInfoPanel->Visible = false;
      InspectionRestartButton->Enabled = true;
      CloseBitBtn->Enabled = true;
      CameraTestButton->Enabled = true;

      LastUVLaserStatus[0] = 0;
      LastUVLaserStatus[1] = 0;
	
			StopInfoPanel->Visible = false;
		}
	}
	else
	{
		if (InspectState == INSPECTION_STATE_STOPPING && Machine.Status.OperationState == MACHINE_STATE_STOP)
		{
			// 불량이미지가 모두 올라오지 않은상태에서 이쪽으로 빠지는 경우 불량이미지를 모두 폐기함
			// Machine이 Stop 상태인데 InspectState가 STOPPING 상태라는 것은 DefectCheckTimer 에서 정상적으로 State 처리가 되지 않았다는 것을 의미함
			// < 검사 중지 프로세스 >
			// 피더 안에 약이 없는 경우 InspectionInfoTimer에서 검사 중지 처리하게 됨
			// 이때 InspectState은 INSPECTION_STATE_STOPPING으로 세팅 됨
			// DefectInfoTimer에서 불량 이미지가 모두 올라온 경우 InspectState가 STOP으로 세팅하면서 버튼을 Enable 시키고 타이머가 false 상태가 되어야함
			// (검사 중지 버튼을 누른 경우 InspectState은 INSPECTION_STATE_MACHINE_STOP으로 세팅 됨)

			InspectionResultTimer->Enabled = false;
			DefectCheckTimer->Enabled = false;
			InspectionInfoTimer->Enabled = false;

			InspectState = INSPECTION_STATE_STOP;

			if (!bCalledWriteFunc)
			{
				/*if(MachineSetupData.CompanyID== INTERNATIONAL_MACHINE2)
				{
				if(!TestMode)
				SaveInspectResult();
				}
				else */
				SaveInspectResult();
			}

			int inspectionCount[4];
			inspectionCount[0] = TabletInspectInfo.TotalTabletCount - TabletInspectInfo_Begin.TotalTabletCount;
			inspectionCount[1] = TabletInspectInfo.GoodTabletCount - TabletInspectInfo_Begin.GoodTabletCount;
			inspectionCount[2] = TabletInspectInfo.DefectTabletCount - TabletInspectInfo_Begin.DefectTabletCount;
			inspectionCount[3] = TabletInspectInfo.UnInsTabletCount - TabletInspectInfo_Begin.UnInsTabletCount;

			AddCSVActionLog(ECSV_ACTION_INSPECTION_PAUSE, UserInfo.Name, ProductData.ProductName, (unsigned char *)inspectionCount, 4 * sizeof(unsigned int));

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

			InspectionStartButton->Enabled = true;
			SpeedControlButton->Enabled = true;
			InspectionStartButton->Enabled = true;
			SpeedControlButton->Enabled = true;
			InspectionStopButton->Enabled = false;
			StopInfoPanel->Visible = false;
			InspectionRestartButton->Enabled = true;
			CloseBitBtn->Enabled = true;
			CameraTestButton->Enabled = true;
			UploadRealtimeCapturedImageTimer->Enabled = false;
			HCBMonitoringTimer->Enabled = false;
			LastUVLaserStatus[0] = 0;
			LastUVLaserStatus[1] = 0;
		}
	}

	if (SimulationInspectionCheckBox->Checked)
	{
		Comm_Request(COMM_HCB, CMD_VIRTUAL_INSPECTION_END, NULL, 0);

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

  if (PCProgramOption.UVLaserEnabled && MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
		InspectionStartStep = 0;
		PcUiFlag.InsReady = 0;
		PcUiFlag.InsActive = 0;
		Machine.SetUIFlagData();

		GradeSettingButton->Enabled = true;
		SpeedControlButton->Enabled = true;
		NCControlButton->Enabled = true;

		if (SuccessRun != true)
		{
			StopInfoPanel->Visible = false;
			InspectionStartButton->Enabled = true;
			SpeedControlButton->Enabled = true;
			InspectionStopButton->Enabled = false;

			InspectionRestartButton->Enabled = true;
			NCControlButton->Enabled = true;
			GradeSettingButton->Enabled = true;
			CloseBitBtn->Enabled = true;
      CameraTestButton->Enabled = true;
		}

		/*for(int i = 0; i < 4 ; ++i)
		{
		LastUVLaserStatus[i] = 0;
		}*/
	}
  else if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    UVLaser.SELMAStatus.Ready = 0;
    UVLaser.SELMAStatus.Active = 0;
  }
	SuccessRun = false;
}

void __fastcall TInspectionForm::InspectionWaitStop(int type)
{
  //type = INSPECTION_STATE_WAIT_STOP_RESUME 
  //wait_stop_step = INSPECTION_STATE_WAIT_STOP1
  bool Breakout = false;
  if(wait_stop_step == 0)
  {
    if(type ==  INSPECTION_STATE_WAIT_STOP_RESUME)
      Breakout = true;
  }
  else
  {
     if(type != INSPECTION_STATE_WAIT_STOP_RESUME)
      Breakout = true;
  }

  if(Breakout == false)
  {
    Comm_Request(COMM_HCB, CMD_INSPECTION_WAITSTOP, &type, sizeof(int));
    if(type == INSPECTION_STATE_WAIT_STOP1|| type == INSPECTION_STATE_WAIT_STOP2)
    {
      wait_stop_step = type;
      UVLaser.SELMAStatus.Ready = 1;
      UVLaser.SELMAStatus.Active = 0;
    }
    else
    {
      wait_stop_step = 0;
      UVLaser.SELMAStatus.Ready = 0;
      UVLaser.SELMAStatus.Active = 1;
    }
  }



}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::FormDestroy(TObject *Sender)
{
	if (InspectState != INSPECTION_STATE_STOP)
	{
		InspectionStop();
	}
	delete SubDefectInfoForm;

	if (ThroughputChartList) delete[] ThroughputChartList;

	delete Current3DBitmap;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ShowImageButtonClick(TObject *Sender)
{
	if (IsChartView)
	{
		if(InspectionStopButton->Enabled == false)
			SubDefectInfoForm->InitDefectInfo(ProductData.ProductCode, ProductData.LOTName);
		else
			SubDefectInfoForm->InitDefectInfo(ProductData.ProductCode, ProductData.LOTName,0,true);

		SubDefectInfoForm->Show();
		IsChartView = false;
		ShowImageButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_15;
	}
	else
	{
		SubDefectInfoForm->Hide();
		IsChartView = true;
		ShowImageButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_11;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ThroughPutChartSpeedButtonClick(TObject *Sender)
{
	DefectRatioChartLabel->Font->Color = clBlack;
	ThroughPutChartLabel->Font->Color = clBlue;
	VibratorInfoLabel->Font->Color = clBlack;
	ThroughputPanel->Visible = true;
	DefectRatioPanel->Visible = false;
	VibratorInfoPanel->Visible = false;
	VibratorInfoTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::DefectRatioChartSpeedButtonClick(TObject *Sender)
{
	ThroughPutChartLabel->Font->Color = clBlack;
	DefectRatioChartLabel->Font->Color = clBlue;
	VibratorInfoLabel->Font->Color = clBlack;
	DefectRatioPanel->Visible = true;
	ThroughputPanel->Visible = false;
	VibratorInfoPanel->Visible = false;
	VibratorInfoTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::InspectChartSpeedButtonClick(
	TObject *Sender)
{
	CountCheckLabel->Font->Color = clBlack;
	InspectChartLabel->Font->Color = clBlue;
	MisejectSpeedButton->Font->Color = clBlack;
	EjectorSettingLabel->Font->Color = clBlack;
  SimulationButton->Font->Color = clBlack;

	InspectionCountInfoPanel->Visible = false;
	InspectChartPanel->Visible = true;
	MisejectInfoPanel->Visible = false;
	EjectorSettingPanel->Visible = false;
  SimulationPanel->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::CountCheckSpeedButtonClick(
	TObject *Sender)
{
	CountCheckLabel->Font->Color = clBlue;
	InspectChartLabel->Font->Color = clBlack;
	MisejectSpeedButton->Font->Color = clBlack;
	EjectorSettingLabel->Font->Color = clBlack;
  SimulationButton->Font->Color = clBlack;

	InspectionCountInfoPanel->Visible = true;
	InspectChartPanel->Visible = false;
	MisejectInfoPanel->Visible = false;
	EjectorSettingPanel->Visible = false;
  SimulationPanel->Visible = false;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DeleteInspectResult(bool bDefectReIns)
{
	AnsiString defectDir = GetDefectDataPath(ProductData.ProductCode, ProductData.LOTName);
	if (DirectoryExists(defectDir))
	{
		TSearchRec sr;
		int iAttributes = faAnyFile & (~faDirectory);
		if (FindFirst(defectDir + "\\*.*", iAttributes, sr) == 0)
		{
			do
			{
				if ((sr.Attr & iAttributes) == sr.Attr)
				{
					DeleteFile(defectDir + "\\" + sr.Name);
				}
			} while (FindNext(sr) == 0);
			FindClose(sr);
		}
	}

	DefectDataDB.CleanDefectData();

  if(!bDefectReIns)
  {
    // delete throughput chart
    if (ThroughputChartListSize != THROUGHPUT_CHART_DEFAULT_SIZE)
    {
      if (ThroughputChartList) delete[] ThroughputChartList;
      ThroughputChartList = new double[THROUGHPUT_CHART_DEFAULT_SIZE];
      ThroughputChartListSize = THROUGHPUT_CHART_DEFAULT_SIZE;
    }
    ThroughputChartCount = 0;
  }
}
//--------------------------------------------------------------------------
void __fastcall TInspectionForm::CloseBitBtnClick(TObject *Sender)
{
	if (MessageDlgFA(INSPECTIONFORM_MSG_05, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
	{
		if (InspectState != INSPECTION_STATE_STOP)
		{
			Machine.VFStartSpeedMode(300);
			InspectionStop();
		}
		ModalResult = mrCancel;
	}

	AppOnOffFlag = false;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::InspectionRestartButtonClick(
	TObject *Sender)
{

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
  {
    if(AjantaFormInitCheck == false)
    {
      InspectionStartButton->Click();
      return;
    }
  }	
  	InspectionStop_flag = false;
	InspectionStop_count = 0;

	// 이미지 영역 확인
	bool bErrorCamera[SYSTEM_TOTAL_CAMERA_COUNT];
	if (checkCameraArea(&ProductData, bErrorCamera))
	{
		AnsiString ErrorString;
		AnsiString nextString;
		ErrorString = "Incorrect Camera Area (CAM No.";

		int errorCameraCount = 0;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (bErrorCamera[globalCameraIndex]) errorCameraCount++;
		}

		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			if (bErrorCamera[globalCameraIndex])
			{
				errorCameraCount--;
				if (errorCameraCount)
				{
					ErrorString += IntToStr(globalCameraIndex + 1) + ", ";
				}
				else
				{
					ErrorString += IntToStr(globalCameraIndex + 1) + ")";
				}
			}
		}

		ShowMessageFA(ErrorString);
		return;
	}
	//// end

	if (!SimulationInspectionCheckBox->Checked)
	{
		if (PCProgramOption.HIprogram)
		{
			if (!TabletGradeData_PC.EngravePositionDefectCheckSW)
			{
				ShowMessageFA(INSPECTIONFORM_MSG_26); // For SELMA200, 다국어 수정 필요
				return;
			}
		}

    if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
      if(MachineSetupData.InterlockInfo.ACdomesticMode)
      {
        if (MachineSetupData.InterlockInfo.DoorInterlockEnabled)
        {
          if (!Machine.InterlockCheck())
          {
            ShowMessageFA(Machine.GetInterlockMessage());
            LinkSignalInit();
            return;
          }
        }
      }
      else
      {
        if(!Machine.PortStatus.IPStatus[OP_SAFETY_CIRCUIT_SELECT])
        {
          if (!Machine.InterlockCheck())
          {
            ShowMessageFA(Machine.GetInterlockMessage());
            LinkSignalInit();
            return;
          }
        }
      }
    }
    else
    {
      if (MachineSetupData.InterlockInfo.DoorInterlockEnabled)
      {
        if (!Machine.InterlockCheck())
        {
          ShowMessageFA(Machine.GetInterlockMessage());
          LinkSignalInit();
          return;
        }
      }
    }

		if (!Machine.CanInspectionStart(ProductData.LampKind))
		{
			ShowMessageFA(Machine.GetInspectionStartFailMessage(ProductData.LampKind));
			return;
		}
	

		if (!Machine.CanInspectionStart(ProductData.LampKind))
		{
			ShowMessageFA(Machine.GetInspectionStartFailMessage(ProductData.LampKind));
			return;
		}
	}
	int tempInspectionSetupSW = CPBSetupInfo.InspectionSetupDataValid;

	if (!SendInspectionSetupData())
	{
		return;
	}

	if (tempInspectionSetupSW == false)
	{
		WaitingForm->SetMessage(MAINFORM_MSG_13);
		WaitingForm->Show();
    Application->ProcessMessages();
		SubDefectInfoForm->RefreshInspectionSetupData();

		WaitingForm->Hide();
	}

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

  TPBActiveCheckBox->Enabled = false;
  if(TPBActiveCheckBox->Checked)
  {
    bExecuteTPB = true;
    TPBCameraSettingForm->CaptureTrigger = true;
  }

	ColorCountClear_Func(); //for PC_SIM

	Machine.VFStartSpeedMode(BeforeSpeed);

	DHStartFlag = false;

	TcpSndTimer1->Enabled = true; //TCPIP
	
	if (SimulationInspectionCheckBox->Checked)
	{
		SetSPBVirtualInspectionImage();

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

		int buff;

		buff = StrToInt(Edit2->Text);

		Comm_Request(COMM_HCB, CMD_ALARM_RESET);
		Comm_Request(COMM_HCB, CMD_VIRTUAL_INSPECTION_START, &buff, sizeof(int));
	}

	if((PCProgramOption.DHprogram == true) && (PCProgramOption.DistributorType4 == 1) && (InspectionOption.SpecialInsCheckbox == 1))
	{
		int checkDistributor = 0;

		if(Comm_Request(COMM_HCB, CMD_READ_DISTRIBUTOR_SIGNAL, NULL, 0, &checkDistributor, sizeof(int)))
		{

		}
		else
		{
			checkDistributor = 1;
		}

		if(checkDistributor == 1)
		{
			return;
		}
	}  	
	
	InspectionRestart();

  ClearLaserMonitoringData();
  for(int i = LaserMonitoringStringGrid->FixedRows; i < LaserMonitoringStringGrid->RowCount; ++i)
  {
    LaserMonitoringStringGrid->Rows[i]->Clear();
  }
  LaserMonitoringStringGrid->RowCount = 2;
  
	MarkingInfoPagePanel->Visible = false;
	TPHCheckTabletCount = TabletInspectInfo.TotalTabletCount;
	LastTPHCheckedTime = Now().Val;
	
	if ( MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
	{
    last_vb_sensor_value = Machine.PortStatus.IPStatus[IP_VB_SENSOR];
    Using_CaptuerSensorTimer = false;
    SD2CaptureSensor_UITimer = 0;
		UVLaser.SELMAStatus.Active = 1;
		UVLaser.SELMAStatus.Ready = 0;
		last_inspection_good_count = TabletInspectInfo.GoodTabletCount - ProductData.DischargeCount;
	}
	
	bSuspendCheck = false;
	if (!IsChartView)
		ShowImageButton->Click();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::SystemTimeTimerTimer(TObject *Sender)
{
	DateTimeLabel->Caption = Now().DateTimeString();

	CheckMachineState();

	if ((InspectionInfoTimer->Enabled == false) && (StopInfoPanel->Visible == true))
	{
    if(DefectCheckTimer->Enabled == false)
    {
      if (InspectionCompleteTime.Val)
      {
        TDateTime diff;
        unsigned short h, m, s, ms;
        diff = Now().Val - InspectionCompleteTime.Val;
        diff.DecodeTime(&h, &m, &s, &ms);
        if (ms > 250)
        {
          InspectionStartButton->Enabled = true;
          SpeedControlButton->Enabled = true;
          InspectionStopButton->Enabled = false;
          StopInfoPanel->Visible = false;
          InspectionRestartButton->Enabled = true;
          CloseBitBtn->Enabled = true;
          CameraTestButton->Enabled = true;
          InspectionCompleteTime.Val = 0;

          LastUVLaserStatus[0] = 0;
          LastUVLaserStatus[1] = 0;

          if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1 )
          {
            UVLaser.SELMAStatus.Ready = 0;
            UVLaser.SELMAStatus.Active = 0;
            wait_stop_step = 0;
          }
        }
      }
    }
    
	 if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
	 {
	     if (Machine.Status.OperationState == MACHINE_STATE_STOP || Machine.Status.OperationState == MACHINE_STATE_EMERGENCY_STOP)
	     {
		     	StopInfoPanel->Visible = false;
		     	InspectionStartButton->Enabled = true;
		     	InspectionStopButton->Enabled = false;
		     	InspectionRestartButton->Enabled = true;
	     }
     }    
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearDefectInfoList(void)
{
	for (int defectIndex = 0; defectIndex < MAX_DEFECT_SERIES_COUNT + 1; defectIndex++)
	{
		DefectSeriesCount[defectIndex] = 0;
	}

	RefreshDefectsInfo();
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::Panel5DblClick(TObject *Sender)
{
	if (UserInfo.AccessLevel == SYSTEM_HIGHEST_ACCESS_LEVEL)
	{
		TMachineControlForm *machineControlForm = new TMachineControlForm(this);
		machineControlForm->ShowModal();
		delete machineControlForm;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DefectDataInfoPanelResize(TObject *Sender)
{
	DefectDataStringGrid->ColWidths[1] = DefectDataStringGrid->ClientWidth - DefectDataStringGrid->ColWidths[0] - 1;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DisplayGradeInfo(void)
{

	FrontDirtyGradeInfoStringGrid->RowCount = 4;
	FrontDirtyGradeInfoStringGrid->ColCount = 3;
	FrontDirtyGradeInfoStringGrid->ColWidths[0] = 150;
	FrontDirtyGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	FrontDirtyGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	FrontDirtyGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

	FrontDirtyGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_STRGRID_CELL_16;
	FrontDirtyGradeInfoStringGrid->Cells[0][2] = INSPECTIONFORM_STRGRID_CELL_01;
	FrontDirtyGradeInfoStringGrid->Cells[0][3] = INSPECTIONFORM_STRGRID_CELL_06;
	FrontDirtyGradeInfoStringGrid->Cells[1][1] = IntToStr(TabletGradeData_PC.front_dirty_Intensity);
	FrontDirtyGradeInfoStringGrid->Cells[2][1] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.front_dirty_Size) / 100.0) + "mm";
	FrontDirtyGradeInfoStringGrid->Cells[1][2] = IntToStr(TabletGradeData_PC.front_print_dirty_Inetensity);
	FrontDirtyGradeInfoStringGrid->Cells[1][3] = IntToStr(TabletGradeData_PC.front_edge_dirty_Intensity);
	FrontDirtyGradeInfoStringGrid->Cells[2][3] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.front_edge_dirty_Size) / 100.0) + "mm";

	FrontStainGradeInfoStringGrid->RowCount = 4;
	FrontStainGradeInfoStringGrid->ColCount = 3;
	FrontStainGradeInfoStringGrid->ColWidths[0] = 150;
	FrontStainGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	FrontStainGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	FrontStainGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

	FrontStainGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_STRGRID_CELL_16;
	FrontStainGradeInfoStringGrid->Cells[0][2] = INSPECTIONFORM_STRGRID_CELL_06;
	FrontStainGradeInfoStringGrid->Cells[0][3] = INSPECTIONFORM_STRGRID_CELL_09;
	FrontStainGradeInfoStringGrid->Cells[1][1] = IntToStr(TabletGradeData_PC.front_stain_Intensity);
	FrontStainGradeInfoStringGrid->Cells[2][1] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.front_stain_Size) / 100.0) + "mm";
	FrontStainGradeInfoStringGrid->Cells[1][2] = IntToStr(TabletGradeData_PC.front_edge_Intensity);
	FrontStainGradeInfoStringGrid->Cells[2][2] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.front_edge_Size) / 100.0) + "mm";
	FrontStainGradeInfoStringGrid->Cells[1][3] = IntToStr(TabletGradeData_PC.front_Color_Dirty_Intensity);
	FrontStainGradeInfoStringGrid->Cells[2][3] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.front_Color_Dirty_Size) / 100.0) + "mm";

	PrintGradeInfoStringGrid->RowCount = 2;
	PrintGradeInfoStringGrid->ColCount = 3;
	PrintGradeInfoStringGrid->ColWidths[0] = 150;
	PrintGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	PrintGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	PrintGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

	PrintGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_STRGRID_CELL_15;
	PrintGradeInfoStringGrid->Cells[1][1] = FloatToStr(DefectSizePixelToMili((TabletGradeData_PC.front_print_erase_Intensity + 1) * (TabletGradeData_PC.front_print_erase_Intensity)) / 100.0) + " mm";

	ThreeDCameraGradeInfoStringGrid->RowCount = 6;
	ThreeDCameraGradeInfoStringGrid->ColCount = 3;
	ThreeDCameraGradeInfoStringGrid->ColWidths[0] = 245;
	ThreeDCameraGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	ThreeDCameraGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	ThreeDCameraGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

	ThreeDCameraGradeInfoStringGrid->Cells[0][1] = GRADESETTING_BUTTON_CAPTION_04;
  ThreeDCameraGradeInfoStringGrid->Cells[0][2] = GRADESETTING_BUTTON_CAPTION_03;
	ThreeDCameraGradeInfoStringGrid->Cells[0][3] = GRADESETTING_TEXT_CAPTION_11;
	ThreeDCameraGradeInfoStringGrid->Cells[0][4] = INSPECTIONFORM_STRGRID_CELL_02;
	ThreeDCameraGradeInfoStringGrid->Cells[0][5] = INSPECTIONFORM_STRGRID_CELL_05;

	ThreeDCameraGradeInfoStringGrid->Cells[1][1] = FloatToStr((float)TabletGradeData_PC.option_Breaking_Intensity*30.0 / 10.0 / 1000.0) + "mm";//IntToStr(TabletGradeData_PC.option_Breaking_Intensity);
	ThreeDCameraGradeInfoStringGrid->Cells[2][1] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.option_Breaking_Size) / 100.0) + "mm";

	ThreeDCameraGradeInfoStringGrid->Cells[1][2] = FloatToStr((float)TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type1*30.0 / 10.0 / 1000.0) + "mm";//IntToStr(TabletGradeData_PC.option_front_sticking_Intensity);
	ThreeDCameraGradeInfoStringGrid->Cells[2][2] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.option_front_edgeBreaking_Size_Type1) / 100.0) + "mm";

  ThreeDCameraGradeInfoStringGrid->Cells[1][3] = FloatToStr((float)TabletGradeData_PC.option_front_edgeBreaking_Intensity_Type2*30.0 / 10.0 / 1000.0) + "mm";//IntToStr(TabletGradeData_PC.option_front_sticking_Intensity);
	ThreeDCameraGradeInfoStringGrid->Cells[2][3] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.option_front_edgeBreaking_Size_Type2) / 100.0) + "mm";

	ThreeDCameraGradeInfoStringGrid->Cells[1][4] = IntToStr(TabletGradeData_PC.option_PrintMark_Intensity);
	ThreeDCameraGradeInfoStringGrid->Cells[2][4] = FloatToStr((float)TabletGradeData_PC.EngraveDistinguishGradeFor3D*30.0 / 10.0 / 100.0) + "mm";
	ThreeDCameraGradeInfoStringGrid->Cells[1][5] = FloatToStr((float)TabletGradeData_PC.threeD_Height_Minus_Limit *30.0 / 1000.0) + "mm";
	ThreeDCameraGradeInfoStringGrid->Cells[2][5] = FloatToStr((float)TabletGradeData_PC.threeD_Height_Plus_Limit  *30.0 / 1000.0) + "mm";

	SideGradeInfoStringGrid->RowCount = 7;
	SideGradeInfoStringGrid->ColCount = 3;
	SideGradeInfoStringGrid->ColWidths[0] = 245;
	SideGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	SideGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	SideGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

  if(ProductData.TabletType != TABLET_TYPE_SUGAR_COATED)
  {
    SideGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_PANEL_CAPTION_40;
    SideGradeInfoStringGrid->Cells[1][1] = IntToStr(TabletGradeData_PC.side_dirty_Intensity);
    SideGradeInfoStringGrid->Cells[2][1] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_dirty_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][2] = INSPECTIONFORM_PANEL_CAPTION_45;
    SideGradeInfoStringGrid->Cells[1][2] = IntToStr(TabletGradeData_PC.side_stain_Intensity);
    SideGradeInfoStringGrid->Cells[2][2] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_stain_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][3] = INSPECTIONFORM_STRGRID_CELL_24;
    SideGradeInfoStringGrid->Cells[1][3] = IntToStr(TabletGradeData_PC.Side_Edge_Neighbor_Intensity);
    SideGradeInfoStringGrid->Cells[2][3] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.Side_Edge_Neighbor_Defect_Size) / 100.0) + "mm";

    if(ProductData.TabletShape == TABLET_SHAPE_CIRCLE || ProductData.TabletShape == TABLET_SHAPE_OBLONG || ProductData.TabletShape == TABLET_SHAPE_OVAL)
    {
      SideGradeInfoStringGrid->Cells[0][4] = NEW_ADD_STRING_81;
      SideGradeInfoStringGrid->Cells[1][4] = IntToStr(TabletGradeData_PC.Side_Edge_Neighbor_Break_Intensity);
      SideGradeInfoStringGrid->Cells[2][4] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.Side_Edge_Neighbor_Break_Size) / 100.0) + "mm";
    }
    else
    {
      SideGradeInfoStringGrid->Cells[0][4] = NEW_ADD_STRING_81;
      SideGradeInfoStringGrid->Cells[1][4] = "";
      SideGradeInfoStringGrid->Cells[2][4] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.Side_Edge_Neighbor_Break_Size) / 100.0) + "mm";
    }

    SideGradeInfoStringGrid->Cells[0][5] = NEW_ADD_STRING_74;
    SideGradeInfoStringGrid->Cells[1][5] = IntToStr(TabletGradeData_PC.Side_Edge_Dark_Intensity);
    SideGradeInfoStringGrid->Cells[2][5] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.Side_Edge_Dark_Defect_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][6] = INSPECTIONFORM_STRGRID_CELL_25;
    SideGradeInfoStringGrid->Cells[1][6] = IntToStr(TabletGradeData_PC.side_Color_Dirty_Intensity);
    SideGradeInfoStringGrid->Cells[2][6] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_Color_Dirty_Size) / 100.0) + "mm";
  }
  else
  {
    SideGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_PANEL_CAPTION_40;
    SideGradeInfoStringGrid->Cells[1][1] = IntToStr(TabletGradeData_PC.side_dirty_Intensity);
    SideGradeInfoStringGrid->Cells[2][1] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_dirty_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][2] = INSPECTIONFORM_PANEL_CAPTION_45;
    SideGradeInfoStringGrid->Cells[1][2] = IntToStr(TabletGradeData_PC.side_stain_Intensity);
    SideGradeInfoStringGrid->Cells[2][2] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_stain_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][3] = INSPECTIONFORM_STRGRID_CELL_25;
    SideGradeInfoStringGrid->Cells[1][3] = IntToStr(TabletGradeData_PC.side_Color_Dirty_Intensity);
    SideGradeInfoStringGrid->Cells[2][3] = FloatToStr(DefectSizePixelToMili(TabletGradeData_PC.side_Color_Dirty_Size) / 100.0) + "mm";

    SideGradeInfoStringGrid->Cells[0][4] = "";
    SideGradeInfoStringGrid->Cells[1][4] = "";
    SideGradeInfoStringGrid->Cells[2][4] = "";

    SideGradeInfoStringGrid->Cells[0][5] = "";
    SideGradeInfoStringGrid->Cells[1][5] = "";
    SideGradeInfoStringGrid->Cells[2][5] = "";

    SideGradeInfoStringGrid->Cells[0][6] = "";
    SideGradeInfoStringGrid->Cells[1][6] = "";
    SideGradeInfoStringGrid->Cells[2][6] = "";
  }

	ColorGradeInfoStringGrid->RowCount = 2;
	ColorGradeInfoStringGrid->ColCount = 3;
	ColorGradeInfoStringGrid->ColWidths[0] = 245;
	ColorGradeInfoStringGrid->Cells[0][0] = INSPECTIONFORM_STRGRID_CELL_07;
	ColorGradeInfoStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_03;
	ColorGradeInfoStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_22;

	ColorGradeInfoStringGrid->Cells[0][1] = INSPECTIONFORM_STRGRID_CELL_10;
	ColorGradeInfoStringGrid->Cells[1][1] = IntToStr(TabletGradeData_PC.front_color_Intensity);
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::DefectCheckTimerTimer(TObject *Sender)
{
	bool timerEnabled = DefectCheckTimer->Enabled;
	bool bDefectExist = false;
	bool bInspectionFinished = false;
	bool bThreeD;

	DefectCheckTimer->Enabled = false;
	TDefectImageInfo defectImageInfo;
	bool bImageReceived;
	
	try
	{
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
			if (!Comm_IsConnected(COMM_SPB + spbIndex)) continue;

			bImageReceived = false;
			int escapeCount = 0.2 * DefectCheckTimer->Interval + 1;   // 1초에 200 개까지 처리 가능하도록.. escape count 를 결정 escape count 는 spb 오류 시 빠져나올 수 있도록 해준다.

			if (DefectedTabletList.size() == 0) break;
			int minDefectTabletNumber = DefectedTabletList.front().DefectTabletNumber;

			if (!Comm_Request(COMM_SPB + spbIndex, CMD_DEFECT_IMAGE_EXIST, &minDefectTabletNumber, sizeof(int), &defectImageInfo, sizeof(TDefectImageInfo)))
			{
				throw Exception("");
			}
			if (defectImageInfo.DefectExists)
			{
				bDefectExist = true;
				// check real defect
				bool checkedTabletNumber;
				if (LastCheckedTabletNumber >= defectImageInfo.DefectTabletNumber)      // HCB로 부터 결과를 들어 알고 있는 tablet 의 defect 이미지인가?
				{
					checkedTabletNumber = true;
				}
				else
				{
					checkedTabletNumber = false;
				}

				bool realDefect = false;
				list<TDefectTabletListUnit>::iterator it;
				TDefectTabletListUnit theDefectTabletListUnit;
				for (it = DefectedTabletList.begin(); it != DefectedTabletList.end(); ++it)
				{
					if (it->DefectTabletNumber == defectImageInfo.DefectTabletNumber)
					{
						theDefectTabletListUnit = *it;
						realDefect = true;
						break;
					}
				}
				if (checkedTabletNumber)
				{
					if (realDefect)
					{
						for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
						{
							if (defectImageInfo.DefectCameraMask[camIndex])
							{
								// read defect image and data
								int requestCamIndex = camIndex;
								TDefectData_SPB receivedDefectData;
								if (!Comm_Request(COMM_SPB + spbIndex, CMD_DEFECT_DATA, &requestCamIndex, sizeof(int),
									&receivedDefectData, sizeof(TDefectData_SPB)))
								{
									throw Exception("");
								}

								bool checkList = true;
								int cnt;
								for (cnt = 0; cnt < 512; cnt++)
								{
									//정제 번호가 기록된 경우
									if (DefectTalbetNumList[cnt][0] == receivedDefectData.TabletNumber)
									{
										checkList = false;
										if (receivedDefectData.CPBDefectInfo.defectSeries > 250 && receivedDefectData.CPBDefectInfo.defectSeries < 260)
										{
											if (!DefectTalbetNumList[cnt][2])
											{
												DefectTalbetNumList[cnt][2] = 1;
												DefectSeriesCount[DefectTalbetNumList[cnt][1]]--;
											}
										}
										break;
									}
								}
								//정제 번호가 기록된 것이 없는 경우
								if (checkList)
								{
									if (receivedDefectData.CPBDefectInfo.defectSeries < UNINS_CLOSED)
										DefectSeriesCount[receivedDefectData.CPBDefectInfo.defectSeries]++;
									if (receivedDefectData.CPBDefectInfo.defectSeries > UNINS_BRIGHTNESS_CHASE)
										DefectSeriesCount[MAX_CPB_DEFECT_SERIES_COUNT + receivedDefectData.CPBDefectInfo.defectSeries - THIN_TALBET]++;

									DefectTalbetNumList[DefectTabletNumIndex][0] = receivedDefectData.TabletNumber;
									DefectTalbetNumList[DefectTabletNumIndex][1] = receivedDefectData.CPBDefectInfo.defectSeries;
									if (receivedDefectData.CPBDefectInfo.defectSeries > 250 && receivedDefectData.CPBDefectInfo.defectSeries < 260)
										DefectTalbetNumList[DefectTabletNumIndex][2] = 1;

									DefectTabletNumIndex++;
									if (DefectTabletNumIndex > 511) DefectTabletNumIndex = 0;
									DefectTalbetNumList[DefectTabletNumIndex][0] = 0;
									DefectTalbetNumList[DefectTabletNumIndex][1] = 0;
									DefectTalbetNumList[DefectTabletNumIndex][2] = 0;
								}

								int globalCameraIndex = SPBSystemSetupData[spbIndex].GlobalCameraIndex[camIndex];
								if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
								{
									if (!Comm_Request(COMM_SPB + spbIndex, CMD_DEFECT_IMAGE, &requestCamIndex, sizeof(int),
										DefectImage, SYSTEM_CAMERA_WIDTH_3D * SYSTEM_CAMERA_HEIGHT_3D))
									{
										throw Exception("");
									}
								}
								else
								{
									if (!Comm_Request(COMM_SPB + spbIndex, CMD_DEFECT_IMAGE, &requestCamIndex, sizeof(int),
										DefectImage, SourceImageWidth[0] * SourceImageHeight[0]))
									{
										throw Exception("");
									}
								}

								if (theDefectTabletListUnit.DefectImageKind == DEFECT_IMAGE_KIND_CLOSED && receivedDefectData.CPBDefectInfo.defectSeries != UNINS_CLOSED)
								{
									// discard it
									continue;
								}

                if(theDefectTabletListUnit.DefectImageKind != DEFECT_IMAGE_KIND_UNPRINTED && receivedDefectData.CPBDefectInfo.defectSeries == DEFECT_UNPRINT)
                {
                  // discard it
									continue;
                }

                if(theDefectTabletListUnit.DefectImageKind == DEFECT_IMAGE_KIND_UNPRINTED && receivedDefectData.CPBDefectInfo.defectSeries != DEFECT_UNPRINT)
                {
                  // discard it
									continue;
                }

                if(theDefectTabletListUnit.DefectImageKind == DEFECT_IMAGE_KIND_UNPRINTED && receivedDefectData.CPBDefectInfo.defectSeries == DEFECT_UNPRINT)
                {
                  if(!CounterSensorPanel->Visible)
                  {
                    // discard it
								  	continue;
                  }
                }

								memcpy(&(CurrentDefectData.CPBDefectInfo), &(receivedDefectData.CPBDefectInfo), sizeof(TDefectInformation));
								CurrentDefectData.TabletNumber = receivedDefectData.TabletNumber;
								CurrentDefectData.GlobalCameraIndex = receivedDefectData.GlobalCameraIndex;
								CurrentDefectData.CameraInspectPosition = CameraMapInfo[CurrentDefectData.GlobalCameraIndex].CameraInspectPosition;

								// bayer conversion
								if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
								{
                  memcpy(RealDefectBayerImage, DefectImage, SYSTEM_CAMERA_WIDTH_3D * SYSTEM_CAMERA_HEIGHT_3D);

									CurrentDefectImage->Stretch = true;
									CurrentDefectImage->Proportional = false;
									CurrentDefectImage->Width = IMAGE_WIDTH_3D * 2;
									CurrentDefectImage->Height = IMAGE_HEIGHT_3D;
									CurrentDefectImage->Picture->Bitmap->Width = IMAGE_WIDTH_3D;
									CurrentDefectImage->Picture->Bitmap->Height = IMAGE_HEIGHT_3D;
									CurrentDefectImage->Picture->Bitmap->PixelFormat = pf8bit;
									SetGrayPalette(CurrentDefectImage->Picture->Bitmap);

									ImageConversion_3D(CurrentDefectImage->Picture->Bitmap, IMAGE_WIDTH_3D, IMAGE_HEIGHT_3D, DefectImage, SYSTEM_CAMERA_WIDTH_3D, SYSTEM_CAMERA_HEIGHT_3D);
								}
								else
								{
                  memcpy(RealDefectBayerImage, DefectImage, SourceImageWidth[0] * SourceImageHeight[0]);

                  int StartY =  ProductData.BoundaryTop[globalCameraIndex];
                  int EndY = ProductData.BoundaryBottom[globalCameraIndex];


                  if(SourceImageWidth[0] == 1280)
                  {
                    StartY *= 2;
                    EndY *= 2;
                  }

                  if (CurrentDefectData.GlobalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD2_2D_FRONT_FACE_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_OTHER_SIDE_FACE_00_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_OTHER_SIDE_FACE_P45_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_SIDE_FACE_M45_CAMERA_INDEX - 1 ||
                      CurrentDefectData.GlobalCameraIndex == SD1_2D_OTHER_SIDE_FACE_M45_CAMERA_INDEX - 1)
                    {
                      int Temp = SourceImageHeight[0] - EndY; // starty
                      int Temp2 =  SourceImageHeight[0] - StartY;
                      StartY = Temp;
                      EndY = Temp2;
                    }
                    
                  memset(DefectImage,0,sizeof(unsigned char)*(SourceImageWidth[0] * (StartY)));
                  memset(&DefectImage[(SourceImageWidth[0] * (EndY))],0,sizeof(unsigned char)*((SourceImageHeight[0]- (EndY))*SourceImageWidth[0]));

									CurrentDefectImage->Width = SYSTEM_CAMERA_WIDTH;
									CurrentDefectImage->Height = SYSTEM_CAMERA_HEIGHT;
									CurrentDefectImage->Picture->Bitmap->Width = SourceImageWidth[0];
									CurrentDefectImage->Picture->Bitmap->Height = SourceImageHeight[0];
									CurrentDefectImage->Picture->Bitmap->PixelFormat = pf24bit;

									GetNFACamera2DColorImage(CurrentDefectImage->Picture->Bitmap, DefectImage, SourceImageWidth[0], SourceImageHeight[0], globalCameraIndex, TabletSetupData.ImageOffSetSW[globalCameraIndex], TabletSetupData.referenceImageForOffset[globalCameraIndex], ProductData.SubSamplingMode);
								}

								// refresh string grid
								DefectDataStringGrid->Cells[1][0] = IntToStr(CurrentDefectData.TabletNumber);

								//DefectDataStringGrid->Cells[1][1] = IntToStr(CurrentDefectData.GlobalCameraIndex + 1);
                AnsiString ConvertString = ConvertCameraIndex(CurrentDefectData.GlobalCameraIndex);
                DefectDataStringGrid->Cells[1][1] = ConvertString;


								DefectDataStringGrid->Cells[1][2] = GetDefectSeriesStr(CurrentDefectData.CPBDefectInfo.defectSeries);

								if (CurrentDefectData.CPBDefectInfo.defectSeries == FAT_TALBET || CurrentDefectData.CPBDefectInfo.defectSeries == THIN_TALBET)
									DefectDataStringGrid->Cells[1][3] = FloatToStr((float)CurrentDefectData.CPBDefectInfo.size * 30 / 1000.0) + " mm";
								else if (CurrentDefectData.CPBDefectInfo.defectSeries == DEFECT_3D_PRINT_ERASE)
									DefectDataStringGrid->Cells[1][3] = FloatToStr(CurrentDefectData.CPBDefectInfo.size) + " %";
                else if (CurrentDefectData.CPBDefectInfo.defectSeries == DEFECT_FRONT_WHITE_ENGRAVE)
									DefectDataStringGrid->Cells[1][3] = IntToStr(CurrentDefectData.CPBDefectInfo.size) + " Grade";
                else if(CurrentDefectData.CPBDefectInfo.defectSeries == DEFECT_PRINT_POSITION_ERROR)
                  DefectDataStringGrid->Cells[1][3] = FloatToStr(CurrentDefectData.CPBDefectInfo.size*0.04) + " mm";
                else if(CurrentDefectData.CPBDefectInfo.defectSeries == DEFECT_PRINT_ROTATION_ERROR)
                  DefectDataStringGrid->Cells[1][3] = IntToStr(CurrentDefectData.CPBDefectInfo.size) + " Degree";
								else
									DefectDataStringGrid->Cells[1][3] = FloatToStr(DefectSizePixelToMili(CurrentDefectData.CPBDefectInfo.size) / 100.0) + "mm";

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

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

										memcpy(pTempLineT, pBitmapB, CurrentDefectImage->Picture->Bitmap->Width * 3);
										memcpy(pTempLineB, pBitmapT, CurrentDefectImage->Picture->Bitmap->Width * 3);
										memcpy(pBitmapT, pTempLineT, CurrentDefectImage->Picture->Bitmap->Width * 3);
										memcpy(pBitmapB, pTempLineB, CurrentDefectImage->Picture->Bitmap->Width * 3);
									}
									delete[] pTempLineT;
									delete[] pTempLineB;
								}
								if (!InspectionOption.UnsaveDefectImage)
								{
									// save defect information
									int imageIndex = SaveDefectInfo();
									TFileContainer DefectImageContainer;
									AnsiString defectContainerFileName = GetDefectImageContainerFileName(imageIndex, ProductData.ProductCode, ProductData.LOTName);
									DefectImageContainer.Open(defectContainerFileName, true, DEFECT_DATA_CONTAINER_SIZE);
									if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
									{
										AnsiString bitmapName = "Image" + IntToStr(imageIndex + 1) + ".fbm";
										DefectImageContainer.SaveBitmapData(bitmapName, ECM_ZIP, RealDefectBayerImage, SYSTEM_CAMERA_WIDTH_3D, SYSTEM_CAMERA_HEIGHT_3D, 8, globalCameraIndex, EBK_3D);
									}
									else
									{
										AnsiString bitmapName = "Image" + IntToStr(imageIndex + 1) + ".fbm";
										DefectImageContainer.SaveBitmapData(bitmapName, ECM_ZIP, RealDefectBayerImage, SourceImageWidth[0], SourceImageHeight[0], 8, globalCameraIndex);
									}
								}

								if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
								{
									memcpy(DefectRawImage_3D, DefectImage, SYSTEM_CAMERA_WIDTH_3D * SYSTEM_CAMERA_HEIGHT_3D);
									Repaint3DImage();
									Current3DBitmap->Assign(CurrentDefectImage->Picture->Bitmap);
								}

								if (globalCameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX - 1 &&
									globalCameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX - 1)
								{
									bThreeD = false;

									// show defected position
									CurrentDefectImage->Canvas->Pen->Color = clWhite;
									CurrentDefectImage->Canvas->Pen->Width = 2;
									CurrentDefectImage->Canvas->Brush->Style = bsClear;
									CurrentDefectImage->Canvas->Rectangle(
										(CurrentDefectData.CPBDefectInfo.defectPositionStartX - 4) * rate[bThreeD], (CurrentDefectData.CPBDefectInfo.defectPositionStartY - 4) * rate[bThreeD],
										(CurrentDefectData.CPBDefectInfo.defectPositionEndX + 4) * rate[bThreeD], (CurrentDefectData.CPBDefectInfo.defectPositionEndY + 4) * rate[bThreeD]);

									CurrentDefectImage->Canvas->Pen->Color = clRed;
									CurrentDefectImage->Canvas->Pen->Width = 2;
									CurrentDefectImage->Canvas->Brush->Style = bsClear;
									CurrentDefectImage->Canvas->Rectangle(
										(CurrentDefectData.CPBDefectInfo.defectPositionStartX - 2) * rate[bThreeD], (CurrentDefectData.CPBDefectInfo.defectPositionStartY - 2) * rate[bThreeD],
										(CurrentDefectData.CPBDefectInfo.defectPositionEndX + 2) * rate[bThreeD], (CurrentDefectData.CPBDefectInfo.defectPositionEndY + 2) * rate[bThreeD]);
								}
								else
								{
									bThreeD = true;
								}

								// show boundary area
								CurrentDefectImage->Canvas->Pen->Color = clBlue;
								CurrentDefectImage->Canvas->Pen->Width = 2;
								CurrentDefectImage->Canvas->Brush->Style = bsClear;
								CurrentDefectImage->Canvas->Rectangle(
									(ProductData.BoundaryLeft[CurrentDefectData.GlobalCameraIndex]) * rate[bThreeD], (ProductData.BoundaryTop[CurrentDefectData.GlobalCameraIndex]) * rate[bThreeD],
									(ProductData.BoundaryRight[CurrentDefectData.GlobalCameraIndex]) * rate[bThreeD], (ProductData.BoundaryBottom[CurrentDefectData.GlobalCameraIndex]) * rate[bThreeD]);

								CurrentDefectImage->Repaint();

								bImageReceived = true;

								if (theDefectTabletListUnit.DefectImageKind == DEFECT_IMAGE_KIND_DEFECT || theDefectTabletListUnit.DefectImageKind == DEFECT_IMAGE_KIND_UNPRINTED)
								{
									DefectTabletNumberHeap[globalCameraIndex][defectImageInfo.DefectTabletNumber & DEFECT_SERIES_HEAP_MASK] = defectImageInfo.DefectTabletNumber;
									DefectSeriesHeap[globalCameraIndex][defectImageInfo.DefectTabletNumber & DEFECT_SERIES_HEAP_MASK] = receivedDefectData.CPBDefectInfo.defectSeries;
								}
							} // end if (defectImageInfo.DefectCameraMask[camIndex])
						} // end for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
					} // end if (realDefect)
					else
					{
						if (!Comm_Request(COMM_SPB + spbIndex, CMD_DISCARD_DEFECT_IMAGE))
						{
							throw Exception("");
						}
					}
				} // end if (checkedTabletNumber)
				else	// unchecked tablet number
				{
					// 기계가 정지된 상태면 체크하지 않은 defect image 를 모두 discard 한다. (정제 유실 관련 이미지를 discard 하기 위해)
					if (Machine.Status.OperationState == MACHINE_STATE_STOP || Machine.Status.OperationState == MACHINE_STATE_CLEANING)
					{
						if (!Comm_Request(COMM_SPB + spbIndex, CMD_DISCARD_DEFECT_IMAGE))
						{
							throw Exception("");
						}
					}
				}
			} // end if (defectImageInfo.DefectExists)
			else
			{

			}

			escapeCount--;
			if (escapeCount == 0)
			{

			}
		} // end for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)

		if (!bDefectExist)
		{
			ProcessDefectSeries(true);
		}

		// check inspection end
		if (!bDefectExist || InspectionOption.UnsaveDefectImage)
		{
			if (InspectState == INSPECTION_STATE_STOPPING && (Machine.Status.OperationState == MACHINE_STATE_STOP || Machine.Status.OperationState == MACHINE_STATE_CLEANING))
			{
				bInspectionFinished = true;
			}

			if (bInspectionFinished)
			{
				if (InspectionStopOption == INSPECTION_STOP_OPTION_MACHINE_STOP)
				{
					InspectState = INSPECTION_STATE_MACHINE_STOP;
				}
				else
				{
					InspectState = INSPECTION_STATE_STOP;
				}

				// save inspect info
				if (!bCalledWriteFunc)
				{
					/*if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
					{
					if(!TestMode)
					SaveInspectResult();
					}
					else  */
					SaveInspectResult();

				}
				int inspectionCount[4];
				inspectionCount[0] = TabletInspectInfo.TotalTabletCount - TabletInspectInfo_Begin.TotalTabletCount;
				inspectionCount[1] = TabletInspectInfo.GoodTabletCount - TabletInspectInfo_Begin.GoodTabletCount;
				inspectionCount[2] = TabletInspectInfo.DefectTabletCount - TabletInspectInfo_Begin.DefectTabletCount;
				inspectionCount[3] = TabletInspectInfo.UnInsTabletCount - TabletInspectInfo_Begin.UnInsTabletCount;

				AddCSVActionLog(ECSV_ACTION_INSPECTION_PAUSE, UserInfo.Name, ProductData.ProductName, (unsigned char *)inspectionCount, 4 * sizeof(unsigned int));

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

				InspectionStartButton->Enabled = true;
				SpeedControlButton->Enabled = true;
				InspectionStopButton->Enabled = false;
				StopInfoPanel->Visible = false;
				InspectionRestartButton->Enabled = true;
				CloseBitBtn->Enabled = true;
        			CameraTestButton->Enabled = true;

        			LastUVLaserStatus[0] = 0;
				LastUVLaserStatus[1] = 0;
			}
		}
		if(InspectionStop_flag)
		{
		
			if(InspectionStop_count > 1000)
			{
				Machine.MachineStop();
				if (InspectionStopOption == INSPECTION_STOP_OPTION_MACHINE_STOP)
				{
					InspectState = INSPECTION_STATE_MACHINE_STOP;
				}
				else
				{
					InspectState = INSPECTION_STATE_STOP;
				}				
				if (!bCalledWriteFunc)
				{
					/*if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
					{
					if(!TestMode)
					SaveInspectResult();
					}
					else  */
					SaveInspectResult();

				}
				int inspectionCount[4];
				inspectionCount[0] = TabletInspectInfo.TotalTabletCount - TabletInspectInfo_Begin.TotalTabletCount;
				inspectionCount[1] = TabletInspectInfo.GoodTabletCount - TabletInspectInfo_Begin.GoodTabletCount;
				inspectionCount[2] = TabletInspectInfo.DefectTabletCount - TabletInspectInfo_Begin.DefectTabletCount;
				inspectionCount[3] = TabletInspectInfo.UnInsTabletCount - TabletInspectInfo_Begin.UnInsTabletCount;

				AddCSVActionLog(ECSV_ACTION_INSPECTION_PAUSE, UserInfo.Name, ProductData.ProductName, (unsigned char *)inspectionCount, 4 * sizeof(unsigned int));

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

				InspectionStartButton->Enabled = true;
				SpeedControlButton->Enabled = true;
				InspectionStopButton->Enabled = false;
				StopInfoPanel->Visible = false;
				InspectionRestartButton->Enabled = true;
				CloseBitBtn->Enabled = true;
        			CameraTestButton->Enabled = true;
				InspectionStop_flag = false;
				InspectionStop_count = 0;
        			LastUVLaserStatus[0] = 0;
				LastUVLaserStatus[1] = 0;		
			}
			else 
			{
				InspectionStop_count++;
			}
				
		}
	}
	catch (...)
	{

	}

	if (bInspectionFinished)
	{
		timerEnabled = false;
		StopInfoPanel->Visible = false;
		Repaint();
	}

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

void __fastcall TInspectionForm::InspectionResultSpeedButtonClick(
	TObject *Sender)
{
	if (InspectionResultPanel->Visible)
	{
		InspectionResultPanel->Visible = false;
	}
	else
	{
		InspectionResultPanel->BringToFront();
		InspectionResultPanel->Visible = true;
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ProcessingCheckStartButtonClick(
	TObject *Sender)
{
	ProcessingCheckTimer->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ProcessingCheckStopButtonClick(
	TObject *Sender)
{
	ProcessingCheckTimer->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ProcessingCheckTimerTimer(TObject *Sender)
{
	bool timerEnabled = ProcessingCheckTimer->Enabled;
	ProcessingCheckTimer->Enabled = false;
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (!Comm_IsConnected(COMM_SPB + spbIndex)) continue;

		if (!Comm_Request(COMM_SPB + spbIndex, CMD_PROCESSING_TIME, NULL, 0,
			ProcessingTimeList[spbIndex], SPB_TABLET_LIST_COUNT * sizeof(TProcessingTime)))
		{
			timerEnabled = false;
		}
	}

	RefreshProcessingInfo();
	ProcessingCheckTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::RefreshProcessingInfo(void)
{
	/*
	int spbIndex, camIndex;
	if (ProcessingInfoSPBSpeedButton1->Down)
	{
	spbIndex = 0;
	}
	else if (ProcessingInfoSPBSpeedButton2->Down)
	{
	spbIndex = 1;
	}
	else if (ProcessingInfoSPBSpeedButton3->Down)
	{
	spbIndex = 2;
	}
	else
	{
	spbIndex = 3;
	}

	if (ProcessingInfoCamSpeedButton1->Down)
	{
	camIndex = 0;
	}
	else if (ProcessingInfoCamSpeedButton2->Down)
	{
	camIndex = 1;
	}
	else
	{
	camIndex = 2;
	}

	CaptureTimeChart->Series[0]->Clear();
	ProcessingWaitingTimeChart->Series[0]->Clear();
	ProcessingTimeChart->Series[0]->Clear();
	ProcessingCPUChart->Series[0]->Clear();
	double captureTimeChartList[SPB_TABLET_LIST_COUNT];
	double processingWaitingTimeChartList[SPB_TABLET_LIST_COUNT];
	double processingTimeChartList[SPB_TABLET_LIST_COUNT];
	double processingCPUChartList[SPB_TABLET_LIST_COUNT];


	ProcessingTimeStringGrid->Cells[0][0] = "#Object";
	ProcessingTimeStringGrid->Cells[1][0] = INSPECTIONFORM_STRGRID_CELL_21;
	ProcessingTimeStringGrid->Cells[2][0] = INSPECTIONFORM_STRGRID_CELL_20;
	ProcessingTimeStringGrid->Cells[3][0] = INSPECTIONFORM_STRGRID_CELL_04;
	ProcessingTimeStringGrid->Cells[4][0] = "이미지 전송";
	ProcessingTimeStringGrid->Cells[5][0] = "Processing";
	ProcessingTimeStringGrid->Cells[6][0] = "Polling Interval";
	ProcessingTimeStringGrid->Cells[7][0] = INSPECTIONFORM_STRGRID_CELL_18;
	ProcessingTimeStringGrid->Cells[8][0] = INSPECTIONFORM_STRGRID_CELL_17;
	ProcessingTimeStringGrid->Cells[9][0] = "CPU";

	ProcessingTimeStringGrid->ColWidths[9] = 32;
	ProcessingTimeStringGrid->ColWidths[1] = 64;

	for (int listIndex = 0; listIndex < SPB_TABLET_LIST_COUNT; listIndex++)
	{
	captureTimeChartList[listIndex] = (int)(ProcessingTimeList[spbIndex][listIndex].CaptureEndTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].CaptureStartTime[camIndex]);
	processingWaitingTimeChartList[listIndex] = (int)(ProcessingTimeList[spbIndex][listIndex].ProcessingStartTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].CaptureEndTime[camIndex]);
	processingTimeChartList[listIndex] = (int)(ProcessingTimeList[spbIndex][listIndex].ProcessingEndTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].ProcessingStartTime[camIndex]);
	processingCPUChartList[listIndex] = ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] + 1;

	ProcessingTimeStringGrid->Cells[0][listIndex + 1] = IntToStr(ProcessingTimeList[spbIndex][listIndex].TabletNumber);
	ProcessingTimeStringGrid->Cells[1][listIndex + 1] = IntToStr((int)ProcessingTimeList[spbIndex][listIndex].CaptureStartTime[camIndex]);
	ProcessingTimeStringGrid->Cells[2][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].CaptureEndTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].CaptureStartTime[camIndex]));
	ProcessingTimeStringGrid->Cells[3][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].ImageSendStartTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].CaptureEndTime[camIndex]));
	ProcessingTimeStringGrid->Cells[4][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].ProcessingStartTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].ImageSendStartTime[camIndex]));
	ProcessingTimeStringGrid->Cells[5][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].ProcessingEndTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].ProcessingStartTime[camIndex]));
	ProcessingTimeStringGrid->Cells[6][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].ProcessingEndTime[camIndex] - ProcessingTimeList[spbIndex][listIndex].BeforePollingTime[camIndex]));
	ProcessingTimeStringGrid->Cells[7][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].CompleteTime - ProcessingTimeList[spbIndex][listIndex].ProcessingEndTime[camIndex]));
	ProcessingTimeStringGrid->Cells[8][listIndex + 1] = IntToStr((int)(ProcessingTimeList[spbIndex][listIndex].CompleteTime - ProcessingTimeList[spbIndex][listIndex].CaptureStartTime[camIndex]));
	ProcessingTimeStringGrid->Cells[9][listIndex + 1] = IntToStr(ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] + 1);
	}

	CaptureTimeChart->Series[0]->AddArray(captureTimeChartList, SPB_TABLET_LIST_COUNT - 1);
	ProcessingWaitingTimeChart->Series[0]->AddArray(processingWaitingTimeChartList, SPB_TABLET_LIST_COUNT - 1);
	ProcessingTimeChart->Series[0]->AddArray(processingTimeChartList, SPB_TABLET_LIST_COUNT - 1);
	ProcessingCPUChart->Series[0]->AddArray(processingCPUChartList, SPB_TABLET_LIST_COUNT - 1);
	for (int listIndex = 0; listIndex < SPB_TABLET_LIST_COUNT; listIndex++)
	{
	if (ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] < 8)
	{
	ProcessingCPUChart->Series[0]->ValueColor[listIndex] = clRed;
	}
	else if (ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] < 16)
	{
	ProcessingCPUChart->Series[0]->ValueColor[listIndex] = 0x007FFF;
	}
	else if (ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] < 24)
	{
	ProcessingCPUChart->Series[0]->ValueColor[listIndex] = clYellow;
	}
	else if (ProcessingTimeList[spbIndex][listIndex].ProcessingCPB[camIndex] < 32)
	{
	ProcessingCPUChart->Series[0]->ValueColor[listIndex] = clGreen;
	}
	else
	{
	ProcessingCPUChart->Series[0]->ValueColor[listIndex] = clBlue;
	}
	}
	*/
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::ProcessingInfoSPBSpeedButtonClick(
	TObject *Sender)
{
	/*
	TTntSpeedButton *theSpeedButton = (TTntSpeedButton *) Sender;
	ProcessingInfoSPBSpeedButton1->Font->Color = clBlack;
	ProcessingInfoSPBSpeedButton2->Font->Color = clBlack;
	ProcessingInfoSPBSpeedButton3->Font->Color = clBlack;
	ProcessingInfoSPBSpeedButton4->Font->Color = clBlack;
	theSpeedButton->Font->Color = clBlue;
	RefreshProcessingInfo();
	*/
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ProcessingInfoCamSpeedButtonClick(
	TObject *Sender)
{
	/*
	TTntSpeedButton *theSpeedButton = (TTntSpeedButton *) Sender;
	ProcessingInfoCamSpeedButton1->Font->Color = clBlack;
	ProcessingInfoCamSpeedButton2->Font->Color = clBlack;
	ProcessingInfoCamSpeedButton3->Font->Color = clBlack;
	theSpeedButton->Font->Color = clBlue;
	RefreshProcessingInfo();
	*/
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::InspectionResultTimerTimer(
	TObject *Sender)
{
	bool timerEnabled = InspectionResultTimer->Enabled;
	InspectionResultTimer->Enabled = false;

	if (Comm_Request(COMM_HCB, CMD_INSPECTION_RESULT, NULL, 0, &InspectionResultTable, sizeof(TInspectionResultTable)))
	{
		int currentTableIndex = (InspectionResultTable.CurrentIndex + 1) & RESULT_TABLE_MASK;
		int minCheckedTabletNumber = InspectionResultTable.Table[currentTableIndex].TabletNumber;

		for (int tableIndex = 0; tableIndex < RESULT_TABLE_SIZE - 1; tableIndex++)
		{
			if (InspectionResultTable.Table[currentTableIndex].TabletNumber > LastCheckedTabletNumber)
			{
				if(EnableLaserTest->Checked)
				{
					if (InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DEFECT ||
						InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_INSERTED ||
						InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DISAPPEARED ||
						InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_CLOSED_UNINS ||
						InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_CLOSED_DEFECT ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_CLOSED_TABLET)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_TABLET_POSITION)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_TABLET_POSITION)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_TABLET_POSITION)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED)))
						{
						if (DefectedTabletList.size() >= 512)   // spb에서 최대 소지할 수 있는 defect image 수 보다 크게
						{
							DefectedTabletList.pop_front();
						}
						TDefectTabletListUnit aTabletListUnit;
						aTabletListUnit.DefectTabletNumber = InspectionResultTable.Table[currentTableIndex].TabletNumber;
						if (InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DEFECT)
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_DEFECT;
						}
						else if (InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_CLOSED_TABLET))
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_CLOSED;
						}
						else
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_UNINS;
						}

						DefectedTabletList.push_back(aTabletListUnit);
					}
				}
				else
				{
					if (InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DEFECT ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_CLOSED_TABLET)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_TABLET_POSITION)) ||
						(InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED)))
					{
						if (DefectedTabletList.size() >= 512)   // spb에서 최대 소지할 수 있는 defect image 수 보다 크게
						{
							DefectedTabletList.pop_front();
						}
						TDefectTabletListUnit aTabletListUnit;
						aTabletListUnit.DefectTabletNumber = InspectionResultTable.Table[currentTableIndex].TabletNumber;
						if (InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DEFECT)
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_DEFECT;
						}
						else if (InspectionResultTable.Table[currentTableIndex].Result == (TABLET_RESULT_SPB_MASK | SPB_TABLET_RESULT_UNINS_CLOSED_TABLET))
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_CLOSED;
						}
						else
						{
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_UNINS;
						}

						DefectedTabletList.push_back(aTabletListUnit);
					}
					else if (InspectionResultTable.Table[currentTableIndex].Result == TABLET_RESULT_DEFECT_UNPRINT)
					{
						if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable && CounterSensorPanel->Visible)
						{
							if (DefectedTabletList.size() >= 512)   // spb에서 최대 소지할 수 있는 defect image 수 보다 크게
							{
								DefectedTabletList.pop_front();
							}
							TDefectTabletListUnit aTabletListUnit;
							aTabletListUnit.DefectTabletNumber = InspectionResultTable.Table[currentTableIndex].TabletNumber;
							aTabletListUnit.DefectImageKind = DEFECT_IMAGE_KIND_UNPRINTED;

							DefectedTabletList.push_back(aTabletListUnit);
						}
					}

				}
				LastCheckedTabletNumber = InspectionResultTable.Table[currentTableIndex].TabletNumber;
			}
			currentTableIndex = (currentTableIndex + 1) & RESULT_TABLE_MASK;
		}
	}

	if (InspectionResultPanel->Visible)
	{
		DisplayInspectionResultTable();
	}

	ProcessDefectSeries(false);

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

void __fastcall TInspectionForm::VibratorInfoSpeedButtonClick(
	TObject *Sender)
{
	ThroughPutChartLabel->Font->Color = clBlack;
	DefectRatioChartLabel->Font->Color = clBlack;
	VibratorInfoLabel->Font->Color = clBlue;
	DefectRatioPanel->Visible = false;
	ThroughputPanel->Visible = false;
	VibratorInfoPanel->Visible = true;
	VibratorInfoTimer->Enabled = true;

	RefreshVibratorInfo();
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::RefreshVibratorInfo(void)
{
	if (Comm_Request(COMM_HCB, CMD_VIBRATOR_INFO, NULL, 0, &VibratorInfo, sizeof(TVibratorInfo)))
	{
		VibratorInfoChart->Series[0]->Clear();
		VibratorInfoChart->Series[1]->Clear();
		VibratorInfoChart->Series[2]->Clear();
		VibratorInfoChart->Series[3]->Clear();
		VibratorInfoChart->Series[4]->Clear();

		if (ProductData.MachineRunOption.MaxSpeedTrainingMode == MAX_SPEED_TRAINING_MODE_AUTO)
		{
			VFAutoModePanel->Visible = true;
			VFManualModePanel->Visible = false;
			VFManualModeControlPanel->Visible = false;

			if (DefaultLCID == 1042 || DefaultLCID == 2066)
			{
				VibratorInfoChart->Series[0]->Title = "동작 속도";
				VibratorInfoChart->Series[1]->Title = "평균 속도";
				VibratorInfoChart->Series[2]->Title = "평균 센서 비율";
				VibratorInfoChart->Series[3]->Title = "측정 센서 비율";
				VibratorInfoChart->Series[4]->Title = "설정 비율";
			}
            else if(DefaultLCID == 1028)
            {
            }
			else
			{
				VibratorInfoChart->Series[0]->Title = "Operating Speed";
				VibratorInfoChart->Series[1]->Title = "Average Speed";
				VibratorInfoChart->Series[2]->Title = "Sensor Average Ratio";
				VibratorInfoChart->Series[3]->Title = "Measured Sensor Ratio";
				VibratorInfoChart->Series[4]->Title = "Setting Ratio";
			}
			int currentVFListIndex = VibratorInfo.CurrentListIndex & VFINFO_LIST_MASK;
			double VF_NowSpeed[VFINFO_LIST_COUNT];
			double VF_AverageSpeed[VFINFO_LIST_COUNT];
			double VF_AverageRatio1[VFINFO_LIST_COUNT];
			double VF_AverageRatio2[VFINFO_LIST_COUNT];
			double VF_CheckedRatio1[VFINFO_LIST_COUNT];
			double VF_CheckedRatio2[VFINFO_LIST_COUNT];
			double VF_SetRatio1[VFINFO_LIST_COUNT];
			double VF_SetRatio2[VFINFO_LIST_COUNT];

			for (int vfIndex = 0; vfIndex < VFINFO_LIST_COUNT; vfIndex++)
			{
				VF_NowSpeed[vfIndex] = VibratorInfo.NowSpeedList[currentVFListIndex];
				VF_AverageSpeed[vfIndex] = VibratorInfo.AverageSpeedList[currentVFListIndex];
				VF_AverageRatio1[vfIndex] = VibratorInfo.AverageSensor1RatioList[currentVFListIndex];
				VF_AverageRatio2[vfIndex] = VibratorInfo.AverageSensor2RatioList[currentVFListIndex];
				VF_CheckedRatio1[vfIndex] = VibratorInfo.VFSensor1RatioList[currentVFListIndex];
				VF_CheckedRatio2[vfIndex] = VibratorInfo.VFSensor2RatioList[currentVFListIndex];
				VF_SetRatio1[vfIndex] = VibratorInfo.SetRatio1;
				VF_SetRatio2[vfIndex] = VibratorInfo.SetRatio2;
				currentVFListIndex = (currentVFListIndex + 1) & VFINFO_LIST_MASK;
			}

			VibratorInfoChart->Series[0]->AddArray(VF_NowSpeed, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[1]->AddArray(VF_AverageSpeed, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[2]->AddArray(VF_AverageRatio1, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[3]->AddArray(VF_CheckedRatio1, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[4]->AddArray(VF_SetRatio1, VFINFO_LIST_COUNT - 1);

			AutoModeSensor1OnRatioLabel->Caption = IntToStr(VibratorInfo.Sensor1ON_NowRatio) + "%";
			AutoModeSensor2OnRatioLabel->Caption = IntToStr(VibratorInfo.Sensor2ON_NowRatio) + "%";
			SetRatio1_Label->Caption = IntToStr(VibratorInfo.SetRatio1) + "%";
			SetRatio2_Label->Caption = IntToStr(VibratorInfo.SetRatio2) + "%";

			NowSpeed_Label->Caption = IntToStr(VibratorInfo.NowSpeed);
		}
		else	// manual mode
		{
			VFManualModePanel->Visible = true;
			VFAutoModePanel->Visible = false;
			VFManualModeControlPanel->Visible = true;

			if (DefaultLCID == 1042 || DefaultLCID == 2066)
			{
				VibratorInfoChart->Series[0]->Title = "동작 속도";
				VibratorInfoChart->Series[1]->Title = "평균 속도";
				VibratorInfoChart->Series[2]->Title = "평균 센서 비율";
				VibratorInfoChart->Series[3]->Title = "측정 센서 비율";
				VibratorInfoChart->Series[4]->Title = "설정 비율";
			}
            else if(DefaultLCID == 1028)
            {
            }            
			else
			{
				VibratorInfoChart->Series[0]->Title = "Operating Speed";
				VibratorInfoChart->Series[1]->Title = "Average Speed";
				VibratorInfoChart->Series[2]->Title = "Sensor Average Ratio";
				VibratorInfoChart->Series[3]->Title = "Measured Sensor Ratio";
				VibratorInfoChart->Series[4]->Title = "Setting Ratio";
			}

			double VFSpeedList[VFINFO_LIST_COUNT];
			double VFMaxSpeedList[VFINFO_LIST_COUNT];
			double VFLowSensorRatioList[VFINFO_LIST_COUNT];
			double VFHighSensorRatioList[VFINFO_LIST_COUNT];
			double VF_SetRatioList[VFINFO_LIST_COUNT];

			int currentVFListIndex = VibratorInfo.CurrentListIndex & VFINFO_LIST_MASK;
			for (int vfIndex = 0; vfIndex < VFINFO_LIST_COUNT; vfIndex++)
			{
				VFSpeedList[vfIndex] = VibratorInfo.VFSpeedList[currentVFListIndex];
				VFMaxSpeedList[vfIndex] = ProductData.MachineRunOption.ManualMaxSpeed;
				VFLowSensorRatioList[vfIndex] = VibratorInfo.VFSensor1RatioList[currentVFListIndex];
				VFHighSensorRatioList[vfIndex] = VibratorInfo.VFSensor2RatioList[currentVFListIndex];
				VF_SetRatioList[vfIndex] = ProductData.MachineRunOption.ManualModeSensorActiveRatio;
				currentVFListIndex = (currentVFListIndex + 1) & VFINFO_LIST_MASK;
			}

			VibratorInfoChart->Series[0]->AddArray(VFSpeedList, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[2]->AddArray(VFLowSensorRatioList, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[3]->AddArray(VFHighSensorRatioList, VFINFO_LIST_COUNT - 1);
			VibratorInfoChart->Series[4]->AddArray(VF_SetRatioList, VFINFO_LIST_COUNT - 1);

			ManualModeSensor1OnRatioLabel->Caption = IntToStr(VibratorInfo.VFSensor1RatioList[(VibratorInfo.CurrentListIndex - 1) & VFINFO_LIST_MASK]) + "%";
			ManualModeSensor2OnRatioLabel->Caption = IntToStr(VibratorInfo.VFSensor2RatioList[(VibratorInfo.CurrentListIndex - 1) & VFINFO_LIST_MASK]) + "%";
			WCHAR TempString[100];
			wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_01, (ProductData.MachineRunOption.ManualModeSensorIndex + 1));
			VibratorManualSensorIndexLabel->Caption = TempString;
			VibratorManualSensorRatioLabel->Caption = IntToStr(ProductData.MachineRunOption.ManualModeSensorActiveRatio) + "%";
			VibratorCurrentSpeedLabel->Caption = IntToStr(VibratorInfo.VFSpeedList[(VibratorInfo.CurrentListIndex - 1) & VFINFO_LIST_MASK]);
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::VibratorInfoTimerTimer(TObject *Sender)
{
	bool timerEnabled = VibratorInfoTimer->Enabled;
	VibratorInfoTimer->Enabled = false;
	RefreshVibratorInfo();
	VibratorInfoTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::Repaint3DImage()
{
	Graphics::TBitmap *tempBitmap = new Graphics::TBitmap;
	tempBitmap->Width = IMAGE_WIDTH_3D;
	tempBitmap->Height = IMAGE_HEIGHT_3D;
	tempBitmap->PixelFormat = pf8bit;

	CurrentDefectImage->Width = IMAGE_WIDTH_3D * 2;
	CurrentDefectImage->Height = IMAGE_HEIGHT_3D;
	CurrentDefectImage->Picture->Bitmap->Width = IMAGE_WIDTH_3D * 2;
	CurrentDefectImage->Picture->Bitmap->Height = IMAGE_HEIGHT_3D;
	CurrentDefectImage->Picture->Bitmap->PixelFormat = pf24bit;

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

	int bitmapWidth = IMAGE_WIDTH_3D;
	int bitmapHeight = IMAGE_HEIGHT_3D;

	byte *tempBitmapA = new byte[bitmapWidth * bitmapHeight * 2];
	byte *tempBitmapB = new byte[bitmapWidth * bitmapHeight * 2];
	memset(tempBitmapA, 0, bitmapWidth * bitmapHeight * 2);

	for (int y = 0; y < bitmapHeight; y++)
	{
		byte *pSrc = (byte *)tempBitmap->ScanLine[y];
		for (int x = 0; x < bitmapWidth * 2; x += 2)
		{
			tempBitmapA[y * bitmapWidth * 2 + x] = pSrc[x / 2];
		}
	}

	for (int y = 1; y < bitmapHeight - 1; y++)
	{
		for (int x = 1; x < bitmapWidth * 2 - 1; x += 2)
		{
			int tempAddress = (y * bitmapWidth * 2 + x);
			int tempSum = 0;
			int tempCount = 0;
			if (tempBitmapA[tempAddress - 1])
			{
				tempSum += tempBitmapA[tempAddress - 1];
				tempCount++;
			}
			if (tempBitmapA[tempAddress + 1])
			{
				tempSum += tempBitmapA[tempAddress + 1];
				tempCount++;
			}
			if (tempBitmapA[tempAddress - 1 - bitmapWidth * 2])
			{
				tempSum += tempBitmapA[tempAddress - 1 - bitmapWidth * 2];
				tempCount++;
			}
			if (tempBitmapA[tempAddress - 1 + bitmapWidth * 2])
			{
				tempSum += tempBitmapA[tempAddress - 1 + bitmapWidth * 2];
				tempCount++;
			}
			if (tempBitmapA[tempAddress + 1 - bitmapWidth * 2])
			{
				tempSum += tempBitmapA[tempAddress + 1 - bitmapWidth * 2];
				tempCount++;
			}
			if (tempBitmapA[tempAddress + 1 + bitmapWidth * 2])
			{
				tempSum += tempBitmapA[tempAddress + 1 + bitmapWidth * 2];
				tempCount++;
			}

			if (tempCount)
				tempBitmapA[(tempAddress)] = tempSum / tempCount;
		}
	}

	memset(tempBitmapB, 0, bitmapWidth * bitmapHeight * 2);
	for (int y = 0; y < bitmapHeight; y++)
	{
		for (int x = 0; x < bitmapWidth * 2; x++)
		{
			int tempAddress = (y * bitmapWidth * 2 + x);
      tempBitmapB[tempAddress] = tempBitmapA[tempAddress];
		}
	}

	memcpy(tempBitmapA, tempBitmapB, bitmapWidth * bitmapHeight * 2);
	for (int y = 1; y < bitmapHeight - 1; y++)
	{
		for (int x = 1; x < bitmapWidth * 2 - 1; x++)
		{
			int tempAddress = (y * bitmapWidth * 2 + x);
			int tempSum = 0;
			int tempCount = 0;

			if (tempBitmapA[tempAddress] == 0)
			{
				if (tempBitmapB[tempAddress - bitmapWidth * 2])
				{
					tempSum += tempBitmapB[tempAddress - bitmapWidth * 2];
					tempCount++;
				}
				if (tempBitmapB[tempAddress + bitmapWidth * 2])
				{
					tempSum += tempBitmapB[tempAddress + bitmapWidth * 2];
					tempCount++;
				}
				if (tempBitmapB[tempAddress - bitmapWidth * 2 - 1])
				{
					tempSum += tempBitmapB[tempAddress - bitmapWidth * 2 - 1];
					tempCount++;
				}
				if (tempBitmapB[tempAddress - bitmapWidth * 2 + 1])
				{
					tempSum += tempBitmapB[tempAddress - bitmapWidth * 2 + 1];
					tempCount++;
				}
				if (tempBitmapB[tempAddress + bitmapWidth * 2 - 1])
				{
					tempSum += tempBitmapB[tempAddress + bitmapWidth * 2 - 1];
					tempCount++;
				}
				if (tempBitmapB[tempAddress + bitmapWidth * 2 + 1])
				{
					tempSum += tempBitmapB[tempAddress + bitmapWidth * 2 + 1];
					tempCount++;
				}

				if (tempCount >= 1)
					tempBitmapA[(tempAddress)] = tempSum / tempCount;
			}
		}
	}

	for (int y = 0; y < bitmapHeight; y++)
	{
		byte *pBitmap = (byte *)CurrentDefectImage->Picture->Bitmap->ScanLine[y];
		for (int x = 0; x < bitmapWidth * 2; x++)
		{
			pBitmap[3 * x] = pBitmap[3 * x + 1] = pBitmap[3 * x + 2] = tempBitmapA[y * bitmapWidth * 2 + x];
		}
	}

	delete[] tempBitmapA;
	delete[] tempBitmapB;

	delete tempBitmap;
}
//---------------------------------------------------------------------------
int __fastcall TInspectionForm::GetInspectionID(void)
{
	return (Now().Val * 1440);		// 1분에 1씩 증가한다.
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::OnUserChange(void)
{
  if(!ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_INSPECTIONFORM_GRADESETTING])
	{
    GradeSettingButton->Visible = false;
	}
  else
    GradeSettingButton->Visible = true;

  if(!ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_CALIBRATIONFORM_SPEED_CONTROL])
  {
    SpeedControlButton->Visible =false;
  }
  else
  {
    SpeedControlButton->Visible =true;
  }

  if(!ProgramAccessAuthorityData.ProgramAccessAuthorityTable[UserInfo.AccessLevel][ACCESS_PGM_EVT_MACHINESETUPFORM_ADJUST_VALUE])
  {
    NCControlButton->Visible =false;
  }
  else
  {
    NCControlButton->Visible =true;
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::VFSpeedControlUpDownClick(TObject *Sender,
	TUDBtnType Button)
{
	VFSpeedControlEdit->Text = IntToStr(VFSpeedControlUpDown->Position);
	ChangeVFSpeed(VFSpeedControlUpDown->Position);
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ChangeVFSpeed(int speed)
{
	Machine.VibratorSpeedChange(speed);
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::VFSpeedControlEditClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeypad() == mrOk)
	{
		theEdit->Text = KeyboardForm->Text;
		int speed = StrToInt(theEdit->Text);
		VFSpeedControlUpDown->Position = speed;
		ChangeVFSpeed(speed);
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::VibrationStopButtonClick(TObject *Sender)
{
	Machine.VFStop();
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ChartSelectionLabelDblClick(
	TObject *Sender)
{
	if (UserInfo.AccessLevel == SYSTEM_HIGHEST_ACCESS_LEVEL)
	{
		if (InspectionResultSpeedButton->Visible)
		{
			InspectionResultSpeedButton->Visible = false;
		}
		else
		{
			InspectionResultSpeedButton->Visible = true;
		}

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

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

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

		if (CounterSensorPanel->Visible)
		{
			CounterSensorPanel->Visible = false;
		}
		else
		{
			CounterSensorPanel->Visible = true;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::SendInspectionReadyCommand(int disk1TargetSpeed, int disk1BaseSpeed,
	int disk2TargetSpeed, int disk2BaseSpeed, bool *cameraEnabled)
{
	int defaultTriggerFreq;

	TInspectData InspectData;
	int writeMask;

  memset(ThreeDParamSetSatus,0,sizeof(int)*2);
  
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		writeMask = 0;

		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
			writeMask |= CAMERA_WRITE_MASK_3D_ROI;
		else
			writeMask |= CAMERA_WRITE_MASK_2D_ROI;

		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
			writeMask |= CAMERA_WRITE_MASK_3D_SH;
		else
			writeMask |= CAMERA_WRITE_MASK_2D_SH;

		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
		{
			writeMask |= CAMERA_WRITE_MASK_TH;
		}

    if (cameraEnabled[globalCameraIndex])
    {
      if(CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
      {
        int ThreedCameraIndex = 0;
        if(globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX-1) ThreedCameraIndex = 0;
        else ThreedCameraIndex = 1;

        if(ThreeDParamSetSatus[ThreedCameraIndex] == 0)
        {
          if(ProductData.ExposureTime3D[ThreedCameraIndex] != -1)
          {
            Set3DCamera_CaptureParameter(globalCameraIndex,ProductData.AnalogGain3D[ThreedCameraIndex],ProductData.ExposureTime3D[ThreedCameraIndex]);
          }
          else
          {
            Set3DCamera_CaptureParameter(globalCameraIndex,ThreeDCameraDefaultInformation[globalCameraIndex].AnalogCameraGain,ThreeDCameraDefaultInformation[globalCameraIndex].ExposureTime);
          }
		      ThreeDParamSetSatus[ThreedCameraIndex] =1;
        }
      }
      else
      {
        RefreshCameraInfoForInspectionSetting(&ProductData, ProductData.ShutterSpeed[globalCameraIndex], writeMask, globalCameraIndex, cameraEnabled, false);
        SetCameraGain(globalCameraIndex + 1, SYSTEM_DEFAULT_ANLOG_GAIN, ProductData.DigitalGainV[globalCameraIndex], 0);
      }
    }
	}

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    if(cameraEnabled[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] == false)
    {
      Set3DCamera_CaptureParameter(SD1_3D_FRONT_FACE_CAMERA_INDEX - 1, ThreeDCameraDefaultInformation[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].AnalogCameraGain, ThreeDCameraDefaultInformation[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].ExposureTime);
    }

    if(cameraEnabled[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1] == false)
    {
      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);
    }
  }

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		InspectData.CamMask = 0;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
      if(globalCameraIndex + 1 < HALF_INSPECTION_CAMERA_INDEX)
        defaultTriggerFreq = RANGER_3D_BASE_SHUTTER_SPEED;
      else
        defaultTriggerFreq = RANGER_3D_BASE_SHUTTER_SPEED2;

      bool ApplyLSFTable = false;
      if(PCProgramOption.ApplyLSFTableSW)
      {
        if(globalCameraIndex + 1 < HALF_INSPECTION_CAMERA_INDEX)
        {
          if(GlobalSD1LSFTable[disk1TargetSpeed])
          {
            defaultTriggerFreq = GlobalSD1LSFTable[disk1TargetSpeed];
            ApplyLSFTable = true;
          }
        }
        else
        {
          if(GlobalSD2LSFTable[disk2TargetSpeed])
          {
            defaultTriggerFreq = GlobalSD2LSFTable[disk2TargetSpeed];
            ApplyLSFTable = true;
          }
        }
      }

			int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
			if (spbIndex == CameraMapInfo[globalCameraIndex].SPBIndex)
			{
				for (int captureIndex = 0; captureIndex < SYSTEM_MACHINE_CAPTURE_COUNT; captureIndex++)
				{
					if (MachineSetupData.MachineCaptureInfo.CamMask[captureIndex] & (0x0001 << globalCameraIndex))
					{
            if (captureIndex < 3)
            {
              if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D) // 3d camera
              {
                InspectData.ShutterDelay[camIndex] = MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex] * disk1TargetSpeed / disk1BaseSpeed;
                InspectData.TriggerFreq[camIndex] = defaultTriggerFreq * disk1TargetSpeed / disk1BaseSpeed;

                if(ApplyLSFTable)
                {
                  InspectData.TriggerFreq[camIndex] = defaultTriggerFreq;
                }
              }
              else
              {
			if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
			{
				InspectData.ShutterDelay[camIndex] = (MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex]-(ProductData.StudiedSensor1Length/2)) * disk1TargetSpeed / disk1BaseSpeed;
			}
			else
			{
				InspectData.ShutterDelay[camIndex] = (MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex]) * disk1TargetSpeed / disk1BaseSpeed;
			
			}	
                InspectData.TriggerFreq[camIndex] = 1000;
              }
            }
            else
            {
              if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D) // 3d camera
              {
                InspectData.ShutterDelay[camIndex] = MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex] * disk2TargetSpeed / disk2BaseSpeed;
                InspectData.TriggerFreq[camIndex] = defaultTriggerFreq * disk2TargetSpeed / disk2BaseSpeed;

                if(ApplyLSFTable)
                {
                  InspectData.TriggerFreq[camIndex] = defaultTriggerFreq;
                }
              }
              else
              {
			if (0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
			{
				InspectData.ShutterDelay[camIndex] = (MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex]-(ProductData.StudiedSensor1Length/2)) * disk1TargetSpeed / disk1BaseSpeed;
			}
			else
			{
				InspectData.ShutterDelay[camIndex] = (MachineSetupData.MachineCaptureInfo.IlluminatorDelay[captureIndex]) * disk1TargetSpeed / disk1BaseSpeed;
			
			}	
                InspectData.TriggerFreq[camIndex] = 1000;
              }
            }
						InspectData.ShutterSpeed[camIndex] = ProductData.ShutterSpeed[globalCameraIndex];
					}
				}

				if (cameraEnabled[globalCameraIndex])
				{
					InspectData.CamMask |= (0x0001 << camIndex);
				}

				if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
				{
					InspectData.SubSamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
				}
				else
				{
					if (ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
						InspectData.SubSamplingMode[camIndex] = RESOLUTION_HIGH_QUALITY;
					else
						InspectData.SubSamplingMode[camIndex] = RESOLUTION_NORMAL_QUALITY;
				}
			}
		}

		// max waiting time 50ms -> 250ms
		// 5mm 정제 33만정 검사 진행 시 CPU 부족 발생
		// 28~9만정까지는 수용가능할 것으로 보임
		InspectData.TotalTabletCount = TabletInspectInfo.TotalTabletCount;
		InspectData.TabletType= ProductData.TabletType;
		InspectData.MaxProcessingWaitingTime = 250;// 250 -> 50 -> 100
		if(InspectionOption.LaserActiveMode)
		{
			InspectData.LaserStatus = 1;
		}
		else
		{
			InspectData.LaserStatus = 0; 
		}
		InspectData.SensorLength= ProductData.StudiedSensor1Length;
		// 250ms WaitingTime을 부여하는 경우 SPB에서 CPU 할당을 대기하는 동안 다음 Index에 대한 아무런 처리가 진행되지 않아 통신 타임아웃이 발생할 수 있음(State -> NONE)
																							 // 작은 정제 검사시 (5mm) CPU부족은 주로 3,4번 SPB에서 발생하므로 (실제로 카메라당 CPU 개수가 1, 2번에 비해 적음) 측면 영역에 대한 CPB상의 런타임을 줄여봐야 쓰것다

																							 // 5mm 정제 30만 속도에서 CPU 부족이 발생함... Waiting Time을 조금씩 수정해보자(1)(80) -> 80정도로는 별차이도 없음..

		if (!Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_READY, &InspectData, sizeof(TInspectData)))
		{
			//ShowMessageFA(SPBConnection[spbIndex].GetLastErrorMessage());
		}

    int data;
    int side_thick = 0;
    side_thick = (ProductData.TabletSideThick * 20 *0.8) * disk1TargetSpeed / disk1BaseSpeed;
    data = (MachineSetupData.LasercomplexerInfo.Laser_deley_time-CAPTURE_INT_DELAY_50US-(ProductData.StudiedSensor1Length/2)) * disk1TargetSpeed / disk1BaseSpeed;
//    data = data-100;
    if (!Comm_Request(COMM_SPB + spbIndex, CMD_GET_MAX_LASER_PROCESSING_TIME, &data, sizeof(int), NULL, 0))
    {

    }
	}

  if(0)//MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    // CAPTURE_TYPE_SINGLE_CAPTURE 모드에서는 함수가 호출되어서는 안됨
    SendThreeDCameraSensorOnOffSignal(1, RecentDisk1ThreeDCameraLSFValue, RecentDisk2ThreeDCameraLSFValue);
	}
}
//---------------------------------------------------------------------------

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

void __fastcall TInspectionForm::MisejectSpeedButtonClick(TObject *Sender)
{
 	CountCheckSpeedButton->Font->Color = clBlack;
	InspectChartSpeedButton->Font->Color = clBlack;
	MisejectSpeedButton->Font->Color = clBlue;
	EjectorSettingSpeedButton->Font->Color = clBlack;
  SimulationButton->Font->Color = clBlack;

	InspectionCountInfoPanel->Visible = false;
	InspectChartPanel->Visible = false;
	MisejectInfoPanel->Visible = true;
	EjectorSettingPanel->Visible = false;
  SimulationPanel->Visible = false;
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::CleaningButtonClick(TObject *Sender)
{
	// 추후 레이저 프린터 알람 확인용으로 추가 예정

	if (CleaningButton->Caption == INSPECTIONFORM_BUTTON_CAPTION_04)
	{
		if (ProductData.ProductCode.IsEmpty())
		{
			ShowMessageFA(INSPECTIONFORM_MSG_24);
			return;
		}

		Machine.MachineReady();
	}
	else
	{
		Machine.MachineCleaning();
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::CheckMachineState(void)
{
	if (Machine.Status.OperationState == MACHINE_STATE_CLEANING || Machine.Status.OperationState == MACHINE_STATE_DETACHING)
	{
		CleaningButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_04;
		CleaningButton->Enabled = true;
	}
	else if (Machine.Status.OperationState == MACHINE_STATE_STOP || Machine.Status.OperationState == MACHINE_STATE_ATTACHING)
	{
		CleaningButton->Caption = INSPECTIONFORM_BUTTON_CAPTION_16;
    if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
       if(wait_stop_step != 0)
    		CleaningButton->Enabled = false;
       else
        CleaningButton->Enabled = true;
    }
    else
		  CleaningButton->Enabled = true;
	}
	else
	{
		CleaningButton->Enabled = false;
	}

	if (Machine.Status.OperationState == MACHINE_STATE_RUN ||
		Machine.Status.OperationState == MACHINE_STATE_STARTING)
	{
		UnmanedOperationButton->Enabled = true;
	}
	else
	{
		UnmanedOperationButton->Enabled = false;
	}

  if(Machine.Status.OperationState == MACHINE_STATE_STOP)
  {
    if(wait_stop_step == 0 && MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
      if(!Machine.PortStatus.OPStatus[OP_MISEJECT_ACTUATOR_ON] && Machine.PortStatus.OPStatus[OP_MISEJECT_ACTUATOR_OFF])
      {
        Machine.MisejectOpen();
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::OptionalInfoPanelDblClick(TObject *Sender)
{
	if (OptionalDisplayKind == OPTION_DISPLAY_KIND_GRADE)
	{
		OptionalInfoPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_11;
		OptionalDisplayKind = OPTION_DISPLAY_KIND_MACHINE;
		MachineInfoPanel->BringToFront();
	}
	else if (OptionalDisplayKind == OPTION_DISPLAY_KIND_MACHINE)
	{
		OptionalInfoPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_36;
		OptionalDisplayKind = OPTION_DISPLAY_KIND_TABLET_INFO;
		TabletInfoPanel->BringToFront();
	}
  else if(OptionalDisplayKind == OPTION_DISPLAY_KIND_TABLET_INFO)
	{
    if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
    {
      OptionalInfoPanel->Caption = "Laser Monitoring";
      OptionalDisplayKind = OPTION_DISPLAY_KIND_LASER_INFO;
      LaserStatusInfoPanel->BringToFront();
    }
    else
    {
      OptionalInfoPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_07;
		  OptionalDisplayKind = OPTION_DISPLAY_KIND_GRADE;
		  GradeInfoPanel->BringToFront();
    }
	}
	else
	{
		OptionalInfoPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_07;
		OptionalDisplayKind = OPTION_DISPLAY_KIND_GRADE;
		GradeInfoPanel->BringToFront();
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::SystemMonitoringTimerTimer(
	TObject *Sender)
{

	SDMotorRPMPanel->Caption = IntToStr((int)(Machine.GetServoMotorRPM(SD1_MOTOR_INDEX))) + "RPM";


	if(MachineSetupData.MachineType == MACHINE_TYPE_SELMA_ADVANCED || MachineSetupData.MachineType == MACHINE_TYPE_LIMA_ADVANCED)
	{
		BFIDMotorRPMPanel->Caption = IntToStr((int)(Machine.GetServoMotorRPM(BF_OD_IN_MOTOR_INDEX))) + "RPM";
		BFODMotorRPMPanel->Caption = IntToStr((int)(Machine.GetServoMotorRPM(BF_OD_OUT_MOTOR_INDEX))) + "RPM";
	}
    else
    {
		BFIDMotorRPMPanel->Caption = IntToStr((int)(Machine.GetServoMotorRPM(BF_ID_MOTOR_INDEX))) + "RPM";
		BFODMotorRPMPanel->Caption = IntToStr((int)(Machine.GetServoMotorRPM(BF_OD_IN_MOTOR_INDEX))) + "RPM";
    }
	
	VFSpeedPanel->Caption = IntToStr(Machine.Status.VFSpeed);
	BFEmptySensorRatioPanel->Caption = IntToStr(Machine.Status.BFEmptySensorRatio) + "%";
	BFFullSensorRatioPanel->Caption = IntToStr(Machine.Status.BFFullSensorRatio) + "%";

	for (int thermometerIndex = 0; thermometerIndex < SYSTEM_MAX_THERMOMETER_COUNT; thermometerIndex++)
	{
		TTntPanel *temperaturePanel = (TTntPanel *)FindComponent("TemperatuePanel" + IntToStr(thermometerIndex + 1));
		TTntPanel *humidityPanel = (TTntPanel *)FindComponent("HumidityPanel" + IntToStr(thermometerIndex + 1));
		if (temperaturePanel)
		{
			temperaturePanel->Caption = FloatToStr(SystemMonitorInfo.CurrentTemperature[thermometerIndex] / 100.0) + "℃";
			if (SystemMonitorInfo.CurrentTemperature[thermometerIndex] < 3000)
			{
				temperaturePanel->Font->Color = clBlue;
			}
			else if (SystemMonitorInfo.CurrentTemperature[thermometerIndex] < 4000)
			{
				temperaturePanel->Font->Color = clLime;
			}
			else if (SystemMonitorInfo.CurrentTemperature[thermometerIndex] < 5000)
			{
				temperaturePanel->Font->Color = clYellow;
			}
			else
			{
				temperaturePanel->Font->Color = clRed;
			}
		}
		if (humidityPanel)
		{
			humidityPanel->Caption = FloatToStr(SystemMonitorInfo.CurrentHumidity[thermometerIndex] / 100.0) + "%Rh";
		}
	}

	PressurePanel1->Caption = FloatToStr(SystemMonitorInfo.Pressure[0]) + "kPa";
	if (SystemMonitorInfo.Pressure[0] > 500)
	{
		PressurePanel1->Font->Color = clLime;
	}
	else if (SystemMonitorInfo.Pressure[0] > 400)
	{
		PressurePanel1->Font->Color = clYellow;
	}
	else
	{
		PressurePanel1->Font->Color = clRed;
	}
	PressurePanel2->Caption = FloatToStr(SystemMonitorInfo.Pressure[1]) + "kPa";
	PressurePanel3->Caption = FloatToStr(SystemMonitorInfo.Pressure[2]) + "kPa";

	WCHAR TempString[100];

	wsprintfW(TempString, L"%SHz", FloatToStrF(SystemMonitorInfo.InverterSpeed[0] / 30.0, ffFixed, 10, 3));
	InverterSpeedPanel1->Caption = TempString;
	wsprintfW(TempString, L"%SHz", FloatToStrF(SystemMonitorInfo.InverterSpeed[1] / 30.0, ffFixed, 10, 3));
	InverterSpeedPanel2->Caption = TempString;
	wsprintfW(TempString, L"%SHz", FloatToStrF(SystemMonitorInfo.InverterSpeed[2] / 30.0, ffFixed, 10, 3));
	InverterSpeedPanel3->Caption = TempString;

  if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if(InspectionRestartButton->Enabled)
      UVLaser.SELMAStatus.InsRestart_ActiveStatus = 1;
    else
      UVLaser.SELMAStatus.InsRestart_ActiveStatus = 0;

    Panel105->Visible = true;
  }

}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::RefreshDefectsInfo(void)
{
	const int DISPLAY_DEFECT_COUNT = 10;
	int DefectCountList[MAX_DEFECT_SERIES_COUNT + 1];
	int DefectSeriesList[MAX_DEFECT_SERIES_COUNT + 1];

	for (int defectSeriesIndex = 0; defectSeriesIndex < MAX_DEFECT_SERIES_COUNT + 1; defectSeriesIndex++)
	{
		DefectCountList[defectSeriesIndex] = DefectSeriesCount[defectSeriesIndex];
		if (defectSeriesIndex < MAX_CPB_DEFECT_SERIES_COUNT)
		{
			DefectSeriesList[defectSeriesIndex] = defectSeriesIndex;
		}
		else
		{
			DefectSeriesList[defectSeriesIndex] = defectSeriesIndex - MAX_CPB_DEFECT_SERIES_COUNT + THIN_TALBET;
		}
	}

	// sort
	for (int i = 0; i < MAX_DEFECT_SERIES_COUNT; i++)
	{
		for (int j = i; j < MAX_DEFECT_SERIES_COUNT; j++)
		{
			if (DefectCountList[i] < DefectCountList[j])
			{
				int temp = DefectCountList[i];
				DefectCountList[i] = DefectCountList[j];
				DefectCountList[j] = temp;

				temp = DefectSeriesList[i];
				DefectSeriesList[i] = DefectSeriesList[j];
				DefectSeriesList[j] = temp;
			}
		}
	}

	float defectCountList[DISPLAY_DEFECT_COUNT];
	int defectSeriesList[DISPLAY_DEFECT_COUNT];
	int defectSeriesCount = 0;
	defectCountList[DISPLAY_DEFECT_COUNT - 1] = 0;
	for (int defectSeriesIndex = 0; defectSeriesIndex < MAX_DEFECT_SERIES_COUNT; defectSeriesIndex++)
	{
		if (DefectCountList[defectSeriesIndex] > 0)
		{
			if (defectSeriesCount < DISPLAY_DEFECT_COUNT)
			{
				if (defectSeriesCount < DISPLAY_DEFECT_COUNT - 1)
				{
					defectCountList[defectSeriesCount] = DefectCountList[defectSeriesIndex];
					defectSeriesList[defectSeriesCount] = DefectSeriesList[defectSeriesIndex];
					defectSeriesCount++;
				}
				else
				{
					defectCountList[DISPLAY_DEFECT_COUNT - 1] += DefectCountList[defectSeriesIndex];
				}
			}
		}
	}

	defectCountList[defectSeriesCount] = defectCountList[DISPLAY_DEFECT_COUNT - 1];

	TColor defectColorList[DISPLAY_DEFECT_COUNT] = { clLime, clRed, clYellow, clBlue, clFuchsia,
		(TColor)0x808040, (TColor)0x0080FF, clOlive, (TColor)0xFFFF80, clPurple };

	DefectChart->Series[0]->Clear();

	for (int defectSeriesIndex = 0; defectSeriesIndex < defectSeriesCount + 1; defectSeriesIndex++)
	{
		if (defectSeriesIndex < DISPLAY_DEFECT_COUNT)
		{
			if (defectCountList[defectSeriesIndex] > 0)
			{
				DefectChart->Series[0]->Add(defectCountList[defectSeriesIndex], IntToStr(defectSeriesIndex), defectColorList[defectSeriesIndex]);
			}
		}
	}

	for (int defectSeriesIndex = 0; defectSeriesIndex < DISPLAY_DEFECT_COUNT; defectSeriesIndex++)
	{
		TTntShape *defectSeriesShape = (TTntShape *)FindComponent("DefectSeriesShape" + IntToStr(defectSeriesIndex + 1));
		TTntLabel *defectNameLabel = (TTntLabel *)FindComponent("DefectNameLabel" + IntToStr(defectSeriesIndex + 1));
		TTntLabel *defectCountLabel = (TTntLabel *)FindComponent("DefectCountLabel" + IntToStr(defectSeriesIndex + 1));
		if (defectCountList[defectSeriesIndex] > 0 && defectSeriesIndex <= defectSeriesCount)
		{
			if (defectSeriesShape)
			{
				defectSeriesShape->Brush->Color = defectColorList[defectSeriesIndex];
				defectSeriesShape->Visible = true;
			}
			if (defectNameLabel)
			{
				if (defectSeriesIndex == defectSeriesCount)
				{
					defectNameLabel->Caption = INSPECTIONFORM_LABEL_CAPTION_20;
				}
				else
				{
					defectNameLabel->Caption = GetDefectSeriesStr(defectSeriesList[defectSeriesIndex]);
				}
				defectNameLabel->Visible = true;
			}
			if (defectCountLabel)
			{
				defectCountLabel->Caption = FloatToStr(defectCountList[defectSeriesIndex]);
				defectCountLabel->Visible = true;
			}
		}
		else
		{
			if (defectSeriesShape)
			{
				defectSeriesShape->Brush->Color = defectColorList[defectSeriesIndex];
				defectSeriesShape->Visible = false;
			}
			if (defectNameLabel)
			{
				defectNameLabel->Caption = GetDefectSeriesStr(defectSeriesList[defectSeriesIndex]);
				defectNameLabel->Visible = false;
			}
			if (defectCountLabel)
			{
				defectCountLabel->Caption = FloatToStr(defectCountList[defectSeriesIndex]);
				defectCountLabel->Visible = false;
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DisplayInspectionOption(void)
{
	if (!InspectionOption.MachineStopActivated)
	{
		MachineStopDefectRatioPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	}
	else
	{
		WCHAR TempString[100];
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_06, InspectionOption.MachineStopDefectRatio);
		MachineStopDefectRatioPanel->Caption = TempString;
	}
	if (!InspectionOption.MachineStopActivated)
	{
		MachineStopUnInsRatioPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	}
	else
	{
		WCHAR TempString[100];
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_06, InspectionOption.MachineStopUnInsRatio);
		MachineStopUnInsRatioPanel->Caption = TempString;
	}

  if (InspectionOption.DesiredInspectionCount <= 0)
	{
		MachineStopGPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	}
	else
	{
		WCHAR TempString[100];
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_03, InspectionOption.DesiredInspectionCount);
		MachineStopGPCountPanel->Caption = TempString;
	}

  if(InspectionOption.MachineStopTotalCount>0)
  {
    MachineStopTotalCountPanel->Caption =  IntToStr(InspectionOption.MachineStopTotalCount);
  }
  else
  {
    MachineStopTotalCountPanel->Caption =  "Infinity";
  }

	if (InspectionOption.MachineStopDPLimitCountActive == 0)
	{
		MachineStopDPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	}
	else
	{
		WCHAR TempString[100];
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_03, InspectionOption.MachineStopDPCount);
		MachineStopDPCountPanel->Caption = TempString;
	}
	if (InspectionOption.MachineStopUPLimitCountActive == 0)
	{
		MachineStopUPCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_26;
	}
	else
	{
		WCHAR TempString[100];
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_03, InspectionOption.MachineStopUPCount);
		MachineStopUPCountPanel->Caption = TempString;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearDefectTabletCount(void)
{
	TabletInspectInfo.DefectTabletCount = 0;
	TabletInspectInfo.SPBProcessingNCTabletCount = 0;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearUninspectedTabletCount(void)
{
	TabletInspectInfo.UnInsTabletCount = 0;
	TabletInspectInfo.SPBTOTabletCount = 0;
	TabletInspectInfo.SPBUnInsTabletCount = 0;
	TabletInspectInfo.DisappearedTabletCount = 0;
	TabletInspectInfo.InsertedTabletCount = 0;
	TabletInspectInfo.ClosedTabletDefectCount = 0;
	TabletInspectInfo.ClosedTabletUninsCount = 0;
	TabletInspectInfo.ClosedTabletCount = 0;
	TabletInspectInfo.WrongNumberTabletCount = 0;
	TabletInspectInfo.NumberUndefTabletCount = 0;
	TabletInspectInfo.CaptureNotReadyTabletCount = 0;
	TabletInspectInfo.BufferFullTabletCount = 0;
	TabletInspectInfo.CaptureTimoutTabletCount = 0;
	TabletInspectInfo.ProcessingTimoutTabletCount = 0;
	TabletInspectInfo.CPBFullTabletCount = 0;
	TabletInspectInfo.ProcessingErrorTabletCount = 0;
	TabletInspectInfo.UnInsTabletPositionCount = 0;
	TabletInspectInfo.UnInsBrightnessDropCount = 0;
	TabletInspectInfo.UnInsBrightnessChaseCount = 0;

	TabletInspectInfo.Sensor1MisFeedingTabletCount = 0;
	TabletInspectInfo.Sensor2MisFeedingTabletCount = 0;
	TabletInspectInfo.Sensor1MultiTabletCount = 0;
	TabletInspectInfo.Sensor2MultiTabletCount = 0;
	TabletInspectInfo.NozzErrorDefectTabletCount = 0;
	TabletInspectInfo.NozzErrorUnInsTabletCount = 0;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearInspectionStatistics(bool NewInspection)
{

  if(NewInspection)
  {
    InspectionRatioChart->Series[0]->Clear();
    InspectionRatioChart->Series[1]->Clear();
    InspectionRatioChart->Series[2]->Clear();

    InspectionRatioChart->BottomAxis->SetMinMax(0,100);
    InspectionRatioChart->BottomAxis->Scroll(0,100);
    InspectionRatioChart->Refresh();

    memset(GPRatioChartList, 0, RATIO_CHART_COUNT * sizeof(double));
	  memset(DPRatioChartList, 0, RATIO_CHART_COUNT * sizeof(double));
  	memset(UPRatioChartList, 0, RATIO_CHART_COUNT * sizeof(double));
	  InspectionRatioChartCount = 0;
  }

	CheckTPCount = TabletInspectInfo.TotalTabletCount;
	CheckGPCount = TabletInspectInfo.GoodTabletCount;
	CheckDPCount = TabletInspectInfo.DefectTabletCount;
	CheckUPCount = TabletInspectInfo.UnInsTabletCount;
  SectionRatioLabel->Caption = "0 %";
	TPHCheckTabletCount = TabletInspectInfo.TotalTabletCount;
	LastTPHCheckedTime = Now().Val;
	CurrentTPH = 0;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DisplayTabletInspectionInfo(void)
{
	TotalTabletCountLabel->Caption = IntToStr(TabletInspectInfo.GoodTabletCount + TabletInspectInfo.DefectTabletCount + TabletInspectInfo.UnInsTabletCount);
	GoodTabletCountLabel->Caption = IntToStr(TabletInspectInfo.GoodTabletCount);
	DefectTabletCountLabel->Caption = IntToStr(TabletInspectInfo.DefectTabletCount);
	UnInsTabletCountLabel->Caption = IntToStr(TabletInspectInfo.UnInsTabletCount);
	UnPrintTabletCountLabel->Caption = IntToStr(TabletInspectInfo.UnPrintTabletCount);
	CountedTabletCountLabel->Caption = IntToStr(TabletInspectInfo.CounterSensorTabletCount);
  UnPrintCountLabel->Caption = IntToStr(TabletInspectInfo.UnPrintTabletCount);

	/*
	//sjm TCPIP
	if(TcpSndFlag == True)
	{
	//MODUS_HEAD.transaction_id1 	= 0;
	//MODUS_HEAD.transaction_id2 	= 0;
	MODUS_HEAD.protocol_id1	 	= 0;
	MODUS_HEAD.protocol_id2	 	= 0;
	MODUS_HEAD.length1			= 0;
	MODUS_HEAD.unit_id 			= 0;
	MODUS_HEAD.function_code	= "R";
	if(CurrentTPH < 0 ) CurrentTPH = 0;

	MODUS_HEAD.length2 = CommControlForm->TxDatalength(MODUS_HEAD.function_code
	+"G"+GoodTabletCountLabel->Caption
	+"D"+DefectTabletCountLabel->Caption
	+"U"+UnInsTabletCountLabel->Caption
	+"S"+IntToStr(CurrentTPH)
	+"E") + 1;
	CommControlForm->TxDataToTcp(IntToStr(MODUS_HEAD.transaction_id1)
	+IntToStr(MODUS_HEAD.transaction_id2)
	+IntToStr(MODUS_HEAD.protocol_id1)
	+IntToStr(MODUS_HEAD.protocol_id2)
	+IntToStr(MODUS_HEAD.length1)
	+IntToStr(MODUS_HEAD.length2)
	+IntToStr(MODUS_HEAD.unit_id)
	+MODUS_HEAD.function_code
	+"G"+GoodTabletCountLabel->Caption
	+"D"+DefectTabletCountLabel->Caption
	+"U"+UnInsTabletCountLabel->Caption
	+"S"+IntToStr(CurrentTPH)
	+"E");
	}
	*/

	SPBPNCCountLabel->Caption = IntToStr(TabletInspectInfo.SPBProcessingNCTabletCount);
	SPBTOCountLabel->Caption = IntToStr(TabletInspectInfo.SPBTOTabletCount);
	ClosedTabletCountLabel->Caption = IntToStr(TabletInspectInfo.ClosedTabletCount);
	DisappearedTabletCountLabel->Caption = IntToStr(TabletInspectInfo.DisappearedTabletCount);
	InsertedTabletCountLabel->Caption = IntToStr(TabletInspectInfo.InsertedTabletCount);
	ClosedTabletUninsCountLabel->Caption = IntToStr(TabletInspectInfo.ClosedTabletUninsCount);
	ClosedTabletDefectCountLabel->Caption = IntToStr(TabletInspectInfo.ClosedTabletDefectCount);
	WrongNumberTabletCountLabel->Caption = IntToStr(TabletInspectInfo.WrongNumberTabletCount);
	NumberUndefTabletCountLabel->Caption = IntToStr(TabletInspectInfo.NumberUndefTabletCount);
	CaptureNotReadyTabletCountLabel->Caption = IntToStr(TabletInspectInfo.CaptureNotReadyTabletCount);
	BufferFullTabletCountLabel->Caption = IntToStr(TabletInspectInfo.BufferFullTabletCount);


	CaptureTimeoutTabletCountLabel->Caption = IntToStr(TabletInspectInfo.CaptureTimoutTabletCount);

	ProcessingTimeoutTabletCountLabel->Caption = IntToStr(TabletInspectInfo.ProcessingTimoutTabletCount);
	CPBFullTabletCountLabel->Caption = IntToStr(TabletInspectInfo.CPBFullTabletCount);
	ProcErrorTabletCountLabel->Caption = IntToStr(TabletInspectInfo.ProcessingErrorTabletCount);
	UnInsTabletPositionCountLabel->Caption = IntToStr(TabletInspectInfo.UnInsTabletPositionCount);
	UnInsBrightnessDropCountLabel->Caption = IntToStr(TabletInspectInfo.UnInsBrightnessDropCount);
	UnInsBrightnessChaseCountLabel->Caption = IntToStr(TabletInspectInfo.UnInsBrightnessChaseCount);
	TotalUnInsCountLabel->Caption = IntToStr(TabletInspectInfo.UnInsTabletCount);

	MissFeedingTabletCountLabel->Caption = IntToStr(TabletInspectInfo.Sensor1MisFeedingTabletCount + TabletInspectInfo.Sensor2MisFeedingTabletCount);
	MultiTabletCountLabel->Caption = IntToStr(TabletInspectInfo.Sensor1MultiTabletCount + TabletInspectInfo.Sensor2MultiTabletCount);
	NozzErrorUnInsTabletCountLabel->Caption = IntToStr(TabletInspectInfo.NozzErrorUnInsTabletCount);
	NozzErrorDefectTabletCountLabel->Caption = IntToStr(TabletInspectInfo.NozzErrorDefectTabletCount);

	MisejectActiveCountLabel->Caption = IntToStr(TabletInspectInfo.MisejectActiveCount);
	GoodTabletLostCountLabel->Caption = IntToStr(TabletInspectInfo.GoodTabletLostCount);
	MisejectTabletInsertCountLabel->Caption = IntToStr(TabletInspectInfo.MisejectTabletInsertCount);
	MisejectDefectTabletCountLabel->Caption = IntToStr(TabletInspectInfo.MisejectDefectTabletCount);
	MisejectUnInsTabletCountLabel->Caption = IntToStr(TabletInspectInfo.MisejectUnInsTabletCount);
	FRMismatchTabletCountLabel->Caption = IntToStr(TabletInspectInfo.FRMismatchTabletCount);

	WCHAR TempString[100];
	wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_04, CurrentTPH);
	TPHLabel->Caption = TempString;
	TPHPanel->Caption = IntToStr(CurrentTPH) + " T/H";
  	InspectInfo_Additional.InspectionSpeed = CurrentTPH;
	if (ElapsedTime > 0)
	{
		wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_04, (int)(TabletInspectInfo.TotalTabletCount / (ElapsedTime * 24)));
		TotalTPHLabel->Caption = TempString;
		TotalTPHPanel->Caption = IntToStr((int)(TabletInspectInfo.TotalTabletCount / (ElapsedTime * 24))) + " T/H";
	}
	else
	{
		TotalTPHPanel->Caption = "0 Tablet/Hour";
	}

	TotalTabletCountPanel->Caption = IntToStr(TabletInspectInfo.GoodTabletCount + TabletInspectInfo.DefectTabletCount + TabletInspectInfo.UnInsTabletCount);
  	InspectInfo_Additional.InspectionQuantity= TabletInspectInfo.GoodTabletCount + TabletInspectInfo.DefectTabletCount + TabletInspectInfo.UnInsTabletCount;
	GoodProductCountPanel->Caption = IntToStr(TabletInspectInfo.GoodTabletCount);
	DefectProductCountPanel->Caption = IntToStr(TabletInspectInfo.DefectTabletCount);
	UnInsProductCountPanel->Caption = IntToStr(TabletInspectInfo.UnInsTabletCount);
  
  DefectTotalCountPanel->Caption = IntToStr(TabletInspectInfo.DefectTabletCount);

	ProductRatioPanel->Caption = FloatToStrF((double)TabletInspectInfo.GoodTabletCount / (TabletInspectInfo.GoodTabletCount + TabletInspectInfo.DefectTabletCount) * 100, ffGeneral, 4, 2) + "%";
  	double CalcRatio = ((double)TabletInspectInfo.GoodTabletCount / ((double)TabletInspectInfo.GoodTabletCount + (double)TabletInspectInfo.DefectTabletCount) * 100.0f);
  	if(CalcRatio > 0)
    	InspectInfo_Additional.InspectionYield = CalcRatio;
	// display elapsed time
	int elapsedTimeHour = ElapsedTime * 24;
	int elapsedTimeMin = ElapsedTime * 24 * 60 - elapsedTimeHour * 60;
	int elapsedTimeSec = ElapsedTime * 24 * 3600 - elapsedTimeHour * 3600 - elapsedTimeMin * 60;

	wsprintfW(TempString, INSPECTIONFORM_LABEL_CAPTION_02, elapsedTimeHour, elapsedTimeMin, elapsedTimeSec);
	ElapsedTimeLabel->Caption = TempString;
	InspectionTimeLabel->Caption = TempString;

	// draw chart
	if (DefaultLCID == 1042 || DefaultLCID == 2066)
	{
		InspectionChart->Series[0]->Clear();
		InspectionChart->Series[0]->Add(TabletInspectInfo.GoodTabletCount, "양 품", clLime);
		InspectionChart->Series[0]->Add(TabletInspectInfo.DefectTabletCount, "불 량", clRed);
		InspectionChart->Series[0]->Add(TabletInspectInfo.UnInsTabletCount, "미 검", clYellow);
	}
	else
	{
		InspectionChart->Series[0]->Clear();
		InspectionChart->Series[0]->Add(TabletInspectInfo.GoodTabletCount, "Good Tablet", clLime);
		InspectionChart->Series[0]->Add(TabletInspectInfo.DefectTabletCount, "Defect Tablet", clRed);
		InspectionChart->Series[0]->Add(TabletInspectInfo.UnInsTabletCount, "Un-Inspection", clYellow);
	}
	
// cjg OPC Test
	if(hOPC_DLL)
	{
		(*pSetTabletInspectInfo)(&TabletInspectInfo);
		(*pSetMESProductData)(&MESProductData);
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::UpdateThroughputChart(void)
{
	ThroughputChart->Series[0]->Clear();
	ThroughputChartList[ThroughputChartCount] = CurrentTPH;
	ThroughputChartList[ThroughputChartCount + 1] = CurrentTPH;

	ThroughputChartCount++;
	ThroughputChart->Series[0]->AddArray(ThroughputChartList, ThroughputChartCount);
	if (ThroughputChartCount >= 100 && ThroughputChartAutoScroll)
	{
		ThroughputChart->BottomAxis->SetMinMax(ThroughputChartCount - 99, ThroughputChartCount + 1);
	}

	if (ThroughputChartCount + 1 >= ThroughputChartListSize)
	{
		double *tempArray = new double[ThroughputChartListSize];
		memcpy(tempArray, ThroughputChartList, ThroughputChartListSize * sizeof(double));
		delete[] ThroughputChartList;
		ThroughputChartList = new double[ThroughputChartListSize * 2];
		memcpy(ThroughputChartList, tempArray, ThroughputChartListSize * sizeof(double));
		delete[] tempArray;
		ThroughputChartListSize *= 2;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::UpdateInspectionRatioChart(void)
{
  //int TotalCount = TabletInspectInfo.GoodTabletCount +TabletInspectInfo.DefectTabletCount + TabletInspectInfo.UnInsTabletCount;
	int countedTabletCount = TabletInspectInfo.TotalTabletCount - (CheckTPCount - CheckUPCount);
	int countedTotalTabletCount =  TabletInspectInfo.TotalTabletCount - CheckTPCount;

	InspectionRatioChart->Series[0]->Clear();
	InspectionRatioChart->Series[1]->Clear();
	InspectionRatioChart->Series[2]->Clear();

	if (countedTabletCount > 0)
	{
		if (InspectionRatioChartCount < RATIO_CHART_COUNT)
		{
			GPRatioChartList[InspectionRatioChartCount] = (TabletInspectInfo.GoodTabletCount - CheckGPCount) * 100.0 / countedTabletCount;
			DPRatioChartList[InspectionRatioChartCount] = (TabletInspectInfo.DefectTabletCount - CheckDPCount) * 100.0 / countedTabletCount;
			UPRatioChartList[InspectionRatioChartCount] = (TabletInspectInfo.UnInsTabletCount - CheckUPCount) * 100.0 / countedTotalTabletCount;//countedTabletCount;
		}
		else
		{
			for (int listIndex = 0; listIndex < RATIO_CHART_COUNT - 1; listIndex++)
			{
				GPRatioChartList[listIndex] = GPRatioChartList[listIndex + 1];
				DPRatioChartList[listIndex] = DPRatioChartList[listIndex + 1];
				UPRatioChartList[listIndex] = UPRatioChartList[listIndex + 1];
			}

			GPRatioChartList[RATIO_CHART_COUNT - 1] = (TabletInspectInfo.GoodTabletCount - CheckGPCount) * 100.0 / countedTabletCount;
			DPRatioChartList[RATIO_CHART_COUNT - 1] = (TabletInspectInfo.DefectTabletCount - CheckDPCount) * 100.0 / countedTabletCount;
			UPRatioChartList[RATIO_CHART_COUNT - 1] = (TabletInspectInfo.UnInsTabletCount - CheckUPCount) * 100.0 / countedTotalTabletCount;//countedTabletCount;
		}
	}

  CheckTPCount =  TabletInspectInfo.TotalTabletCount;
	CheckGPCount = TabletInspectInfo.GoodTabletCount;
	CheckDPCount = TabletInspectInfo.DefectTabletCount;
	CheckUPCount = TabletInspectInfo.UnInsTabletCount;
	InspectionRatioChart->Series[0]->AddArray(GPRatioChartList, RATIO_CHART_COUNT);
	InspectionRatioChart->Series[1]->AddArray(DPRatioChartList, RATIO_CHART_COUNT);
	InspectionRatioChart->Series[2]->AddArray(UPRatioChartList, RATIO_CHART_COUNT);

  WCHAR TempString[100];

	if (InspectionRatioChartCount >= RATIO_CHART_COUNT)
	{
		for (int listIndex = 0; listIndex < RATIO_CHART_COUNT - 1; listIndex++)
		{
			InspectionRatioChart->Series[0]->XLabel[listIndex] = InspectionRatioChartCount - 100 + listIndex;
		}

    wsprintfW(TempString, L"%S", FloatToStrF(GPRatioChartList[RATIO_CHART_COUNT - 1], ffFixed, 10, 2));
	}
  else
  {
    wsprintfW(TempString, L"%S", FloatToStrF(GPRatioChartList[InspectionRatioChartCount], ffFixed, 10, 2));
  }


	SectionRatioLabel->Caption = TempString;
  SectionRatioLabel->Caption += " %";

	InspectionRatioChartCount++;

}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::CheckMachineSuspend(void)
{
	unsigned char suspendReason, machineSuspended;
	//sjm Chg Time
	//TTabletInspectReport tabletInspectReport;

	machineSuspended = Machine.Status.Suspended;
	suspendReason = Machine.Status.SuspendReason;

  if(!bUninsMachineStopSW)
  {
    AlarmForm->unInsReason = "";

    if (Machine.AlarmStatus.UPRatioOver || Machine.AlarmStatus.CritUPRatioOver)
    {
      bUninsMachineStopSW = true;
      
      WideString uninsReason = GetUninspectReason();

      if(uninsReason != NULL)
      {
        AlarmForm->unInsReason = uninsReason;
        //ShowMessageFA(INSPECTIONFORM_MSG_13 + uninsReason);
      }
    }
  }

	if (bSuspendCheck)
		return;

	if (machineSuspended)
	{
    //sjm Chg Time
		//tabletInspectReport.InspectionEndTime = Now().Val;
    EndOperName = UserInfo.Name;
		//ChgInspectionEndTime = tabletInspectReport.InspectionEndTime;
    ChgInspectionEndTime = Now().Val;

		AddCSVEventLog(ECSV_EVENT_MACHINE_SUSPEND, &suspendReason, sizeof(unsigned char));
		ConfirmSuspendStatus();

		if (suspendReason == MACHINE_SUSPEND_REASON_FEEDER_EMPTY)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_10);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_FEEDER_TROUBLE)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_07);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_DEFECT)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_15);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_UNINSPECT)
		{
      ShowMessageFA(INSPECTIONFORM_MSG_13);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_TIMEOUT)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_22);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_TABLET_DISAPPEAR)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_21);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_REGULATOR)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_08);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_BLOWER_OL)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_01);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_VD1_STALL)
		{
			while (true)
			{
				ShowMessageFA(INSPECTIONFORM_MSG_02);
				if (MessageDlgFA(INSPECTIONFORM_MSG_17, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
				{
					break;
				}
			}
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_VD2_STALL)
		{
			while (true)
			{
				ShowMessageFA(INSPECTIONFORM_MSG_03);
				if (MessageDlgFA(INSPECTIONFORM_MSG_17, mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
				{
					break;
				}
			}
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_GP_COUNT_REACHED)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_11);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_BRIGHTNESS_DOWN)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_20);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_DOOR_OPEN)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_09);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_DP_COUNT_REACHED)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_16);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_UP_COUNT_REACHED)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_12);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_VISION_SENSOR_1)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_19);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_VISION_SENSOR_2)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_18);
		}
		else if (suspendReason == MACHINE_SUSPEND_REASON_TIME_OVER)
		{
			ShowMessageFA(INSPECTIONFORM_MSG_04);
		}
		else if(suspendReason == MACHINE_SUSPEND_REASON_VB_SENSOR_EMPTY)
		{
			//ShowMessageFA(INSPECTIONFORM_MSG_18);
			//UVLaser.SELMAStatus.Ready = 1;
			//InspectionStopButton->Enabled = true;
		}
		else
		{
			ShowMessageFA(INSPECTIONFORM_MSG_06);
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DisplayInspectionResultTable(void)
{
	InspectionResultImage->Canvas->Brush->Color = clBlack;
	InspectionResultImage->Canvas->FillRect(Rect(0, 0, InspectionResultImage->Width, InspectionResultImage->Height));
	for (int tableIndex = 0; tableIndex < RESULT_TABLE_SIZE; tableIndex++)
	{
		int indexX = tableIndex % 16;
		int indexY = tableIndex / 16;
		if (tableIndex == InspectionResultTable.CurrentIndex || InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_NONE)
		{
			InspectionResultImage->Canvas->Brush->Color = clWhite;
			InspectionResultImage->Canvas->FillRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19));
		}
		else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_GOOD)
		{
			InspectionResultImage->Canvas->Brush->Color = clLime;
			InspectionResultImage->Canvas->FillRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19));
		}
		else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_DEFECT)
		{
			InspectionResultImage->Canvas->Brush->Color = clRed;
			InspectionResultImage->Canvas->FillRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19));
		}
		else
		{
			InspectionResultImage->Canvas->Brush->Color = clYellow;
			InspectionResultImage->Canvas->FillRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19));
			InspectionResultImage->Canvas->Font->Color = clBlack;
			InspectionResultImage->Canvas->Font->Size = 8;
			if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_UNINS_SPB_TIMEOUT)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB TO");
			}
			else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_UNINS_SPB_PROCESSING_NOT_COMPLETE)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "PROC NC");
			}
			else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_INSERTED)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "Inserted");
			}
			else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_DISAPPEARED)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "Disappeared");
			}
			else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_CLOSED_UNINS)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "Early");
			}
			else if (InspectionResultTable.Table[tableIndex].Result == TABLET_RESULT_CLOSED_DEFECT)
			{
				InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "Late");
			}
			else    // spb unins
			{
				int spbUnIns = (InspectionResultTable.Table[tableIndex].Result & ~TABLET_RESULT_SPB_MASK);
				if (spbUnIns == SPB_TABLET_RESULT_UNINS_IMAGE_BUFFER_FULL)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_BF");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_TABLET_NUMBER_UNDEFINED)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_NU");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_WRONG_TABLET_NUMBER)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_WN");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_CAPTURE_TIMEOUT)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_CTO");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_CNR");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_PROCESSING_TIMEOUT)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_PTO");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_PROCESSING_ERROR)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_PERR");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_CPB_FULL)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "SPB_CPBF");
				}
				else if (spbUnIns == SPB_TABLET_RESULT_UNINS_CLOSED_TABLET)
				{
					InspectionResultImage->Canvas->TextRect(Rect(indexX * 60 + 1, indexY * 20 + 1, indexX * 60 + 59, indexY * 20 + 19), indexX * 60 + 3, indexY * 20 + 3, "CLOSED");
				}
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::MakeHCBInspectionOption(int suctionDiskSpeed)
{
	if (InspectionOption.IsSingleDiscMode)
	{
		HCBInspectionOption.InspectionMode = 0;
	}
	else
	{
		HCBInspectionOption.InspectionMode = 1;
	}

	if (InspectionOption.MachineStopActivated)
	{
		HCBInspectionOption.MachineStopActivated = 1;
	}
	else
	{
		HCBInspectionOption.MachineStopActivated = 0;
	}

	HCBInspectionOption.InspectionNCAsDefect = 1;

	HCBInspectionOption.MachineStopDefectRatio = InspectionOption.MachineStopDefectRatio;
	HCBInspectionOption.MachineStopUnInsRatio = InspectionOption.MachineStopUnInsRatio;

	HCBInspectionOption.SPBMask = 0;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (InspectionOption.CameraEnabled[globalCameraIndex])
		{
			HCBInspectionOption.SPBMask |= (0x0001 << CameraMapInfo[globalCameraIndex].SPBIndex);
		}
	}

	HCBInspectionOption.TabletLength = ProductData.TabletLength;
	for (int globalCamIndex = 0; globalCamIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCamIndex++)
	{
		HCBInspectionOption.CameraMapInfo_SPB[globalCamIndex] = CameraMapInfo[globalCamIndex].SPBIndex;
		HCBInspectionOption.CameraMapInfo_CAM[globalCamIndex] = CameraMapInfo[globalCamIndex].CamIndex;
	}

	if (ProductData.EngraveType != ENGRAVE_TYPE_EMPTY && ProductData.EngraveType != ENGRAVE_TYPE_UNKNOWN)
	{
		// 2015-10-29 revision by moon
		// UnInspectionOption은 관련 카메라가 enable상태일때 flag를 넘긴다

		if (InspectionOption.CheckUnPrint)
		{
			HCBInspectionOption.CheckUnPrint = 1;
			HCBInspectionOption.UnPrintInspectionType = 0x000000;

			if (ProductData.EngravePos == ENGRAVE_POS_ONESIDE)
			{
				HCBInspectionOption.UnPrintInspectionType |= 0x100000;

				if (InspectionOption.CameraEnabled[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1])
				{
					HCBInspectionOption.UnPrintInspectionType |= 0x010000;
				}
			}
			else if (ProductData.EngravePos == ENGRAVE_POS_SAME)
			{
				if (InspectionOption.CameraEnabled[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1])
				{
					HCBInspectionOption.UnPrintInspectionType |= 0x000010;
				}
			}
			else if (ProductData.EngravePos == ENGRAVE_POS_DIFF)
			{
				if (InspectionOption.CameraEnabled[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_2D_FRONT_FACE_CAMERA_INDEX - 1] &&
					InspectionOption.CameraEnabled[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1])
				{
					HCBInspectionOption.UnPrintInspectionType |= 0x000001;
				}
			}
		}
		else
		{
			HCBInspectionOption.CheckUnPrint = 0;
			HCBInspectionOption.UnPrintInspectionType = 0x000000;
		}
	}
	else
	{
		HCBInspectionOption.CheckUnPrint = 0;
		HCBInspectionOption.UnPrintInspectionType = 0x000000;
	}

	HCBInspectionOption.CheckFrontRear = 0;
	if (ProductData.TabletLayerCount > 1 &&
		(ProductData.MultiLayeredTabletColor[0] != ProductData.MultiLayeredTabletColor[ProductData.TabletLayerCount - 1]))	// two color
	{
		if (InspectionOption.CameraEnabled[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1] &&
			InspectionOption.CameraEnabled[SD2_3D_FRONT_FACE_CAMERA_INDEX - 1])
			HCBInspectionOption.CheckFrontRear = 1;
	}

	HCBInspectionOption.MachineStopTotalCount = InspectionOption.MachineStopTotalCount;
	HCBInspectionOption.DesiredGPCount = InspectionOption.DesiredInspectionCount;
	HCBInspectionOption.MachineStopDPCount = InspectionOption.MachineStopDPCount;
	HCBInspectionOption.MachineStopUPCount = InspectionOption.MachineStopUPCount;
  HCBInspectionOption.QMachineMisejectActiveLimitCount = InspectionOption.QMachineMisejectActiveLimitCount;

	HCBInspectionOption.InspectionID = GetInspectionID();
	HCBInspectionOption.SuctionDiskSpeed = suctionDiskSpeed;

	HCBInspectionOption.StudiedTabletSensor1Length = ProductData.StudiedSensor1Length;
	HCBInspectionOption.StudiedTabletSensor2Length = ProductData.StudiedSensor2Length;

	//sjm add 깨진정제
	HCBInspectionOption.StudiedTabletSensor3Length = ProductData.StudiedSensor3Length;
	//ShowMessage("MakeHCBInspectionOption");
	//ShowMessage(ProductData.StudiedSensor3Length);

	HCBInspectionOption.StudiedSensorIntervalA = ProductData.StudiedSensorIntervalA;
	HCBInspectionOption.StudiedSensorIntervalB = ProductData.StudiedSensorIntervalB;
	HCBInspectionOption.TabletSideThick = ProductData.TabletSideThick*10;

	HCBInspectionOption.CaptureMode = 0;
  HCBInspectionOption.LaserStatus = InspectionOption.LaserActiveMode;

	getEjectInformation();
	writeEjectInformation();

  if(PCProgramOption.UVLaserEnabled)
  {
	  HCBInspectionOption.EjectMode = EJECT_NORMAL_MODE;
  }
  else
  {
	HCBInspectionOption.EjectMode = EjectorSettingInfo.EjectMode;
  }

	HCBInspectionOption.BlowInterval = EjectorSettingInfo.BlowInterval;
	HCBInspectionOption.BlowStart = EjectorSettingInfo.BlowStart;
	HCBInspectionOption.BlowLength = EjectorSettingInfo.BlowLength;
	HCBInspectionOption.UnInsBlowCheck = EjectorSettingInfo.UnInsBlowCheck;
  HCBInspectionOption.MisejectActiveTime = EjectorSettingInfo.MisejectActiveTime*20000.0f;

	// SELMA 200 스페셜모드 양품카운트
	HCBInspectionOption.SPModeGoodTabletCollectCount1 = EjectorSettingInfo.SPGoodTabletCollectCount1;
	HCBInspectionOption.SPModeGoodTabletCollectCount2 = EjectorSettingInfo.SPGoodTabletCollectCount2;

	//한국콜마  if문 살려야 함.
	if (DistributorTntPanel->Visible == true)
		HCBInspectionOption.DistributorCheck = 1;
	else
		HCBInspectionOption.DistributorCheck = 0;
	HCBInspectionOption.DistributorGoodTabletCount1 = EjectorSettingInfo.DistributorGoodTabletCount1;
	HCBInspectionOption.DistributorGoodTabletCount2 = EjectorSettingInfo.DistributorGoodTabletCount2;
	HCBInspectionOption.DistributorGoodTabletCount3 = EjectorSettingInfo.DistributorGoodTabletCount3;
  
	//한국콜마
	if (PCProgramOption.DistributorType1)
	{
		HCBInspectionOption.DHCountCheck[1] = 1;
		HCBInspectionOption.DHCountCheck[2] = 0;
		HCBInspectionOption.DHCountCheck[3] = 0;
		HCBInspectionOption.DHCountCheck[4] = 0;
	}
	else if (PCProgramOption.DistributorType2)
	{
		HCBInspectionOption.DHCountCheck[1] = 0;
		HCBInspectionOption.DHCountCheck[2] = 1;
		HCBInspectionOption.DHCountCheck[3] = 0;
		HCBInspectionOption.DHCountCheck[4] = 0;
	}
	else if (PCProgramOption.DistributorType3)
	{
		HCBInspectionOption.DHCountCheck[1] = 0;
		HCBInspectionOption.DHCountCheck[2] = 0;
		HCBInspectionOption.DHCountCheck[3] = 1;
		HCBInspectionOption.DHCountCheck[4] = 0;
    HCBInspectionOption.DistributorConveyerEnable = PCProgramOption.DistributorConveyerEnable == true ? 1 : 0;
	}
	else if (PCProgramOption.DistributorType4)
	{
		if(InspectionOption.SpecialInsCheckbox == 1)
		{
			HCBInspectionOption.DHCountCheck[1] = 0;
			HCBInspectionOption.DHCountCheck[2] = 0;
			HCBInspectionOption.DHCountCheck[3] = 0;
			HCBInspectionOption.DHCountCheck[4] = 1;
	    		HCBInspectionOption.DistributorConveyerEnable = PCProgramOption.DistributorConveyerEnable == true ? 1 : 0;
		}
		else
		{
			HCBInspectionOption.DHCountCheck[1] = 0;
			HCBInspectionOption.DHCountCheck[2] = 0;
			HCBInspectionOption.DHCountCheck[3] = 0;
			HCBInspectionOption.DHCountCheck[4] = 0;
	    		HCBInspectionOption.DistributorConveyerEnable = 0;
		}
	}

	HCBInspectionOption.SendCompleteSigDistributor = PCProgramOption.SendCompleteSigDistributor;

	///// 분배기(대화제약) /////insp
  HCBInspectionOption.DHSpecialInsCheckbox = InspectionOption.SpecialInsCheckbox;

	for (int i = 0; i < 6; i++)
	{
		HCBInspectionOption.DHSpecialInsCount[i] = ProductData.SpecialInsCount[i];
	}
	if (!InspectionOption.ReInspectionType == RE_INSPECTION_TYPE_NEW)
	{
		DHStartFlag = false;
	}
	if (DHStartFlag)
	{
		HCBInspectionOption.DHCountCheck[0] = 0;
	}
	
	if(NFALaserinfo.LaserMachineStatus == LaserMachineStatus_Run)
	{
		HCBInspectionOption.LaserStatus = 1;
	}
	else
	{
		HCBInspectionOption.LaserStatus = 0;
	}
	
	///// end /////
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::SPBInspectionSetup(void)
{
	int speedControlIndex = MachineOperationInfo.SpeedIndex;

	// send setup data (for iamge processing)
	int tempInspectionSetupSW = CPBSetupInfo.InspectionSetupDataValid;
	if (!SendInspectionSetupData())
	{
		return;
	}

	if (tempInspectionSetupSW == false)
	{
		WaitingForm->SetMessage(MAINFORM_MSG_13);
		WaitingForm->Show();
    Application->ProcessMessages();
		SubDefectInfoForm->RefreshInspectionSetupData();

		WaitingForm->Hide();
	}

	// send clear command
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_CLEAR);
	}

	ColorCountClear_Func(); //for PC_SIM

													// spb inspection setup
	SendInspectionReadyCommand(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][speedControlIndex], MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed,
		ProductData.MotorSpeedList[SD2_MOTOR_INDEX][speedControlIndex], MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed, InspectionOption.CameraEnabled);
}
//---------------------------------------------------------------------------
bool __fastcall TInspectionForm::HCBInspectionSetup(void)
{
	struct
	{
		THCBInspectionOption InspectionOption;
		TTabletInspectInfo TabletInspectInfo;
	} hcbInspectionData;

	memcpy(&(hcbInspectionData.InspectionOption), &HCBInspectionOption, sizeof(THCBInspectionOption));
	memcpy(&(hcbInspectionData.TabletInspectInfo), &TabletInspectInfo, sizeof(TTabletInspectInfo));

	return Comm_Request(COMM_HCB, CMD_INSPECTION_READY, &hcbInspectionData, sizeof(hcbInspectionData));
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearDefectInfoHeap(void)
{
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		memset(DefectTabletNumberHeap[globalCameraIndex], 0, DEFECT_SERIES_HEAP_SIZE * sizeof(int));
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::UnmanedOperationButtonClick(
	TObject *Sender)
{
	TUnmanedOperationForm *unmanedOperationForm = new TUnmanedOperationForm(this);
	unmanedOperationForm->ShowModal();
	delete unmanedOperationForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ThroughputChartMouseDown(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	ThroughputChartAutoScroll = false;
	ThroughputChartDownX = X;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ThroughputChartMouseUp(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	ThroughputChartAutoScroll = true;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ThroughputChartMouseMove(TObject *Sender,
	TShiftState Shift, int X, int Y)
{
	if (!ThroughputChartAutoScroll)
	{
		int ScrollValue = (ThroughputChartDownX - X);
		if (ThroughputChart->BottomAxis->Minimum + ScrollValue < 0)
		{
			ScrollValue = -ThroughputChart->BottomAxis->Minimum;
		}
		if (ThroughputChart->BottomAxis->Maximum + ScrollValue > max(100, ThroughputChartCount + 1))
		{
			ScrollValue = max(100, ThroughputChartCount + 1) - ThroughputChart->BottomAxis->Maximum;
		}

		ThroughputChart->BottomAxis->SetMinMax(ThroughputChart->BottomAxis->Minimum + ScrollValue,
			ThroughputChart->BottomAxis->Maximum +  ScrollValue);

		ThroughputChartDownX = X;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ProcessDefectSeries(bool processAllData)
{
	RefreshDefectsInfo();
}
//---------------------------------------------------------------------------
bool __fastcall TInspectionForm::ReadSetupData(TTabletSetupData *tabletSetupData)
{
	AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";
	if (FileExists(setupDataFileName))
	{
		TFileStream *fileStream = new TFileStream(setupDataFileName, fmOpenRead);
		if (fileStream)
		{
			memset(tabletSetupData, 0, sizeof(TTabletSetupData));
			fileStream->Read(tabletSetupData, fileStream->Size);
			delete fileStream;
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ThroughputChartDblClick(TObject *Sender)
{
	if (ThroughputChart->Series[0]->Marks->Visible)
	{
		ThroughputChart->Series[0]->Marks->Visible = false;
	}
	else
	{
		ThroughputChart->Series[0]->Marks->Visible = true;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::Panel37DblClick(TObject *Sender)
{
	TLogViewerForm *logViewerForm = new TLogViewerForm(this);
	logViewerForm->ShowModal();
	delete logViewerForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::AppUpdateTimer2Timer(TObject *Sender)
{
	if (AppOnOffFlag == true)
	{
		ClientForm->SendCmd(TabletInspectInfo.GoodTabletCount,
			TabletInspectInfo.DefectTabletCount,
			TabletInspectInfo.UnInsTabletCount,
			CurrentTPH);
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::APPClick(TObject *Sender)
{
	AnsiString filepath = "D:\\Project\\sLaser\\sLaser.exe";
	AnsiString PgmName = "NFA sLaser";
	if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
	{
		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);
		}
	}
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::EjectorSettingSpeedButtonClick(
	TObject *Sender)
{
	CountCheckLabel->Font->Color = clBlack;
	InspectChartLabel->Font->Color = clBlack;
	MisejectSpeedButton->Font->Color = clBlack;
	EjectorSettingLabel->Font->Color = clBlue;
  SimulationButton->Font->Color = clBlack;

	InspectionCountInfoPanel->Visible = false;
	InspectChartPanel->Visible = false;
	MisejectInfoPanel->Visible = false;
	EjectorSettingPanel->Visible = true;
  SimulationPanel->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::EjectorMode2RBClick(TObject *Sender)
{
	if (EjectorMode1RB->Checked)
	{
		EjectorLabel1->Font->Color = clWhite;

		EjectorEdit1->Enabled = false;
		EjectorEdit2->Enabled = false;
		EjectorEdit3->Enabled = false;

		EjectorCB1->Visible = false;
		EjectorCB1->Font->Color = clWhite;

		ApplyDefaultEjectInfoBtn->Enabled = true;

		EjectorMode1RB->Font->Color = clWhite;
		EjectorMode2RB->Font->Color = clGray;

		EjectorLabel5->Font->Color = clYellow;
		EjectorLabel6->Font->Color = clGray;

		//한국콜마
		//Q사 수거 Label.
		Label23->Visible = false;
		Label30->Visible = false;
		Label37->Visible = false;
		GoodCollect1Edit->Visible = false;
		GoodCollect2Edit->Visible = false;

		//GroupBox10->Visible = false;
		if (PCProgramOption.TwoSplitterEnable)
		{
			if (MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
			{
				DistributorTntPanel->Visible = true;
				GroupBox10->Visible = true;   //통 판넬.
				TntDistributorPanel2->Left = 64;
				TntLabel2->Left = 60;
				TntDistributorPanel3->Visible = true;
				TntLabel7->Visible = true;
			}
			else
			{
        DistributorTntPanel->Visible = true;
				GroupBox10->Visible = true;   //통 판넬.
				TntDistributorPanel2->Left = 64;
				TntLabel2->Left = 60;

        DistributorGoodCollect3Edit->Visible = false;
        TntLabel6->Visible = false;
				TntDistributorPanel3->Visible = false;
				TntLabel7->Visible = false;
			}
		}
		else
		{
			DistributorTntPanel->Visible = false;
			GroupBox10->Visible = false;   //통 판넬.
		}

	}
	else
	{
		EjectorLabel1->Font->Color = clWhite;

		EjectorEdit1->Enabled = true;
		EjectorEdit2->Enabled = true;
		EjectorEdit3->Enabled = true;

		ApplyDefaultEjectInfoBtn->Enabled = true;

		EjectorMode1RB->Font->Color = clGray;
		EjectorMode2RB->Font->Color = clWhite;

		EjectorLabel5->Font->Color = clGray;
		EjectorLabel6->Font->Color = clYellow;


		if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1 || MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
		{
			//TwoSplitterPanel 용임.
			Label23->Visible = true;
			Label30->Visible = true;
			Label37->Visible = true;
			GoodCollect1Edit->Visible = true;
			GoodCollect2Edit->Visible = true;

			GroupBox10->Visible = true;
			//한국콜마
			TntDistributorPanel3->Visible = false;
			TntLabel7->Visible = false;
			TntDistributorPanel2->Left = 80;
			TntLabel2->Left = 80;
      if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
      {
  			EjectorCB1->Visible = false;
      }
      else
        EjectorCB1->Visible = true;


		}
		else
		{
			EjectorCB1->Visible = true;
			GroupBox10->Visible = false;
		}
		//한국콜마
		DistributorTntPanel->Visible = false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::setEjectInformation()
{
	AnsiString fileName;
	fileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\EjectInformation.ini";

	if (FileExists(fileName))
	{
		readEjectInformation(fileName);
	}
	else
	{
		DefaultEjectInformation();
		writeEjectInformation();
	}

	EjectorSettingInfo.BlowStart = 0;
	EjectorSettingInfo.BlowLength = 0;
	EjectorSettingInfo.BlowInterval = 0;
	//EjectorSettingInfo.UnInsBlowCheck = 0;

	setEjectComponent();
}

//---------------------------------------------------------------------------
void __fastcall TInspectionForm::readEjectInformation(AnsiString FileName)
{
	try
	{
		TIniFile *iniFile = new TIniFile(FileName);
		if (iniFile)
		{
			EjectorSettingInfo.EjectMode = iniFile->ReadInteger("EjectInformation", "Mode", EJECT_NORMAL_MODE);
			EjectorSettingInfo.BlowInterval = iniFile->ReadInteger("EjectInformation", "Interval", 120);
			EjectorSettingInfo.BlowStart = iniFile->ReadInteger("EjectInformation", "Start", 25);
			EjectorSettingInfo.BlowLength = iniFile->ReadInteger("EjectInformation", "Length", 10);
			EjectorSettingInfo.UnInsBlowCheck = iniFile->ReadInteger("EjectInformation", "UnInspection Blow", 0);
      EjectorSettingInfo.MisejectActiveTime =iniFile->ReadFloat("EjectInformation", "Miseject Active time", MachineSetupData.EjectorInfo.MisejectActiveDelay/20000.0f);
      if(EjectorSettingInfo.MisejectActiveTime < 0)
      {
        EjectorSettingInfo.MisejectActiveTime = 6;
      }

			EjectorSettingInfo.SPGoodTabletCollectCount1 = iniFile->ReadInteger("EjectInformation", "Special Mode Good Tablet Collect Count1", MachineSetupData.EjectorInfo.SpModeGoodTabletCollectCount1);
			EjectorSettingInfo.SPGoodTabletCollectCount2 = iniFile->ReadInteger("EjectInformation", "Special Mode Good Tablet Collect Count2", MachineSetupData.EjectorInfo.SpModeGoodTabletCollectCount2);
			//한국콜마
			EjectorSettingInfo.DistributorGoodTabletCount1 = iniFile->ReadInteger("EjectInformation", "DistributorGoodTabletCount1", MachineSetupData.EjectorInfo.DistributorGoodTabletCount1);
			EjectorSettingInfo.DistributorGoodTabletCount2 = iniFile->ReadInteger("EjectInformation", "DistributorGoodTabletCount2", MachineSetupData.EjectorInfo.DistributorGoodTabletCount2);
			EjectorSettingInfo.DistributorGoodTabletCount3 = iniFile->ReadInteger("EjectInformation", "DistributorGoodTabletCount3", MachineSetupData.EjectorInfo.DistributorGoodTabletCount3);

			delete iniFile;
		}
	}
	catch (...)
	{

	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::writeEjectInformation()
{
	try
	{
		AnsiString fileName;
		fileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\EjectInformation.ini";

		TIniFile *iniFile = new TIniFile(fileName);
		if (iniFile)
		{
			iniFile->WriteInteger("EjectInformation", "Mode", EjectorSettingInfo.EjectMode);
			iniFile->WriteInteger("EjectInformation", "Interval", EjectorSettingInfo.BlowInterval);
			iniFile->WriteInteger("EjectInformation", "Start", EjectorSettingInfo.BlowStart);
			iniFile->WriteInteger("EjectInformation", "Length", EjectorSettingInfo.BlowLength);
			iniFile->WriteInteger("EjectInformation", "UnInspection Blow", EjectorSettingInfo.UnInsBlowCheck);
			iniFile->WriteInteger("EjectInformation", "Special Mode Good Tablet Collect Count1", EjectorSettingInfo.SPGoodTabletCollectCount1);
			iniFile->WriteInteger("EjectInformation", "Special Mode Good Tablet Collect Count2", EjectorSettingInfo.SPGoodTabletCollectCount2);
      iniFile->WriteFloat("EjectInformation", "Miseject Active time", EjectorSettingInfo.MisejectActiveTime);
			//한국콜마
			iniFile->WriteInteger("EjectInformation", "DistributorGoodTabletCount1", EjectorSettingInfo.DistributorGoodTabletCount1);
			iniFile->WriteInteger("EjectInformation", "DistributorGoodTabletCount2", EjectorSettingInfo.DistributorGoodTabletCount2);
			iniFile->WriteInteger("EjectInformation", "DistributorGoodTabletCount3", EjectorSettingInfo.DistributorGoodTabletCount3);
			delete iniFile;
		}
	}
	catch (...)
	{

	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DefaultEjectInformation()
{
	EjectorSettingInfo.EjectMode = MachineSetupData.EjectorInfo.EjectorDefaultMode;
	EjectorSettingInfo.SPGoodTabletCollectCount1 = MachineSetupData.EjectorInfo.SpModeGoodTabletCollectCount1;
	EjectorSettingInfo.SPGoodTabletCollectCount2 = MachineSetupData.EjectorInfo.SpModeGoodTabletCollectCount2;
	//한국콜마
	EjectorSettingInfo.DistributorGoodTabletCount1 = MachineSetupData.EjectorInfo.DistributorGoodTabletCount1;
	EjectorSettingInfo.DistributorGoodTabletCount2 = MachineSetupData.EjectorInfo.DistributorGoodTabletCount2;
	EjectorSettingInfo.DistributorGoodTabletCount3 = MachineSetupData.EjectorInfo.DistributorGoodTabletCount3;

	/*
	EjectorSettingInfo.BlowInterval = 120;

	switch(ProductData.TabletShape)
	{
	case TABLET_SHAPE_CIRCLE:
	case TABLET_SHAPE_HEXAGON:
	case TABLET_SHAPE_TRIANGLE:
	case TABLET_SHAPE_SQUARE:
	case TABLET_SHAPE_OCTAGON:
	EjectorSettingInfo.BlowStart = ProductData.StudiedSensor2Length / 3;
	EjectorSettingInfo.BlowLength = ProductData.StudiedSensor2Length / 3;

	break;

	case TABLET_SHAPE_OBLONG:
	case TABLET_SHAPE_OVAL:
	if(ProductData.TabletLength >= EJECT_INFO_STD_LENGTH) //19mm 보다 큰 정제
	{
	EjectorSettingInfo.BlowStart = EJECT_INFO_DEFAULT_START_POS;
	EjectorSettingInfo.BlowLength = EJECT_INFO_DEFAULT_END_POS;
	}
	else
	{
	EjectorSettingInfo.BlowStart = ((EJECT_INFO_DEFAULT_START_POS * ProductData.TabletLength) / EJECT_INFO_STD_LENGTH) + 2; // +2, -3 FM70 크기에 맞추기위한 상수값
	EjectorSettingInfo.BlowLength = ((EJECT_INFO_DEFAULT_END_POS * ProductData.TabletLength) / EJECT_INFO_STD_LENGTH) - 3;
	}
	break;

	case TABLET_SHAPE_ETC:
	if(ProductData.Arrange == NOT_ARRANGE)
	{
	EjectorSettingInfo.BlowStart = ProductData.StudiedSensor2Length / 3;
	EjectorSettingInfo.BlowLength = ProductData.StudiedSensor2Length / 3;
	}
	else if(ProductData.Arrange == ARRANGE)
	{
	if(ProductData.TabletLength >= EJECT_INFO_STD_LENGTH) //19mm 보다 큰 정제
	{
	EjectorSettingInfo.BlowStart = EJECT_INFO_DEFAULT_START_POS;
	EjectorSettingInfo.BlowLength = EJECT_INFO_DEFAULT_END_POS;
	}
	else
	{
	EjectorSettingInfo.BlowStart = ((EJECT_INFO_DEFAULT_START_POS * ProductData.TabletLength) / EJECT_INFO_STD_LENGTH) + 2; // +2, -3 FM70 크기에 맞추기위한 상수값
	EjectorSettingInfo.BlowLength = ((EJECT_INFO_DEFAULT_END_POS * ProductData.TabletLength) / EJECT_INFO_STD_LENGTH) - 3;
	}
	}
	break;

	default:
	EjectorSettingInfo.BlowStart = ProductData.StudiedSensor2Length / 3;
	EjectorSettingInfo.BlowLength = ProductData.StudiedSensor2Length / 3;
	break;
	}

	EjectorSettingInfo.UnInsBlowCheck = 0; // 기본값은 미검을 불어내지 않음 (양품 노즐 / 불량 + 미검 자유낙하)
	*/
	EjectorSettingInfo.BlowStart = 0;
	EjectorSettingInfo.BlowLength = 0;
	EjectorSettingInfo.BlowInterval = 0;
	EjectorSettingInfo.UnInsBlowCheck = 0;
  EjectorSettingInfo.MisejectActiveTime = MachineSetupData.EjectorInfo.MisejectActiveDelay / 20000.0f;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::setEjectComponent()
{
	if (EjectorSettingInfo.EjectMode == EJECT_NORMAL_MODE)
		EjectorMode1RB->Checked = true;
	else
		EjectorMode2RB->Checked = true;

	EjectorEdit1->Text = IntToStr(EjectorSettingInfo.BlowInterval);
	EjectorEdit2->Text = IntToStr(EjectorSettingInfo.BlowStart);
	EjectorEdit3->Text = IntToStr(EjectorSettingInfo.BlowLength);
	GoodCollect1Edit->Text = IntToStr(EjectorSettingInfo.SPGoodTabletCollectCount1);
  GoodCollect2Edit->Text = IntToStr(EjectorSettingInfo.SPGoodTabletCollectCount2);
  MisejectTimeEdit->Text = FloatToStr(EjectorSettingInfo.MisejectActiveTime);
 

	//한국콜마
	DistributorGoodCollect1Edit->Text = IntToStr(EjectorSettingInfo.DistributorGoodTabletCount1);
	DistributorGoodCollect2Edit->Text = IntToStr(EjectorSettingInfo.DistributorGoodTabletCount2);
	DistributorGoodCollect3Edit->Text = IntToStr(EjectorSettingInfo.DistributorGoodTabletCount3);

	EjectorCB1->Checked = EjectorSettingInfo.UnInsBlowCheck;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::getEjectInformation()
{
	if (EjectorMode1RB->Checked)
		EjectorSettingInfo.EjectMode = EJECT_NORMAL_MODE;
	else if (EjectorMode2RB->Checked)
		EjectorSettingInfo.EjectMode = EJECT_SPECIAL_MODE;

	EjectorSettingInfo.BlowInterval = StrToInt(EjectorEdit1->Text);
	EjectorSettingInfo.BlowStart = StrToInt(EjectorEdit2->Text);
	EjectorSettingInfo.BlowLength = StrToInt(EjectorEdit3->Text);
	EjectorSettingInfo.SPGoodTabletCollectCount1 = StrToInt(GoodCollect1Edit->Text);
	EjectorSettingInfo.SPGoodTabletCollectCount2 = StrToInt(GoodCollect2Edit->Text);
  EjectorSettingInfo.MisejectActiveTime = MachineSetupData.EjectorInfo.MisejectActiveDelay / 20000.0f;//StrToFloat(MisejectTimeEdit->Text);
	//한국콜마
	EjectorSettingInfo.DistributorGoodTabletCount1 = StrToInt(DistributorGoodCollect1Edit->Text);
	EjectorSettingInfo.DistributorGoodTabletCount2 = StrToInt(DistributorGoodCollect2Edit->Text);
	EjectorSettingInfo.DistributorGoodTabletCount3 = StrToInt(DistributorGoodCollect3Edit->Text);

	EjectorSettingInfo.UnInsBlowCheck = EjectorCB1->Checked;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::EjectorEdit1Click(TObject *Sender)
{
  TTntEdit *theEdit = (TTntEdit *) Sender;
	KeyboardForm->Text = theEdit->Text;
  if (KeyboardForm->ShowKeypad() == mrOk)
  {

    if(theEdit->Tag == 999)
    {
      double TempText = StrToFloat(KeyboardForm->Text);
      TempText = floor(TempText*10)/10;
      if(TempText > 60)
        TempText = 60;

      theEdit->Text = FloatToStr(TempText);
    }
    else
  		theEdit->Text = IntToStr(StrToInt(KeyboardForm->Text));
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ApplyDefaultEjectInfoBtnClick(
	TObject *Sender)
{
	DefaultEjectInformation();
	writeEjectInformation();
	setEjectComponent();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::EjectorLabel5Click(TObject *Sender)
{
	EjectorMode1RB->Checked = true;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::EjectorLabel6Click(TObject *Sender)
{
	EjectorMode2RB->Checked = true;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::TntFormClose(TObject *Sender,
	TCloseAction &Action)
{
	LinkSignalInit(false);

	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
	{
		UVLinkTimer->Enabled = false;
		//ProductData.DischargeCount = 0;
		UVLaser.SELMAStatus.Ready = 0;
		UVLaser.SELMAStatus.Active = 0;
    UVLaser.SELMAStatus.EMR = 0;
    UVLaser.SELMAStatus.InsRestart_ActiveStatus = 0;
    UVLaser.UVLaserStatus.InsForm_Active = 0;
    last_inspection_good_count = 0;

    SystemTimeTimer->Enabled = false;
	}
	getEjectInformation();
	writeEjectInformation();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::TntFormActivate(TObject *Sender)
{
	SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
	SetWindowPos(Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
	SetForegroundWindow(Handle);

  SetScreenPosition(this);

    if((PCProgramOption.DHprogram == true) && (PCProgramOption.DistributorType4 == true))
	{
   		DistributorMonitorButton->Visible = true;
        DistributorTimer->Enabled = true;
    }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::CheckMachineAlarmStatus()
{
	if (Machine.Status.AlarmExist)
	{
    wait_stop_step = 0;
		InspectionStopOption = INSPECTION_STOP_OPTION_MACHINE_STOP;
		InspectState = INSPECTION_STATE_STOPPING;
		InspectionStopButton->Enabled = false;
		StopInfoPanel->Visible = true;
		//ProductData.DischargeCount = 0;

    if (PCProgramOption.UVLaserEnabled && MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	  {
			PcUiFlag.InsReady = 0;
			PcUiFlag.InsActive = 0;
			Machine.SetUIFlagData();
	  }
    else if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
    {
      UVLaser.SELMAStatus.Ready = 0;
      UVLaser.SELMAStatus.Active = 0;
    }

		if (AlarmForm->SpbDisconnect)
			InspectionPause();
	}
}
//---------------------------------------------------------------------------


//sjm TCPIP : 타이머에 의해서 5초에 한번씩만 전송 하자.....
void __fastcall TInspectionForm::TcpSndTimer1Timer(TObject *Sender)
{
	if (TcpSndFlag == true)
	{
		//MODUS_HEAD.transaction_id1 	= 0;
		//MODUS_HEAD.transaction_id2 	= 0;
		MODUS_HEAD.protocol_id1 = 0;
		MODUS_HEAD.protocol_id2 = 0;
		MODUS_HEAD.length1 = 0;
		MODUS_HEAD.unit_id = 0;
		MODUS_HEAD.function_code = "R";
		if (CurrentTPH < 0) CurrentTPH = 0;

		MODUS_HEAD.length2 = CommControlForm->TxDatalength(MODUS_HEAD.function_code
			+ "G" + GoodTabletCountLabel->Caption
			+ "D" + DefectTabletCountLabel->Caption
			+ "U" + UnInsTabletCountLabel->Caption
			+ "S" + IntToStr(CurrentTPH)
			+ "E") + 1;
		CommControlForm->TxDataToTcp(IntToStr(MODUS_HEAD.transaction_id1)
			+ IntToStr(MODUS_HEAD.transaction_id2)
			+ IntToStr(MODUS_HEAD.protocol_id1)
			+ IntToStr(MODUS_HEAD.protocol_id2)
			+ IntToStr(MODUS_HEAD.length1)
			+ IntToStr(MODUS_HEAD.length2)
			+ IntToStr(MODUS_HEAD.unit_id)
			+ MODUS_HEAD.function_code
			+ "G" + GoodTabletCountLabel->Caption
			+ "D" + DefectTabletCountLabel->Caption
			+ "U" + UnInsTabletCountLabel->Caption
			+ "S" + IntToStr(CurrentTPH)
			+ "E");
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::BitBtn1Click(TObject *Sender)
{
	if (SimulationInspectionCheckBox->Checked)
	{
		int buff;

		buff = StrToInt(Edit2->Text);

		Comm_Request(COMM_HCB, CMD_VIRTUAL_INSPECTION_REFRESH, &buff, sizeof(int));
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::BitBtn2Click(TObject *Sender)
{
	TInspectionStatusForm *inspectionStatusForm = new TInspectionStatusForm(this);
	inspectionStatusForm->ShowModal();
	delete inspectionStatusForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::SetSPBVirtualInspectionImage()
{
	bool bThreeD;
	for (int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
	{
		if (cameraIndex != SD1_3D_FRONT_FACE_CAMERA_INDEX &&
			cameraIndex != SD2_3D_FRONT_FACE_CAMERA_INDEX)
		{
			bThreeD = false;
		}
		else
		{
			bThreeD = true;
		}

		if (InspectionOption.CameraEnabled[cameraIndex - 1])
    {
			if (CameraMapInfo[cameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[cameraIndex - 1] != 0)
			{
				int spbIndex = CameraMapInfo[cameraIndex - 1].SPBIndex;
        int imgNumber;
        imgNumber = StrToInt(Edit1->Text);

				memset(BayerImage, 0, sizeof(BayerImage));
				ExtractBayerImage(BayerImage, imgNumber, cameraIndex);

				int x, y;
				int tempAddress;
        int camnum;
        camnum = CameraMapInfo[cameraIndex - 1].CamIndex;

        Comm_RequestEx(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_SET_IMAGE, &camnum, sizeof(int), BayerImage, SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD]);
			}
    }
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::DistributorGoodCollect1EditClick(
	TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeypad() == mrOk)
	{
		theEdit->Text = KeyboardForm->Text;
	}
}
//---------------------------------------------------------------------------

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

void __fastcall TInspectionForm::DistributorGoodCollect3EditClick(
	TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeypad() == mrOk)
	{
		theEdit->Text = KeyboardForm->Text;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::CheckLinkBoard()
{
       /*	if (Machine.PortStatus.IPStatus[IP_LINK_READY])
		TntPanel4->Font->Color = clBlue;
	else
		TntPanel4->Font->Color = clRed;
	if (Machine.PortStatus.IPStatus[IP_LINK_ACTION])
		TntPanel5->Font->Color = clBlue;
	else
		TntPanel5->Font->Color = clRed;
	if(Machine.PortStatus.IPStatus[IP_LINK_EMR])
	  TntPanel6->Font->Color = clBlue;
	else
	  TntPanel6->Font->Color = clRed;


 	if (Machine.PortStatus.OPStatus[OP_LINK_READY])
		TntPanel11->Font->Color = clBlue;
	else
		TntPanel11->Font->Color = clRed;
	if (Machine.PortStatus.OPStatus[OP_LINK_ACTION])
		TntPanel10->Font->Color = clBlue;
	else
		TntPanel10->Font->Color = clRed;
	if(Machine.PortStatus.OPStatus[OP_LINK_EMR])
	  TntPanel8->Font->Color = clBlue;
	else
	  TntPanel8->Font->Color = clRed; */

}

void __fastcall TInspectionForm::UVLinkTimerTimer(TObject *Sender)
{
  bool TimerEnable = UVLinkTimer->Enabled;
  UVLinkTimer->Enabled = false;
	if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
	{
    if (ExternalWriteInspectionResult)
    {
      ExternalWriteInspectionResult = false;
      SaveInspectResult();
    }
    if(InspectionOption.QMachineDischargeActive && (InspectionTimeLabel->Caption != NULL && !InspectionTimeLabel->Caption.IsEmpty()) )
    {
      if(ProductData.DischargeCount < 0)
        ProductData.DischargeCount = 0;
      QDischargeCountPanel->Caption =  IntToStr(ProductData.DischargeCount) + " / " + IntToStr(InspectionOption.QMachineDischargeActiveCount);
    }
    else
      QDischargeCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;

    if(InspectionOption.QMachineMisejectActive == 1 && (InspectionTimeLabel->Caption != NULL && !InspectionTimeLabel->Caption.IsEmpty()))
      QMisejectCountPanel->Caption = IntToStr(TabletInspectInfo.MisejectActiveCount) + " / " +  IntToStr(InspectionOption.QMachineMisejectActiveLimitCount);
    else
      QMisejectCountPanel->Caption = INSPECTIONFORM_PANEL_CAPTION_27;

    if(UVLaser.UVLaserStatus.DLLLoadStatus)
    {
      if(!UVLaser.UVLaserStatus.NotRunFlag)
      {
        InspectionStartButton->Visible = true;
        InspectionRestartButton->Visible = true;
        switch (UVLaser.DLL_Command)
        {
          case COMMAND_None:
              //TO DO
            break;
          case COMMAND_Start:					// start
            if(InspectionStartButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.StartCommandApply = 1;
              if(InspectionRestartButton->Enabled == false)
              {
                AcrociaStartCommandFlag = true;
                InspectionStartButton->Click();
                AcrociaStartCommandFlag = false;
              }
              else
              {
                AcrociaStartCommandFlag = false;
                InspectionRestartButton->Click();
              }

              wait_stop_step = 0;
            }
            break;
          case COMMAND_ReStart:				// restart
            if(InspectionRestartButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.RestartCommandApply = 1;
              InspectionRestartButton->Click();
              wait_stop_step = 0;
            }
            break;
          case COMMAND_Resume:				// resume from waitstop
            if(wait_stop_step == INSPECTION_STATE_WAIT_STOP1 || wait_stop_step == INSPECTION_STATE_WAIT_STOP2)
            {
              UVLaser.UVLaserStatus.ResumeCommandApply = 1;
              InspectionWaitStop(INSPECTION_STATE_WAIT_STOP_RESUME);
              CommandWaitAction  = 0;
            }
            //TO DO
            break;
          case COMMAND_EmergencyStop:

            if (InspectionStopButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.EMStopCommandApply = 1;
              wait_stop_step = 0;
              CommandWaitAction  =0;
              InspectionStopButton->Click();
            }
            break;
          case COMMAND_Stop:
            if (InspectionStopButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.StopCommandApply = 1;
              wait_stop_step = 0;
              CommandWaitAction  = 0;
              InspectionStopButton->Click();
            }
            break;
          case COMMAND_WaitStop1:
            if (InspectionStopButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.WaitStop1CommandApply = 1;
                InspectionWaitStop(INSPECTION_STATE_WAIT_STOP1);
            }
            break;
          case COMMAND_WaitStop2:
            if (InspectionStopButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.WaitStop2CommandApply =1;
                InspectionWaitStop(INSPECTION_STATE_WAIT_STOP2);
            }
            break;
          case COMMAND_DischargeCountReset:	// counter reset
              SkipDischargeQuestion = 1;
              UVLaser.UVLaserStatus.DischargeResetCommandApply = 1;
              QDischargeResetBtn->Click();
            break;
          case COMMAND_ProductDataClear:
            if(InspectionStopButton->Enabled == false && InspectionRestartButton->Enabled == true)
            {
              UVLaser.UVLaserStatus.ProductDataClearApply =1;
              AcrociaInspectDataClearCommandFunc();
            }
            break;
          default:
            break;
        }
      }
      else if(UVLaser.UVLaserStatus.NotRunFlag)
      {
        if (InspectionStopButton->Enabled == true)
        {
          wait_stop_step = 0;
          InspectionStopButton->Click();
        }
        InspectionStartButton->Visible = false;
        InspectionRestartButton->Visible = false;
      }

      ConvertMESData();

      if(UVLaser.UVLaserStatus.Ready == 0) // notready
      {
        if(UVLaser.SELMAStatus.Active && wait_stop_step != INSPECTION_STATE_WAIT_STOP1 && wait_stop_step != INSPECTION_STATE_WAIT_STOP2)
        {
          InspectionWaitStop(INSPECTION_STATE_WAIT_STOP1);
        }
      }
      else if(UVLaser.UVLaserStatus.Ready == 1)
      {
        if(MachineSetupData.HopperEmptyEnable )
        {
          if(Machine.WarningStatus.VBFeederEmpty == 0 && Machine.PortStatus.IPStatus[IP_VB_SENSOR] == 1)
          {
            if(wait_stop_step == INSPECTION_STATE_WAIT_STOP1|| wait_stop_step == INSPECTION_STATE_WAIT_STOP2)
            {
              InspectionWaitStop(INSPECTION_STATE_WAIT_STOP_RESUME);
            }
          }
        }
        else
        {
          if(wait_stop_step == INSPECTION_STATE_WAIT_STOP1|| wait_stop_step == INSPECTION_STATE_WAIT_STOP2)
          {
            InspectionWaitStop(INSPECTION_STATE_WAIT_STOP_RESUME);
          }
        }
      }
    }
    else
    {
      UVLaser.UVLaserStatus.Ready = 1;
    }


    if(MachineSetupData.HopperEmptyEnable)
    {
      if(UVLaser.UVLaserStatus.Ready == 1)//1UVLaser.UVLaserStatus.Ready == 0)
      {
        if(StopInfoPanel->Visible == false)
        {
          if(UVLaser.SELMAStatus.Active || UVLaser.SELMAStatus.Ready)
          {
            if(Machine.PortStatus.IPStatus[IP_VB_SENSOR] == 0)   // 1 0 0 // Machine.WarningStatus.VBFeederEmpty == 1 &&
            {
              if(wait_stop_step != INSPECTION_STATE_WAIT_STOP1 && wait_stop_step != INSPECTION_STATE_WAIT_STOP2)
              {
                if(!Using_CaptuerSensorTimer)
                {
                  Using_CaptuerSensorTimer = true;
                  SD2CaptureSensor_UITimer = 0;
                }
                else
                {
                  if(Machine.PortStatus.IPStatus[IP_DISK_2_CAPTURE_SENSOR])
                    SD2CaptureSensor_UITimer = 0;
                  else
                    SD2CaptureSensor_UITimer++;

                  // 10 sec 1s = 20    50
                  if(SD2CaptureSensor_UITimer >= 2000 + (MachineSetupData.DiskStartDelay*200))
                  {
                    Using_CaptuerSensorTimer = false;
                    SD2CaptureSensor_UITimer = 0;

                    //if(last_vb_sensor_value != Machine.WarningStatus.VBFeederEmpty)
                    //{
                    InspectionWaitStop(INSPECTION_STATE_WAIT_STOP1);
                    last_vb_sensor_value = 0;
                    CommandWaitAction = 3;
                    //}
                  }
                }
              }
            }
            else if(Machine.PortStatus.IPStatus[IP_VB_SENSOR] == 1) // Machine.WarningStatus.VBFeederEmpty == 0 && 
            {
              //if(last_vb_sensor_value != Machine.WarningStatus.VBFeederEmpty)
              if(wait_stop_step == INSPECTION_STATE_WAIT_STOP1|| wait_stop_step == INSPECTION_STATE_WAIT_STOP2)
                {
                  InspectionWaitStop(INSPECTION_STATE_WAIT_STOP_RESUME);
                last_vb_sensor_value = 1;  // maybe no use 
                  CommandWaitAction = 0;
                }
            }
          }
          else
          {
            Using_CaptuerSensorTimer = false;
            SD2CaptureSensor_UITimer = 0;
          }
        }
      }
    }
	}
  else if(MachineSetupData.CompanyID == DOMESTIC_MACHINE2 && PCProgramOption.UVLaserEnabled)
  {
    Application->ProcessMessages();
    // SYstemTimer 에서 SELMA 의 알람 처리
    Machine.ReadPortStatus();
    CheckLinkBoard();
    bool LINK_MACHINE_STOP = false;

    if (PcUiFlag.EMR)
    {
      if (InspectionStopButton->Enabled == true)
        InspectionStopButton->Click();
    }

    if (!PcUiFlag.InsReady)
    {
      if (DefaultLCID == 1042 || DefaultLCID == 2066)
        InspectionStartButton->Caption = "검사 준비";
      else
        InspectionStartButton->Caption = "Ready";

      //return;
    }
    else // 알람 처리
    {
      if (!Machine.PortStatus.IPStatus[IP_LINK_EMR])
      {
        if (LastUVLaserStatus[3] == 0)
        {
          AlarmForm->LaserPrinterEMRAlarm = true;
          AlarmForm->Show();
          LastUVLaserStatus[3] = 1;
          LINK_MACHINE_STOP = true;
        }
      }
      else
      {
        if (LastUVLaserStatus[3] == 1)
        {
          AlarmForm->LaserPrinterEMRAlarm = false;
          LastUVLaserStatus[3] = 0;
        }
      }
    }


    if (LINK_MACHINE_STOP == false)
    {
      if (Machine.PortStatus.IPStatus[IP_LINK_READY])
      {
        if (InspectionStartStep == 1 && PcUiFlag.InsReady)
        {
          if (DefaultLCID == 1042 || DefaultLCID == 2066)
            InspectionStartButton->Caption = "검사 시작";
          else
            InspectionStartButton->Caption = "Start";

          InspectionStartButton->Enabled = true;

          LastUVLaserStatus[0] = 1;
          InspectionStartStep = 2;
        }

        // 시작한 준비가 끝나면 2 서로 Ready가 들어와있는 상태
        // 내가 신호를 보냈을때 inspectionstep 2 장비 돌 준비까지 끝나면  장비가 돌면 3

        if (PcUiFlag.InsActive) // 검사 시작이 되었을때 // 빨강 빨강일?? 내가 스타트를 눌렀어
        {
          /*if(InspectionStartStep == 2) InspectionStartStep =3;

          if(Machine.PortStatus.IPStatus[IP_LINK_ACTION])
          {
          LaserLinkIntervalTime = 0;

          if(LastUVLaserStatus[1] == 0)
          {
          if(InspectionStartStep == 3 && PcUiFlag.InsReady)
          {
          if(1)//Machine.PortStatus.IPStatus[IP_VB_SENSOR])
          {
          LastUVLaserStatus[1] = 1;
          InspectionStartButton->Click();

          }
          }
          }
          }
          else // SELMA 는 켜져있는데 레이저에서 반응이 없을때
          {
          if(LastUVLaserStatus[1] == 1)
          {
          InspectionStopButton->Click();
          LastUVLaserStatus[1] = 0;
          }
          if(LaserLinkIntervalTime >= 100000)
          {
          LINK_MACHINE_STOP = true;
          LaserLinkIntervalTime = 0;
          }
          else
          LaserLinkIntervalTime++;
          }                          */
        }
        else // 레이저 쪽에서 먼저 신호가 들어올때
        {
          if (Machine.PortStatus.IPStatus[IP_LINK_ACTION])
          {
            if (InspectionStartStep == 2) InspectionStartStep = 3;

            if (LastUVLaserStatus[1] == 0)
            {
              if (InspectionStartStep == 3 && PcUiFlag.InsReady)
              {
                if (1)//Machine.PortStatus.IPStatus[IP_VB_SENSOR])
                {
                  LastUVLaserStatus[1] = 1;
                  InspectionStartButton->Click();
                }
              }
            }
          }
        }

        if (LINK_MACHINE_STOP)
        {
          if (InspectionStopButton->Enabled == true)
          {
            InspectionStopButton->Click();
          }
          /*if(InspectionStartStep == 3 || InspectionStartStep == 2)
          {
          InspectionStopButton->Click();
          }*/
          /*else
          {
          for(int i = 0; i < 4 ; ++i)
          {
          if(i != 3)
          LastUVLaserStatus[i] = 0;
          }
          //memset(LastUVLaserStatus,0,sizeof(LastUVLaserStatus));
          }  */
          //return;
        }
      }
    }
    else // Laser Not Ready
    {
      if (!Machine.PortStatus.IPStatus[IP_LINK_EMR])
      {
        if (LastUVLaserStatus[3] == 0)
        {
          AlarmForm->LaserPrinterEMRAlarm = true;
          AlarmForm->Show();
          LastUVLaserStatus[3] = 1;
          LINK_MACHINE_STOP = true;
        }
      }
      else
      {
        if (LastUVLaserStatus[3] == 1)
        {
          AlarmForm->LaserPrinterEMRAlarm = false;
          LastUVLaserStatus[3] = 0;
        }
      }

      if (LastUVLaserStatus[1] == 1)
      {
        InspectionStopButton->Click();
      }

      //return;
    }

  }



  UVLinkTimer->Enabled = TimerEnable;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::AlarmTimerTimer(TObject *Sender)
{
	if (MachineSetupData.CompanyID == INTERNATIONAL_MACHINE2)
	{
		if (!Machine.Status.AlarmExist && StopInfoPanel->Visible == true)
		{
			if (!InspectionStopAlarm)
			{
				InspectionStopAlarm = true;
				Machine.AlarmBuzzerON();
			}
		}

		if (!Machine.Status.AlarmExist && StopInfoPanel->Visible == false)
		{
			if (InspectionStopAlarm)
			{
				InspectionStopAlarm = false;
				Machine.AlarmBuzzerOff();
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::LinkSignalInit(bool Clear)
{
	if (PCProgramOption.UVLaserEnabled && MachineSetupData.CompanyID == DOMESTIC_MACHINE2)
	{
	if (!Clear)
		{
			PcUiFlag.EMR = 0;
			Machine.SetUIFlagData();
			for (int i = 0; i < 4; ++i)
			{
				LastUVLaserStatus[i] = 0;
			}
		}
		else
		{
			if (InspectionStopButton->Enabled == true)
				InspectionStopButton->Click();
		}
	}
  else if(MachineSetupData.CompanyID == INTERNATIONAL_MACHINE1)
  {
    if (!Clear)
		{
			memset(&UVLaser.UVLaserStatus,0x00,sizeof(TTUVLaserPortStatus));
		}
		else
		{
			if (InspectionStopButton->Enabled == true)
				InspectionStopButton->Click();
		}
  }
}

void __fastcall TInspectionForm::ConvertMESData()
{
	try
	{
		memcpy(&MESUpDate_Param.TGradeData ,&TabletGradeData_PC, sizeof(TTabletGradeData));
		memcpy(&MESUpDate_Param.TInspectInfomation ,&TabletInspectInfo, sizeof(TTabletInspectInfo));
		memcpy(&MESUpDate_Param.TInspectOption ,&InspectionOption, sizeof(TInspectionOption));
    memcpy(&MESUpDate_Param.TInspectAddtionInfo, &InspectInfo_Additional, sizeof(TInspectionAdditionalInfo));
	}
	catch(...)
	{

	}
}

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

WideString __fastcall TInspectionForm::GetUninspectReason(void)
{
  // 장비가 미검사 비율 초과에 의해 멈추었을때 어떤 미검이 발생하였는지를 분석하기 위한 함수
  // PC프로그램에서는 현재 카운트 정보와 8초 전의 카운트 정보를 가지고있음
  // 아젠타 요청에 의해 초안으로 캡쳐타임아웃 미검 카운트만 비교
  // 추후 경우에 따라 다른 미검항목을 분석하는 코딩이 진행될 수 있음

  WideString retString = "";
  if(bSetPrevCount)
  {
    int deltaTotalCount, deltaUninsCount, deltaCaptureTimeoutCount, deltaCameraNotReadyCount;
    float CaptureTimeoutRatio;

    deltaTotalCount = TabletInspectInfo.TotalTabletCount - prevTabletInspectInfo.TotalTabletCount;
    deltaUninsCount = TabletInspectInfo.UnInsTabletCount - prevTabletInspectInfo.UnInsTabletCount;
    deltaCaptureTimeoutCount = TabletInspectInfo.CaptureTimoutTabletCount - prevTabletInspectInfo.CaptureTimoutTabletCount;
    deltaCameraNotReadyCount = TabletInspectInfo.CaptureNotReadyTabletCount - prevTabletInspectInfo.CaptureNotReadyTabletCount;

    if(deltaTotalCount > 0 && deltaUninsCount > 0)
    {
      // 전체 미검량에서 (캡쳐타임아웃 + 캡쳐준비안됨)의 빈도율을 계산
      CaptureTimeoutRatio = (deltaCaptureTimeoutCount + deltaCameraNotReadyCount) * 100 / (float)deltaUninsCount;

      if(CaptureTimeoutRatio > ERROR_CODE_CAPTURE_TIMEOUT_RATIO)
      {
        retString = "(Reason : Machine is not getting product images)";
      }
    }
  }

  return retString;
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::QDischargeResetBtnClick(TObject *Sender)
{
  switch(((TTntButton*)(Sender))->Tag)
  {
    case 0:
      if(SkipDischargeQuestion)
      {
        //last_inspection_good_count = ProductData.DischargeCount;
        last_inspection_good_count = TabletInspectInfo.GoodTabletCount;
        ProductData.DischargeCount = 0;
        SkipDischargeQuestion = 0;
        //ProductData.DischargeCount = TabletInspectInfo.GoodTabletCount - last_inspection_good_count;
        //SkipDischargeQuestion = 0;
      }
      else
      {
        if (MessageDlgFA("Reset?", mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
        {
          SkipDischargeQuestion = 0;
          last_inspection_good_count = TabletInspectInfo.GoodTabletCount;
          ProductData.DischargeCount = 0;
        }
      }
      ExternalWriteInspectionResult = true;
    break;
    case 1:
      if (MessageDlgFA("Reset?", mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
      {
        Comm_Request(COMM_HCB, CMD_ACROCIA_INSPECTION_INFO_RESET);
        TabletInspectInfo.MisejectActiveCount = 0;
        ExternalWriteInspectionResult = true;
      }
    break;
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::TntFormShow(TObject *Sender)
{
   UVLaser.UVLaserStatus.InsForm_Active = true;  
}
void TInspectionForm::AcrociaInspectDataClearCommandFunc()
{
  AnsiString resultDir;
  AnsiString resultFileName;
  try
  {
    resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Result";
    resultFileName = resultDir + "\\" + ProductData.LOTName + ".dat";
    DeleteFile(resultFileName.c_str());
    resultFileName = resultDir + "\\" + ProductData.LOTName + ".trp";
    DeleteFile(resultFileName.c_str());
    resultDir = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\Report";
    resultFileName = resultDir + "\\" + ProductData.LOTName + ".dsi";
    DeleteFile(resultFileName.c_str());
  }
  catch(...)
  {
  }

  DeleteInspectResult(false);
  ClearDefectInfoList();

  memset(&TabletInspectInfo, 0, sizeof(TTabletInspectInfo));
  memset(DefectTalbetNumList, 0, sizeof(DefectTalbetNumList));
  Comm_Request(COMM_HCB, CMD_ACROCIA_INSPECTION_INFO_RESET);
	ProductData.DischargeCount = 0;
	ElapsedTime = 0;
	last_inspection_good_count = 0;
	DefectTabletNumIndex = 0;
  ClearInspectionStatistics(true);
  ThroughputChart->Series[0]->Clear();
  InspectionChart->Series[0]->Clear();
  RefreshDefectsInfo();
  DisplayTabletInspectionInfo();
  DisplayInspectionOption();
  InspectionRestartButton->Enabled = false;


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


void __fastcall TInspectionForm::LaserMcbap_StartClick(TObject *Sender)
{
	int data[2];
	data[0] = StrToInt(LMCPeriodEdit->Text)/50;
	data[1] = StrToInt(DataPeriodEdit->Text)/50;
	if(!Comm_IsConnected(COMM_SPB + 6))
	{
		ShowMessageFA("Board dissconnected");
	}
	else
	{
		Comm_Request(COMM_SPB + 6, CMD_LASER_MCBSP_START, data, sizeof(data));
}
}

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

void __fastcall TInspectionForm::LaserMcbsp_StopClick(TObject *Sender)
{
	if(!Comm_IsConnected(COMM_SPB + 6))
	{
		ShowMessageFA("Board dissconnected");
	}
	else
	{
		Comm_Request(COMM_SPB + 6, CMD_LASER_MCBSP_STOP);
	}
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::DataPeriodEditChange(TObject *Sender)
{
	int period;
	period = StrToInt(DataPeriodEdit->Text);
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::LMCPeriodEditChange(TObject *Sender)
{
	int period;
	period = StrToInt(LMCPeriodEdit->Text);
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::TrigOnBtnClick(TObject *Sender)
{
  Comm_Request(COMM_HCB, CMD_LASER_SWITCH_ON);
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::EnableLaserTestClick(TObject *Sender)
{
	int testmodeSW=0;
  if(EnableLaserTest->Checked)
  {
    TrigOnBtn->Visible = true;
    testmodeSW = 1;
  }
  else
  {
    TrigOnBtn->Visible = false;
    testmodeSW = 0;
  }

	Comm_Request(COMM_HCB, CMD_LASER_TESTMODE_ON, &testmodeSW, sizeof(int));
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::CPBStatusCheckTimerTimer(TObject *Sender)
{
  if(!MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable) return;
  
  int spbIndex = CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].SPBIndex;

  if(Comm_IsConnected(COMM_SPB + spbIndex))
  {
    CPBStatusGroupBox->Caption = "CPB Status (#" + IntToStr(spbIndex + 1) + ")";

    if(Comm_Request(COMM_SPB + spbIndex, CMD_CPB_STATUS, NULL, 0, CPBStatus, sizeof(TCPBStatus) * SYSTEM_CPB_COUNT))
    {
      for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
      {
        bool isDown = false;
        if(!CPBStatus[cpbIndex].Enabled || CPBStatus[cpbIndex].IsDown || CPBStatus[cpbIndex].reserved == 0)
        {
          isDown = true;
        }

        TTntShape *tempCPBStatusShape = (TTntShape *)FindComponent("CPBStatusShape" + IntToStr(cpbIndex + 1));

        if(tempCPBStatusShape)
        {
          if(isDown)
          {
            tempCPBStatusShape->Pen->Color = clRed;
            tempCPBStatusShape->Brush->Color = clRed;
          }
          else
          {
            //reserved [0 : down / 1 : idle / 2 : busy]
            if(CPBStatus[cpbIndex].reserved == 1)
            {
              tempCPBStatusShape->Pen->Color = clGreen;
              tempCPBStatusShape->Brush->Color = clGreen;
            }
            else if(CPBStatus[cpbIndex].reserved == 2)
            {
              tempCPBStatusShape->Pen->Color = 0x003198FF;
              tempCPBStatusShape->Brush->Color = 0x003198FF;
            }
          }
        }
      }
    }
  }
  else
  {
    CPBStatusGroupBox->Caption = "#" + IntToStr(spbIndex + 1) + " Board Disconnected";

    for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++) // init
    {
      TTntShape *tempCPBStatusShape = (TTntShape *)FindComponent("CPBStatusShape" + IntToStr(cpbIndex + 1));

      if(tempCPBStatusShape)
      {
        tempCPBStatusShape->Pen->Color = clRed;
        tempCPBStatusShape->Brush->Color = clRed;
      }
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::UploadRealtimeCapturedImageTimerTimer(
      TObject *Sender)
{
  bool timerEnableStatus = UploadRealtimeCapturedImageTimer->Enabled;
  UploadRealtimeCapturedImageTimer->Enabled = false;

  if(!MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable) return;

  struct
  {
    int ExistImage;
    int RemainingImageCount;
  }Data;

  TFileStream *pFileStream = NULL;
  bool Pass = false;
  for(int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    if(globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1 || globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
    {
      int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
      if(Comm_IsConnected(COMM_SPB + spbIndex))
      {
        if(Comm_Request(COMM_SPB + spbIndex, CMD_CHECK_RT_IMAGE_EXIST, NULL, NULL, &Data, sizeof(Data)))
        {
          if(Data.ExistImage) // exist
          {
            if(globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
            {
              RT2DBuffering->Position = Data.RemainingImageCount;

              int nInterval = 0;
              if(RT2DBuffering->Position >= RT2DBuffering->Max * 80 / 100)
              {
                nInterval = 8;
              }
              else if(RT2DBuffering->Position >= RT2DBuffering->Max * 60 / 100)
              {
                nInterval = 4;
              }
              else if(RT2DBuffering->Position >= RT2DBuffering->Max * 40 / 100)
              {
                nInterval = 2;
              }
              else
              {
                nInterval = 1;
              }

              if(prev2DImageControlInterval != nInterval)
              {
                Comm_Request(COMM_SPB + spbIndex, CMD_REFRESH_RT_IMG_INTERVAL, &nInterval, sizeof(int), NULL, 0);
                prev2DImageControlInterval = nInterval;
              }
            }
            else if(globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
            {
              RT3DBuffering->Position = Data.RemainingImageCount;

              int nInterval = 0;
              if(RT3DBuffering->Position >= RT3DBuffering->Max * 80 / 100)
              {
                nInterval = 8;
              }
              else if(RT3DBuffering->Position >= RT3DBuffering->Max * 60 / 100)
              {
                nInterval = 4;
              }
              else if(RT3DBuffering->Position >= RT3DBuffering->Max * 40 / 100)
              {
                nInterval = 2;
              }
              else
              {
                nInterval = 1;
              }

              if(prev3DImageControlInterval != nInterval)
              {
                Comm_Request(COMM_SPB + spbIndex, CMD_REFRESH_RT_IMG_INTERVAL, &nInterval, sizeof(int), NULL, 0);
                prev3DImageControlInterval = nInterval;
              }
            }

            if(Comm_Request(COMM_SPB + spbIndex, CMD_GET_REALTIME_IMAGE, NULL, NULL, RealtimeUploadImage, REALTIME_CAMERA_WIDTH * REALTIME_CAMERA_HEIGHT))
            {
              int cameraIndex = *((int*)RealtimeUploadImage + 0);
              int TabletNumber = *((int*)RealtimeUploadImage + 1);

              int printdata[4];
              memset(printdata, 0, sizeof(int) * 4);
              printdata[0] = *((int*)RealtimeUploadImage + 2);
              printdata[1] = *((int*)RealtimeUploadImage + 3);
              printdata[2] = *((int*)RealtimeUploadImage + 4);
              printdata[3] = *((int*)RealtimeUploadImage + 5);

              if(TabletNumber)
              {
                if(RTTabletMinNumber > TabletNumber) RTTabletMinNumber = TabletNumber;
                if(RTTabletMaxNumber < TabletNumber) RTTabletMaxNumber = TabletNumber;

                int fileIndex = 0;
                int dataIndex = 0;

                AnsiString CameraType;

                if(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX)
                {
                  CameraType = "2D";
                  fileIndex =  (TabletNumber - 1) / 1000 + 1;
                  dataIndex =  (TabletNumber - 1) % 1000 + 1;
                }
                else
                {
                  CameraType = "3D";
                  fileIndex =  (TabletNumber - 1) / 1000 + 1;
                  dataIndex =  (TabletNumber - 1) % 1000 + 1;
                }

                if(prevPageIndex != fileIndex)
                {
                  // clear
                  prevPageIndex = fileIndex;
                  for(int i = LaserMonitoringStringGrid->FixedRows; i < LaserMonitoringStringGrid->RowCount; ++i)
                  {
                    LaserMonitoringStringGrid->Rows[i]->Clear();
                  }
                }

                AnsiString dirPathName = ProgramPath.Root + "\\Laser Monitoring";
                AnsiString lmFileName = dirPathName + "\\Marking" + IntToStr(fileIndex) + "_" + CameraType + ".dat";

                if(FileExists(lmFileName))
                {
                  pFileStream = new TFileStream(lmFileName, fmOpenWrite);
                }
                else
                {
                  pFileStream = new TFileStream(lmFileName, fmCreate);
                  pFileStream->Position = 0;

                  unsigned char *nullData = new unsigned char [REALTIME_IMAGE_SIZE * 1000];
                  memset(nullData, 0, REALTIME_IMAGE_SIZE * 1000);
                  pFileStream->Write(nullData, REALTIME_IMAGE_SIZE * 1000);
                  delete nullData;
                }

                if(pFileStream->Size < REALTIME_IMAGE_SIZE * 1000) // 1000개의 데이터
                {
                  pFileStream->Seek(pFileStream->Size, soFromBeginning);
                }
                else
                {
                  // over write
                  pFileStream->Seek((dataIndex - 1) * REALTIME_IMAGE_SIZE, soFromBeginning);
                }

                pFileStream->Write(RealtimeUploadImage, REALTIME_IMAGE_SIZE);

                // average data

                if(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX)
                {
                  if(!(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0))
                  {
                    AverageBrightness += printdata[0];
                    AverageThetaResult += printdata[1];
                    AverageXResult += printdata[2];
                    AverageYResult += printdata[3];
                    AverageResultCount++;
                  }
                }

                int AverageValue[4];
                memset(AverageValue, 0, sizeof(int) * 4);
                if(AverageResultCount)
                {
                  AverageValue[0] = AverageBrightness / AverageResultCount;
                  AverageValue[1] = AverageThetaResult / AverageResultCount;
                  AverageValue[2] = AverageXResult / AverageResultCount;
                  AverageValue[3] = AverageYResult / AverageResultCount;
                }

                int AvgBrightness = AverageValue[0];
                int AvgBrightnessPercentage;
                if(AvgBrightness >= PrintMinColor && AvgBrightness <= meanTabletColor)
                {
                  AvgBrightnessPercentage = (meanTabletColor - AvgBrightness) * 100 / (meanTabletColor - PrintMinColor);
                }
                else if(AvgBrightness > meanTabletColor)
                {
                  AvgBrightnessPercentage = 0;
                }
                else
                {
                  AvgBrightnessPercentage = 100;
                }

                AverageBrightnessLabel->Caption = IntToStr(AvgBrightnessPercentage) + "%";
                AverageThetaLabel->Caption = IntToStr(AverageValue[1]) + " º";
                AverageXLabel->Caption = FloatToStrF(AverageValue[2] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                AverageYLabel->Caption = FloatToStrF(AverageValue[3] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";

                Pass = false;
                for(int i = 1; i < LaserMonitoringStringGrid->RowCount; ++i)
                {
                  if(LaserMonitoringStringGrid->Cells[1][i] == IntToStr(TabletNumber))
                  {
                    if(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX)
                    {
                      if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
                      {
                        LaserMonitoringStringGrid->Cells[2][i] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[3][i] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[4][i] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[5][i] = "Unprinted";
                      }
                      else
                      {
                        int Brightness = printdata[0];
                        int BrightnessPercentage;
                        if(Brightness >= PrintMinColor && Brightness <= meanTabletColor)
                        {
                          BrightnessPercentage = (meanTabletColor - Brightness) * 100 / (meanTabletColor - PrintMinColor);
                        }
                        else if(Brightness > meanTabletColor)
                        {
                          BrightnessPercentage = 0;
                        }
                        else
                        {
                          BrightnessPercentage = 100;
                        }
                        
                        LaserMonitoringStringGrid->Cells[2][i] = IntToStr(BrightnessPercentage) + " %";
                        LaserMonitoringStringGrid->Cells[3][i] = IntToStr(printdata[1]) + " º";
                        LaserMonitoringStringGrid->Cells[4][i] = FloatToStrF(printdata[2] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                        LaserMonitoringStringGrid->Cells[5][i] = FloatToStrF(printdata[3] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                      }
                    }
                    else // 3D
                    {
                      if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
                      {
                        LaserMonitoringStringGrid->Cells[6][i] = "Blank";
                        LaserMonitoringStringGrid->Cells[7][i] = "Blank";
                        LaserMonitoringStringGrid->Cells[8][i] = "Blank";
                      }
                      else
                      {
                        LaserMonitoringStringGrid->Cells[6][i] = IntToStr(printdata[0]) + " º";
                        LaserMonitoringStringGrid->Cells[7][i] = FloatToStrF(printdata[1] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                        LaserMonitoringStringGrid->Cells[8][i] = FloatToStrF(printdata[2] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                      }
                    }
                    Pass = true;
                    break;
                  }
                }

                if(!Pass)
                {
                  int TargetRowIndex = dataIndex;
                  if(LaserMonitoringStringGrid->RowCount < TargetRowIndex + 1)
                  {
                    LaserMonitoringStringGrid->RowCount = TargetRowIndex + 1;
                  }

                  if(cameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX)
                  {
                    if(TargetRowIndex > -1)
                    {
                      LaserMonitoringStringGrid->Cells[0][TargetRowIndex] = IntToStr(TargetRowIndex);
                      LaserMonitoringStringGrid->Cells[1][TargetRowIndex] = IntToStr(TabletNumber);
                      if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
                      {
                        LaserMonitoringStringGrid->Cells[2][TargetRowIndex] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[3][TargetRowIndex] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[4][TargetRowIndex] = "Unprinted";
                        LaserMonitoringStringGrid->Cells[5][TargetRowIndex] = "Unprinted";

                        LaserMonitoringStringGrid->Cells[6][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[7][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[8][TargetRowIndex] = "";
                      }
                      else
                      {
                        int Brightness = printdata[0];
                        int BrightnessPercentage;
                        if(Brightness >= PrintMinColor && Brightness <= meanTabletColor)
                        {
                          BrightnessPercentage = (meanTabletColor - Brightness) * 100 / (meanTabletColor - PrintMinColor);
                        }
                        else if(Brightness > meanTabletColor)
                        {
                          BrightnessPercentage = 0;
                        }
                        else
                        {
                          BrightnessPercentage = 100;
                        }
                        
                        LaserMonitoringStringGrid->Cells[2][TargetRowIndex] = IntToStr(BrightnessPercentage) + " %";
                        LaserMonitoringStringGrid->Cells[3][TargetRowIndex] = IntToStr(printdata[1]) + " º";
                        LaserMonitoringStringGrid->Cells[4][TargetRowIndex] = FloatToStrF(printdata[2] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                        LaserMonitoringStringGrid->Cells[5][TargetRowIndex] = FloatToStrF(printdata[3] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";

                        LaserMonitoringStringGrid->Cells[6][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[7][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[8][TargetRowIndex] = "";
                      }
                    }
                  }
                  else
                  {
                    if(TargetRowIndex > -1)
                    {
                      LaserMonitoringStringGrid->Cells[0][TargetRowIndex] = IntToStr(TargetRowIndex);
                      LaserMonitoringStringGrid->Cells[1][TargetRowIndex] = IntToStr(TabletNumber);
                      if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
                      {
                        LaserMonitoringStringGrid->Cells[2][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[3][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[4][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[5][TargetRowIndex] = "";

                        LaserMonitoringStringGrid->Cells[6][TargetRowIndex] = "Blank";
                        LaserMonitoringStringGrid->Cells[7][TargetRowIndex] = "Blank";
                        LaserMonitoringStringGrid->Cells[8][TargetRowIndex] = "Blank";
                      }
                      else
                      {
                        LaserMonitoringStringGrid->Cells[2][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[3][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[4][TargetRowIndex] = "";
                        LaserMonitoringStringGrid->Cells[5][TargetRowIndex] = "";
                        
                        LaserMonitoringStringGrid->Cells[6][TargetRowIndex] = IntToStr(printdata[0]) + " º";
                        LaserMonitoringStringGrid->Cells[7][TargetRowIndex] = FloatToStrF(printdata[1] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                        LaserMonitoringStringGrid->Cells[8][TargetRowIndex] = FloatToStrF(printdata[2] * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
                      }
                    }
                  }

                  if(LaserMonitoringStringGrid->RowCount < 1001)
                  {
                    ++LaserMonitoringStringGrid->RowCount;
                  }
                }

                if(pFileStream != NULL)
                {
                  delete pFileStream;
                  pFileStream = NULL;
                }
              }
            }
          }
          else
          {
            if(globalCameraIndex == SD1_2D_FRONT_FACE_CAMERA_INDEX - 1)
            {
              RT2DBuffering->Position = 0;
            }
            else if(globalCameraIndex == SD1_3D_FRONT_FACE_CAMERA_INDEX - 1)
            {
              RT3DBuffering->Position = 0;
            }
          }
        }
      }
    }
  }

  RT2DBuffering->Hint = IntToStr(RT2DBuffering->Position) + " / " + IntToStr(RT2DBuffering->Max);
  RT3DBuffering->Hint = IntToStr(RT3DBuffering->Position) + " / " + IntToStr(RT3DBuffering->Max);

  if((InspectState == INSPECTION_STATE_STOP || InspectState == INSPECTION_STATE_MACHINE_STOP) && InspectionStopButton->Enabled == false && RT2DBuffering->Position == 0 && RT3DBuffering->Position == 0)
  {
    UploadRealtimeCapturedImageTimer->Enabled = false;
    CurrentMarkingInfoPageCount->Text = "1";

    int StartPageIndex = (RTTabletMinNumber - 1) / 1000;
    int lastPageIndex = (RTTabletMaxNumber - 1) / 1000;

    if(RTTabletMaxNumber != 0 && RTTabletMinNumber != 0xF0000000)
    {
      MaxMarkingInfoPageCount->Caption = IntToStr((lastPageIndex - StartPageIndex) + 1);
    }
    else
    {
      MaxMarkingInfoPageCount->Caption = "1";
    }

    if(LaserMonitoringStringGrid->RowCount > 2)
    {
      RefreshMarkingInfomationData(1);
    }
    
    MarkingInfoPagePanel->Visible = true;
  }
  else
  {
    UploadRealtimeCapturedImageTimer->Enabled = timerEnableStatus;
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::RefreshMarkingInfomationData(int page)
{
  if(RTTabletMinNumber == 0xF0000000) return;
  
  int StartPageIndex = (RTTabletMinNumber - 1) / 1000;

  int DataSize = REALTIME_CAMERA_WIDTH * REALTIME_CAMERA_HEIGHT;
  AnsiString dirPathName = ProgramPath.Root + "\\Laser Monitoring";
  AnsiString lmFileName2D = dirPathName + "\\Marking" + IntToStr(page + StartPageIndex) + "_2D.dat";
  AnsiString lmFileName3D = dirPathName + "\\Marking" + IntToStr(page + StartPageIndex) + "_3D.dat";
  unsigned char * ImageData = new unsigned char[REALTIME_CAMERA_WIDTH*REALTIME_CAMERA_HEIGHT];
  TFileStream *pFileStream;
  int printdata[4];

  for(int i = LaserMonitoringStringGrid->FixedRows; i < LaserMonitoringStringGrid->RowCount; ++i)
  {
    LaserMonitoringStringGrid->Rows[i]->Clear();
  }
  
  LaserMonitoringStringGrid->RowCount = 1000 + 1;
  for(int dataIndex = 0; dataIndex < LaserMonitoringStringGrid->RowCount; dataIndex++)
  {
    LaserMonitoringStringGrid->Cells[0][dataIndex + 1] = IntToStr(dataIndex + 1);
    LaserMonitoringStringGrid->Cells[1][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[2][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[3][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[4][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[5][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[6][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[7][dataIndex + 1] = "";
    LaserMonitoringStringGrid->Cells[8][dataIndex + 1] = "";
  }

  memset(ImageData, 0, REALTIME_CAMERA_WIDTH * REALTIME_CAMERA_HEIGHT);
  
  if(FileExists(lmFileName2D))
  {
    pFileStream = new TFileStream(lmFileName2D, fmOpenRead);
    if(pFileStream)
    {
      while(true)
      {
        if(pFileStream->Position + DataSize <= pFileStream->Size)
        {
          pFileStream->Read(ImageData, sizeof(char)*(REALTIME_CAMERA_WIDTH*REALTIME_CAMERA_HEIGHT));

          int tabletNumber = *((int*)ImageData + 1);
          if(tabletNumber)
          {
            int dataPos = (tabletNumber - 1) % 1000 + 1;
            LaserMonitoringStringGrid->Cells[1][dataPos] = IntToStr(*((int*)ImageData + 1));

            int printdata[4];
            memset(printdata, 0, sizeof(int) * 4);
            printdata[0] = *((int*)ImageData + 2);
            printdata[1] = *((int*)ImageData + 3);
            printdata[2] = *((int*)ImageData + 4);
            printdata[3] = *((int*)ImageData + 5);

            if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
            {
              LaserMonitoringStringGrid->Cells[2][dataPos] = "Unprinted";
              LaserMonitoringStringGrid->Cells[3][dataPos] = "Unprinted";
              LaserMonitoringStringGrid->Cells[4][dataPos] = "Unprinted";
              LaserMonitoringStringGrid->Cells[5][dataPos] = "Unprinted";
            }
            else
            {
              int Brightness = *((int*)ImageData + 2);
              int BrightnessPercentage;
              if(Brightness >= PrintMinColor && Brightness <= meanTabletColor)
              {
                BrightnessPercentage = (meanTabletColor - Brightness) * 100 / (meanTabletColor - PrintMinColor);
              }
              else if(Brightness > meanTabletColor)
              {
                BrightnessPercentage = 0;
              }
              else
              {
                BrightnessPercentage = 100;
              }

              LaserMonitoringStringGrid->Cells[2][dataPos] = IntToStr(BrightnessPercentage) + " %";
              LaserMonitoringStringGrid->Cells[3][dataPos] = IntToStr(*((int*)ImageData + 3)) + " º";
              LaserMonitoringStringGrid->Cells[4][dataPos] = FloatToStrF(*((int*)ImageData + 4) * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
              LaserMonitoringStringGrid->Cells[5][dataPos] = FloatToStrF(*((int*)ImageData + 5) * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
            }
          }
        }
        else
        {
          break;
        }
      }
    }
  }

  if(pFileStream)
  {
    delete pFileStream;
    pFileStream = NULL;
  }

  memset(ImageData, 0, REALTIME_CAMERA_WIDTH * REALTIME_CAMERA_HEIGHT);

  if(FileExists(lmFileName3D))
  {
    pFileStream = new TFileStream(lmFileName3D, fmOpenRead);
    if(pFileStream)
    {
      while(true)
      {
        if(pFileStream->Position + DataSize <= pFileStream->Size)
        {
          pFileStream->Read(ImageData, sizeof(char)*(REALTIME_CAMERA_WIDTH * REALTIME_CAMERA_HEIGHT));

          int tabletNumber = *((int*)ImageData + 1);
          if(tabletNumber)
          {
            int dataPos = (tabletNumber - 1) % 1000 + 1;

            int printdata[4];
            memset(printdata, 0, sizeof(int) * 4);
            printdata[0] = *((int*)ImageData + 2);
            printdata[1] = *((int*)ImageData + 3);
            printdata[2] = *((int*)ImageData + 4);
            printdata[3] = *((int*)ImageData + 5);

            LaserMonitoringStringGrid->Cells[1][dataPos] = IntToStr(*((int*)ImageData + 1));

            if(printdata[0] == 0 && printdata[1] == 0 && printdata[2] == 0 && printdata[3] == 0)
            {
              LaserMonitoringStringGrid->Cells[6][dataPos] = "Blank";
              LaserMonitoringStringGrid->Cells[7][dataPos] = "Blank";
              LaserMonitoringStringGrid->Cells[8][dataPos] = "Blank";
            }
            else
            {
              LaserMonitoringStringGrid->Cells[6][dataPos] = IntToStr(*((int*)ImageData + 2)) + " º";
              LaserMonitoringStringGrid->Cells[7][dataPos] = FloatToStrF(*((int*)ImageData + 3) * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
              LaserMonitoringStringGrid->Cells[8][dataPos] = FloatToStrF(*((int*)ImageData + 4) * MILLIMETER_PER_PIXEL, ffGeneral, 4, 2) + " um";
            }
          }
        }
        else
        {
          break;
        }
      }
    }
  }

  delete[] ImageData;
  if(pFileStream)
  {
    delete pFileStream;
    pFileStream = NULL;
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ClearLaserMonitoringData()
{
  AnsiString dirPathName = ProgramPath.Root + "\\Laser Monitoring";

  if (!DirectoryExists(dirPathName))
	{
		ForceDirectories(dirPathName);
	}
  else
  {
    RemoveWholeDir(dirPathName);
  }

  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    if (!Comm_IsConnected(COMM_SPB + spbIndex)) continue;
    
    Comm_Request(COMM_SPB + spbIndex, CMD_CLEAR_RT_MARKING_INFO);
  }

  prev2DImageControlInterval = prev3DImageControlInterval = 1;

  if(CameraMapInfo[SD1_2D_FRONT_FACE_CAMERA_INDEX - 1].SPBIndex == CameraMapInfo[SD1_3D_FRONT_FACE_CAMERA_INDEX - 1].SPBIndex)
  {
    RT2DBuffering->Max = (MAX_RT_IMAGE_BUFFER_SIZE - 1) / 2;
    RT3DBuffering->Max = (MAX_RT_IMAGE_BUFFER_SIZE - 1) / 2;
  }
  else
  {
    RT2DBuffering->Max = (MAX_RT_IMAGE_BUFFER_SIZE - 1);
    RT3DBuffering->Max = (MAX_RT_IMAGE_BUFFER_SIZE - 1);
  }

  prevPageIndex = 1;

  AverageBrightness = AverageThetaResult = AverageXResult = AverageYResult = AverageResultCount = 0;

  AverageBrightnessLabel->Caption = "N/A";
  AverageThetaLabel->Caption = "N/A";
  AverageXLabel->Caption = "N/A";
  AverageYLabel->Caption = "N/A";
}

//---------------------------------------------------------------------------
void __fastcall TInspectionForm::LaserMonitoringStringGridDblClick(TObject *Sender)
{
  if((InspectState == INSPECTION_STATE_STOP || InspectState == INSPECTION_STATE_MACHINE_STOP) && RT2DBuffering->Position == 0 && RT3DBuffering->Position == 0)
  {
    if(RTTabletMinNumber == 0xF0000000) return;
    
    int StartPageIndex = (RTTabletMinNumber - 1) / 1000;

    TLaserInspectionMarkingInfoForm *form = new TLaserInspectionMarkingInfoForm(this);
    int SelectRow = LaserMonitoringStringGrid->Row;
    if(SelectRow > 0 && !LaserMonitoringStringGrid->Cells[1][SelectRow].IsEmpty())
    {
      form->SetImage(StrToInt(CurrentMarkingInfoPageCount->Text) + StartPageIndex, StrToInt(LaserMonitoringStringGrid->Cells[1][SelectRow]), LaserMonitoringStringGrid->Cells[2][SelectRow]);
      form->ShowModal();
    }
    delete form;
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::RemoveWholeDir(AnsiString folderName)
{
	TSearchRec sr;
	int iAttributes = faAnyFile;
	if (FindFirst(folderName + "\\*.*", iAttributes, sr) == 0)
	{
		do
		{
			if (sr.Name == "." || sr.Name == "..") continue;
			if (sr.Attr & faDirectory)
			{
				RemoveWholeDir(folderName + "\\" + sr.Name);
			}
			else
			{
        DeleteFile(folderName + "\\" + sr.Name);
			}

		} while (FindNext(sr) == 0);
		FindClose(sr);
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::ChangeMarkingInfoPage(TObject *Sender)
{
  TTntButton * Btn =(TTntButton *)Sender;
  int cPage = StrToInt(CurrentMarkingInfoPageCount->Text);
  int mPage = StrToInt(MaxMarkingInfoPageCount->Caption);
  if(Btn->Tag == 0)
  {
    if(cPage > 1)
    {
      RefreshMarkingInfomationData(cPage-1);
      CurrentMarkingInfoPageCount->Text = IntToStr(cPage-1);
    }
  }
  else
  {
    if(cPage < mPage)
    {
      RefreshMarkingInfomationData(cPage+1);
      CurrentMarkingInfoPageCount->Text = IntToStr(cPage+1);
    }
  }
}
//---------------------------------------------------------------------------

bool __fastcall TInspectionForm::ReadStudyData(TTabletStudyData *tabletStudyData)
{
	AnsiString studyDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".stu";
	if (FileExists(studyDataFileName))
	{
		TFileStream *fileStream = new TFileStream(studyDataFileName, fmOpenRead);
		if (fileStream)
		{
			fileStream->Read(tabletStudyData, sizeof(TTabletStudyData));
			delete fileStream;
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::HCBMonitoringTimerTimer(TObject *Sender)
{
  bool timerEnabled = HCBMonitoringTimer->Enabled;
  HCBMonitoringTimer->Enabled = false;

  int requestNum = 1;
  TTabletInfo HCBTabletInfo;

	if(Comm_Request(COMM_HCB, CMD_TABLET_PROCESS_INFO, &requestNum, sizeof(int), &HCBTabletInfo, sizeof(TTabletInfo)))
  {
    while(1)
    {
      if((HCBTabletInfo.Disk2TabletList[LastCheckHCBListIndex].State == TABLET_STATE_COMPLETE ||
          HCBTabletInfo.Disk2TabletList[LastCheckHCBListIndex].State == TABLET_STATE_ERROR) &&
          HCBTabletInfo.Disk2TabletList[LastCheckHCBListIndex].EjectionCheck != TABLET_EJECTION_CHECK_NONE)
      {       
        HCBTabletUnitList.push_back(HCBTabletInfo.Disk2TabletList[LastCheckHCBListIndex]);
        LastCheckHCBListIndex = (LastCheckHCBListIndex + 1) % HCB_TABLET_LIST_COUNT;

        if(HCBTabletUnitList.size() == HCB_MONITORING_DATA_COUNT) // file size = THCBDisk2TabletUnit * 1000개 정제)
        {
          WriteHCBMonitoringData(false);
        }
      }
      else
      {
        break;
      }                                        
    }
  }

  if((InspectState == INSPECTION_STATE_STOP || InspectState == INSPECTION_STATE_MACHINE_STOP) && InspectionStopButton->Enabled == false)
  {
    // 정지상태
    WriteHCBMonitoringData(true);
    timerEnabled = false;
    HCBMonitoringButton->Enabled = true;
  }

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

void __fastcall TInspectionForm::StandbyHCBMonitoring()
{
  LastCheckHCBListIndex = 0;
  HCBTabletUnitList.clear();
  HCBMonitoringButton->Enabled = false;

  AnsiString RootPathName = ProgramPath.Root + "\\HCB Monitoring";

  if (!DirectoryExists(RootPathName))
	{
		ForceDirectories(RootPathName);
	}

  AnsiString TimeLabel;
  DateTimeToString(TimeLabel, "yymmdd HHmm.ss", Now());

  HCBMonitoringFilePath = RootPathName + "\\" + ProductData.ProductCode + "\\" + ProductData.LOTName + "\\" + TimeLabel;

  if (!DirectoryExists(HCBMonitoringFilePath))
	{
		ForceDirectories(HCBMonitoringFilePath);
	}
  else
  {
    // 동일 시간 대에 형성된 데이터가 존재하는 경우 삭제 : windows 시간 등을 조작하는 경우 발생할 수 있음
    RemoveWholeDir(HCBMonitoringFilePath);
  }

  TIniFile *iniFile;

  iniFile = new TIniFile(HCBMonitoringFilePath + "\\data.ini");
  if(iniFile)
  {
    iniFile->WriteInteger("Data", "Count", 0);
    iniFile->WriteString("Data", "Product Name", ProductData.ProductCode);
    iniFile->WriteString("Data", "LOT Name", ProductData.LOTName);
    iniFile->WriteFloat("Data", "Inspection Start Time", Now());
    iniFile->WriteInteger("Data", "Disk Speed", ProductData.MotorSpeedList[SD1_MOTOR_INDEX][MachineOperationInfo.SpeedIndex]);
    iniFile->WriteInteger("Data", "Base Speed", MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed);
    iniFile->WriteInteger("Data", "Interval A", ProductData.StudiedSensorIntervalA);
    iniFile->WriteInteger("Data", "Interval B", ProductData.StudiedSensorIntervalB);

    iniFile->WriteInteger("Data", "Defect Ejector Delay", MachineSetupData.EjectorInfo.DefectEjectorDelay);
    iniFile->WriteInteger("Data", "UnIns Ejector Delay", MachineSetupData.EjectorInfo.UnInsEjectorDelay);
    iniFile->WriteInteger("Data", "Good Ejector Delay", MachineSetupData.EjectorInfo.GoodEjectorDelay);
    iniFile->WriteInteger("Data", "Defect Ejector Length", MachineSetupData.EjectorInfo.DefectEjectorLength);
    iniFile->WriteInteger("Data", "UnIns Ejector Length", MachineSetupData.EjectorInfo.UnInsEjectorLength);
    iniFile->WriteInteger("Data", "Good Ejector Length", MachineSetupData.EjectorInfo.GoodEjectorLength);

    delete iniFile;
  }
}

//---------------------------------------------------------------------------
void __fastcall TInspectionForm::WriteHCBMonitoringData(bool bFinish)
{
  if(HCBTabletUnitList.size())
  {
    TIniFile *iniFile = new TIniFile(HCBMonitoringFilePath + "\\data.ini");

    int lastFileIndex;
    if(iniFile)
    {
      lastFileIndex = iniFile->ReadInteger("Data", "Count", 0);
      if(lastFileIndex > 9)
      {
         delete iniFile;
         return;
      }
    }
    else
    {
      lastFileIndex = 0;
    }

    AnsiString FileName = HCBMonitoringFilePath + "\\Result" + IntToStr(lastFileIndex + 1) + ".hmf";
                                                
    TFileStream *pFileStream = NULL;
    pFileStream = new TFileStream(FileName, fmCreate);
    pFileStream->Position = 0;
    
    vector<THCBDisk2TabletUnit>::iterator it;
    for (it = HCBTabletUnitList.begin(); it < HCBTabletUnitList.end(); it++)
    {
      pFileStream->Write(it, sizeof(THCBDisk2TabletUnit));
    }

    delete pFileStream;

    if(HCBTabletUnitList.size() == HCB_MONITORING_DATA_COUNT)
    {
      iniFile->WriteInteger("Data", "Count", lastFileIndex + 1);
    }

    if(bFinish)
    {
      iniFile->WriteFloat("Data", "Inspection End Time", Now());

      int TotalTabletCount = TabletInspectInfo.TotalTabletCount - TabletInspectInfo_Begin.TotalTabletCount;
      int GoodTabletCount = TabletInspectInfo.GoodTabletCount - TabletInspectInfo_Begin.GoodTabletCount;
      int DefectTabletCount = TabletInspectInfo.DefectTabletCount - TabletInspectInfo_Begin.DefectTabletCount;
      int UnInsTabletCount = TabletInspectInfo.UnInsTabletCount - TabletInspectInfo_Begin.UnInsTabletCount;
      int S3PassedTabletCount = TabletInspectInfo.CounterSensorTabletCount - TabletInspectInfo_Begin.CounterSensorTabletCount;

      iniFile->WriteInteger("Data", "Total Tablet Count", TotalTabletCount);
      iniFile->WriteInteger("Data", "Good Tablet Count", GoodTabletCount);
      iniFile->WriteInteger("Data", "Defect Tablet Count", DefectTabletCount);
      iniFile->WriteInteger("Data", "Uninspection Tablet Count", UnInsTabletCount);
      iniFile->WriteInteger("Data", "Couunter Sensor Count", S3PassedTabletCount);
    }

    delete iniFile;


    if(bFinish)
    {
      AnsiString RootPathName = ProgramPath.Root + "\\HCB Monitoring";
      iniFile = new TIniFile(RootPathName + "\\recent.ini");
      if(iniFile)
      {
        iniFile->WriteString("Recent", "Product", ProductData.ProductCode);
        iniFile->WriteString("Recent", "LOT", ProductData.LOTName);
        iniFile->WriteString("Recent", "Path", HCBMonitoringFilePath);

        delete iniFile;
      }
    }

    HCBTabletUnitList.clear();
  }
}
//---------------------------------------------------------------------------
void __fastcall TInspectionForm::HCBMonitoringButtonClick(TObject *Sender)
{
  bool bExistRecentFile = false;

  AnsiString RootPathName = ProgramPath.Root + "\\HCB Monitoring";
  AnsiString FileName = RootPathName + "\\recent.ini";

  AnsiString RecentInspectionFilePath;
  AnsiString ProductName, LOTName;
  if(FileExists(FileName))
  {
    TIniFile *iniFile;

    iniFile = new TIniFile(RootPathName + "\\recent.ini");
    if(iniFile)
    {
      ProductName = iniFile->ReadString("Recent", "Product", "");
      LOTName = iniFile->ReadString("Recent", "LOT", "");
      RecentInspectionFilePath = iniFile->ReadString("Recent", "Path", "");

      delete iniFile;
    }

    if(ProductName == ProductData.ProductName)
    {
      if(RecentInspectionFilePath != "")
      {
        bExistRecentFile = true;
      }
    }
  }

  THCBMonitoringForm *pHCBMonitoringForm = new THCBMonitoringForm(this);

  if(bExistRecentFile)
  {
    if (MessageDlgFA("Would you like to read the latest information? (" + ProductName + ", " + LOTName + ")", mtConfirmation, TMsgDlgButtons() << mbOK << mbCancel) == mrOk)
    {
      pHCBMonitoringForm->bRecentFileLoad = true;
      pHCBMonitoringForm->RecentFilePath = RecentInspectionFilePath;
    }
    else
    {
      pHCBMonitoringForm->bRecentFileLoad = false;
      pHCBMonitoringForm->RecentFilePath = "";
    }
  }
  else
  {
    pHCBMonitoringForm->bRecentFileLoad = false;
    pHCBMonitoringForm->RecentFilePath = "";
  }
  
  pHCBMonitoringForm->ShowModal();
  delete pHCBMonitoringForm;
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::UnInsCountCheckingBtnClick(
      TObject *Sender)
{
  UnInsCountCheckingBtn->Font->Color = clBlue;
	DefectCountCheckingBtn->Font->Color = clBlack;
  
  UnInsCountPanel->Visible = true;
  DefectCountPanel->Visible = false;

  UnInsCountPanel->BringToFront();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::DefectCountCheckingBtnClick(
      TObject *Sender)
{
  UnInsCountCheckingBtn->Font->Color = clBlack;
	DefectCountCheckingBtn->Font->Color = clBlue;
  
  UnInsCountPanel->Visible = false;
  DefectCountPanel->Visible = true;
  
  DefectCountPanel->BringToFront();
}
//---------------------------------------------------------------------------


void __fastcall TInspectionForm::SimulationButtonClick(TObject *Sender)
{
  CountCheckSpeedButton->Font->Color = clBlack;
	InspectChartSpeedButton->Font->Color = clBlack;
	MisejectSpeedButton->Font->Color = clBlack;
	EjectorSettingSpeedButton->Font->Color = clBlack;
  SimulationButton->Font->Color = clBlue;

	InspectionCountInfoPanel->Visible = false;
	InspectChartPanel->Visible = false;
	MisejectInfoPanel->Visible = false;
	EjectorSettingPanel->Visible = false;
  SimulationPanel->Visible = true;

  if(MachineSetupData.LasercomplexerInfo.Laser_complexer_Enable)
  {
    TestSimulBox->Visible = true;
  }
  else
  {
    TestSimulBox->Visible = false;
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::CameraTestButtonClick(TObject *Sender)
{
  TCameraTestForm *pCameraTestForm = new TCameraTestForm(this);

  if(pCameraTestForm->AbnormalSW)
  {
    WideString failMsg = CAMERATEST_FORM_TEXT_33;
    MessageDlgFA(failMsg, mtConfirmation, TMsgDlgButtons() << mbOK);
  }
  else
  {
    pCameraTestForm->ShowModal();
  }

  delete pCameraTestForm;
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::Panel39DblClick(TObject *Sender)
{
  TntPanel5->BringToFront();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::Panel70DblClick(TObject *Sender)
{
  TntPanel4->BringToFront();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::InspectChartLabelClick(TObject *Sender)
{
  TTntLabel * Label = (TTntLabel*)Sender;
  int tag = Label->Tag;
  if(tag == 0)
  {
    InspectChartSpeedButton->Click();
    InspectChartSpeedButton->Down = true;
  }
  else if(tag == 1)
  {
    CountCheckSpeedButton->Click();
    CountCheckSpeedButton->Down = true;
  }
  else
  {
    EjectorSettingSpeedButton->Click();
    EjectorSettingSpeedButton->Down = true;
  }

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

void __fastcall TInspectionForm::ThroughPutChartLabelClick(TObject *Sender)
{
  TTntLabel * Label = (TTntLabel*)Sender;
  int tag = Label->Tag;
  if(tag == 0)
  {
    ThroughPutChartSpeedButton->Click();
    ThroughPutChartSpeedButton->Down = true;
  }
  else if(tag == 1)
  {
    DefectRatioChartSpeedButton->Click();
    DefectRatioChartSpeedButton->Down = true;
  }
  else
  {
    VibratorInfoSpeedButton->Click();
    VibratorInfoSpeedButton->Down = true;
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::ShowTPBButtonClick(TObject *Sender)
{
  TPBCameraSettingForm->ShowModal();
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::MachineStopCheckTimerTimer(
      TObject *Sender)
{
  if((InspectState == INSPECTION_STATE_STOP || InspectState == INSPECTION_STATE_MACHINE_STOP) && InspectionStopButton->Enabled == false)
  {
    if(bExecuteTPB)
    {
      bExecuteTPB = false;
      TPBActiveCheckBox->Enabled = true;
      if(TPBActiveCheckBox->Checked)
      {
        TPBCameraSettingForm->CaptureTrigger = false;
      }
    }
    else
    {
      TPBActiveCheckBox->Enabled = true;
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::DistributorTimerTimer(TObject *Sender)
{
    AnsiString tempString = "[DistributorOn], Time : ";
    AnsiString tempTimeString;
    AnsiString tempDisStepString;    
    AnsiString DistributorString;

	if(Comm_Request(COMM_HCB, CMD_DISTRIBUTOR_MONITOR, NULL, 0, &DistributorMonitor, sizeof(TDistributorMonitor)))
    {
    	if((DistributorMonitor.DisStep != LastDistributorDisStep) && (DistributorMonitor.DisStep > LastDistributorDisStep))
        {
        	if(DistributorMonitor.DisStep > 0 || DistributorMonitor.DisStep < 255)
            {
        		tempTimeString = Now().DateTimeString();
            	tempDisStepString = IntToStr(DistributorMonitor.DisStep);
            	DistributorString = tempString + tempTimeString + ", Count : " + tempDisStepString;

        		DistributorMonitorMemo->Lines->Add(DistributorString);
            }
        }

      	LastDistributorDisStep = DistributorMonitor.DisStep;
    }
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::TntButton1Click(TObject *Sender)
{
	DistributorMonitorPanel->Visible = false;	
}
//---------------------------------------------------------------------------

void __fastcall TInspectionForm::DistributorMonitorButtonClick(
      TObject *Sender)
{
	DistributorMonitorPanel->Visible = true;
    DistributorMonitorPanel->BringToFront();	
}
//---------------------------------------------------------------------------

