//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 완료 및 예정                                                                                                             
// CameraIndex 관련 수정 완료
// SPB06, SPB07 버전 상태에 따라 추후 접근해야할 SPB Index의 제한이 필요할 수 도 있음
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Setup_Form.h"
#include "Environment.h"
#include "Message_Form.h"
#include "MultiLanguage.h"
#include "Common_PC.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"

#define SYSTEM_SPB_COUN		1
TSetupForm *SetupForm;
//---------------------------------------------------------------------------
__fastcall TSetupForm::TSetupForm(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);
  }

  GetDefaultString();
	SetupMode = SETUP_MODE_NONE;
	TabletSetupData = NULL;
	Tablet3DSetupData = NULL;
	Setup3DNeeded = false;
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::GetDefaultString()
{
	CancelButton->Caption = SETUPFORM_BUTTON_CAPTION_01;
	Label17->Caption = SETUPFORM_LABEL_CAPTION_01;
  TntLabel8->Caption = SETUPFORM_LABEL_CAPTION_01;
	Label31->Caption = SETUPFORM_LABEL_CAPTION_02;
  TntLabel10->Caption = SETUPFORM_LABEL_CAPTION_02;
	InformationLabel->Caption = SETUPFORM_LABEL_CAPTION_03;
	SendCaptureSetupDataLabel1->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel1->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel1->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel1->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel1->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCaptureSetupDataLabel2->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel2->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel2->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel2->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel2->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCaptureSetupDataLabel4->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel4->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel4->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel4->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel4->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCaptureSetupDataLabel3->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel3->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel3->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel3->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel3->Caption = SETUPFORM_LABEL_CAPTION_05;

  SendCaptureSetupDataLabel5->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel5->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel5->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel5->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel5->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCaptureSetupDataLabel6->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendCharacterDataLabel6->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendSetupDataLabel6->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendStudyDataLabel6->Caption = SETUPFORM_LABEL_CAPTION_05;
  SendGradeDataLabel6->Caption = SETUPFORM_LABEL_CAPTION_05;

  LoadSetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_05;
  MakeCharacterDataLabel->Caption = SETUPFORM_LABEL_CAPTION_05;
  ModifySetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_05;

	Label8->Caption = SETUPFORM_LABEL_CAPTION_06;
	Label15->Caption = SETUPFORM_LABEL_CAPTION_07;
  TntLabel7->Caption = SETUPFORM_LABEL_CAPTION_07;
	Label6->Caption = SETUPFORM_LABEL_CAPTION_09;
	Label7->Caption = SETUPFORM_LABEL_CAPTION_12;
	Label11->Caption = SETUPFORM_LABEL_CAPTION_13;
  TntLabel5->Caption = SETUPFORM_LABEL_CAPTION_13;
	Label9->Caption = SETUPFORM_LABEL_CAPTION_14;
  TntLabel4->Caption = SETUPFORM_LABEL_CAPTION_14;
	Label13->Caption = SETUPFORM_LABEL_CAPTION_15;
  TntLabel6->Caption = SETUPFORM_LABEL_CAPTION_15;
	InformationLabel->Caption = SETUPFORM_LABEL_CAPTION_16;
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::InitSetup(ESetupMode setupMode)
{
	SetupMode = setupMode;
	SetupStep = SETUP_STEP_INIT;
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::FormDestroy(TObject *Sender)
{
  Comm_IsActiveForm = false;
	if (TabletSetupData)
	{
		delete TabletSetupData;
		TabletSetupData = NULL;
	}
	if (Tablet3DSetupData)
	{
		delete Tablet3DSetupData;
		Tablet3DSetupData = NULL;
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SetupTimerTimer(TObject *Sender)
{
	try
	{
    Application->ProcessMessages();
		if (SetupMode == SETUP_MODE_STUDY)
		{
			if (SetupStep == SETUP_STEP_INIT)
			{
				InitDisplay();
				InitSetupData();
				SetupStep = SETUP_STEP_READY;
			}
			else if (SetupStep == SETUP_STEP_READY)
			{
				SendCaptureSetupData();
				SendTabletCharacterData();
				SendTabletSetupData();
				SetupStep = SETUP_STEP_SEND_COMPLETE;
			}
			else if (SetupStep == SETUP_STEP_SEND_COMPLETE)
			{
				SendSetupStartCommand();
				SetupStep = SETUP_STEP_CPB_WAITING;
			}
			else if (SetupStep == SETUP_STEP_CPB_WAITING)
			{
				int completeSPBCount = PollingCPBSetupStatus();

        int spbSetCount = 0;
        for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		    {
          if(!(validSPBMask & (0x01 << spbIndex))) continue;

          spbSetCount++;
        }

				if (completeSPBCount >= spbSetCount)
				{
					SetupStep = SETUP_STEP_CPB_SETUP_COMPLETE;
				}
			}
			else if (SetupStep == SETUP_STEP_CPB_SETUP_COMPLETE)
			{
				SetupStep = SETUP_STEP_NONE;
				ModalResult = mrOk;
			}
		}
		else if (SetupMode == SETUP_MODE_INSPECTION)
		{
			if (SetupStep == SETUP_STEP_INIT)
			{
				InitDisplay();
				InitSetupData();
				SetupStep = SETUP_STEP_READY;
			}
			else if (SetupStep == SETUP_STEP_READY)
			{
				SendCaptureSetupData();
				SendTabletCharacterData();
				SendTabletSetupData();
				SendTabletStudyData();
				SendTabletGradeData();
				SetupStep = SETUP_STEP_SEND_COMPLETE;
			}
			else if (SetupStep == SETUP_STEP_SEND_COMPLETE)
			{
				SendSetupStartCommand();
				SetupStep = SETUP_STEP_CPB_WAITING;
			}
			else if (SetupStep == SETUP_STEP_CPB_WAITING)
			{
				int completeSPBCount = PollingCPBSetupStatus();

				int spbSetCount = 0;
        for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		    {
          if(!(validSPBMask & (0x01 << spbIndex))) continue;

          spbSetCount++;
        }

				if (completeSPBCount >= spbSetCount)
				{
					SetupStep = SETUP_STEP_CPB_SETUP_COMPLETE;
				}
			}
			else if (SetupStep == SETUP_STEP_CPB_SETUP_COMPLETE)
			{
				SetupStep = SETUP_STEP_NONE;
				ModalResult = mrOk;
			}
		}
		else if (SetupMode == SETUP_MODE_GRADE_CHANGE)
		{
			if (SetupStep == SETUP_STEP_INIT)
			{
				InitDisplay();
				SetupStep = SETUP_STEP_READY;
			}
			else if (SetupStep == SETUP_STEP_READY)
			{
				SendTabletGradeData();
				SetupStep = SETUP_STEP_SEND_COMPLETE;
			}
			else if (SetupStep == SETUP_STEP_SEND_COMPLETE)
			{
				SendSetupStartCommand();
				SetupStep = SETUP_STEP_CPB_WAITING;
			}
			else if (SetupStep == SETUP_STEP_CPB_WAITING)
			{
				int completeSPBCount = PollingCPBSetupStatus();

				int spbSetCount = 0;
        for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		    {
          if(!(validSPBMask & (0x01 << spbIndex))) continue;

          spbSetCount++;
        }

				if (completeSPBCount >= spbSetCount)
				{
					SetupStep = SETUP_STEP_CPB_SETUP_COMPLETE;
				}
			}
			else if (SetupStep == SETUP_STEP_CPB_SETUP_COMPLETE)
			{
				SetupStep = SETUP_STEP_NONE;
				ModalResult = mrOk;
			}
		}
	}
	catch (Exception &ec)
	{
		SetupMode = SETUP_MODE_NONE;
		if (ec.Message != "")
		{
			ShowMessageFA(ec.Message);
		}
		ModalResult = mrCancel;
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::FormActivate(TObject *Sender)
{
  int BoardIndex = 0;
  Comm_IsActiveForm = true;
/*  
  for(BoardIndex = 1;BoardIndex<SYSTEM_SPB_MAX_COUNT+1;++BoardIndex)
  {
     if(Comm_GetIgnoreState(BoardIndex) == false)
       Comm_Connect(BoardIndex);
  }
*/
	 for (int spbIndex = 0; spbIndex < SYSTEM_SPB_MAX_COUNT; spbIndex++)
	{
	 	TTntPanel *BoardLabel = (TTntPanel *) FindComponent("IPBPanel" + IntToStr(spbIndex + 1));
		if(BoardLabel)
		{
			BoardLabel->Visible = false;
		}
	}

	 for (int spbIndex = MachineSetupData.IPB_BoardCount; spbIndex > 0 ; spbIndex--)
	{
	 	TTntPanel *BoardLabel = (TTntPanel *) FindComponent("IPBPanel" + IntToStr(spbIndex));
		if(BoardLabel)
		{
			BoardLabel->Visible = true;
		}
	}
  
	SetupTimer->Enabled = true;
}
//---------------------------------------------------------------------------
bool __fastcall TSetupForm::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;

      //ShowMessage(IntToStr(tabletSetupData->ImageCutStartX[0]));

			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::WriteSetupData(TTabletSetupData *tabletSetupData)
{
	AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt";

	if (FileExists(setupDataFileName))
	{
		TFileStream *fileStream  = new TFileStream(setupDataFileName, fmOpenWrite);
		if (fileStream)
		{
			fileStream->Write(tabletSetupData, sizeof(TTabletSetupData));
			delete fileStream;
		}
	}
}
//---------------------------------------------------------------------------
bool __fastcall TSetupForm::Read3DSetupData(TTablet3DSetupData *tablet3DSetupData)
{
	AnsiString setupDataFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".sdt_3D";

	memset(tablet3DSetupData, 0, sizeof(TTablet3DSetupData));
	if (FileExists(setupDataFileName))
	{
		TFileStream *fileStream  = new TFileStream(setupDataFileName, fmOpenRead);
		if (fileStream)
		{
			fileStream->Read(tablet3DSetupData, sizeof(TTablet3DSetupData));
			delete fileStream;
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		return false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::InitDisplay(void)
{
	TTntLabel *statusLabel;
	if (SetupMode == SETUP_MODE_STUDY)
	{
		InformationLabel->Caption = SETUPFORM_LABEL_CAPTION_16;
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
      if(!(validSPBMask & (0x01 << spbIndex))) continue;

			statusLabel = (TTntLabel *) FindComponent("SendStudyDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = SETUPFORM_LABEL_CAPTION_08;
			statusLabel->Left = (statusLabel->Parent->Width - statusLabel->Width) / 2;
			statusLabel = (TTntLabel *) FindComponent("SendGradeDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = SETUPFORM_LABEL_CAPTION_08;
			statusLabel->Left = (statusLabel->Parent->Width - statusLabel->Width) / 2;
		}
	}
	else if (SetupMode == SETUP_MODE_INSPECTION)
	{
		InformationLabel->Caption = SETUPFORM_LABEL_CAPTION_04;
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
      if(!(validSPBMask & (0x01 << spbIndex))) continue;
      
			statusLabel = (TTntLabel *) FindComponent("SendStudyDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = SETUPFORM_LABEL_CAPTION_05;		
			statusLabel = (TTntLabel *) FindComponent("SendGradeDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = SETUPFORM_LABEL_CAPTION_05;
		}
	}
	else if (SetupMode == SETUP_MODE_GRADE_CHANGE)
	{
		InformationLabel->Caption = SETUPFORM_LABEL_CAPTION_04;
		LoadSetupDataLabel->Caption = "Pass";
		MakeCharacterDataLabel->Caption = "Pass";
		ModifySetupDataLabel->Caption = "Pass";

		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
      if(!(validSPBMask & (0x01 << spbIndex))) continue;
      
			statusLabel = (TTntLabel *) FindComponent("SendCaptureSetupDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = "Pass";
			statusLabel = (TTntLabel *) FindComponent("SendCharacterDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = "Pass";
			statusLabel = (TTntLabel *) FindComponent("SendSetupDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = "Pass";
			statusLabel = (TTntLabel *) FindComponent("SendStudyDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = "Pass";
			statusLabel = (TTntLabel *) FindComponent("SendGradeDataLabel" + IntToStr(spbIndex + 1));
			statusLabel->Caption = SETUPFORM_LABEL_CAPTION_05;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::InitSetupData(void)
{
	Setup3DNeeded = false;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
		{
			Setup3DNeeded = true;
			break;
		}
	}

  // 임시
  Setup3DNeeded = true;

	// load setup data
	TabletSetupData = new TTabletSetupData;
	Tablet3DSetupData = new TTablet3DSetupData;
	if (TabletSetupData == NULL || Tablet3DSetupData == NULL)
	{
		throw Exception("Out Of Memory.");
	}
	if (!ReadSetupData(TabletSetupData))
	{
		LoadSetupDataLabel->Font->Color = clRed;
		LoadSetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
		throw Exception("Can Not Read The Setup Data.");
	}
	if (Setup3DNeeded)
	{
		if (!Read3DSetupData(Tablet3DSetupData))
		{
			LoadSetupDataLabel->Font->Color = clRed;
			LoadSetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			throw Exception("Cann't Read 3D Setup Data.");
		}
	}

	LoadSetupDataLabel->Font->Color = clLime;
	LoadSetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
	this->Repaint();

	MakeTabletCharacterData(&ProductData, &TabletCharacter, &MachineParams);
	MakeCharacterDataLabel->Font->Color = clLime;
	MakeCharacterDataLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
	this->Repaint();

	// modify disk base height position
  int tempLeft, tempRight, tempTop, tempBottom;
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
    TabletSetupData->DiskBaseHeightPosition[globalCameraIndex] = MachineParams.DiscCenterPos[globalCameraIndex] / 4 * 4;
    
    tempLeft = ProductData.BoundaryLeft[globalCameraIndex] / 4 * 4;
    tempRight = ProductData.BoundaryRight[globalCameraIndex] / 4 * 4;
    tempTop = ProductData.BoundaryTop[globalCameraIndex] / 4 * 4;
    tempBottom = ProductData.BoundaryBottom[globalCameraIndex] / 4 * 4;

    ProductData.BoundaryLeft[globalCameraIndex] = tempLeft;
    ProductData.BoundaryRight[globalCameraIndex] = tempRight;
    ProductData.BoundaryTop[globalCameraIndex] = tempTop;
    ProductData.BoundaryBottom[globalCameraIndex] = tempBottom;

    TabletSetupData->ImageCutStartX[globalCameraIndex] = tempLeft;
		TabletSetupData->ImageCutEndX[globalCameraIndex] = tempRight;
		TabletSetupData->ImageCutStartY[globalCameraIndex] = tempTop;
		TabletSetupData->ImageCutEndY[globalCameraIndex] = tempBottom;
	}

	// write setup data
	WriteSetupData(TabletSetupData);

  // write product data
  AnsiString fileName = GetProductDataFileName(ProductData.ProductCode);
	WriteProductData(fileName, ProductData);

	// make tablet capture setup data 
	for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
		TabletCaptureSetupData.RangeLeft[globalCameraIndex] = ProductData.BoundaryLeft[globalCameraIndex];
		TabletCaptureSetupData.RangeTop[globalCameraIndex] = ProductData.BoundaryTop[globalCameraIndex];
		TabletCaptureSetupData.RangeRight[globalCameraIndex] = ProductData.BoundaryRight[globalCameraIndex];
		TabletCaptureSetupData.RangeBottom[globalCameraIndex] = ProductData.BoundaryBottom[globalCameraIndex];
	}

  for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
	{
    if(ProductData.SubSamplingMode == IMAGE_FULL_SCALE_MODE)
    {
      if (CameraMapInfo[globalCameraIndex].CameraInspectPosition != CAMERA_POSITION_3D)
      {
        TabletCaptureSetupData.RangeLeft[globalCameraIndex] *= 2;
        TabletCaptureSetupData.RangeTop[globalCameraIndex] *= 2;
        TabletCaptureSetupData.RangeRight[globalCameraIndex] *= 2;
        TabletCaptureSetupData.RangeBottom[globalCameraIndex] *= 2;
      }
    }
  }

	ModifySetupDataLabel->Font->Color = clLime;
	ModifySetupDataLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
	this->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendCaptureSetupData(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;
    
		TTntLabel *statusLabel = (TTntLabel *) FindComponent("SendCaptureSetupDataLabel" + IntToStr(spbIndex + 1));
		TTntShape *statusShape = (TTntShape *) FindComponent("SendCaptureSetupDataShape" + IntToStr(spbIndex + 1));
		if (!Comm_Request(COMM_SPB + spbIndex, CMD_TABLET_CAPTURE_SETUP_DATA, &TabletCaptureSetupData,
			sizeof(TTabletCaptureSetupData)))
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clRed;
				statusLabel->Color = clRed;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			}
			throw Exception("Failed In Data Transfer.");
		}
		else
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clLime;
				statusLabel->Color = clLime;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
			}
		}
		this->Repaint();
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendTabletCharacterData(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;
    
		TTntLabel *statusLabel = (TTntLabel *) FindComponent("SendCharacterDataLabel" + IntToStr(spbIndex + 1));
		TTntShape *statusShape = (TTntShape *) FindComponent("SendCharacterDataShape" + IntToStr(spbIndex + 1));
		if (!Comm_Request(COMM_SPB + spbIndex, CMD_TABLET_CHARACTER, &TabletCharacter,
			sizeof(TTabletCharacter)))
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clRed;
				statusLabel->Color = clRed;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			}
			throw Exception("Failed In Data Transfer.");
		}
		else
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clLime;
				statusLabel->Color = clLime;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
			}
		}
		this->Repaint();
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendTabletSetupData(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;

		TTntLabel *statusLabel = (TTntLabel *) FindComponent("SendSetupDataLabel" + IntToStr(spbIndex + 1));
		TTntShape *statusShape = (TTntShape *) FindComponent("SendSetupDataShape" + IntToStr(spbIndex + 1));
		try
		{
			Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 50000);
			if (!Comm_RequestEx(COMM_SPB + spbIndex, CMD_SETUP_DATA, NULL, 0,
				TabletSetupData, sizeof(TTabletSetupData)))
			{
				Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
				throw Exception("Failed In Data Transfer.");
			}
			if (Setup3DNeeded)
			{
				if (!Comm_RequestEx(COMM_SPB + spbIndex, CMD_SETUP_DATA_3D, NULL, 0,
					Tablet3DSetupData, sizeof(TTablet3DSetupData)))
				{
					Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
					throw Exception("Failed In Data Transfer.");
				}
			}
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clLime;
				statusLabel->Color = clLime;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
			}
			Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
			this->Repaint();
		}
		catch (Exception &ec)
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clRed;
				statusLabel->Color = clRed;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			}
			throw ec;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendTabletStudyData(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;

		TTntLabel *statusLabel = (TTntLabel *) FindComponent("SendStudyDataLabel" + IntToStr(spbIndex + 1));
		TTntShape *statusShape = (TTntShape *) FindComponent("SendStudyDataShape" + IntToStr(spbIndex + 1));
		if (!Comm_RequestEx(COMM_SPB + spbIndex, CMD_STUDY_DATA, NULL, 0,
			&TabletStudyResultData_PC, sizeof(TTabletStudyResultData)))
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clRed;
				statusLabel->Color = clRed;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			}
			throw Exception("Failed In Data Transfer.");
		}
		else
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clLime;
				statusLabel->Color = clLime;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
			}
		}
		this->Repaint();
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendTabletGradeData(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;
    
		TTntLabel *statusLabel = (TTntLabel *) FindComponent("SendGradeDataLabel" + IntToStr(spbIndex + 1));
		TTntShape *statusShape = (TTntShape *) FindComponent("SendGradeDataShape" + IntToStr(spbIndex + 1));
		if (!Comm_Request(COMM_SPB + spbIndex, CMD_GRADE_DATA, &TabletGradeData_PC,
			sizeof(TTabletGradeData)))
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clRed;
				statusLabel->Color = clRed;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_10;
			}
			throw Exception("Failed In Data Transfer.");
		}
		else
		{
			if (statusLabel && statusShape)
			{
				statusShape->Brush->Color = clLime;
				statusLabel->Color = clLime;
				statusLabel->Font->Color = clBlack;
				statusLabel->Caption = SETUPFORM_LABEL_CAPTION_11;
			}
		}
		this->Repaint();
	}
}
//---------------------------------------------------------------------------
void __fastcall TSetupForm::SendSetupStartCommand(void)
{
	int mode;
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;
    
		if (SetupMode == SETUP_MODE_STUDY)
		{
			mode = SPB_SETUP_MODE_STUDY;
			Comm_Request(COMM_SPB + spbIndex, CMD_SETUP_START, &mode, sizeof(int));
		}
		else if (SetupMode == SETUP_MODE_INSPECTION)
		{
			mode = SPB_SETUP_MODE_INSPECTION;
			Comm_Request(COMM_SPB + spbIndex, CMD_SETUP_START, &mode, sizeof(int));
		}
		else
		{
			mode = SPB_SETUP_MODE_GRADE_CHANGE;
			Comm_Request(COMM_SPB + spbIndex, CMD_SETUP_START, &mode, sizeof(int));
		}
	}
}
//---------------------------------------------------------------------------
int __fastcall TSetupForm::PollingCPBSetupStatus(void)
{
	TSPBProcessingSetupInfo SPBProcessingSetupInfo;
	int completeSPBCount = 0;
  AnsiString tempString1;
  AnsiString tempString2;

  if(DefaultLCID == 1042) // 한국어
  {
    tempString1 = "전송 중..";
    tempString2 = "완료";
  }
  else
  {
    tempString1 = "Transmitting..";
    tempString2 = "Completed";
  }

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(validSPBMask & (0x01 << spbIndex))) continue;

		TTntLabel *statusImage = (TTntLabel *) FindComponent("CPBSetupImage" + IntToStr(spbIndex + 1));
		Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 10000);
		Comm_Request(COMM_SPB + spbIndex, CMD_SPB_SETUP_STATUS, NULL, 0,
			&SPBProcessingSetupInfo, sizeof(TSPBProcessingSetupInfo));
		Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
		if (statusImage)
		{
			statusImage->Canvas->Font->Name = this->Font->Name;
			if (SPBProcessingSetupInfo.SetupStep == PROCESSING_SETUP_STEP_SETUP ||
				SPBProcessingSetupInfo.SetupStep == PROCESSING_SETUP_STEP_COM_WAITING)
			{
				if (SPBProcessingSetupInfo.AvailCPBCount > 0 && SPBProcessingSetupInfo.SetupCPBCount + SPBProcessingSetupInfo.FailCPBCount < SPBProcessingSetupInfo.AvailCPBCount)
				{
					statusImage->Canvas->Brush->Color = clYellow;
					statusImage->Canvas->Font->Color = clBlack;
					statusImage->Canvas->Pen->Color = clBlack;
					statusImage->Canvas->TextRect(Rect(0, 0,
						statusImage->Width * (SPBProcessingSetupInfo.SetupCPBCount + SPBProcessingSetupInfo.FailCPBCount) / SPBProcessingSetupInfo.AvailCPBCount, statusImage->Height),
						(statusImage->Width - statusImage->Canvas->TextWidth(tempString1)) / 2, (statusImage->Height - statusImage->Canvas->TextHeight(tempString1)) / 2, tempString1);
					statusImage->Canvas->Brush->Color = clBlack;
					statusImage->Canvas->Pen->Color = clWhite;
					statusImage->Canvas->Font->Color = clWhite;
					statusImage->Canvas->TextRect(Rect(statusImage->Width * (SPBProcessingSetupInfo.SetupCPBCount + SPBProcessingSetupInfo.FailCPBCount) / SPBProcessingSetupInfo.AvailCPBCount, 0,
						statusImage->Width, statusImage->Height),
						(statusImage->Width - statusImage->Canvas->TextWidth(tempString1)) / 2, (statusImage->Height - statusImage->Canvas->TextHeight(tempString1)) / 2, tempString1);
				}
			}
			else if (SPBProcessingSetupInfo.SetupStep == PROCESSING_SETUP_STEP_COMPLETE)
			{
				statusImage->Canvas->Brush->Color = clLime;
				statusImage->Canvas->FillRect(Rect(0, 0, statusImage->Width, statusImage->Height));
				statusImage->Canvas->Font->Color = clBlack;
				statusImage->Canvas->TextRect(Rect(0, 0, statusImage->Width, statusImage->Height),
					(statusImage->Width - statusImage->Canvas->TextWidth(tempString2)) / 2, (statusImage->Height - statusImage->Canvas->TextHeight(tempString2)) / 2, tempString2);
			}
		}
		if (SPBProcessingSetupInfo.SetupStep == PROCESSING_SETUP_STEP_COMPLETE)
		{
			completeSPBCount++;
		}
	}
	return completeSPBCount;
}
//---------------------------------------------------------------------------
bool __fastcall SendInspectionSetupData(void)
{
  // White Balance 값 전송
  TSetupForm *setupForm = new TSetupForm(Application);
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  for(int cameraIndex = 0; cameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
  {
    ReadCameraWhiteBalanceColorInfo(fileName, cameraIndex);
  }

  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		Comm_Request(COMM_SPB + spbIndex, CMD_SET_CAMERA_WHITE_BALANCE, WhiteBalanceInfo, sizeof(TWhiteBalanceInfo) * SYSTEM_TOTAL_CAMERA_COUNT);

    if (Comm_IsConnected(COMM_SPB + spbIndex))
    {
		setupForm->validSPBMask += (0x1<<spbIndex);
	}
	}
  //개별 테스트필요시 해당 주석을 풀고 해당 보드에맞는 값을 세팅하면됨.
//  setupForm->validSPBMask = 0x01;

  // White Balance 값 전송 완료

  
	bool returnValue = true;
	if (!CPBSetupInfo.InspectionSetupDataValid)
	{
		setupForm->InitSetup(SETUP_MODE_INSPECTION);
		int modalResult = setupForm->ShowModal();
		delete setupForm;

		if (modalResult == mrOk)
		{
			CPBSetupInfo.InspectionSetupDataValid = true;
			CPBSetupInfo.StudySetupDataValid = false;
			CPBSetupInfo.GradeDataValid = true;
		}
		else
		{
			returnValue = false;
		}
	}
	else if (!CPBSetupInfo.GradeDataValid)
	{
		setupForm->InitSetup(SETUP_MODE_GRADE_CHANGE);
		int modalResult = setupForm->ShowModal();
		delete setupForm;

		if (modalResult == mrOk)
		{
			CPBSetupInfo.GradeDataValid = true;
		}
		else
		{
			returnValue = false;
		}
	}
	return returnValue;
}
//---------------------------------------------------------------------------

bool __fastcall SendInspectionSetupDataForSimulation(int spbMask, int mode)
{
  // White Balance 값 전송
  AnsiString fileName;
  fileName = ProgramPath.Env + "\\WhiteBalanceInfo.ini";
  
  for(int cameraIndex = 0; cameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
  {
    int spbIndex = (0x01) << CameraMapInfo[cameraIndex].SPBIndex;
    if(spbMask & spbIndex)
      ReadCameraWhiteBalanceColorInfo(fileName, cameraIndex);
  }

  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(spbMask & (0x01 << spbIndex))) continue;

    Comm_Request(COMM_SPB + spbIndex, CMD_SET_CAMERA_WHITE_BALANCE, WhiteBalanceInfo, sizeof(TWhiteBalanceInfo) * SYSTEM_TOTAL_CAMERA_COUNT);
	}
  // White Balance 값 전송 완료
  
	bool returnValue = true;

  TSetupForm *setupForm = new TSetupForm(Application);
  setupForm->validSPBMask = spbMask;
  setupForm->InitSetup(mode);
  int modalResult = setupForm->ShowModal();
  delete setupForm;

  if (modalResult == mrOk)
  {
    CPBSetupInfo.InspectionSetupDataValid = true;
    CPBSetupInfo.StudySetupDataValid = false;
    CPBSetupInfo.GradeDataValid = true;
  }
  else
  {
    returnValue = false;
  }

	return returnValue;
}
//---------------------------------------------------------------------------
 

unsigned int CheckSum(unsigned int* src, unsigned int len)
{
	register unsigned int sum = 0;
	while (len--)
	{
		sum += *src++;
	}
	return sum;
}
