//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 변경사항 없음
//---------------------------------------------------------------------------

#include <vcl.h>
#include <FileCtrl.hpp>
#pragma hdrstop

#include "VirtualMachine_Form.h"
#include "Environment.h"
#include "VirtualImageControl_Form.h"
#include "SPB_Processing.h"
#include "Virtual_SPB_Form.h"
#include "Virtual_CPB_Form.h"
#include "spb_module_main.h"
#include "MultiLanguage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

#define COMM_HCB				0
#define COMM_SPB				1
#define COMM_SPB_1				1
#define COMM_SPB_2				2
#define COMM_SPB_3				3
#define COMM_SPB_4				4
#define COMM_SPB_5				5
#define COMM_SPB_6				6

#define TOTAL_COMM_COUNT		7

#define TARGET_HCB_PROGRAM_REV			106
#define TARGET_HCB_DATA_REV				105

TVirtualMachineForm *VirtualMachineForm;
//---------------------------------------------------------------------------
__fastcall TVirtualMachineForm::TVirtualMachineForm(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);
  }

	for (int stepMotorIndex = 0; stepMotorIndex < MAX_STEP_MOTOR_COUNT; stepMotorIndex++)
	{
		StepMotorData[stepMotorIndex].TargetPos = 0;
		MachineStatus.StepMotorAbsEncoder[stepMotorIndex] = 0;
	}

//	SPBProcessingSetupInfo.AvailCPBCount = 40;
//	SPBProcessingSetupInfo.SetupCPBCount = 0;
//	SPBProcessingSetupInfo.CurrentCPBIndex = 40;
//	SPBProcessingSetupInfo.SetupStep = PROCESSING_SETUP_STEP_NONE;

	TimerCount = 0;

	MainControlData.State = MAIN_CONTROL_STATE_CLEANING;
	MainControlData.Mode = MAIN_CONTROL_MODE_NONE;
	MainControlData.HomeDetected = FALSE;
	MainControlData.PosState = MAIN_CONTROL_POS_STATE_NONE;

	memset(&MachineWarningState, 0, sizeof(TMachineWarningState));
	memset(&MachineAlarmState, 0, sizeof(TMachineAlarmState));

	HCBProgramHeader.ProjectID = PROJECT_ID_ELMA_100;
	HCBProgramHeader.ProgramRev = TARGET_HCB_PROGRAM_REV;
	strcpy(HCBProgramHeader.ProjectName, PROJECT_NAME_ELMA_100);
	HCBDBHeader.DataRev = TARGET_HCB_DATA_REV;

	SPBProgramHeader.ProjectID = PROJECT_ID_ELMA_100;
	SPBProgramHeader.ProgramRev = TARGET_SPB_PROGRAM_REV;
	strcpy(SPBProgramHeader.ProjectName, PROJECT_NAME_ELMA_100);

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		CaptureStatus[spbIndex].OnCapture = false;
		CaptureStatus[spbIndex].CaptureBuffer = NULL;
	}
	VirtualCaptureOn = false;
	VirtualCaptureDir = "";

	VirtualSPBForm = new TVirtualSPBForm(Owner);
	VirtualCPBForm = new TVirtualCPBForm(Owner);

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		VirtualSystemSetup(spbIndex, &SPBSystemSetupData[spbIndex]);
	}

	IdleProcessData.CurrentIndex = 0;
	IdleProcessData.CurrentTime = 0;
	for (int listIndex = 0; listIndex < IDLE_PROCESS_LIST_COUNT; listIndex++)
	{
		IdleProcessData.Time[listIndex] = 0;
		IdleProcessData.TimeCounter[listIndex] = 0;
	}
	LastCheckCount = GetTickCount();
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_StepMotorControl(TMachineControlData_StepMotor *stepMotorData)
{
	if (stepMotorData->Action == 3)
	{
		MC_Step_Motor_MovePos(stepMotorData->MotorIndex, stepMotorData->TargetEncoderPosition);
	}
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_Step_Motor_MovePos(int motorIndex, int targetEncoderPosition)
{
	StepMotorData[motorIndex].TargetPos = targetEncoderPosition;
}
//---------------------------------------------------------------------------
bool __fastcall TVirtualMachineForm::CommRequest(int commIndex, unsigned short command, void *data, unsigned int dataLength,
	void *receiveBuffer, unsigned int receiveBufferMaxSize)
{
	if (commIndex == COMM_HCB)
	{
		if (command == CMD_STATUS)
		{
			int statusKind;
			statusKind = *(int *) data;
			if (statusKind == 0)
			{
				memcpy(receiveBuffer, &MachineStatus, sizeof(TMachineStatus));
			}
		}
		else if (command == CMD_MACHINE_CONTROL)
		{
			TMachineControlHeader *machineControlHeader;
			machineControlHeader = (TMachineControlHeader *)data;
			if (machineControlHeader->Target == MACHINE_CONTROL_GENERAL)
			{
				TMachineControlData_General *generalData;
				generalData = (TMachineControlData_General *)data;
				MC_GeneralControl(generalData->ActionN, generalData->Value);
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_PROCEDURE)
			{
				TMachineControlData_Procedure *procedureData;
				procedureData = (TMachineControlData_Procedure *)data;
				MC_Procedure(procedureData);
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_BOWL_FEEDER)
			{
				TMachineControlData_BowlFeeder *bfData;
				bfData = (TMachineControlData_BowlFeeder *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_SUCTION_DISK)
			{
				TMachineControlData_SuctionDisk *vdData;
				vdData = (TMachineControlData_SuctionDisk *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_RINGBLOWER)
			{
				TMachineControlData_RingBlower *ringBlowerData;
				ringBlowerData = (TMachineControlData_RingBlower *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_SERVOMOTOR)
			{
				TMachineControlData_ServoMotor *servoMotorData;
				servoMotorData = (TMachineControlData_ServoMotor *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_VIBRATOR)
			{
				TMachineControlData_VibrationFeeder *vibratorData;
				vibratorData = (TMachineControlData_VibrationFeeder *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_ILLUMINATOR)
			{
				TMachineControlData_Illuminator *illuminatorData;
				illuminatorData = (TMachineControlData_Illuminator *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_EJECTOR)
			{
				TMachineControlData_Ejector *ejectorData;
				ejectorData = (TMachineControlData_Ejector *)data;
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_STEPMOTOR)
			{
				TMachineControlData_StepMotor *stepMotorData;
				stepMotorData = (TMachineControlData_StepMotor *)data;
				MC_StepMotorControl(stepMotorData);
			}
			else if (machineControlHeader->Target == MACHINE_CONTROL_MISEJECT)
			{
				TMachineControlData_Miseject *misejectData;
				misejectData = (TMachineControlData_Miseject *) data;
			}
		}
		else if (command == CMD_MACHINE_CAPTURE)
		{
			memcpy(&MachineCaputreSetupData, data, sizeof(TMachineCaptureSetupData));
			AnsiString virtualCaputreDir = "";
			TVirtualImageControlForm *virtualImageControlForm = new TVirtualImageControlForm(this);
			if (virtualImageControlForm->ShowModal() == mrOk)
			{
				VirtualCaptureDir = virtualImageControlForm->DirName;
				VirtualOptionCaptureMode = virtualImageControlForm->OptionCaptureMode;
				VirtualNewCaptureMode = virtualImageControlForm->NewImageVersion;

				if (!VirtualNewCaptureMode)
				{
					ApplyVirtualCapture();
				}
				else
				{
					ApplyVirtualNewCapture();
				}
				VirtualCaptureOn = true;
			}
		}
		else if (command == CMD_STUDY_READY)
		{
			AnsiString virtualCaputreDir = "";
			TVirtualImageControlForm *virtualImageControlForm = new TVirtualImageControlForm(this);
			if (virtualImageControlForm->ShowModal() == mrOk)
			{
				VirtualCaptureDir = virtualImageControlForm->DirName;
				VirtualOptionCaptureMode = virtualImageControlForm->OptionCaptureMode;
				VirtualNewCaptureMode = virtualImageControlForm->NewImageVersion;

				if (!VirtualNewCaptureMode)
				{
					ApplyVirtualCapture();
				}
				else
				{
					ApplyVirtualNewCapture();
				}
				VirtualCaptureOn = true;
			}
		}
		else if (command == CMD_INSPECTION_READY)
		{
			THCBInspectionOption *hcbInspectionOption;
			TTabletInspectInfo *tabletInspectInfo;
			hcbInspectionOption = (THCBInspectionOption *) data;
			tabletInspectInfo = (TTabletInspectInfo *)((unsigned char *) data + sizeof(THCBInspectionOption));
			memcpy(&InspectionOption, hcbInspectionOption, sizeof(THCBInspectionOption));

			AnsiString virtualCaputreDir = "";
			TVirtualImageControlForm *virtualImageControlForm = new TVirtualImageControlForm(this);
			if (virtualImageControlForm->ShowModal() == mrOk)
			{
				VirtualCaptureDir = virtualImageControlForm->DirName;
				VirtualOptionCaptureMode = virtualImageControlForm->OptionCaptureMode;
				VirtualNewCaptureMode = virtualImageControlForm->NewImageVersion;

				if (!VirtualNewCaptureMode)
				{
					ApplyVirtualCapture();
				}
				else
				{
					ApplyVirtualNewCapture();
				}
				VirtualCaptureOn = true;
			}

			for (int tableIndex = 0; tableIndex < RESULT_TABLE_SIZE; tableIndex++)
			{
				InspectionResultTable.Table[tableIndex].TabletNumber = 0;
				InspectionResultTable.Table[tableIndex].Result = TABLET_RESULT_NONE;
			}
			InspectionResultTable.CurrentIndex = 0;
			PollingInspectionResultTabletNumber = 1;


			TabletInspectInfo.TotalTabletCount = 0;
			TabletInspectInfo.GoodTabletCount = 0;
			TabletInspectInfo.DefectTabletCount = 0;
			TabletInspectInfo.UnInsTabletCount = 0;
		}
		else if (command == CMD_TABLET_PROCESS_INFO)
		{
			int requestNum;

			requestNum = *(int *) data;

			if (requestNum == 1)
			{
				memcpy(receiveBuffer, &TabletInfo, sizeof(TTabletInfo));
			}
		}
		else if (command == CMD_TABLET_INSPECT_INFO)
		{
			int requestNum;

			requestNum = *(int *) data;

			if (requestNum == 1)
			{
//				TabletInspectInfo.ElapsedTime = SimpleTabletCounter.ElapsedTime;
//				TabletInspectInfo.ThroughPut = SimpleTabletCounter.CPM;
				memcpy(receiveBuffer, &TabletInspectInfo, sizeof(TTabletInspectInfo));
			}
		}
		else if (command == CMD_IDLE_PROCESS_INFO)
		{
			memcpy(receiveBuffer, &IdleProcessData, sizeof(TIdleProcessData));			
		}
		else if (command == CMD_READ_PROGRAM_HEADER)
		{
			memcpy(receiveBuffer, &HCBProgramHeader, sizeof(THCBProgramHeader));
		}
		else if (command == CMD_READ_MS_HEADER)
		{
			memcpy(receiveBuffer, &HCBMachineSpecificHeader, sizeof(THCBMachineSpecificHeader));
		}
		else if (command == CMD_INSPECTION_RESULT)
		{
			memcpy(receiveBuffer, &InspectionResultTable, sizeof(TInspectionResultTable));
		}
		else if (command == CMD_INSPECTION_RESUME)
		{
			memcpy(&TabletInspectInfo, data, sizeof(TTabletInspectInfo));
			PollingInspectionResultTabletNumber = TabletInspectInfo.TotalTabletCount + 1;
//			TabletControl_ContinueInspection(smallData);
//			SimpleTabletCounter_Reset();
//			SimpleTabletCounter.ElapsedTime = TabletInspectInfo.ElapsedTime;
//			SimpleTabletCounter.Counter = TabletInspectInfo.TotalTabletCount;
//			SimpleTabletCounter.LastCheckingTime = Board1MSTmr;
		}
		else
		{
			if (receiveBuffer != NULL)
			{
				memset(receiveBuffer, 0, receiveBufferMaxSize);
			}
		}
	}
	else
	{
		int spbIndex = commIndex - COMM_SPB;
		/*if (command == CMD_CAMERA_COMMAND_RESULT)
		{
			*(int *) receiveBuffer = 1;
		}
		else */
    if (command == CMD_CPB_STATUS)
		{
			memset(receiveBuffer, 3, receiveBufferMaxSize);
//			*((int *)receiveBuffer + 0) = 0;
//			*((int *)receiveBuffer + 1) = 0;
//			*((int *)receiveBuffer + 2) = 0;
//			*((int *)receiveBuffer + 3) = 0;
//			*((int *)receiveBuffer + 4) = 0;
//			*((int *)receiveBuffer + 5) = 0;
//			*((int *)receiveBuffer + 6) = 0;
//			*((int *)receiveBuffer + 7) = 0;
		}
		else if (command == CMD_SETUP_START)
		{
			int mode;
			mode = *(int *) data;
			Virtual_SPB_Setup_Start(spbIndex, mode);
//			SPBProcessingSetupInfo.SetupStep = PROCESSING_SETUP_STEP_SETUP;
//			SPBProcessingSetupInfo.SetupCPBCount = 0;
//			SPBProcessingSetupInfo.CurrentCPBIndex = 0;
		}
		else if (command == CMD_SPB_SETUP_STATUS)
		{
			TSPBProcessingSetupInfo *spbProcessingSetupInfo = GetSPBProcessingSetupInfo(spbIndex);
			memcpy(receiveBuffer, &SPBProcessingSetupInfo, sizeof(TSPBProcessingSetupInfo));
		}
		else if (command == CMD_CAPTURE_SETUP)
		{
			CaptureStatus[spbIndex].OnCapture = true;
/*
//			if (!VirtualCaptureOn)
			{
				AnsiString virtualCaputreDir = "";
				//if (SelectDirectory(virtualCaputreDir, TSelectDirOpts() << sdAllowCreate << sdPerformCreate << sdPrompt,SELDIRHELP)
				//if (SelectDirectory("이미지 경로 선택",  ExtractFileDrive(GetCurrentDir()), virtualCaputreDir))
				//if (SelectDirectory("이미지 경로 선택", "", virtualCaputreDir))
				TVirtualImageControlForm *virtualImageControlForm = new TVirtualImageControlForm(this);
				if (virtualImageControlForm->ShowModal() == mrOk)
				{
					//VirtualCaptureDir = virtualCaputreDir;
					VirtualCaptureDir = virtualImageControlForm->DirName;
					VirtualOptionCaptureMode = virtualImageControlForm->OptionCaptureMode;
					VirtualNewCaptureMode = virtualImageControlForm->NewImageVersion;

					if (!VirtualNewCaptureMode)
					{
						ApplyVirtualCapture();
					}
					else
					{
						ApplyVirtualNewCapture();
					}
					VirtualCaptureOn = true;
				}
			}
*/
		}
		else if (command == CMD_CAPTURE_STOP)
		{
			VirtualCaptureOn = false;
		}
		else if (command == CMD_CAPTURE_EXIST)
		{
			unsigned int camIndex = *(unsigned int *)data;
			unsigned int returnData[2];
			returnData[0] = CaptureStatus[spbIndex].TotalCaptureCount[camIndex] - CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex];
			returnData[1] = CaptureStatus[spbIndex].TotalCaptureCount[camIndex];
			memcpy(receiveBuffer, returnData, 2 * sizeof(unsigned int));
		}
		else if (command == CMD_CAPTURE_UPLOAD)
		{
			unsigned int camIndex = *(unsigned int *)data;
			unsigned char *captureBuffer = NULL;
			if (!VirtualNewCaptureMode)
			{
				captureBuffer = GetCurrentCaptureBuffer(spbIndex, camIndex);
			}
			else
			{
				captureBuffer = GetCurrentNewCaptureBuffer(spbIndex, camIndex);
			}

			if (captureBuffer == NULL)
			{
				memset(receiveBuffer, 0, receiveBufferMaxSize);
			}
			else
			{
				memcpy(receiveBuffer, captureBuffer, receiveBufferMaxSize);
			}
			if (CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex] < CaptureStatus[spbIndex].TotalCaptureCount[camIndex])
			{
				CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex]++;
			}
			FlushCurrentImageBuffer(spbIndex, camIndex);
		}
		else if (command == CMD_TABLET_CHARACTER)
		{
			memcpy(&TabletCharacter_SPB, data, sizeof(TTabletCharacter));
		}
		else if (command == CMD_GRADE_DATA)
		{
			memcpy(&TabletGradeData_SPB, data, sizeof(TTabletGradeData));
		}

		else if (command == CMD_TABLET_CAPTURE_SETUP_DATA)
		{
			Virtual_SPB_Tablet_Capture_Setup(spbIndex, (TTabletCaptureSetupData *)data);
		}
		else if (command == CMD_STUDY_READY)
		{
			memcpy(&StudySetupData_SPB, data, sizeof(TStudySetupData));
			Virtual_SPB_Study_Ready(spbIndex);
			Virtual_SPB_Init_Tablet_Capture_StudyMode(spbIndex);
		}
		else if (command == CMD_INSPECTION_READY)
		{
			memcpy(&InspectData_SPB, data, sizeof(TInspectData));
			Virtual_SPB_Inspection_Ready(spbIndex);
			Virtual_SPB_Init_Tablet_Capture_InspectionMode(spbIndex, InspectData_SPB.CamMask);
		}
		else if (command == CMD_STUDY_RESULT)
		{
			int camIndex;
			camIndex = *(int *) data;
			memcpy(receiveBuffer, GetVirtualStudyResultData(spbIndex, camIndex), sizeof(TStudyResultData_SPB));
		}
		else if (command == CMD_DEFECT_IMAGE_EXIST)
		{
			int minDefectTabletNumber;
			TDefectImageInfo defectImageInfo;
			minDefectTabletNumber = *(int *)data;
			Virtual_SPB_SearchDefectImage(spbIndex, minDefectTabletNumber, &defectImageInfo);
			memcpy(receiveBuffer, &defectImageInfo, sizeof(TDefectImageInfo));
		}
		else if (command == CMD_DEFECT_IMAGE)
		{
			int bufferIndex;
			bufferIndex = *(int *)data;
			memcpy(receiveBuffer, Virtual_GetDefectImageAddr(spbIndex, bufferIndex), receiveBufferMaxSize);
			/*
			*resultLargeDataAddress = (unsigned char *)GetDefectImageAddr(bufferIndex);
			if (SystemSetupData.CameraKind[bufferIndex] == CAMERA_KIND_RANGER_3D)
			{
				*resultLargeDataSize = SYSTEM_CAMERA_WIDTH_3D * SYSTEM_CAMERA_HEIGHT_3D;
			}
			else
			{
				*resultLargeDataSize = CAPTURE_WIDTH * CAPTURE_HEIGHT;
			}
			*/
		}
		else if (command == CMD_DISCARD_DEFECT_IMAGE)
		{
			Virtual_SPB_DiscardDefectImage(spbIndex);
		}
		else if (command == CMD_DEFECT_DATA)
		{
			int bufferIndex;
			bufferIndex = *(int *)data;
			memcpy(receiveBuffer, Virtual_GetDefectDataAddr(spbIndex, bufferIndex), sizeof(TDefectData_SPB));
		}
		else if (command == CMD_READ_PROGRAM_HEADER)
		{
			memcpy(receiveBuffer, &SPBProgramHeader, sizeof(TSPBProgramHeader));
		}		
		else
		{
			if (receiveBuffer != NULL)
			{
				memset(receiveBuffer, 0, receiveBufferMaxSize);
			}
		}
	}
	return true;
}
//---------------------------------------------------------------------------
bool __fastcall TVirtualMachineForm::CommRequestEx(int commIndex, unsigned short command, void *shortData, unsigned int shortDataLength,
	void *longData, unsigned int longDataLength, void *receiveBuffer, unsigned int receiveBufferMaxSize,
	TUSBCompletionRoutine CompletionRoutine, TOverlapIOStr *OverlapIOStr)
{
	if (commIndex == COMM_HCB)
	{
	}
	else
	{
		int spbIndex = commIndex - COMM_SPB;
		if (command == CMD_SETUP_DATA)
		{
			memcpy(&TabletSetupData_SPB, longData, longDataLength);
		}
		else if (command == CMD_STUDY_DATA)
		{
			memcpy(&TabletStudyResultData_SPB, longData, longDataLength);
		}
		else if (command == CMD_SETUP_DATA_3D)
		{
			memcpy(&Tablet3DSetupData_SPB, longData, longDataLength);
		}

	}
	return true;
}
//---------------------------------------------------------------------------

void __fastcall TVirtualMachineForm::VirtualMachineTimerTimer(
	  TObject *Sender)
{
	VirtualMachineTimer->Enabled = false;
	TimerCount++;
	if (TimerCount == 10)	// 10ms
	{
		TimerCount = 0;
	}

	for (int stepMotorIndex = 0; stepMotorIndex < MAX_STEP_MOTOR_COUNT; stepMotorIndex++)
	{
		if (MachineStatus.StepMotorAbsEncoder[stepMotorIndex] < StepMotorData[stepMotorIndex].TargetPos)
		{
			MachineStatus.StepMotorAbsEncoder[stepMotorIndex] += 500;
			if (MachineStatus.StepMotorAbsEncoder[stepMotorIndex] > StepMotorData[stepMotorIndex].TargetPos)
			{
				MachineStatus.StepMotorAbsEncoder[stepMotorIndex] = StepMotorData[stepMotorIndex].TargetPos;
			}
		}
		else if (MachineStatus.StepMotorAbsEncoder[stepMotorIndex] > StepMotorData[stepMotorIndex].TargetPos)
		{
			MachineStatus.StepMotorAbsEncoder[stepMotorIndex] -= 500;
			if (MachineStatus.StepMotorAbsEncoder[stepMotorIndex] < StepMotorData[stepMotorIndex].TargetPos)
			{
				MachineStatus.StepMotorAbsEncoder[stepMotorIndex] = StepMotorData[stepMotorIndex].TargetPos;
			}
		}
	}
/*
	if (SPBProcessingSetupInfo.SetupStep == PROCESSING_SETUP_STEP_SETUP)
	{
		if (SPBProcessingSetupInfo.CurrentCPBIndex < SPBProcessingSetupInfo.AvailCPBCount)
		{
			SPBProcessingSetupInfo.CurrentCPBIndex++;
			SPBProcessingSetupInfo.SetupCPBCount = SPBProcessingSetupInfo.CurrentCPBIndex;
		}
		else
		{
			SPBProcessingSetupInfo.SetupStep = PROCESSING_SETUP_STEP_COMPLETE;
		}
	}
*/
	// status list
	if (MachineWarningState.WarningExist)
	{
		MachineStatus.WarningExist = 1;
	}
	if (MachineAlarmState.AlarmExist)
	{
		MachineStatus.AlarmExist = 1;
	}

	switch(MainControlData.State)
	{
		case MAIN_CONTROL_STATE_STOP:
			MachineStatus.OperationState = MACHINE_STATE_STOP;
			break;
		case MAIN_CONTROL_STATE_RUN:
			MachineStatus.OperationState = MACHINE_STATE_RUN;
			break;
		case MAIN_CONTROL_STATE_CLEANING:
			MachineStatus.OperationState = MACHINE_STATE_CLEANING;
			break;
		case MAIN_CONTROL_STATE_ATTACHING:
			MachineStatus.OperationState = MACHINE_STATE_ATTACHING;
			break;
		case MAIN_CONTROL_STATE_DETACHING:
			MachineStatus.OperationState = MACHINE_STATE_DETACHING;
			break;
		case MAIN_CONTROL_STATE_STARTING:
			MachineStatus.OperationState = MACHINE_STATE_STARTING;
			break;
		case MAIN_CONTROL_STATE_STOPPING:
			MachineStatus.OperationState = MACHINE_STATE_STOPPING;
			break;
		case MAIN_CONTROL_STATE_EMERGENCY_STOP:
			MachineStatus.OperationState = MACHINE_STATE_EMERGENCY_STOP;
			break;
	}
	PollingInspectionResult();

	IdleProcessData.Time[IdleProcessData.CurrentIndex] = IdleProcessData.CurrentTime;
	IdleProcessData.TimeCounter[IdleProcessData.CurrentIndex] = GetTickCount() - LastCheckCount;
	IdleProcessData.CurrentIndex = (IdleProcessData.CurrentIndex + 1) & IDLE_PROCESS_LIST_MASK;
	IdleProcessData.CurrentTime++;
	LastCheckCount = GetTickCount();

	VirtualMachineTimer->Enabled = true;	
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_GeneralControl(int action, int *value)
{
	if (action == 0)
	{

	}
	else if (action == 1)
	{

	}
	else if (action == 2)
	{

	}
	else if (action == 3)
	{
		if (value[0] == 0)
		{
			MC_MainControl_Cleaning();
		}
		else if (value[0] == 1)
		{
//			MC_ReadyState();
		}
		else if (value[0] == 4)
		{
//			MC_HomePositionSetup();
		}
	}
	else if (action == 4)
	{
	
	}
	else if (action == 5)
	{

	}
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_MainControl_Cleaning(void)
{
	if (!MainControlData.HomeDetected)
	{
		MC_HomePositionSetup();
	}
	else
	{
//		NCControlInfo.Command = NC_CONTROL_COMMAND_CLEANING;
//		NCControlInfo.State = NC_CONTROL_STATE_DETACHING;
//		NCControlInfo.PosState = NC_CONTROL_POS_STATE_NONE;
//		NCControlInfo.ControlState = 0;
	}
//	PORT_ModifyOutPort(OP_MAGNETIC_ON, 0);
//	PORT_ModifyOutPort(OP_AIR_BRUSH_1_ACTUATOR, 0);
//	PORT_ModifyOutPort(OP_AIR_BRUSH_2_ACTUATOR, 0);
    MainControlData.State = MAIN_CONTROL_STATE_CLEANING;
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_HomePositionSetup(void)
{
	MainControlData.HomeDetected = TRUE;
	for (int stepMotorIndex = 0; stepMotorIndex < MAX_STEP_MOTOR_COUNT; stepMotorIndex++)
	{
		MachineStatus.StepMotorAbsEncoder[stepMotorIndex] = 0;
		MachineStatus.OriginDetected[stepMotorIndex] = 1;
	}

}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::ApplyVirtualCapture(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
		{
			CaptureStatus[spbIndex].VirtualCaptureList[camIndex].clear();
		}
	}

	for (int imageIndex = 0; imageIndex < 100; imageIndex++)
	{
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			AnsiString imageFileName = "";
			if (!VirtualOptionCaptureMode)
			{
				imageFileName = VirtualCaptureDir + "\\Image" + IntToStr(imageIndex + 1) + "_" + IntToStr(globalCameraIndex + 1) + ".bmp";
			}
			else
			{
				imageFileName = VirtualCaptureDir + "\\Image" + IntToStr(imageIndex + 1) + "_" + IntToStr(globalCameraIndex + 1) + "_O.bmp";
			}
			if (FileExists(imageFileName))
			{
				int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
				int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
				TVirtualCaptureUnit newVirtualCaptureUnit;
				newVirtualCaptureUnit.FileName = imageFileName;
				CaptureStatus[spbIndex].VirtualCaptureList[camIndex].push_back(newVirtualCaptureUnit);
			}
		}
	}

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
		{
			CaptureStatus[spbIndex].TotalCaptureCount[camIndex] = CaptureStatus[spbIndex].VirtualCaptureList[camIndex].size();
			CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex] = 0;
		}
	}

	VirtualSPBForm->ApplyVirtualCapture(VirtualCaptureDir);
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::MC_Procedure(TMachineControlData_Procedure *procedureData)
{
	int motorIndex;
	if (procedureData->Action == 0)		// stop
	{
		MainControlData.State = MAIN_CONTROL_STATE_STOP;
	}
	else if (procedureData->Action == 1)	// run
	{
		MainControlData.State = MAIN_CONTROL_STATE_RUN;
		for (int motorIndex = 0; motorIndex < MAX_SERVO_MOTOR_COUNT; motorIndex++)
		{
			MainControlData.MotorSpeed[motorIndex] = procedureData->MotorSpeed[motorIndex];
		}

	}
	else if (procedureData->Action == 2)	// ready
	{
//		MC_MainControl_Ready();
	}
	else if (procedureData->Action == 3)	// cleaning
	{
		MC_MainControl_Cleaning();
	}
	else if (procedureData->Action == 4)	// suspend reset
	{
		if ((MachineStatus.SuspendReason == MACHINE_SUSPEND_REASON_VD1_STALL ||
			MachineStatus.SuspendReason == MACHINE_SUSPEND_REASON_VD2_STALL) &&
			MainControlData.State == MAIN_CONTROL_STATE_EMERGENCY_STOP)
		{
		}

		MachineStatus.Suspended = 0;
	}
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::ApplyVirtualNewCapture(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
		{
			CaptureStatus[spbIndex].VirtualCaptureList[camIndex].clear();
		}
	}

	for (int imageIndex = 0; imageIndex < 100; imageIndex++)
	{
		AnsiString containerFileName = VirtualCaptureDir + "\\Image" + IntToStr(imageIndex + 1) + ".FAC";
		if (FileExists(containerFileName))
		{
			TFileContainer fileContainer;
			fileContainer.Open(containerFileName);
			for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
			{
				AnsiString imageFileName = "";
				if (!VirtualOptionCaptureMode)
				{
					imageFileName = "Image" + IntToStr(imageIndex + 1) + "_" + IntToStr(globalCameraIndex + 1) + ".fbm";
				}
				else
				{
					imageFileName = "Image" + IntToStr(imageIndex + 1) + "_" + IntToStr(globalCameraIndex + 1) + "_O.fbm";
				}
				if (fileContainer.FileContains(imageFileName))
				{
					int spbIndex = CameraMapInfo[globalCameraIndex].SPBIndex;
					int camIndex = CameraMapInfo[globalCameraIndex].CamIndex;
					TVirtualCaptureUnit newVirtualCaptureUnit;
					newVirtualCaptureUnit.ContainerFileName = containerFileName;
					newVirtualCaptureUnit.FileName = imageFileName;
					CaptureStatus[spbIndex].VirtualCaptureList[camIndex].push_back(newVirtualCaptureUnit);
				}
			}
		}


		TabletInfo.Disk1TabletList[imageIndex].State = TABLET_STATE_CAPTURE_1_COMPLETE;
		TabletInfo.Disk1TabletList[imageIndex].Sensor1Time = (GetTickCount() + imageIndex * 30) * 20;
		TabletInfo.Disk1TabletList[imageIndex].Sensor1Length = MachineCaputreSetupData.StudiedTabletSensorLength *
			MachineCaputreSetupData.SuctionDiskSpeed / MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed + random(20);
		TabletInfo.Disk1TabletList[imageIndex].EstimatedSensor2Time = TabletInfo.Disk1TabletList[imageIndex].Sensor1Time +
			MachineSetupData.SensorIntervalA * MachineCaputreSetupData.SuctionDiskSpeed / MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed;

		TabletInfo.Disk2TabletList[imageIndex].State = TABLET_STATE_COMPLETE;
		TabletInfo.Disk2TabletList[imageIndex].Sensor2Time = TabletInfo.Disk1TabletList[imageIndex].EstimatedSensor2Time + random(200) - 100;
		TabletInfo.Disk2TabletList[imageIndex].Sensor2Length = MachineCaputreSetupData.StudiedTabletSensorLength *
			MachineCaputreSetupData.SuctionDiskSpeed / MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed + random(20);
	}

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
		{
			CaptureStatus[spbIndex].TotalCaptureCount[camIndex] = CaptureStatus[spbIndex].VirtualCaptureList[camIndex].size();
			CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex] = 0;
		}
	}

	VirtualSPBForm->ApplyVirtualNewCapture(VirtualCaptureDir);
/*
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
		{
			for (int captureIndex = 0; captureIndex < CaptureStatus[spbIndex].TotalCaptureCount[camIndex]; captureIndex++)
			{
				VirtualTabletCapture(spbIndex, camIndex);
			}
		}
	}
*/	
}
//---------------------------------------------------------------------------
unsigned char *TVirtualMachineForm::GetCurrentCaptureBuffer(int spbIndex, int camIndex)
{
	int currentCaptureIndex = CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex];
	AnsiString virtualCaptureFileName = CaptureStatus[spbIndex].VirtualCaptureList[camIndex][currentCaptureIndex].FileName;
	Graphics::TBitmap *tempBitmap = new Graphics::TBitmap;
	tempBitmap->LoadFromFile(virtualCaptureFileName);

	if (CaptureStatus[spbIndex].CaptureBuffer) delete[] CaptureStatus[spbIndex].CaptureBuffer;
	if (SPBSystemSetupData[spbIndex].GlobalCameraIndex[camIndex] == 0 || SPBSystemSetupData[spbIndex].GlobalCameraIndex[camIndex] == 5)
	{
		CaptureStatus[spbIndex].CaptureBuffer = new unsigned char[tempBitmap->Width * tempBitmap->Height];
		for (int y = 0; y < tempBitmap->Height; y++)
		{
			byte *pBitmap = (byte *)tempBitmap->ScanLine[tempBitmap->Height - 1 - y];
			for (int x = 0; x < tempBitmap->Width; x++)
			{
				if (y & 1 == 0)
				{
					if (x & 1 == 0)		// b
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 0];
					}
					else				// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 1];
					}
				}
				else
				{
					if (x & 1 == 0)		// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 1];
					}
					else				// r
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 2];
					}
				}
			}
		}
	}
	else if (SPBSystemSetupData[spbIndex].GlobalCameraIndex[camIndex] == 2 || SPBSystemSetupData[spbIndex].GlobalCameraIndex[camIndex] == 4)
	{
		CaptureStatus[spbIndex].CaptureBuffer = new unsigned char[tempBitmap->Width * tempBitmap->Height];
		for (int y = 0; y < tempBitmap->Height; y++)
		{
			byte *pBitmap = (byte *)tempBitmap->ScanLine[tempBitmap->Height - 1 - y];
			for (int x = 0; x < tempBitmap->Width; x++)
			{
				if (y & 1 == 0)
				{
					if (x & 1 == 0)		// b
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * (tempBitmap->Width - 1 - x) + 0];
					}
					else				// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * (tempBitmap->Width - 1 - x) + 1];
					}
				}
				else
				{
					if (x & 1 == 0)		// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * (tempBitmap->Width - 1 - x) + 1];
					}
					else				// r
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * (tempBitmap->Width - 1 - x) + 2];
					}
				}
			}
		}
	}
	else if (SPBSystemSetupData[spbIndex].InspectPosition[camIndex] != CAMERA_POSITION_3D)
	{
		CaptureStatus[spbIndex].CaptureBuffer = new unsigned char[tempBitmap->Width * tempBitmap->Height];
		for (int y = 0; y < tempBitmap->Height; y++)
		{
			byte *pBitmap = (byte *)tempBitmap->ScanLine[y];
			for (int x = 0; x < tempBitmap->Width; x++)
			{
				if (y & 1 == 0)
				{
					if (x & 1 == 0)		// b
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 0];
					}
					else				// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 1];
					}
				}
				else
				{
					if (x & 1 == 0)		// g
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 1];
					}
					else				// r
					{
						CaptureStatus[spbIndex].CaptureBuffer[y * tempBitmap->Width + x] = pBitmap[3 * x + 2];
					}
				}
			}
		}
	}
	else
	{
		CaptureStatus[spbIndex].CaptureBuffer = new unsigned char[SYSTEM_CAMERA_WIDTH_3D * SYSTEM_CAMERA_HEIGHT_3D];
		for (int y = 0; y < tempBitmap->Height; y++)
		{
			byte *pBitmap = (byte *)tempBitmap->ScanLine[y];
			for (int x = 0; x < tempBitmap->Width; x++)
			{
				CaptureStatus[spbIndex].CaptureBuffer[x * SYSTEM_CAMERA_WIDTH_3D + y] = pBitmap[x];
			}
		}
	}

	delete tempBitmap;
	return CaptureStatus[spbIndex].CaptureBuffer;
}
//---------------------------------------------------------------------------
unsigned char *TVirtualMachineForm::GetCurrentNewCaptureBuffer(int spbIndex, int camIndex)
{
	int currentCaptureIndex = CaptureStatus[spbIndex].CurrentCaptureIndex[camIndex];
	AnsiString virtualCaptureContainerFileName = CaptureStatus[spbIndex].VirtualCaptureList[camIndex][currentCaptureIndex].ContainerFileName;
	AnsiString bitmapName = CaptureStatus[spbIndex].VirtualCaptureList[camIndex][currentCaptureIndex].FileName;
	TFileContainer fileContainer;
	TBitmapHeader bitmapHeader;
	fileContainer.Open(virtualCaptureContainerFileName);
	fileContainer.GetBitmapHeader(&bitmapHeader, bitmapName);

	if (CaptureStatus[spbIndex].CaptureBuffer) delete[] CaptureStatus[spbIndex].CaptureBuffer;
	CaptureStatus[spbIndex].CaptureBuffer = new unsigned char[bitmapHeader.Width * bitmapHeader.Height];
	fileContainer.ExtractData(bitmapName, CaptureStatus[spbIndex].CaptureBuffer);

	return CaptureStatus[spbIndex].CaptureBuffer;
}
//---------------------------------------------------------------------------
void TVirtualMachineForm::FlushCurrentImageBuffer(int spbIndex, int camIndex)
{
	if (CaptureStatus[spbIndex].CaptureBuffer)
	{
		delete[] CaptureStatus[spbIndex].CaptureBuffer;
		CaptureStatus[spbIndex].CaptureBuffer = NULL;
	}
}
//---------------------------------------------------------------------------


void __fastcall TVirtualMachineForm::FormDestroy(TObject *Sender)
{
	// clean up
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (CaptureStatus[spbIndex].CaptureBuffer)
		{
			delete[] CaptureStatus[spbIndex].CaptureBuffer;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TVirtualMachineForm::PollingInspectionResult(void)
{
	int goodResultCount, uninsResultCount, noneResultCount, defectResultCount;
	int spbIndex, spbTableIndex, heapIndex;
	int brightnessDropOccured;
	int CheckUnPrint;
	THCBDisk2TabletUnit *disk2TabletUnit;
	THCBDisk2TabletUnit tempDisk2TabletUnit;

	disk2TabletUnit = &tempDisk2TabletUnit;

	CheckUnPrint = 0;

	goodResultCount = 0;
	uninsResultCount = 0;
	noneResultCount = 0;
	defectResultCount = 0;
	for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (SPBProcessingResultData[spbIndex].CompleteCount > SPB_PROCESSING_RESULT_COUNT) continue;
		for (spbTableIndex = 0; spbTableIndex < SPBProcessingResultData[spbIndex].CompleteCount; spbTableIndex++)
		{
			heapIndex = (SPBProcessingResultData[spbIndex].ProcessedTabletNumber[spbTableIndex] & SPB_RESULT_HEAP_MASK);

			SPBResultHeap[spbIndex].ResultList[heapIndex].TabletNumber = SPBProcessingResultData[spbIndex].ProcessedTabletNumber[spbTableIndex];
			SPBResultHeap[spbIndex].ResultList[heapIndex].InspectionResult = SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_PROCESSING_MASK;
//			SPBResultHeap[spbIndex].ResultList[heapIndex].PrintResult[0] = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_PRINT_IS_CAM1) >> SPB_TABLET_RESULT_PRINT_IS_CAM1_SHIFT);
//			SPBResultHeap[spbIndex].ResultList[heapIndex].PrintResult[1] = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_PRINT_IS_CAM2) >> SPB_TABLET_RESULT_PRINT_IS_CAM2_SHIFT);
//			SPBResultHeap[spbIndex].ResultList[heapIndex].PrintResult[2] = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_PRINT_IS_CAM3) >> SPB_TABLET_RESULT_PRINT_IS_CAM3_SHIFT);
			SPBResultHeap[spbIndex].ResultList[heapIndex].PrintResult = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_PRINT_IS_MASK) >> SPB_TABLET_RESULT_PRINT_IS_SHIFT);

			SPBResultHeap[spbIndex].ResultList[heapIndex].ThickErrorSW = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_THICKERROR_MASK) >> SPB_TABLET_RESULT_PRINT_THICKERROR_SHIFT);
			SPBResultHeap[spbIndex].ResultList[heapIndex].Front_Rear = ((SPBProcessingResultData[spbIndex].ProcessingResult[spbTableIndex] & SPB_TABLET_RESULT_FRONT_FACE_MASK) >> SPB_TABLET_RESULT_FRONT_FACE_SHIFT);
		}
	}

/*
	if (TabletControlData.InspectionSPBMask & (0x0001 << spbIndex))
	{
		heapIndex = disk2TabletUnit->TabletNumber & SPB_RESULT_HEAP_MASK;
		if (SPBResultHeap[spbIndex].ResultList[heapIndex].TabletNumber == disk2TabletUnit->TabletNumber)
		{
			disk2TabletUnit->InspectionResult_SPB[spbIndex] = SPBResultHeap[spbIndex].ResultList[heapIndex].InspectionResult;
		}
	}
	else
	{
		disk2TabletUnit->InspectionResult_SPB[spbIndex] = SPB_TABLET_RESULT_GOOD;
	}
*/
	disk2TabletUnit->TabletNumber = PollingInspectionResultTabletNumber;
	int thickErrorVal1, thickErrorVal2;
	int frontPrintVal, rearPrintVal, frontRearVal1, frontRearVal2;

	for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		heapIndex = disk2TabletUnit->TabletNumber & SPB_RESULT_HEAP_MASK;
		if (SPBResultHeap[spbIndex].ResultList[heapIndex].TabletNumber == disk2TabletUnit->TabletNumber)
		{
			disk2TabletUnit->InspectionResult_SPB[spbIndex] = SPBResultHeap[spbIndex].ResultList[heapIndex].InspectionResult;
		}
		else
		{
			disk2TabletUnit->InspectionResult_SPB[spbIndex] = SPB_TABLET_RESULT_NONE;
		}
		if (disk2TabletUnit->InspectionResult_SPB[spbIndex] == SPB_TABLET_RESULT_GOOD)
		{
			if (spbIndex == 0)
			{
				thickErrorVal1 = SPBResultHeap[spbIndex].ResultList[heapIndex].ThickErrorSW;
			}
			else if (spbIndex == 1)
			{
				thickErrorVal2 = SPBResultHeap[spbIndex].ResultList[heapIndex].ThickErrorSW;
			}
			goodResultCount++;
		}
		else if (disk2TabletUnit->InspectionResult_SPB[spbIndex] != SPB_TABLET_RESULT_DEFECT &&
			disk2TabletUnit->InspectionResult_SPB[spbIndex] != SPB_TABLET_RESULT_NONE &&
			disk2TabletUnit->InspectionResult_SPB[spbIndex] != SPB_TABLET_RESULT_PROCESSING)	// unins
		{
			uninsResultCount++;
			disk2TabletUnit->InspectionResult = (TABLET_RESULT_SPB_MASK | disk2TabletUnit->InspectionResult_SPB[spbIndex]);
			if (disk2TabletUnit->InspectionResult_SPB[spbIndex] == SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED)
			{
				brightnessDropOccured = 1;
			}
			break;
		}
		else if (disk2TabletUnit->InspectionResult_SPB[spbIndex] == SPB_TABLET_RESULT_DEFECT)
		{
			defectResultCount++;
		}

		if (disk2TabletUnit->InspectionResult_SPB[spbIndex] == SPB_TABLET_RESULT_NONE)
		{
			noneResultCount++;
		}
	}

	if (goodResultCount == MachineSetupData.IPB_BoardCount)	// good or unprint
	{
		disk2TabletUnit->InspectionResult = TABLET_RESULT_GOOD;

		if (disk2TabletUnit->InspectionResult == TABLET_RESULT_GOOD)
		{
			if (InspectionOption.CheckUnPrint)
			{
				heapIndex = disk2TabletUnit->TabletNumber & SPB_RESULT_HEAP_MASK;
				//frontPrintVal = SPBResultHeap[FrontCamera_SPBIndex].ResultList[heapIndex].PrintResult[FrontCamera_CAMIndex];
				//rearPrintVal = SPBResultHeap[BackCamera_SPBIndex].ResultList[heapIndex].PrintResult[BackCamera_CAMIndex];
				frontPrintVal = SPBResultHeap[0].ResultList[heapIndex].PrintResult;
				rearPrintVal = SPBResultHeap[1].ResultList[heapIndex].PrintResult;

				if ((frontPrintVal | rearPrintVal) != 0x01 || (frontPrintVal & rearPrintVal) != 0x00)
				{
					disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT_UNPRINT;
				}
			}
		}

		if (disk2TabletUnit->InspectionResult == TABLET_RESULT_GOOD)
		{
			if (InspectionOption.CheckFrontRear)
			{
				heapIndex = disk2TabletUnit->TabletNumber & SPB_RESULT_HEAP_MASK;
				frontRearVal1 = SPBResultHeap[0].ResultList[heapIndex].Front_Rear;
				frontRearVal2 = SPBResultHeap[1].ResultList[heapIndex].Front_Rear;

				if ((frontRearVal1 | frontRearVal2) != 0x01 || (frontRearVal1 & frontRearVal2) != 0x00)
				{
					disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT_FR_MISMATCH;
				}
			}
		}

		if (disk2TabletUnit->InspectionResult == TABLET_RESULT_GOOD)
		{
			if (thickErrorVal1 != 0 && thickErrorVal2 != 0)
			{
				disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT;
			}
		}


		if (disk2TabletUnit->InspectionResult == TABLET_RESULT_GOOD)
		{
			TabletInspectInfo.GoodTabletCount++;
		}
		else
		{
			if (disk2TabletUnit->InspectionResult == TABLET_RESULT_DEFECT_UNPRINT)
			{
				TabletInspectInfo.UnPrintTabletCount++;
				TabletInspectInfo.DefectTabletCount++;
			}
			else if (disk2TabletUnit->InspectionResult == TABLET_RESULT_DEFECT_FR_MISMATCH)
			{
				TabletInspectInfo.FRMismatchTabletCount++;
				TabletInspectInfo.DefectTabletCount++;
			}
			else
			{
				TabletInspectInfo.DefectTabletCount++;
			}
		}
/*
		if (thickErrorVal1 == 1 && thickErrorVal2 == 1)
		{
			disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT_THIN_TABLET;
			TabletInspectInfo.DefectTabletCount++;
		}
		else if (thickErrorVal1 == 2 && thickErrorVal2 == 2)
		{
			disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT_FAT_TABLET;
			TabletInspectInfo.DefectTabletCount++;
		}
*/
/*
		else
		{
			disk2TabletUnit->InspectionResult = TABLET_RESULT_GOOD;
			TabletInspectInfo.GoodTabletCount++;
		}
*/
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].Result = disk2TabletUnit->InspectionResult;
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].TabletNumber = disk2TabletUnit->TabletNumber;
		InspectionResultTable.CurrentIndex = (InspectionResultTable.CurrentIndex + 1) & RESULT_TABLE_MASK;

		TabletInspectInfo.TotalTabletCount++;

		PollingInspectionResultTabletNumber++;
	}
	else if (uninsResultCount > 0)
	{
		disk2TabletUnit->State = TABLET_STATE_BLOW_WAITING;
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].Result = disk2TabletUnit->InspectionResult;
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].TabletNumber = disk2TabletUnit->TabletNumber;
		InspectionResultTable.CurrentIndex = (InspectionResultTable.CurrentIndex + 1) & RESULT_TABLE_MASK;
		PollingInspectionResultTabletNumber++;

		TabletInspectInfo.UnInsTabletCount++;
		TabletInspectInfo.TotalTabletCount++;
	}
	else if (noneResultCount == 0 && defectResultCount > 0)	// defect
	{
		disk2TabletUnit->InspectionResult = TABLET_RESULT_DEFECT;
		disk2TabletUnit->State = TABLET_STATE_BLOW_WAITING;
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].Result = disk2TabletUnit->InspectionResult;
		InspectionResultTable.Table[InspectionResultTable.CurrentIndex].TabletNumber = disk2TabletUnit->TabletNumber;
		InspectionResultTable.CurrentIndex = (InspectionResultTable.CurrentIndex + 1) & RESULT_TABLE_MASK;
		PollingInspectionResultTabletNumber++;

		TabletInspectInfo.DefectTabletCount++;
		TabletInspectInfo.TotalTabletCount++;
	}
}
//---------------------------------------------------------------------------
