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

#include <vcl.h>
#pragma hdrstop

#include "TabletCounter_Form.h"
#include "Environment.h"
#include "MultiLanguage.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PERFGRAP"
#pragma link "TntButtons"
#pragma link "TntExtCtrls"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"
TTabletCounterForm *TabletCounterForm;


/*
#define TC_TABLE_CAPACITY		256
typedef struct
{
	int CountingMode;
	unsigned int Counter;
    unsigned int SubCounter[2];
	unsigned int IndexTable[TC_TABLE_CAPACITY];
	int Interval[TC_TABLE_CAPACITY];
	int CurrentTableIndex;
} TTabletCounter;
*/

TTabletCounter TabletCounter_HCB;

//---------------------------------------------------------------------------
__fastcall TIntervalList::TIntervalList()
{

  
	Reset();
}
//---------------------------------------------------------------------------
void __fastcall TIntervalList::First(void)
{
	CurrentQueueIndex = StartQueueIndex;
	FCurrent = &IntervalCQueue[CurrentQueueIndex];
}
//---------------------------------------------------------------------------
bool __fastcall TIntervalList::IsLast(void)
{
	return (QueueCount == 0 || CurrentQueueIndex == ((StartQueueIndex + QueueCount - 1) % MAX_INTERVAL_LIST_SIZE));
}
//---------------------------------------------------------------------------
bool __fastcall TIntervalList::IsFull(void)
{
	return (QueueCount == MAX_INTERVAL_LIST_SIZE);
}
//---------------------------------------------------------------------------
void __fastcall TIntervalList::Next(void)
{
	CurrentQueueIndex = (CurrentQueueIndex + 1) % MAX_INTERVAL_LIST_SIZE;
	FCurrent = &IntervalCQueue[CurrentQueueIndex];
}
//---------------------------------------------------------------------------
void __fastcall TIntervalList::Reset(void)
{
	FirstIntervalIndex = 0;
	StartQueueIndex = 0;
    QueueCount = 0;
    CurrentQueueIndex = 0;
}
//---------------------------------------------------------------------------
void __fastcall TIntervalList::SetValue(int index, int offInterval, int onInterval)
{
	int lastIntervalIndex = FirstIntervalIndex + QueueCount;
    if (index >= lastIntervalIndex)
	for (int tempIndex = lastIntervalIndex; tempIndex <= index; tempIndex++)
    {
		if (this->IsFull())
        {
			StartQueueIndex = (StartQueueIndex + 1) % MAX_INTERVAL_LIST_SIZE;
            FirstIntervalIndex++;
            QueueCount--;
        }
        int newIndex = (StartQueueIndex + QueueCount) % MAX_INTERVAL_LIST_SIZE;
        IntervalCQueue[newIndex].OffInterval = 0;
        IntervalCQueue[newIndex].OnInterval = 0;
        QueueCount++;
    }
	int queueIndex = (StartQueueIndex + (index - FirstIntervalIndex)) % MAX_INTERVAL_LIST_SIZE;
    IntervalCQueue[queueIndex].OffInterval = offInterval;
    IntervalCQueue[queueIndex].OnInterval = onInterval;
}
//---------------------------------------------------------------------------
__fastcall TTabletCounterForm::TTabletCounterForm(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);
  }

//	IntervalListInsertPosition = 0;


/*
    for (int i = 0; i < 1024; i++)
    {
    	OnInterval[i] = 0;
    	OffInterval[i] = 0;
    }
*/
  Label1->Caption = TABLETCOUNTERFORM_LABEL_CAPTION_01;
  Label2->Caption = TABLETCOUNTERFORM_LABEL_CAPTION_02;

  SimpleModeSpeedButton->Caption  	= TABLETCOUNTERFORM_BUTTON_CAPTION_01;
  SpeedButton2->Caption  			= TABLETCOUNTERFORM_BUTTON_CAPTION_02;
  StartCountButton->Caption  		= TABLETCOUNTERFORM_BUTTON_CAPTION_03;
  StopCountButton->Caption  		= TABLETCOUNTERFORM_BUTTON_CAPTION_04;
  ResetCountButton->Caption  		= TABLETCOUNTERFORM_BUTTON_CAPTION_05;

	ImageStartPosition = 0;
    Scale = 1;
	IntervalListReset();
    Panel1->DoubleBuffered = true;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::IntervalListReset(void)
{
	IntervalListStartIndex = 0;
    IntervalListMaxValue = -1;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::StartCountButtonClick(TObject *Sender)
{
	int func;

    if (SimpleModeSpeedButton->Down)
    {
		func = 5;
    }
    else
    {
        func = 1;
    }
	if (!Comm_Request(COMM_HCB, CMD_TABLET_COUNTER, &func, sizeof(int)))
	{
		//ShowMessageW(HCBConnection.GetLastErrorMessage());
	}
	else
	{
		TabletCountTimer->Enabled = true;
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::StopCountButtonClick(TObject *Sender)
{
	int func = 2;
	if (!Comm_Request(COMM_HCB, CMD_TABLET_COUNTER, &func, sizeof(int)))
	{
        //ShowMessageW(HCBConnection.GetLastErrorMessage());
    }
    TabletCountTimer->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::ResetCountButtonClick(TObject *Sender)
{
	int func = 0;
	if (!Comm_Request(COMM_HCB, CMD_TABLET_COUNTER, &func, sizeof(int)))
	{
        //ShowMessageW(HCBConnection.GetLastErrorMessage());
    }

	IntervalListReset();
    ImageStartPosition = 0;
    IntervalList.Reset();
//    TabletCountTimer->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::TabletCountTimerTimer(TObject *Sender)
{
/*
	int func = 3;
    unsigned int count;
    if (!HCBConnection.RequestCommand(CMD_TABLET_COUNTER, &func, sizeof(int), &count, sizeof(unsigned int)))
    {
        ShowMessageW(HCBConnection.GetLastErrorMessage());
        TabletCountTimer->Enabled = false;
    }
    else
    {
    	CountLabel->Caption = IntToStr(count);
    }
*/

  WCHAR TempString[100];
	if (SimpleModeSpeedButton->Down)
    {
		TSimpleTabletCounter SimpleTabletCounter;
        int func = 6;

		if (!Comm_Request(COMM_HCB, CMD_TABLET_COUNTER, &func, sizeof(int), &SimpleTabletCounter, sizeof(TSimpleTabletCounter)))
		{
	        //ShowMessageW(HCBConnection.GetLastErrorMessage());
	        TabletCountTimer->Enabled = false;
	    }
	    else
	    {
	    	CountLabel->Caption = IntToStr(SimpleTabletCounter.Counter);

        wsprintfW(TempString, L"%S/S", FloatToStrF( SimpleTabletCounter.CPM / 60.0, ffFixed, 10, 1));
        CPSLabel->Caption = TempString;
			CPMLabel->Caption = IntToStr(SimpleTabletCounter.CPM) + "/M";
	        CPHLabel->Caption = IntToStr(SimpleTabletCounter.CPM * 60) + "/H";
	        if (SimpleTabletCounter.ElapsedTime > 0)
	        {
            wsprintfW(TempString, L"%S/S", FloatToStrF( SimpleTabletCounter.Counter / (SimpleTabletCounter.ElapsedTime / 1000.0), ffFixed, 10, 1));
            WCPSLabel->Caption = TempString;

				WCPMLabel->Caption = IntToStr((int)(SimpleTabletCounter.Counter / (SimpleTabletCounter.ElapsedTime / 1000.0 / 60.0))) + "/M";
		        WCPHLabel->Caption = IntToStr((int)(SimpleTabletCounter.Counter / (SimpleTabletCounter.ElapsedTime / 1000.0 / 3600.0))) + "/H";
    	    }
	        else
	        {
		        WCPSLabel->Caption = "0/S";
				WCPMLabel->Caption = "0/M";
		        WCPHLabel->Caption = "0/H";
	        }
        }
    }
    else
    {
		int func = 4;
		if (!Comm_Request(COMM_HCB, CMD_TABLET_COUNTER, &func, sizeof(int), &TabletCounter_HCB, sizeof(TTabletCounter)))
		{
	        //ShowMessageW(HCBConnection.GetLastErrorMessage());
	        TabletCountTimer->Enabled = false;
	    }
	    else
	    {
        WCHAR TmpString[100];

	    	CountLabel->Caption = IntToStr(TabletCounter_HCB.Counter);
        wsprintfW(TmpString, L"%S/S", FloatToStrF( TabletCounter_HCB.CPS, ffFixed, 10, 1));
        CPSLabel->Caption = TmpString;

			CPMLabel->Caption = IntToStr(TabletCounter_HCB.CPM) + "/M";
	        CPHLabel->Caption = IntToStr(TabletCounter_HCB.CPM * 60) + "/H";
	        if (TabletCounter_HCB.ElapsedTime > 0)
	        {
            wsprintfW(TmpString, L"%S/S", FloatToStrF( TabletCounter_HCB.Counter / (TabletCounter_HCB.ElapsedTime / 1000.0), ffFixed, 10, 1));
            WCPSLabel->Caption = TmpString;

				WCPMLabel->Caption = IntToStr((int)(TabletCounter_HCB.Counter / (TabletCounter_HCB.ElapsedTime / 1000.0 / 60.0))) + "/M";
		        WCPHLabel->Caption = IntToStr((int)(TabletCounter_HCB.Counter / (TabletCounter_HCB.ElapsedTime / 1000.0 / 3600.0))) + "/H";
    	    }
	        else
	        {
		        WCPSLabel->Caption = "0/S";
				WCPMLabel->Caption = "0/M";
		        WCPHLabel->Caption = "0/H";
	        }
	        int maxNewIndex = -1;
	        for (int i = 0; i < TC_TABLE_CAPACITY; i++)
	        {
				if (TabletCounter_HCB.IndexTable[i] > IntervalListMaxValue - 1) // 불필요한 연산을 줄이기 위해 max value와 비교한다. off, on 의 2회 갱신이므로 max-1 과 비교한다.
	            {
	//				unsigned int offIntervalIndex = i - 1;
	//                int newIndex = TabletCounter.IndexTable[i] - 1;
					int newIndex = TabletCounter_HCB.IndexTable[i];

	                if (TabletCounter_HCB.IndexTable[i] == 0)		// skip first offInterval
	                {
						TabletCounter_HCB.OffInterval[i] = 0;
	                }
	                int offInterval = TabletCounter_HCB.OffInterval[i];
	                int onInterval = TabletCounter_HCB.OnInterval[i];
					IntervalList.SetValue(newIndex, offInterval, onInterval);

	                if (maxNewIndex < newIndex) maxNewIndex = newIndex;
				}
			}
	        if (IntervalListMaxValue < maxNewIndex)
	        {
	            IntervalListMaxValue = maxNewIndex;
	        }

	        int scrollMax = 0;
	    	for (IntervalList.First(); !IntervalList.IsLast(); IntervalList.Next())
	        {
	        	scrollMax += (IntervalList.Current->OnInterval + IntervalList.Current->OffInterval);
	        }
	        ImageScrollBar->Max = scrollMax;
	        DrawImage();
	    }
	}
}
//---------------------------------------------------------------------------
void __fastcall TTabletCounterForm::DrawImage(void)
{

	Image->Canvas->Brush->Style = bsSolid;
    Image->Canvas->Pen->Color = clBlack;
	Image->Canvas->Brush->Color = clBlack;
	Image->Canvas->Rectangle(Rect(0, 0, Image->Width, Image->Height));

    Image->Canvas->Pen->Color = clLime;
    int currentInterval = -ImageStartPosition;

    int posY = 50;
    Image->Canvas->MoveTo(0, posY + 25);
    for (IntervalList.First(); !IntervalList.IsLast(); IntervalList.Next())
    {
    	int offInterval = IntervalList.Current->OffInterval;
    	int onInterval = IntervalList.Current->OnInterval;
        Image->Canvas->LineTo((currentInterval + offInterval) / Scale, posY + 25);
        Image->Canvas->LineTo((currentInterval + offInterval) / Scale, posY - 25);
        Image->Canvas->LineTo((currentInterval + offInterval + onInterval) / Scale, posY - 25);
        Image->Canvas->LineTo((currentInterval + offInterval + onInterval) / Scale, posY + 25);

        while ((currentInterval + offInterval + onInterval) / Scale >= Image->Width)
        {
			currentInterval -= Image->Width * Scale;
            posY += 100;
            Image->Canvas->MoveTo(0, posY + 25);
	        Image->Canvas->LineTo((currentInterval + offInterval) / Scale, posY + 25);
	        Image->Canvas->LineTo((currentInterval + offInterval) / Scale, posY - 25);
	        Image->Canvas->LineTo((currentInterval + offInterval + onInterval) / Scale, posY - 25);
	        Image->Canvas->LineTo((currentInterval + offInterval + onInterval) / Scale, posY + 25);
        }
        currentInterval += (offInterval + onInterval);
    }

    Image->Repaint();

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


void __fastcall TTabletCounterForm::ImageScrollBarChange(TObject *Sender)
{
    ImageStartPosition = ImageScrollBar->Position;
    DrawImage();
}
//---------------------------------------------------------------------------


void __fastcall TTabletCounterForm::ScaleSpeedButtonClick(TObject *Sender)
{
	TTntSpeedButton *theSpeedButton = (TTntSpeedButton *)Sender;
    switch(theSpeedButton->Tag)
    {
    	case 0:
			Scale = 1;
            break;
    	case 1:
			Scale = 2;
            break;
    	case 2:
			Scale = 5;
            break;
    	case 3:
			Scale = 10;
            break;
    	case 4:
			Scale = 20;
            break;
    	case 5:
			Scale = 50;
            break;
    	case 6:
			Scale = 100;
            break;
    }
	DrawImage();
}
//---------------------------------------------------------------------------


