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

#include <vcl.h>
#pragma hdrstop


#include "SystemSimulation_Form.h"
#include "Setup_Form.h"
#include "CommControl_Form.h"
#include "Environment.h"
#include "LogViewer_Form.h"
#include "SystemSetup.h"
#include "CPBStatus_Form.h"
#include "Multilanguage.h"
#include "GradeSetting.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma resource "*.dfm"
TSystemSimulationForm *SystemSimulationForm;
//---------------------------------------------------------------------------
__fastcall TSystemSimulationForm::TSystemSimulationForm(TComponent* Owner)
  : TTntForm(Owner)
{
  pErrorListForm =  new TErrorListForm(this);
  pErrorListForm->Parent = TabSheet1;

  CPBResultStringGrid1->Cells[0][0] = "#Index";
  CPBResultStringGrid1->Cells[1][0] = "#Cam";
  CPBResultStringGrid1->Cells[2][0] = "Result";

  CPBResultStringGrid2->Cells[0][0] = "#Index";
  CPBResultStringGrid2->Cells[1][0] = "#Cam";
  CPBResultStringGrid2->Cells[2][0] = "Result";

  CPBResultStringGrid3->Cells[0][0] = "#Index";
  CPBResultStringGrid3->Cells[1][0] = "#Cam";
  CPBResultStringGrid3->Cells[2][0] = "Result";

  CPBResultStringGrid4->Cells[0][0] = "#Index";
  CPBResultStringGrid4->Cells[1][0] = "#Cam";
  CPBResultStringGrid4->Cells[2][0] = "Result";

  StringGrid1->Cells[0][0] = "Index";
  StringGrid1->Cells[1][0] = "Result";
  StringGrid1->Cells[2][0] = "State";
  StringGrid1->Cells[3][0] = "A/T"; // Tablet Indexing time

  StringGrid1->Cells[4][0] = "C/E";    // Camera Enabled
  StringGrid1->Cells[5][0] = "#1 P/R"; // Camera Processing Result
  StringGrid1->Cells[6][0] = "#1 C/T"; // Camera Captured time
  StringGrid1->Cells[7][0] = "#1 T/T"; // Image Send 로직에 도달한 시간
  StringGrid1->Cells[8][0] = "#1 R/T"; // CPB Processing Run time

  StringGrid1->Cells[9][0] = "C/E";    // Camera Enabled
  StringGrid1->Cells[10][0] = "#2 P/R"; // Camera Processing Result
  StringGrid1->Cells[11][0] = "#2 C/T"; // Camera Captured time
  StringGrid1->Cells[12][0] = "#2 T/T"; // Image Send 로직에 도달한 시간
  StringGrid1->Cells[13][0] = "#2 R/T"; // CPB Processing Run time

  StringGrid1->Cells[14][0] = "C/E";    // Camera Enabled
  StringGrid1->Cells[15][0] = "#3 P/R"; // Camera Processing Result
  StringGrid1->Cells[16][0] = "#3 C/T"; // Camera Captured time
  StringGrid1->Cells[17][0] = "#3 T/T"; // Image Send 로직에 도달한 시간
  StringGrid1->Cells[18][0] = "#3 R/T"; // CPB Processing Run time

  StringGrid1->Cells[19][0] = "C/E";    // Camera Enabled
  StringGrid1->Cells[20][0] = "#4 P/R"; // Camera Processing Result
  StringGrid1->Cells[21][0] = "#4 C/T"; // Camera Captured time
  StringGrid1->Cells[22][0] = "#4 T/T"; // Image Send 로직에 도달한 시간
  StringGrid1->Cells[23][0] = "#4 R/T"; // CPB Processing Run time

  StringGrid1->ColWidths[4] = StringGrid1->ColWidths[9];
  StringGrid1->ColWidths[14] = StringGrid1->ColWidths[9];
  StringGrid1->ColWidths[19] = StringGrid1->ColWidths[9];

  //StringGrid1->ColWidths[7] = StringGrid1->ColWidths[3];
  //StringGrid1->ColWidths[12] = StringGrid1->ColWidths[3];
  //StringGrid1->ColWidths[17] = StringGrid1->ColWidths[3];
  //StringGrid1->ColWidths[22] = StringGrid1->ColWidths[3];

  int fixedColWidth, remainingWidth;
  int assignWidth;
  fixedColWidth = StringGrid1->ColWidths[0] + StringGrid1->ColWidths[1] + StringGrid1->ColWidths[2] + StringGrid1->ColWidths[3] + StringGrid1->ColWidths[4] + StringGrid1->ColWidths[9] + StringGrid1->ColWidths[14] + StringGrid1->ColWidths[19];
  remainingWidth = StringGrid1->Width - fixedColWidth - 15;
  assignWidth = remainingWidth / 16;
  for(int m = 4; m < 24; m++)
  {
    if(m == 4 || m == 9 || m == 14 || m == 19) continue;
    //if(m == 7 || m == 12 || m == 17 || m == 22) continue;

    StringGrid1->ColWidths[m] = assignWidth;
  }


  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    if (Comm_IsConnected(COMM_SPB + spbIndex))
    {
      EnabledSPBMask = 0x01 << spbIndex;
                      
      TTntSpeedButton *tempBtn = ((TTntSpeedButton *)FindComponent("SPBSelectButton"+IntToStr(spbIndex + 1)));
      if(tempBtn)
        tempBtn->Down = true;

      break;
    }
  }

  RefreshEnabledCamera();

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

  TStringGrid *tempTStringGrid;
  for(int i = 0; i < 4; i++)
  {
    tempTStringGrid = ((TStringGrid *)FindComponent("CPBStatusGrid"+IntToStr(i + 1)));

    if(tempTStringGrid)
    {
      tempTStringGrid->Cells[1][0] = "Enabled";
      tempTStringGrid->Cells[2][0] = "IsDown";
      tempTStringGrid->Cells[3][0] = "Step";

      for(int m = 1; m <= 8; m++)
      {
        tempTStringGrid->Cells[0][m] = "CPU #" + IntToStr(m + 8 * i);
      }
    }
  }

  memset(&TabletInspectionResult, 0, sizeof(TTabletInspectionResult));

  globalReadSW = 0;

  previousTabletNumber = 0;
  CurrentTabletNumber = 0;
  lastChecktime = 0;
}
//---------------------------------------------------------------------------
void __fastcall TSystemSimulationForm::CloseButtonClick(TObject *Sender)
{
  CPBSetupInfo.StudySetupDataValid = false;
	CPBSetupInfo.InspectionSetupDataValid = false;
  
  this->Close();
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::Setup()
{
  // send setup data (for image processing)
  AnsiString studyFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".stu";
	if (!LoadStudyData(studyFileName, TabletStudyResultData_PC))
	{
		ShowMessageFA(MAINFORM_MSG_14);
		return;
	}
  
  AnsiString gradeFileName = ProgramPath.Product + "\\" + ProductData.ProductCode + "\\" + ProductData.ProductCode + ".grd";

  if (!LoadGradeData(gradeFileName, TabletGradeData_PC))
  {
    ShowMessageFA(MAINFORM_MSG_11);
    SetDefaultGradeData(TabletGradeData_PC);
  }

  TabletGradeData_PC.dummy[0] = StrToInt(Edit4->Text);

  int mode = SETUP_MODE_INSPECTION;

  if(GradeSendChkBox->Checked)
  {
    mode = SETUP_MODE_GRADE_CHANGE;
  }
   
	if (!SendInspectionSetupDataForSimulation(EnabledSPBMask, mode))
	{
		return;
	}

	// send clear command
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;
    
		Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_CLEAR);
	}
}

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



void __fastcall TSystemSimulationForm::ImageControlTimerTimer(
      TObject *Sender)                                 
{
  bool bEnabledTimer = ImageControlTimer->Enabled;
  TVirtualCPBStatus VirtualCPBStatus[SYSTEM_CPB_COUNT];

  ImageControlTimer->Enabled = false;

  TCPBProcessingData CPBProcessingData;
  TSPBProcessedData SPBProcessedData;
  TSPBSimpleProcessedData SPBSimpleProcessedData;

  //for (int camIndex = 0; camIndex < SYSTEM_SPB_CAMERA_COUNT; camIndex++)
  {
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;

      if(CheckBox2->Checked == true)
        ImageControlTimer->Enabled = false;

      if(!CheckBox2->Checked)
      {
        if(globalReadSW)
        if (Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_DEFECT_DATA, NULL, 0, &CPBProcessingData, sizeof(TCPBProcessingData)))
        {
          if(CPBProcessingData.buff[0] != -1) // processing index
          {
            TStringGrid *pStringGrid = ((TStringGrid *)FindComponent("CPBResultStringGrid"+IntToStr(CPBProcessingData.buff[1] + 1)));
            if(pStringGrid->RowCount < CPBProcessingData.buff[0])
            {
              pStringGrid->RowCount = CPBProcessingData.buff[0];
            }

            pStringGrid->Cells[0][CPBProcessingData.buff[0]] = IntToStr(CPBProcessingData.buff[0]);

            if(CPBProcessingData.buff[2] == 0)
              pStringGrid->Cells[2][CPBProcessingData.buff[0]] = "Good";
            if(CPBProcessingData.buff[2] == 1)
              pStringGrid->Cells[2][CPBProcessingData.buff[0]] = "Defect";
            if(CPBProcessingData.buff[2] == 2)
              pStringGrid->Cells[2][CPBProcessingData.buff[0]] = "Un-Ins";

            pStringGrid->RowCount++;
            pStringGrid->Row = CPBProcessingData.buff[0];

            Graphics::TBitmap *img = new Graphics::TBitmap;
            img->Width = 64;
            img->Height = 48;
            img->PixelFormat = pf24bit;

            Byte *ptr;
            for(int y = 0; y < 48; y++)
            {
              ptr = (Byte *) img->ScanLine[y];
              for(int x = 0; x < 64; x++)
              {
                ptr[x * 3 + 0] = CPBProcessingData.processedImg[64 * y + x];
                ptr[x * 3 + 1] = CPBProcessingData.processedImg[64 * y + x];
                ptr[x * 3 + 2] = CPBProcessingData.processedImg[64 * y + x];
              }
            }

            TImage *tempCPBImage;
            for(int m = 1; m <= 4; m++)
            for(int cpbIndex = 1; cpbIndex <= 24; cpbIndex++)
            {
              tempCPBImage = ((TImage *)FindComponent("ProcessingImageCam" + IntToStr(m) + "_" + IntToStr(cpbIndex)));

              if(tempCPBImage)
              {
                tempCPBImage->Canvas->Brush->Color = clBlack;
                tempCPBImage->Canvas->Brush->Style = bsClear;
                tempCPBImage->Canvas->Pen->Width = 2;
                tempCPBImage->Canvas->Pen->Color = clBlack;
                tempCPBImage->Canvas->Rectangle(1, 1, 63, 47);
              }
            }

            tempCPBImage = ((TImage *)FindComponent("ProcessingImageCam" + IntToStr(CPBProcessingData.buff[1] + 1) + "_" + IntToStr((CPBProcessingData.buff[0] % 24) + 1)));

            if(tempCPBImage)
            {
              tempCPBImage->Picture->Bitmap->Assign(img);

              tempCPBImage->Canvas->Brush->Style = bsClear;
              tempCPBImage->Canvas->Pen->Width = 2;
              tempCPBImage->Canvas->Pen->Color = clGreen;
              tempCPBImage->Canvas->Font->Size = 1;
              tempCPBImage->Canvas->Font->Color = clWhite;

              if(CPBProcessingData.buff[2] == 0)
                tempCPBImage->Canvas->TextOutW(1,1, IntToStr(CPBProcessingData.buff[0]) + "-G");
              else if(CPBProcessingData.buff[2] == 1)
                tempCPBImage->Canvas->TextOutW(1,1, IntToStr(CPBProcessingData.buff[0]) + "-D");
              else if(CPBProcessingData.buff[2] == 2)
                tempCPBImage->Canvas->TextOutW(1,1, IntToStr(CPBProcessingData.buff[0]) + "-U");

              tempCPBImage->Canvas->Rectangle(1, 1, 63, 47);

              tempCPBImage->Refresh();
            }

            delete img;
          }
        }

        if (Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_DEBUGGING_DATA, NULL, 0, VirtualCPBStatus, sizeof(TVirtualCPBStatus) * SYSTEM_CPB_COUNT))
        {
          TColor BColor = clGreen;
          TColor FColor = clRed;
          TColor CColor = clYellow;
          TRect R;

          TStringGrid *tempTStringGrid;
          for(int i = 0; i < 4; i++)
          {
            tempTStringGrid = ((TStringGrid *)FindComponent("CPBStatusGrid"+IntToStr(i + 1)));

            if(tempTStringGrid)
            {
              for(int m = 1; m <= 8; m++)
              {
                R = tempTStringGrid->CellRect(1, m);
                if(VirtualCPBStatus[i * 8 + (m - 1)].Enabled)
                {
                  tempTStringGrid->Canvas->Brush->Color = BColor;
                }
                else
                {
                  tempTStringGrid->Canvas->Brush->Color = FColor;
                }

                tempTStringGrid->Canvas->Font->Color = clBlack;
                tempTStringGrid->Canvas->FillRect(R);
                tempTStringGrid->Canvas->Font = tempTStringGrid->Font;
                tempTStringGrid->Canvas->TextOut(R.Left + 2, R.Top + 2, VirtualCPBStatus[i * 8 + (m - 1)].Enabled);


                R = tempTStringGrid->CellRect(2, m);
                if(!VirtualCPBStatus[i * 8 + (m - 1)].IsDown)
                {
                  tempTStringGrid->Canvas->Brush->Color = BColor;
                }
                else
                {
                  tempTStringGrid->Canvas->Brush->Color = FColor;
                }

                tempTStringGrid->Canvas->Font->Color = clBlack;
                tempTStringGrid->Canvas->FillRect(R);
                tempTStringGrid->Canvas->Font = tempTStringGrid->Font;
                tempTStringGrid->Canvas->TextOut(R.Left + 2, R.Top + 2, VirtualCPBStatus[i * 8 + (m - 1)].IsDown);

                R = tempTStringGrid->CellRect(3, m);
                if(VirtualCPBStatus[i * 8 + (m - 1)].Step == 1)
                {
                  tempTStringGrid->Canvas->Brush->Color = CColor;
                }
                else if(VirtualCPBStatus[i * 8 + (m - 1)].Step == 0)
                {
                  tempTStringGrid->Canvas->Brush->Color = BColor;
                }
                else
                {
                  tempTStringGrid->Canvas->Brush->Color = FColor;
                }

                tempTStringGrid->Canvas->Font->Color = clBlack;
                tempTStringGrid->Canvas->FillRect(R);
                tempTStringGrid->Canvas->Font = tempTStringGrid->Font;
                tempTStringGrid->Canvas->TextOut(R.Left + 2, R.Top + 2, VirtualCPBStatus[i * 8 + (m - 1)].Step);
              }
            }
          }
        }

        if (Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_DEBUGGING_DATA2, NULL, 0, &SPBProcessedData, sizeof(TSPBProcessedData)))
        {
          if(SPBProcessedData.TabletNumber != 0x00FFFFFF && SPBProcessedData.TabletNumber < 1000000 && SPBProcessedData.TabletNumber > 0)
          {
            globalReadSW = 1;
          
            TColor SColor;
            TRect R;
        
            if(StringGrid1->RowCount < SPBProcessedData.TabletNumber)
            {
              StringGrid1->RowCount = SPBProcessedData.TabletNumber;
            }

            StringGrid1->Cells[0][SPBProcessedData.TabletNumber] = IntToStr(SPBProcessedData.TabletNumber);

            int result = 0;
            for(int spbCamIndex = 0; spbCamIndex < 4; spbCamIndex++)
            {
              if(SPBProcessedData.ProcessingResult[spbCamIndex] == TABLET_PROCESSING_RESULT_DEFECT)
              {
                result = 1;
                break;
              }
              else if(SPBProcessedData.ProcessingResult[spbCamIndex] != TABLET_PROCESSING_RESULT_GOOD)
              {
                result = 2;
                break;
              }
            }

            if(result == 0)
            {
              StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "양품";
              TabletInspectionResult.TabletGoodCount++;
            }
            else if(result == 1)
            {
              StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "불량";
              TabletInspectionResult.TabletDefectCount++;
            }

            switch(SPBProcessedData.Result)
            {
              case SPB_TABLET_RESULT_NONE:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "None";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_NoneCount++;
              break;

              case SPB_TABLET_RESULT_PROCESSING:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "검사중";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_ProcessingCount++;

              break;

              case SPB_TABLET_RESULT_UNINS_IMAGE_BUFFER_FULL:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "버퍼가득";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_ImageBufferFull++;
              break;

              case SPB_TABLET_RESULT_UNINS_TABLET_NUMBER_UNDEFINED:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "번호미지정";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Number_UnDefined++;
              break;

              case SPB_TABLET_RESULT_UNINS_WRONG_TABLET_NUMBER:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "번호오류";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Wrong_Number++;
              break;

              case SPB_TABLET_RESULT_UNINS_CAPTURE_TIMEOUT:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "캡쳐TO";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Capture_Timeout++;
              break;

              case SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "캡쳐준비X";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Capture_Not_Ready++;
              break;

              case SPB_TABLET_RESULT_UNINS_PROCESSING_TIMEOUT:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "타임아웃";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Processing_Timeout++;
              break;

              case SPB_TABLET_RESULT_UNINS_PROCESSING_ERROR:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "검사오류";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Processing_Error++;
              break;

              case SPB_TABLET_RESULT_UNINS_CPB_FULL:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "CPU부족";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_CPB_Full++;
              break;

              case SPB_TABLET_RESULT_UNINS_CLOSED_TABLET:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "붙은정제";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Closed_Tablet++;
              break;

              case SPB_TABLET_RESULT_UNINS_TABLET_POSITION:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "자세불안정";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Position_Error++;
              break;

              case SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "밝기저하";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Brightness_Drop++;
              break;

              case SPB_TABLET_RESULT_UNINS_BRIGHTNESS_CHASE:
                StringGrid1->Cells[1][SPBProcessedData.TabletNumber] = "밝기추적";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Brightness_Chase++;
              break;
            }

            RefreshInspectionCount();

            switch(SPBProcessedData.State)
            {
              case SPB_TABLET_STATE_NONE:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "None";
              break;

              case SPB_TABLET_STATE_FINDING_BUFFER:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Set-Buff";
              break;

              case SPB_TABLET_STATE_NUMBERING:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Numbering";
              break;

              case SPB_TABLET_STATE_CAPTURE_READY:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Cap Ready";
              break;

              case SPB_TABLET_STATE_ON_CAPTURE:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "On-Cap";
              break;

              case SPB_TABLET_STATE_CAPTURED:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Captured";
              break;

              case SPB_TABLET_STATE_PROCESSING:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Processing";
              break;

              case SPB_TABLET_STATE_PROCESSING_COMPLETE:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "Complete";
              break;

              default:
                StringGrid1->Cells[2][SPBProcessedData.TabletNumber] = "ERROR";
              break;
            }

            StringGrid1->Cells[3][SPBProcessedData.TabletNumber] = IntToStr(SPBProcessedData.ProcessStartTime) + "ms";

            for(int spbCamIndex = 0; spbCamIndex < 4; spbCamIndex++)
            {
              if(SPBProcessedData.CameraEnabled[spbCamIndex])
              {
                StringGrid1->Cells[4 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "O";
              }
              else
              {
                StringGrid1->Cells[4 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "X";
              }



              switch(SPBProcessedData.ProcessingResult[spbCamIndex])
              {
                case TABLET_PROCESSING_RESULT_UNKNOWN:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "None";
                break;

                case TABLET_PROCESSING_RESULT_GOOD:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  " G";
                break;

                case TABLET_PROCESSING_RESULT_DEFECT:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  " D";
                break;

                case TABLET_PROCESSING_RESULT_ERROR:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "오류";
                break;

                case TABLET_PROCESSING_RESULT_CPB_FULL:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "CPU부족";
                break;

                case TABLET_PROCESSING_RESULT_CLOSED_TABLET:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "붙음";
                break;

                case TABLET_PROCESSING_RESULT_UNINS_TABLET_POSITION:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "자세X";
                break;

                case TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_DROPPED:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "밝기저하";
                break;

                case TABLET_PROCESSING_RESULT_UNINS_BRIGHTNESS_CHASE:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "밝기추적";
                break;

                case TABLET_PROCESSING_RESULT_THIN_TABLET:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "얇음";
                break;

                case TABLET_PROCESSING_RESULT_FAT_TABLET:
                  StringGrid1->Cells[5 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "#" + IntToStr(spbCamIndex + 1) +  "두꺼움";
                break;

              }

              StringGrid1->Cells[6 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = IntToStr(SPBProcessedData.CapturedTime[spbCamIndex]) + "ms";

              if(SPBProcessedData.ImageSendTime[spbCamIndex] > 0)
                StringGrid1->Cells[7 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = IntToStr(SPBProcessedData.ImageSendTime[spbCamIndex]) + "ms";
              else
                StringGrid1->Cells[7 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = "-1ms";

              StringGrid1->Cells[8 + spbCamIndex * 5][SPBProcessedData.TabletNumber] = IntToStr(SPBProcessedData.CPBProcessingTime[spbCamIndex]) + "ms";
            }

            StringGrid1->RowCount++;
            StringGrid1->Row = SPBProcessedData.TabletNumber;
          }
        }

        if(GetTickCount() - lastChecktime > 1000)
        {
          int totalTabletCount = TabletInspectionResult.TabletGoodCount + TabletInspectionResult.TabletDefectCount + TabletInspectionResult.TabletUnInsCount;
          CurrentTabletNumber = totalTabletCount;

          int k = CurrentTabletNumber - previousTabletNumber;
          int ExpectedTHP = k * 3600;

          Label26->Caption = "현재속도 " + IntToStr(ExpectedTHP) + " T/H";

          lastChecktime = GetTickCount();
          previousTabletNumber = totalTabletCount;
        }
      }
      else
      {
        if (Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_DEBUGGING_DATA3, NULL, 0, &SPBSimpleProcessedData, sizeof(TSPBSimpleProcessedData)))
        {
          if(SPBSimpleProcessedData.TabletNumber != 0x00FFFFFF && SPBSimpleProcessedData.TabletNumber < 1000000 && SPBSimpleProcessedData.TabletNumber > 0)
          {
            globalReadSW = 1;

            TColor SColor;
            TRect R;

            if(StringGrid1->RowCount < SPBSimpleProcessedData.TabletNumber)
            {
              StringGrid1->RowCount = SPBSimpleProcessedData.TabletNumber;
            }

            StringGrid1->Cells[0][SPBSimpleProcessedData.TabletNumber] = IntToStr(SPBSimpleProcessedData.TabletNumber);

            switch(SPBSimpleProcessedData.Result)
            {
              case SPB_TABLET_RESULT_GOOD:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "양품";
                TabletInspectionResult.TabletGoodCount++;
              break;

              case SPB_TABLET_RESULT_DEFECT:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "불량";
                TabletInspectionResult.TabletDefectCount++;
              break;

              case SPB_TABLET_RESULT_NONE:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "None";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_NoneCount++;
              break;

              case SPB_TABLET_RESULT_PROCESSING:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "검사중";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_ProcessingCount++;

              break;

              case SPB_TABLET_RESULT_UNINS_IMAGE_BUFFER_FULL:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "버퍼가득";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_ImageBufferFull++;
              break;

              case SPB_TABLET_RESULT_UNINS_TABLET_NUMBER_UNDEFINED:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "번호미지정";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Number_UnDefined++;
              break;

              case SPB_TABLET_RESULT_UNINS_WRONG_TABLET_NUMBER:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "번호오류";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Wrong_Number++;
              break;

              case SPB_TABLET_RESULT_UNINS_CAPTURE_TIMEOUT:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "캡쳐TO";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Capture_Timeout++;
              break;

              case SPB_TABLET_RESULT_UNINS_CAPTURE_NOT_READY:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "캡쳐준비X";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Capture_Not_Ready++;
              break;

              case SPB_TABLET_RESULT_UNINS_PROCESSING_TIMEOUT:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "타임아웃";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Processing_Timeout++;
              break;

              case SPB_TABLET_RESULT_UNINS_PROCESSING_ERROR:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "검사오류";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Processing_Error++;
              break;

              case SPB_TABLET_RESULT_UNINS_CPB_FULL:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "CPU부족";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_CPB_Full++;
              break;

              case SPB_TABLET_RESULT_UNINS_CLOSED_TABLET:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "붙은정제";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Closed_Tablet++;
              break;

              case SPB_TABLET_RESULT_UNINS_TABLET_POSITION:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "자세불안정";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Position_Error++;
              break;

              case SPB_TABLET_RESULT_UNINS_BRIGHTNESS_DROPPED:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "밝기저하";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Brightness_Drop++;
              break;

              case SPB_TABLET_RESULT_UNINS_BRIGHTNESS_CHASE:
                StringGrid1->Cells[1][SPBSimpleProcessedData.TabletNumber] = "밝기추적";
                TabletInspectionResult.TabletUnInsCount++;
                TabletInspectionResult.UnIns_Brightness_Chase++;
              break;
            }

            RefreshInspectionCount();

            for(int spbCamIndex = 0; spbCamIndex < 4; spbCamIndex++)
            {
              StringGrid1->Cells[6 + spbCamIndex * 5][SPBSimpleProcessedData.TabletNumber] = IntToStr(SPBSimpleProcessedData.CapturedTime[spbCamIndex]) + "ms";
            }

            StringGrid1->RowCount++;
            StringGrid1->Row = SPBSimpleProcessedData.TabletNumber;
          }

          if(GetTickCount() - lastChecktime >= 1000)
          {
            CurrentTabletNumber = SPBSimpleProcessedData.currentTabletNumber;

            int k = CurrentTabletNumber - previousTabletNumber;
            int ExpectedTHP = k * 3600;

            Label26->Caption = "현재속도 " + IntToStr(ExpectedTHP) + " T/H";

            lastChecktime = GetTickCount();
            previousTabletNumber = SPBSimpleProcessedData.currentTabletNumber;
          }
        }
      }
    }
  }

  ImageControlTimer->Enabled = bEnabledTimer;
}
//---------------------------------------------------------------------------


void __fastcall TSystemSimulationForm::StopBtnClick(TObject *Sender)
{
  //ImageControlTimer->Enabled = false;

  ProcessingStatusLabel->Caption = "None-Setup";

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

    if(EnabledSPBMask & spbMask)
      Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_END);
  }

  int buff[2]; // 의미 없음
  buff[0] = 0;
  buff[1] = 0;

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

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_END, buff, sizeof(int) * 2);
  }

  InspectionStartButton->Enabled = false;
  //StopBtn->Enabled = false;

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



void __fastcall TSystemSimulationForm::SetupBtnClick(TObject *Sender)
{
  Timer1->Enabled = false;
  ProcessingStatusLabel->Visible = true;

  SetupBtn->Enabled = false;
  InspectionStartButton->Enabled = false;
  //StopBtn->Enabled = false;
  CloseButton->Enabled = false;

  int buff[2]; // 의미 없음
  buff[0] = 0;
  buff[1] = 0;
  
  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_END, buff, sizeof(int) * 2);
	}
  
  ProcessingStatusLabel->Caption = "Data Setting...";

  Setup();

  ProcessingStatusLabel->Caption = "CPB Setup...";

  Application->ProcessMessages();

  Sleep(1500);

  ProcessingStatusLabel->Caption = "StandBy";

  SetupBtn->Enabled = true;
  InspectionStartButton->Enabled = true;
  //StopBtn->Enabled = true;
  CloseButton->Enabled = true;
  Timer1->Enabled = true;

  memset(&TabletInspectionResult, 0, sizeof(TTabletInspectionResult));
  RefreshInspectionCount();
  globalReadSW = 0;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::InspectionStartButtonClick(
      TObject *Sender)
{
  for(int k = 1; k <= 4; k++)
  {
    TStringGrid *pStringGrid = ((TStringGrid *)FindComponent("CPBResultStringGrid"+IntToStr(k)));
    
    pStringGrid->Cells[0][0] = "#Index";
    pStringGrid->Cells[1][0] = "#Cam";
    pStringGrid->Cells[2][0] = "Result";

    for (int m = 1; m < pStringGrid->RowCount; m++)
    {
      pStringGrid->Cells[0][m] = "";
      pStringGrid->Cells[1][m] = "";
      pStringGrid->Cells[2][m] = "";
    }
  }


  for (int m = 1; m < StringGrid1->RowCount; m++)
  {
    StringGrid1->Cells[0][m] = "";
    StringGrid1->Cells[1][m] = "";
    StringGrid1->Cells[2][m] = "";
    StringGrid1->Cells[3][m] = "";

    for(int spbCamIndex = 0; spbCamIndex < 4; spbCamIndex++)
    {
      StringGrid1->Cells[4 + spbCamIndex * 5][m] = "";
      StringGrid1->Cells[5 + spbCamIndex * 5][m] = "";
      StringGrid1->Cells[6 + spbCamIndex * 5][m] = "";
      StringGrid1->Cells[7 + spbCamIndex * 5][m] = "";
      StringGrid1->Cells[8 + spbCamIndex * 5][m] = "";
    }
  }

  ProcessingStatusLabel->Caption = "Processing...";

  //ImageControlTimer->Enabled = true;
  InspectionStartButton->Enabled = false;

  CPBResultStringGrid1->RowCount = 5;
  CPBResultStringGrid2->RowCount = 5;
  CPBResultStringGrid3->RowCount = 5;
  CPBResultStringGrid4->RowCount = 5;

  StringGrid1->RowCount = 5;

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

  bool CameraEnabled[SYSTEM_TOTAL_CAMERA_COUNT];
  int tempCountCount = 0;
  
  for(int tempCameraIndex = 0; tempCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; tempCameraIndex++)
  {
    CameraEnabled[tempCameraIndex] = false;

    int tempSPBIndex = CameraMapInfo[tempCameraIndex].SPBIndex;

    if(spbIndex == tempSPBIndex && CameraMapInfo[tempCameraIndex].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[tempCameraIndex] != 0)
    {
      CameraEnabled[tempCameraIndex] = true;
      tempCountCount++;
    }
  }

  memset(&TabletInspectionResult, 0, sizeof(TTabletInspectionResult));
  
  SendInspectionReadyCommand(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed,
		ProductData.MotorSpeedList[SD2_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed, CameraEnabled);

  int buff[4];
  buff[0] = StrToInt(Edit2->Text);

  int cameraMask = 0;
  for(int m = 1; m <= 4; m++)
  {
    TCheckBox *tempCheckbox = ((TCheckBox *)FindComponent("CameraSelectCheckBox"+IntToStr(m)));

    if(tempCheckbox)
    {
      if(tempCheckbox->Checked) cameraMask |= (0x01 << (m - 1));
    }
  }

  buff[1] = cameraMask;

  if(EnabledSPBMask & 0x01)
    buff[2] = 0;
  else if(EnabledSPBMask & 0x02)
    buff[2] = 1;
  else if(EnabledSPBMask & 0x04)
    buff[2] = 2;
  else if(EnabledSPBMask & 0x08)
    buff[2] = 3;

  buff[3] = RadioGroup1->ItemIndex;

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

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_START, buff, sizeof(int) * 4);
	}

  ImageCountLabel1->Caption = "0";
  ImageCountLabel2->Caption = "0";
  ImageCountLabel3->Caption = "0";
  ImageCountLabel4->Caption = "0";

  ImageLoadProgressBar1->Position = 0;
  ImageLoadProgressBar2->Position = 0;
  ImageLoadProgressBar3->Position = 0;
  ImageLoadProgressBar4->Position = 0;

  CloseButton->Enabled = false;

  int ExpectedTHP;
  ExpectedTHP = StrToInt(Edit2->Text);
  if(ExpectedTHP)
  {
    ExpectedTHP = (1000 / (float)ExpectedTHP) * 3600.0;
    Label21->Caption = "예상속도 " + IntToStr(ExpectedTHP) + " T/H";
  }
  else
  {
    Label21->Caption = "예상속도 0 T/H";
  }

  previousTabletNumber = 0;
  CurrentTabletNumber = 0;
  lastChecktime = 0;
}
//---------------------------------------------------------------------------

bool __fastcall TSystemSimulationForm::GetProcessResult()
{
  
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::Timer1Timer(TObject *Sender)
{
  ProcessingStatusLabel->Visible = !ProcessingStatusLabel->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::FormDestroy(TObject *Sender)
{
  ImageControlTimer->Enabled = false;

  ProcessingStatusLabel->Caption = "None-Setup";

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

    if(EnabledSPBMask & spbMask)
      Comm_Request(COMM_SPB + spbIndex, CMD_INSPECTION_END);
  }

  int buff[2]; // 의미 없음
  buff[0] = 0;
  buff[1] = 0;

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

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_END, buff, sizeof(int) * 2);
	}


  InspectionStartButton->Enabled = false;
  //StopBtn->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::SetProcessingImageButtonClick(
      TObject *Sender)
{
  if(CheckBox3->Checked == false)
  {
    bool bThreeD;

    for(int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
    {
      if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition == CAMERA_POSITION_3D)
      {
        bThreeD = true;
      }
      else
      {
        bThreeD = false;
      }
    
      if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[cameraIndex - 1] != 0)
      {
        int spbMask = 0x01 << CameraMapInfo[cameraIndex - 1].SPBIndex;
        int spbIndex = CameraMapInfo[cameraIndex - 1].SPBIndex;
        if(EnabledSPBMask & spbMask)
        {
          // PC -> SPB 이미지 전송

          int ImageNumber = StrToInt(Edit3->Text);

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

          int x, y;
          int tempAddress;

          /*
          //test pattern
          int p = 0;
          for(y = 0; y < SourceImageHeight[bThreeD]; y++)
          {
            for(x = 0; x < SourceImageWidth[bThreeD]; x++)
            {
              tempAddress = SourceImageWidth[bThreeD] * y + x;

              if(p == 0)
              {
                BayerImage[tempAddress] = 0xFF;
                //p = 1;
              }
              else
              {
                BayerImage[tempAddress] = 0xFE;
                p = 0;
              }
            }
          }
          */

          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]);

          // 전송된 데이터 확인
          unsigned int data[2];
          data[0] = CameraMapInfo[cameraIndex - 1].CamIndex;
          data[1] = SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD];
          memset(BayerImage, 0, sizeof(BayerImage));
          Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_CHECK_IMAGE, data, 2 * sizeof(unsigned int), BayerImage, SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD]);

          Graphics::TBitmap *img = new Graphics::TBitmap;
          img->Width = SourceImageWidth[bThreeD];
          img->Height = SourceImageHeight[bThreeD];
          img->PixelFormat = pf24bit;

          Byte *ptr;

          for(y = 0; y < SourceImageHeight[bThreeD]; y++)
          {
            ptr = (Byte*)img->ScanLine[y];
            for(x = 0; x < SourceImageWidth[bThreeD]; x++)
            {
              tempAddress = SourceImageWidth[bThreeD] * y + x;

              ptr[3*x + 0] = BayerImage[tempAddress];
              ptr[3*x + 1] = BayerImage[tempAddress];
              ptr[3*x + 2] = BayerImage[tempAddress];
            }
          }


          TImage *tempSPBImage;
          tempSPBImage = ((TImage *)FindComponent("SPBImage"+IntToStr((CameraMapInfo[cameraIndex - 1].CamIndex + 1))));

          if(tempSPBImage)
          {
            tempSPBImage->Picture->Bitmap->Assign(img);
            tempSPBImage->Repaint();
          }
        
          delete img;
          // end
        }
      }
    }
  }
  else
  {
    OpenPictureDialog1->FileName = "";

    if(OpenPictureDialog1->Execute())
    {
      memset(BayerImage, 0, sizeof(BayerImage));

      Graphics::TBitmap *img = new Graphics::TBitmap;
      img->LoadFromFile(OpenPictureDialog1->FileName);

      Byte *ptr;

      int x, y;
      int tempAddress;
      for(y = 0; y < MAX_IMAGE_HEIGHT; y++)
      {
        ptr = (Byte*)img->ScanLine[y];
        for(x = 0; x < MAX_IMAGE_WIDTH; x++)
        {
          tempAddress = MAX_IMAGE_WIDTH * y + x;

          BayerImage[tempAddress] = ptr[3*x + 1];
        }
      }

      int spbCamIndex = BayerImage[0];
      int spbIndex = BayerImage[1];
      int globalCameraIndex = BayerImage[2];

      TImage *tempSPBImage;
      tempSPBImage = ((TImage *)FindComponent("SPBImage"+IntToStr((spbCamIndex + 1))));

      if(tempSPBImage)
      {
        tempSPBImage->Picture->Bitmap->Assign(img);
        tempSPBImage->Repaint();
      }

      delete img;

      bool bThreeD;
      if(CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
      {
        bThreeD = true;
      }
      else
      {
        bThreeD = false;
      }

      if(CameraMapInfo[globalCameraIndex].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[globalCameraIndex] != 0)
      {
        int spbMask = 0x01 << spbIndex;
        if(EnabledSPBMask & spbMask)
        {
          // PC -> SPB 이미지 전송
          Comm_RequestEx(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_SET_IMAGE, &spbCamIndex, sizeof(int), BayerImage, SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD]);

          // 전송된 데이터 확인
          unsigned int data[2];
          data[0] = spbCamIndex;
          data[1] = SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD];

          memset(BayerImage, 0, sizeof(BayerImage));
          Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_CHECK_IMAGE, data, 2 * sizeof(unsigned int), BayerImage, SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD]);

          Graphics::TBitmap *img = new Graphics::TBitmap;
          img->Width = SourceImageWidth[bThreeD];
          img->Height = SourceImageHeight[bThreeD];
          img->PixelFormat = pf24bit;

          Byte *ptr;

          for(y = 0; y < SourceImageHeight[bThreeD]; y++)
          {
            ptr = (Byte*)img->ScanLine[y];
            for(x = 0; x < SourceImageWidth[bThreeD]; x++)
            {
              tempAddress = SourceImageWidth[bThreeD] * y + x;

              ptr[3*x + 0] = BayerImage[tempAddress];
              ptr[3*x + 1] = BayerImage[tempAddress];
              ptr[3*x + 2] = BayerImage[tempAddress];
            }
          }

          TImage *tempSPBImage;
          tempSPBImage = ((TImage *)FindComponent("SPBImage"+IntToStr((CameraMapInfo[globalCameraIndex].CamIndex + 1))));

          if(tempSPBImage)
          {
            tempSPBImage->Picture->Bitmap->Assign(img);
            tempSPBImage->Repaint();
          }
        
          delete img;
          // end
        }
      }
    }
  }

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


void __fastcall TSystemSimulationForm::BitBtn1Click(TObject *Sender)
{
  CPBResultStringGrid1->Cells[0][0] = "#Index";
  CPBResultStringGrid1->Cells[1][0] = "#Cam";
  CPBResultStringGrid1->Cells[2][0] = "Result";

  CPBResultStringGrid2->Cells[0][0] = "#Index";
  CPBResultStringGrid2->Cells[1][0] = "#Cam";
  CPBResultStringGrid2->Cells[2][0] = "Result";

  CPBResultStringGrid3->Cells[0][0] = "#Index";
  CPBResultStringGrid3->Cells[1][0] = "#Cam";
  CPBResultStringGrid3->Cells[2][0] = "Result";

  CPBResultStringGrid4->Cells[0][0] = "#Index";
  CPBResultStringGrid4->Cells[1][0] = "#Cam";
  CPBResultStringGrid4->Cells[2][0] = "Result";

  ProcessingStatusLabel->Caption = "Processing...";

  int buff[4];
  buff[0] = StrToInt(Edit2->Text);

  int cameraMask = 0;
  for(int m = 1; m <= 4; m++)
  {
    TCheckBox *tempCheckbox = ((TCheckBox *)FindComponent("CameraSelectCheckBox"+IntToStr(m)));

    if(tempCheckbox)
    {
      if(tempCheckbox->Checked) cameraMask |= (0x01 << (m - 1));
    }
  }

  buff[1] = cameraMask;

  if(EnabledSPBMask & 0x01)
    buff[2] = 0;
  else if(EnabledSPBMask & 0x02)
    buff[2] = 1;
  else if(EnabledSPBMask & 0x04)
    buff[2] = 2;
  else if(EnabledSPBMask & 0x08)
    buff[2] = 3;

  buff[3] = RadioGroup1->ItemIndex;

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

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_REFRESH, buff, sizeof(int) * 4);
	}

  int spbIndex;

  for (spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;
    break;
	}

  int ExpectedTHP;
  ExpectedTHP = StrToInt(Edit2->Text);
  if(ExpectedTHP)
  {
    ExpectedTHP = (1000 / (float)ExpectedTHP) * 3600.0;
    Label21->Caption = "예상속도 " + IntToStr(ExpectedTHP) + " T/H";
  }
  else
  {
    Label21->Caption = "예상속도 0 T/H";
  } 

  /*
  bool CameraEnabled[SYSTEM_TOTAL_CAMERA_COUNT];
  int maxCameraCount = StrToInt(Edit3->Text);
  int tempCountCount = 0;

  for(int tempCameraIndex = 0; tempCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; tempCameraIndex++)
  {
    CameraEnabled[tempCameraIndex] = false;

    int tempSPBIndex = CameraMapInfo[tempCameraIndex].SPBIndex;

    if(spbIndex == tempSPBIndex)
    {
      if(tempCountCount < maxCameraCount)
      {
        CameraEnabled[tempCameraIndex] = true;
        tempCountCount++;
      }
    }
  }

  SendInspectionReadyCommand(ProductData.MotorSpeedList[SD1_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD1_MOTOR_INDEX].BaseSpeed,
		ProductData.MotorSpeedList[SD2_MOTOR_INDEX][0], MachineSetupData.ServoMotorData[SD2_MOTOR_INDEX].BaseSpeed, CameraEnabled);
  */

  //ImageControlTimer->Enabled = true;
  InspectionStartButton->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::FormCreate(TObject *Sender)
{
  pErrorListForm->Align = alClient;
  pErrorListForm->Show();

  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;
  }
  else
  {
    SourceImageWidth[0] = SourceImageWidth[1] = SYSTEM_CAMERA_WIDTH;
    SourceImageHeight[0] = SourceImageHeight[1] = SYSTEM_CAMERA_HEIGHT;
  }
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::Button2Click(TObject *Sender)
{
  int buff[2]; // 의미 없음
  buff[0] = 1;
  buff[1] = 0;

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

		Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_END, buff, sizeof(int) * 2);
	}
}
//---------------------------------------------------------------------------


void __fastcall TSystemSimulationForm::RefreshCameraInfo(int cameraIndex)
{
  /*
  // 사용자가 설정한 ShutterSpeed, Threshold, ROI(는 사실 Default) 를 반영
  int ShutterSpeed = 0;
  int Threshold = 0;
  int WriteMask = 0;

  TTntEdit *shutterSpeedEdit = (TTntEdit *) FindComponent("ShutterSpeedEdit" + IntToStr(cameraIndex + 1));
  if(shutterSpeedEdit)
    ShutterSpeed = StrToInt(shutterSpeedEdit->Text);

  if(CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
    WriteMask |= CAMERA_WRITE_MASK_3D_SH;
  else
    WriteMask |= CAMERA_WRITE_MASK_2D_SH;

  if(CameraMapInfo[cameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
  {
    Threshold = ProductData.ThresholdFor3D[cameraIndex];
    WriteMask |= CAMERA_WRITE_MASK_TH;
  }

  TROIInfo DefaultROIInfo;
  AnsiString filePath;
  filePath = ProgramPath.Env + "\\NFACameraInformation.ini";

  DefaultROIInfo = ReadCameraInformation(filePath, cameraIndex);
  WriteMask |= CAMERA_WRITE_MASK_ROI;

  SetCameraInformation(DefaultROIInfo, ShutterSpeed, Threshold, cameraIndex, WriteMask);
  */
}
//---------------------------------------------------------------------------
void __fastcall TSystemSimulationForm::Button3Click(TObject *Sender)
{
  AnsiString errorMsg;
	struct
	{
		unsigned int runMode;
		int programID;
	} runData;


	runData.runMode = RUN_MODE_RERUN;
	runData.programID = PID_CPB_TABLET_5;

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
    // For SELMA200, 20180221, Rev by moon
    // bEnabledSPB[spbIndex] -> 현재 연결되어 있는 SPB에만 다운로드는 진행한다.
    // 이 방법을 통해 SELMA200에서 SPB06보드가 4장 꽂혀있는 경우, SPB07보드가 3장 꽂혀있는 경우를 구분할 수 있다.
    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;
    else
    {
      TTntSpeedButton *spbSpeedButton = (TTntSpeedButton *)FindComponent("SPBSpeedButton" + IntToStr(spbIndex + 1));

      Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);

      if (Comm_Request(COMM_SPB + spbIndex, CMD_RUN, &runData, sizeof(runData)))
      {
        SPBSystemSetupData[spbIndex].DefaultCPBProgramID = runData.programID;
      }
      Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
    }
	}

	WriteSPBSystemSetupData(ProgramPath.Env + "\\SystemInfor.ini", SPBSystemSetupData);
	SendSystemSetupData();
	CPBSetupInfo.StudySetupDataValid = false;
	CPBSetupInfo.InspectionSetupDataValid = false;
	CPBSetupInfo.GradeDataValid = false;
	CheckCPBBootStatus(true);

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

void __fastcall TSystemSimulationForm::FormKeyPress(TObject *Sender,
      char &Key)
{
  int k = 0;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::Button4Click(TObject *Sender)
{
  bool bThreeD;
  for(int cameraIndex = 1; cameraIndex <= SYSTEM_TOTAL_CAMERA_COUNT; cameraIndex++)
  {
    if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      bThreeD = true;
    }
    else
    {
      bThreeD = false;
    }

    if(CameraMapInfo[cameraIndex - 1].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[cameraIndex - 1] != 0)
    {
      int spbMask = 0x01 << CameraMapInfo[cameraIndex - 1].SPBIndex;
      int spbIndex = CameraMapInfo[cameraIndex - 1].SPBIndex;
      if(EnabledSPBMask & spbMask)
      {
        // 전송된 데이터 확인
        unsigned int data[2];
        data[0] = CameraMapInfo[cameraIndex - 1].CamIndex;
        data[1] = SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD];
        memset(BayerImage, 0, sizeof(BayerImage));
        Comm_Request(COMM_SPB + spbIndex, CMD_VIRTUAL_INSPECTION_CHECK_IMAGE, data, 2 * sizeof(unsigned int), BayerImage, SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD]);

        Graphics::TBitmap *img = new Graphics::TBitmap;
        img->Width = SourceImageWidth[bThreeD];
        img->Height = SourceImageHeight[bThreeD];
        img->PixelFormat = pf24bit;

        int x, y;
        int tempAddress;
        Byte *ptr;

        for(y = 0; y < SourceImageHeight[bThreeD]; y++)
        {
          ptr = (Byte*)img->ScanLine[y];
          for(x = 0; x < SourceImageWidth[bThreeD]; x++)
          {
            tempAddress = SourceImageWidth[bThreeD] * y + x;

            ptr[3*x + 0] = BayerImage[tempAddress];
            ptr[3*x + 1] = BayerImage[tempAddress];
            ptr[3*x + 2] = BayerImage[tempAddress];
          }
        }

        TImage *tempSPBImage;
        tempSPBImage = ((TImage *)FindComponent("SPBImage"+IntToStr((CameraMapInfo[cameraIndex - 1].CamIndex + 1))));

        if(tempSPBImage)
        {
          tempSPBImage->Picture->Bitmap->Assign(img);
          tempSPBImage->Repaint();
        }
        
        delete img;
        // end
      }
    }
  }
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::CapturedImageTimerTimer(
      TObject *Sender)
{ 
  bool bTimerEnabled;
  bool bThreeD;
  
  bTimerEnabled = CapturedImageTimer->Enabled;

  bool bCaptureExist;

	char cameraIndex;
	unsigned int data[2];
	unsigned int receivedData[2];
  unsigned char CaptureData[SYSTEM_CAMERA_HD_WIDTH * SYSTEM_CAMERA_HD_HEIGHT];

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

  for(int allCameraIndex = 0; allCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; allCameraIndex++)
  {
    if(CameraMapInfo[allCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D)
    {
      bThreeD = true;
    }
    else
    {
      bThreeD = false;
    }
    
    if(spbIndex == CameraMapInfo[allCameraIndex].SPBIndex)
    {
      if (CameraMapInfo[allCameraIndex].CameraInspectPosition == CAMERA_POSITION_DISCONNECT || SystemLinkCameraInfo[allCameraIndex] == 0) continue;

      int camIndex = CameraMapInfo[allCameraIndex].CamIndex;

      data[0] = camIndex;
      data[1] = SourceImageWidth[bThreeD] * SourceImageHeight[bThreeD];

      TImage *SPBImage = (TImage *) FindComponent("CapturedImage" + IntToStr(camIndex + 1));
      TProgressBar *ImageLoadProgressBar = (TProgressBar *) FindComponent("ImageLoadProgressBar" + IntToStr(camIndex + 1));
      TLabel *ImageCountLabel = (TLabel *) FindComponent("ImageCountLabel" + IntToStr(camIndex + 1));

      SPBImage->Picture->Bitmap->Width = SourceImageWidth[bThreeD];
      SPBImage->Picture->Bitmap->Height = SourceImageHeight[bThreeD];
      SPBImage->Picture->Bitmap->PixelFormat = pf24bit;

      try
      {
        if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_EXIST, data, sizeof(unsigned int),
          receivedData, sizeof(unsigned int) * 2))
        {
          throw(0);
        }
    
        if (receivedData[0])
        {
          bCaptureExist = true;
        }
        else
        {
          bCaptureExist = false;
        }
    
        if (bCaptureExist)
        {
          if (!Comm_Request(COMM_SPB + spbIndex, CMD_CAPTURE_UPLOAD, data, 2 * sizeof(unsigned int),
            CaptureData, (SourceImageWidth[bThreeD]) * SourceImageHeight[bThreeD]))
          {
            throw(0);
          }

          ImageLoadProgressBar->Position++;
          if(ImageLoadProgressBar->Position == ImageLoadProgressBar->Max)
            ImageLoadProgressBar->Position = 0;

          ImageCountLabel->Caption = IntToStr(ImageLoadProgressBar->Position);

          Graphics::TBitmap *img = new Graphics::TBitmap;
          img->Width = SourceImageWidth[bThreeD];
          img->Height = SourceImageHeight[bThreeD];
          img->PixelFormat = pf24bit;

          Byte *ptr;
          for(int y = 0; y < SourceImageHeight[bThreeD]; y++)
          {
            ptr = (Byte *) img->ScanLine[y];
            for(int x = 0; x < SourceImageWidth[bThreeD]; x++)
            {
              ptr[x * 3 + 0] = CaptureData[SourceImageWidth[bThreeD] * y + x];
              ptr[x * 3 + 1] = CaptureData[SourceImageWidth[bThreeD] * y + x];
              ptr[x * 3 + 2] = CaptureData[SourceImageWidth[bThreeD] * y + x];
            }
          }

          SPBImage->Picture->Bitmap->Assign(img);
          SPBImage->Refresh();

          delete img;
        }
      }
      catch (...)
      {
        bTimerEnabled = false;
      }
    }
  }

  CapturedImageTimer->Enabled = bTimerEnabled;
}
//---------------------------------------------------------------------------


void __fastcall TSystemSimulationForm::SendInspectionReadyCommand(int disk1TargetSpeed, int disk1BaseSpeed,
	int disk2TargetSpeed, int disk2BaseSpeed, bool *cameraEnabled)
{
	TInspectData InspectData;
  int writeMask;

  int tempTriggerFrq = StrToInt(Edit1->Text);

  for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
  {
    // SELMA200, 20180412, 위에는 우짜나...
    writeMask = 0;

    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_3D_ROI;
    else
      writeMask |= CAMERA_WRITE_MASK_2D_ROI;

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

    if(cameraEnabled[globalCameraIndex])
    {
      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++)
	{
    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;
    
		InspectData.CamMask = 0;
		for (int globalCameraIndex = 0; globalCameraIndex < SYSTEM_TOTAL_CAMERA_COUNT; globalCameraIndex++)
		{
			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] = 0;
                InspectData.TriggerFreq[camIndex] = tempTriggerFrq;
              }
              else
              {
                InspectData.ShutterDelay[camIndex] = 0;
                InspectData.TriggerFreq[camIndex] = 1000;
              }
            }
            else
            {
              if (CameraMapInfo[globalCameraIndex].CameraInspectPosition == CAMERA_POSITION_3D) // 3d camera
              {
                InspectData.ShutterDelay[camIndex] = 0;
                InspectData.TriggerFreq[camIndex] = tempTriggerFrq;
              }
              else
              {
                InspectData.ShutterDelay[camIndex] = 0;
                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 = 0;
	InspectData.TabletType= ProductData.TabletType;
	InspectData.MaxProcessingWaitingTime = 250;// 250 -> 50 -> 100
	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;
    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 TSystemSimulationForm::RefreshInspectionCount()
{
  TotalCount->Caption = IntToStr(TabletInspectionResult.TabletGoodCount + TabletInspectionResult.TabletDefectCount + TabletInspectionResult.TabletUnInsCount);

  GoodCountLabel->Caption = IntToStr(TabletInspectionResult.TabletGoodCount);
  DefectCountLabel->Caption = IntToStr(TabletInspectionResult.TabletDefectCount);
  UnInsCountLabel->Caption = IntToStr(TabletInspectionResult.TabletUnInsCount);


  UICount1->Caption = IntToStr(TabletInspectionResult.UnIns_NoneCount);
  UICount2->Caption = IntToStr(TabletInspectionResult.UnIns_ProcessingCount);
  UICount3->Caption = IntToStr(TabletInspectionResult.UnIns_ImageBufferFull);
  UICount4->Caption = IntToStr(TabletInspectionResult.UnIns_Number_UnDefined);
  UICount5->Caption = IntToStr(TabletInspectionResult.UnIns_Wrong_Number);
  UICount6->Caption = IntToStr(TabletInspectionResult.UnIns_Capture_Timeout);
  UICount7->Caption = IntToStr(TabletInspectionResult.UnIns_Capture_Not_Ready);
  UICount8->Caption = IntToStr(TabletInspectionResult.UnIns_Processing_Timeout);
  UICount9->Caption = IntToStr(TabletInspectionResult.UnIns_Processing_Error);
  UICount10->Caption = IntToStr(TabletInspectionResult.UnIns_CPB_Full);
  UICount11->Caption = IntToStr(TabletInspectionResult.UnIns_Closed_Tablet);
  UICount12->Caption = IntToStr(TabletInspectionResult.UnIns_Position_Error);
  UICount13->Caption = IntToStr(TabletInspectionResult.UnIns_Brightness_Drop);
  UICount14->Caption = IntToStr(TabletInspectionResult.UnIns_Brightness_Chase);
}
//---------------------------------------------------------------------------
void __fastcall TSystemSimulationForm::SPBSelectButton1Click(
      TObject *Sender)
{
  TButton *tempBtn;
  EnabledSPBMask = 0x01 << tempBtn->Tag;
  RefreshEnabledCamera();

  GradeSendChkBox->Checked = false;
}
//---------------------------------------------------------------------------

void __fastcall TSystemSimulationForm::RefreshEnabledCamera()
{
  CameraSelectCheckBox1->Checked = false;
  CameraSelectCheckBox1->Enabled = false;

  CameraSelectCheckBox2->Checked = false;
  CameraSelectCheckBox2->Enabled = false;

  CameraSelectCheckBox3->Checked = false;
  CameraSelectCheckBox3->Enabled = false;

  CameraSelectCheckBox4->Checked = false;
  CameraSelectCheckBox4->Enabled = false;

  for(int GCamIndex = 0; GCamIndex < SYSTEM_TOTAL_CAMERA_COUNT; GCamIndex++)
  {
    int spbIndex = CameraMapInfo[GCamIndex].SPBIndex;

    if(!(EnabledSPBMask & (0x01 << spbIndex))) continue;

    int camIndex = CameraMapInfo[GCamIndex].CamIndex;
    TCheckBox *tempCheckbox = ((TCheckBox *)FindComponent("CameraSelectCheckBox"+IntToStr(camIndex + 1)));

    if(CameraMapInfo[GCamIndex].CameraInspectPosition < CAMERA_POSITION_DISCONNECT && SystemLinkCameraInfo[GCamIndex] != 0)
    {
      tempCheckbox->Checked = true;
      tempCheckbox->Enabled = true;
    }
  }  
}

void __fastcall TSystemSimulationForm::FormActivate(TObject *Sender)
{
  SetScreenPosition(this);  
}
//---------------------------------------------------------------------------

