//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 완료
// CPB04, CPB05 version 상태에 따라 사용가능한 CPU 개수가 서로 다르므로 이에 따른 UI 수정 진행
// CPB05 적용 시에는 보드 특성에 따라 추후 추가 작업이 발생할 수 있음
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

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

#define MAX_CPB_BOOT_FAIL_COUNT			3

TCPBStatusForm *CPBStatusForm;
//---------------------------------------------------------------------------
__fastcall TCPBStatusForm::TCPBStatusForm(TComponent* Owner)
	: TTntForm(Owner)
{
  if(DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
    ComponentSetFontName(this, "SimSun");
  else if(DefaultLCID == 1041)
    ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
    {
      CPBNumberLabelList[spbIndex][cpbIndex] = new TTntLabel(this);
      CPBStatusShapeList[spbIndex][cpbIndex] = new TTntShape(this);
    }
  }

  SetCPBStatusComponent();
  
	FCanReboot = false;
	FCPBStatus = ECS_IDLE;

  if(DefaultLCID != 1042)
    GetDefaultString();
}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::GetDefaultString()
{
  CloseButton->Caption = "Close";
  CPBRebootButton->Caption = "Reboot";
  this->Caption = "CPB Status";
  CPBStatusLabel->Caption = "Not enough number of CPB for Normal Operation. Please Restart System.";
  GroupBox5->Caption = "CPB Status";
}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::CloseButtonClick(TObject *Sender)
{
	this->Hide();
}
//---------------------------------------------------------------------------
bool __fastcall CheckCPBBootStatus(bool bCanReboot,bool ReadOnly,bool ApplyHide)
{
  CPBStatusForm->SetCPBStatusComponent();
  
	bool cpbBooting = false;
	bool bootSuccess = true;
  CPBStatusForm->KeepShowing = false;
	TCPBRunStatus cpbRunStatus;

	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		Comm_Request(COMM_SPB + spbIndex, CMD_RUN_INFO, NULL, 0, &cpbRunStatus, sizeof(TCPBRunStatus));
		if (cpbRunStatus.Running)
		{
			cpbBooting = true;
		}
	}

	CPBStatusForm->CanReboot = bCanReboot;
	if (cpbBooting)
	{
		CPBStatusForm->SetCPBStatus(ECS_RUNNING);
    //CPBStatusForm->Show();
		CPBStatusForm->CheckCPBBooting();
	}
	else
	{
		TCPBStatus CPBStatus[SYSTEM_CPB_COUNT];

		int cpbBootFailCount;
		// check complete cpb count
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
			Comm_Request(COMM_SPB + spbIndex, CMD_CPB_STATUS, NULL, 0, CPBStatus, sizeof(TCPBStatus) * SYSTEM_CPB_COUNT);
			cpbBootFailCount = 0;
			for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
			{
				if (SPBSystemSetupData[spbIndex].CPBEnabled[cpbIndex] &&
					CPBStatus[cpbIndex].Status == CPB_STATUS_DISABLED)
				{
					cpbBootFailCount++;
				}
			}
			if (cpbBootFailCount > MAX_CPB_BOOT_FAIL_COUNT)
			{
				bootSuccess = false;
			}
		}
		if (!bootSuccess)
		{
			CPBStatusForm->SetCPBStatus(ECS_CPB_LEAK);
      //CPBStatusForm->Show();
		}
	}
  if(!ReadOnly)
  {
    if(!ApplyHide)
    {
      CPBStatusForm->Show();
      CPBStatusForm->KeepShowing = true;
    }
  }
  
	if (cpbBooting)
	{
		return false;
	}
	else
	{
		return true;
	}
}
//---------------------------------------------------------------------------

void __fastcall TCPBStatusForm::FormShow(TObject *Sender)
{
	this->Left = Screen->Width - this->Width;
	this->Top = Screen->Height - this->Height;
	InitDisplay();
	CPBBootCheckTimer->Enabled = true;
}
//---------------------------------------------------------------------------
void TCPBStatusForm::SetCPBStatus(ECPBStatus status)
{
	FCPBStatus = status;
	switch (FCPBStatus)
	{
		case ECS_IDLE:
			CPBStatusLabel->Font->Color = clLime;
			CPBStatusLabel->Caption = CPBSTATUSFORM_LABEL_CAPTION_02;
			break;
		case ECS_RUNNING:
			CPBStatusLabel->Font->Color = clYellow;
			CPBStatusLabel->Caption = CPBSTATUSFORM_LABEL_CAPTION_01;
			break;
		case ECS_CPB_LEAK:
			CPBStatusLabel->Font->Color = clRed;
			CPBStatusLabel->Caption = CPBSTATUSFORM_LABEL_CAPTION_03;
			break;
	}
}
//---------------------------------------------------------------------------
void TCPBStatusForm::CheckCPBBooting(void)
{

}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::CPBBootCheckTimerTimer(TObject *Sender)
{
	bool timerEnabled = CPBBootCheckTimer->Enabled;
	CPBBootCheckTimer->Enabled = false;
	
	// show cpb status
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (Comm_Request(COMM_SPB + spbIndex, CMD_CPB_STATUS, NULL, 0, CPBStatus, sizeof(TCPBStatus) * SYSTEM_CPB_COUNT))
		{
			for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
			{
				switch (CPBStatus[cpbIndex].Status)
				{
					case CPB_STATUS_DISABLED:
						CPBStatusShapeList[spbIndex][cpbIndex]->Pen->Color = clRed;
						CPBStatusShapeList[spbIndex][cpbIndex]->Brush->Color = clRed;
						break;
					case CPB_STATUS_BOOT_READY:
						CPBStatusShapeList[spbIndex][cpbIndex]->Pen->Color = TColor(0x007FFF);
						CPBStatusShapeList[spbIndex][cpbIndex]->Brush->Color = TColor(0x007FFF);
						break;
					case CPB_STATUS_BOOTING:
					case CPB_STATUS_PROCESSING:
						CPBStatusShapeList[spbIndex][cpbIndex]->Pen->Color = clYellow;
						CPBStatusShapeList[spbIndex][cpbIndex]->Brush->Color = clYellow;
						break;
					case CPB_STATUS_IDLE:
						CPBStatusShapeList[spbIndex][cpbIndex]->Pen->Color = clLime;
						CPBStatusShapeList[spbIndex][cpbIndex]->Brush->Color = clLime;
						break;
				}

			}
		}
		else
		{
			for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
			{
				CPBStatusShapeList[spbIndex][cpbIndex]->Pen->Color = clRed;
				CPBStatusShapeList[spbIndex][cpbIndex]->Brush->Color = clRed;
			}
		}
	}

	bool cpbRunning = false;
	TCPBRunStatus cpbRunStatus;
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		Comm_Request(COMM_SPB + spbIndex, CMD_RUN_INFO, NULL, 0, &cpbRunStatus, sizeof(TCPBRunStatus));
		if (cpbRunStatus.Running)
		{
			cpbRunning = true;
		}
	}

	if (!cpbRunning)
	{
		bool bootSuccess = true;
		int cpbBootFailCount;
		// check complete cpb count
		for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
		{
			SPBBootSuccess[spbIndex] = true;
			Comm_Request(COMM_SPB + spbIndex, CMD_CPB_STATUS, NULL, 0, CPBStatus, sizeof(TCPBStatus) * SYSTEM_CPB_COUNT);
			cpbBootFailCount = 0;
			for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
			{
				if (SPBSystemSetupData[spbIndex].CPBEnabled[cpbIndex] &&
					CPBStatus[cpbIndex].Status == CPB_STATUS_DISABLED)
				{
					cpbBootFailCount++;
				}
			}
			if (cpbBootFailCount > MAX_CPB_BOOT_FAIL_COUNT)
			{
				SPBBootSuccess[spbIndex] = false;
				bootSuccess = false;
			}
		}
		if (bootSuccess)
		{
			timerEnabled = false;
			this->Hide();
		}
		else
		{
			timerEnabled = false;
			CPBRebootButton->Enabled = true;
			SetCPBStatus(ECS_CPB_LEAK);
      if(!KeepShowing)
        this->Show();
		}
	}
	
	CPBBootCheckTimer->Enabled = timerEnabled;
}
//---------------------------------------------------------------------------

void __fastcall TCPBStatusForm::FormHide(TObject *Sender)
{
	CPBBootCheckTimer->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::InitDisplay(void)
{
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
		{
      if(cpbIndex < SPBSystemSetupData[spbIndex].MaxProcessingCoreCount)
      {
        if (SPBSystemSetupData[spbIndex].CPBEnabled[cpbIndex])
        {
          if(ApplyCPBVersion == CPB_VERSION_04)
            CPBNumberLabelList[spbIndex][cpbIndex]->Visible = true;

          CPBStatusShapeList[spbIndex][cpbIndex]->Visible = true;
        }
        else
        {
          if(ApplyCPBVersion == CPB_VERSION_04)
            CPBNumberLabelList[spbIndex][cpbIndex]->Visible = false;

          CPBStatusShapeList[spbIndex][cpbIndex]->Visible = false;
        }
      }
      else
      {
        if(ApplyCPBVersion == CPB_VERSION_04)
          CPBNumberLabelList[spbIndex][cpbIndex]->Visible = false;

        CPBStatusShapeList[spbIndex][cpbIndex]->Visible = false;
      }
		}
	}
	CPBRebootButton->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::SetCanReboot(bool bCanReboot)
{
	FCanReboot = bCanReboot;
	if (FCanReboot)
	{
		CPBRebootButton->Enabled = true;
	}
	else
	{
		CPBRebootButton->Enabled = false;
	}
}
//---------------------------------------------------------------------------
void __fastcall TCPBStatusForm::CPBRebootButtonClick(TObject *Sender)
{
	struct
	{
		unsigned int runMode;
		int programID;
	} runData;
	
	runData.runMode = RUN_MODE_RERUN;
	runData.programID = 0;
	for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
	{
		if (!SPBBootSuccess[spbIndex])
		{
			if (Comm_IsConnected(COMM_SPB + spbIndex))
			{
				Comm_SetMaxWaitingTime(COMM_SPB + spbIndex, 30000);
				Comm_Request(COMM_SPB + spbIndex, CMD_RUN, &runData, sizeof(runData));
				Comm_SetDefaultMaxWaitingTime(COMM_SPB + spbIndex);
			}
		}
	}
	CPBSetupInfo.StudySetupDataValid = false;
	CPBSetupInfo.InspectionSetupDataValid = false;
	CPBSetupInfo.GradeDataValid = false;
	CPBBootCheckTimer->Enabled = true;
}
//---------------------------------------------------------------------------

void TCPBStatusForm::SetCPBStatusComponent()
{
  int CPB04VersionCount = 0;
  for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
  {
    if(SPBSystemSetupData[spbIndex].CPBVersion == CPB_VERSION_04)
    {
      CPB04VersionCount++;
    }
  }

  if(CPB04VersionCount == 6)
  {
    this->Height = 514;

    ApplyCPBVersion = CPB_VERSION_04;
    
    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      TTntGroupBox *spb06GroupBox = (TTntGroupBox *) FindComponent("SPBGroupBox" + IntToStr(spbIndex + 1));
      if (spb06GroupBox)
      {
        spb06GroupBox->Visible = true;

        TTntGroupBox *spb07GroupBox = (TTntGroupBox *) FindComponent("SPB07GroupBox" + IntToStr(spbIndex + 1));
        if(spb07GroupBox) spb07GroupBox->Visible = false;

        for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
        {
          if(cpbIndex < SPBSystemSetupData[spbIndex].MaxProcessingCoreCount)
          {
            CPBNumberLabelList[spbIndex][cpbIndex]->Caption = IntToStr(cpbIndex + 1);
            CPBNumberLabelList[spbIndex][cpbIndex]->Parent = spb06GroupBox;
            CPBNumberLabelList[spbIndex][cpbIndex]->Left = (cpbIndex / 8) * 48 + 16;
            CPBNumberLabelList[spbIndex][cpbIndex]->Top = (cpbIndex % 8) * 24 + 24;
            CPBNumberLabelList[spbIndex][cpbIndex]->Visible = true;

            CPBStatusShapeList[spbIndex][cpbIndex]->Parent = spb06GroupBox;
            CPBStatusShapeList[spbIndex][cpbIndex]->Left = (cpbIndex / 8) * 48 + 32;
            CPBStatusShapeList[spbIndex][cpbIndex]->Top = (cpbIndex % 8) * 24 + 23;
            CPBStatusShapeList[spbIndex][cpbIndex]->Width = 17;
            CPBStatusShapeList[spbIndex][cpbIndex]->Height = 17;
            CPBStatusShapeList[spbIndex][cpbIndex]->Shape = stCircle;
            CPBStatusShapeList[spbIndex][cpbIndex]->Visible = true;
          }
          else
          {
            CPBNumberLabelList[spbIndex][cpbIndex]->Visible = false;
            CPBStatusShapeList[spbIndex][cpbIndex]->Visible = false;
          }
        }
      }
    }
  }
  else
  {
    this->Height = 312;

    int tempIndex;
    ApplyCPBVersion = CPB_VERSION_05;

    for (int spbIndex = 0; spbIndex < MachineSetupData.IPB_BoardCount; spbIndex++)
    {
      TTntGroupBox *spb07GroupBox = (TTntGroupBox *) FindComponent("SPB07GroupBox" + IntToStr(spbIndex + 1));
      if (spb07GroupBox)
      {
        spb07GroupBox->Visible = true;

        TTntGroupBox *spb06GroupBox = (TTntGroupBox *) FindComponent("SPBGroupBox" + IntToStr(spbIndex + 1));
        if(spb06GroupBox) spb06GroupBox->Visible = false;

        for (int cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
        {
          tempIndex = (cpbIndex / 32) + 1;

          TTntGroupBox *cpbGroupBox = (TTntGroupBox *) FindComponent("CPB05GroupBox" + IntToStr(spbIndex * 3 + tempIndex));
          {
            if(cpbGroupBox)
            {
              if(cpbIndex < SPBSystemSetupData[spbIndex].MaxProcessingCoreCount)
              {
                CPBStatusShapeList[spbIndex][cpbIndex]->Parent = cpbGroupBox;
                CPBStatusShapeList[spbIndex][cpbIndex]->Left = ((cpbIndex % 32) / 8) * 19 + 10;
                CPBStatusShapeList[spbIndex][cpbIndex]->Top = (cpbIndex % 8) * 18 + 17;
                CPBStatusShapeList[spbIndex][cpbIndex]->Width = 12;
                CPBStatusShapeList[spbIndex][cpbIndex]->Height = 14;
                CPBStatusShapeList[spbIndex][cpbIndex]->Shape = stCircle;
                CPBStatusShapeList[spbIndex][cpbIndex]->Visible = true;
              }
              else
              {
                CPBNumberLabelList[spbIndex][cpbIndex]->Visible = false;
                CPBStatusShapeList[spbIndex][cpbIndex]->Visible = false;
              }
            }
          }
        }
      }
    }
  }
}


