//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 완료
// Camera Index 관련 일부 수정
//---------------------------------------------------------------------------

#include <vcl.h>
#include <math.h>
#include <inifiles.hpp>
#pragma hdrstop

#include "ProductSearch_Form.h"
#include "Environment.h"
#include "Keyboard_Form.h"
#include "Message_Form.h"
#include "MultiLanguage.h"
#include "Main_Form.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TntButtons"
#pragma link "TntExtCtrls"
#pragma link "TntGrids"
#pragma link "TntStdCtrls"
#pragma resource "*.dfm"

#define max(x, y) (x > y ? x : y)
TProductSearchForm *ProductSearchForm;
//---------------------------------------------------------------------------
__fastcall TProductSearchForm::TProductSearchForm(TComponent* Owner)
	: TTntForm(Owner)
{
	if (DefaultLCID == 1028 || DefaultLCID == 2052 || DefaultLCID == 3076 || DefaultLCID == 4100)
		ComponentSetFontName(this, "SimSun");
  else if(DefaultLCID == 1041)
    ComponentSetFontName(this, "Meiryo UI");
  else if(DefaultLCID == 3082)
  {
    ComponentSetFontName(this, "Segoe UI");
    ComponentSetMultiLine(this);
  }

	GetDefaultString();

	FOnClickOK = NULL;
	FOnClickCancel = NULL;
	ProductListStringGrid->Cells[0][0] = PRODUCTSEARCHFORM_STRGRID_CELL_04;
	ProductListStringGrid->Cells[1][0] = PRODUCTSEARCHFORM_STRGRID_CELL_02;
	ProductListStringGrid->Cells[2][0] = PRODUCTSEARCHFORM_STRGRID_CELL_01;
	ProductListStringGrid->Cells[3][0] = PRODUCTSEARCHFORM_STRGRID_CELL_03;
	ProductListStringGrid->Cells[4][0] = PRODUCTSEARCHFORM_STRGRID_CELL_05;
	ProductListStringGrid->ColWidths[0] = 320;
	ProductListStringGrid->ColWidths[1] = 150;
	ProductListStringGrid->ColWidths[2] = 150;
	ProductListStringGrid->ColWidths[3] = 75;
	ProductListStringGrid->ColWidths[4] = 275;

	ScrollImage->Picture->Bitmap->Width = ScrollImage->Width;
	ScrollImage->Picture->Bitmap->Height = ScrollImage->Height;
	ScrollImage->Picture->Bitmap->PixelFormat = pf24bit;
	for (int y = 0; y < ScrollImage->Height; y++)
	{

		byte *pBitmap = (byte *)ScrollImage->Picture->Bitmap->ScanLine[y];
		byte colorB = 0xFF - abs(y - ScrollImage->Height / 2) * 0x4F / (ScrollImage->Height / 2);
		byte colorG = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
		byte colorR = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
		if (y % 10 == 0)
		{
			colorB = colorG = colorR = 0;
		}
		for (int x = 0; x < ScrollImage->Width; x++)
		{
			pBitmap[x * 3] = colorB;
			pBitmap[x * 3 + 1] = colorG;
			pBitmap[x * 3 + 2] = colorR;
		}
	}
	IsScrollImageMouseDown = false;

	ScrollGroupBox->DoubleBuffered = true;
	TabletImagePanel->DoubleBuffered = true;

	SortBy = NOT_SORT;
	SortAscendingOrder = true;

  DiscSearch();
//	Search("");
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::GetDefaultString()
{
	CancelBitBtn->Caption = PRODUCTSEARCHFORM_BITBTN_CAPTION_01;
	OkBitBtn->Caption = PRODUCTSEARCHFORM_BITBTN_CAPTION_02;
	SearchButton->Caption = PRODUCTSEARCHFORM_BUTTON_CAPTION_01;
	this->Caption = PRODUCTSEARCHFORM_FORM_CAPTION_01;
	ScrollGroupBox->Caption = PRODUCTSEARCHFORM_GROUPBOX_CAPTION_01;
	GroupBox1->Caption = PRODUCTSEARCHFORM_GROUPBOX_CAPTION_02;
	Label1->Caption = PRODUCTSEARCHFORM_LABEL_CAPTION_01;
	SortByInspTimePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_01;
	SortByShapePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_04;
	SortByNamePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_07;
	SortByKindPanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_10;
	SortBySizePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_13;

	//add
	Panel5->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_16;
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::DiscSearch(void)
{
	// make product table
	TSearchRec sr;
	int iAttributes = faDirectory;
	WideString productDir = ProgramPath.Product;

	TotalTabletList.clear();

	if (FindFirst(productDir + "\\*.*", iAttributes, sr) == 0)
	{
		do
		{
			if (sr.Name != "." && sr.Name != ".." &&sr.Name != "LookupTable.dat") // (sr.Attr & iAttributes) == sr.Attr &&  어떤 pc에서는 Attr 값이 제대로 잡히지 않음 없어도 큰 문제가 되지는 않을듯 싶음
			{
				WideString foundProductCode = sr.Name;
				TProductData tempProductData;
				WideString productFileName = productDir + "\\" + foundProductCode + "\\" + foundProductCode + ".dat";
				ReadLightProductData(productFileName, tempProductData);

        TTabletListUnit aListUnit;
        aListUnit.Name = tempProductData.ProductName;
        aListUnit.TabletKind = tempProductData.TabletType;
        aListUnit.TabletShape = tempProductData.TabletShape;
        aListUnit.TabletSize = tempProductData.TabletLength;
        aListUnit.LastInspectionTime = tempProductData.LastInspectionTime.Val;
        aListUnit.newTabletUnit = false;

        TotalTabletList.push_back(aListUnit);
			}
		} while (FindNext(sr) == 0);
		FindClose(sr);
	}

	SaveTabletLookupTable();
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SaveTabletLookupTable(void)
{
	WideString tableFileName = ProgramPath.Product + "\\LookupTable.dat";
  WideString tempProductName;

	TIniFile *iniFile = new TIniFile(tableFileName);
	if (iniFile)
	{
		vector<TTabletListUnit>::iterator it;

    for (it = TotalTabletList.begin(); it < TotalTabletList.end(); it++)
		{
      if(!it->Name.IsEmpty())
      {
        tempProductName = iniFile->ReadString(it->Name, "Product Name", "UNKNOWN");

        if (_tcscmp(tempProductName,L"UNKNOWN") == 0)
        {
          it->newTabletUnit = true;
        }
      }
		}

		for (it = TotalTabletList.begin(); it < TotalTabletList.end(); it++)
		{
      if(it->newTabletUnit && !it->Name.IsEmpty())
      {
        iniFile->WriteString(it->Name, "Product Name", it->Name);
        iniFile->WriteInteger(it->Name, "Tablet Kind", it->TabletKind);
        iniFile->WriteInteger(it->Name, "Tablet Shape", it->TabletShape);
        iniFile->WriteFloat(it->Name, "Tablet Size", it->TabletSize);
        iniFile->WriteFloat(it->Name, "Last Inspection Time", it->LastInspectionTime);
      }
		}
        
		delete iniFile;
	}
	else
	{
		ShowMessageFA(PRODUCTSEARCHFORM_MSG_03);
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::LoadTabletLookupTable(void)
{
	TotalTabletList.clear();

	WideString tableFileName = ProgramPath.Product + "\\LookupTable.dat";
	TIniFile *iniFile = new TIniFile(tableFileName);
	if (iniFile)
	{
		TStringList *sectionNameList = new TStringList;
		iniFile->ReadSections(sectionNameList);

		for (int sectionList = 0; sectionList < sectionNameList->Count; sectionList++)
		{
      try
      {
        TTabletListUnit aListUnit;
        aListUnit.Name = iniFile->ReadString(sectionNameList->Strings[sectionList], "Product Name", "");
        aListUnit.TabletKind = iniFile->ReadInteger(sectionNameList->Strings[sectionList], "Tablet Kind", TABLET_TYPE_UNKNOWN);
        aListUnit.TabletShape = iniFile->ReadInteger(sectionNameList->Strings[sectionList], "Tablet Shape", TABLET_SHAPE_UNKNOWN);
        aListUnit.TabletSize = iniFile->ReadFloat(sectionNameList->Strings[sectionList], "Tablet Size", 0);
        aListUnit.LastInspectionTime = iniFile->ReadFloat(sectionNameList->Strings[sectionList], "Last Inspection Time", 0);
        TotalTabletList.push_back(aListUnit);
      }
      catch(...)
      {
      }
		}

		delete sectionNameList;
		delete iniFile;
	}
	else
	{
		ShowMessageFA(PRODUCTSEARCHFORM_MSG_02);
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::RefreshProductList(void)
{
	LoadTabletLookupTable();
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::Search(WideString codeStr)
{
	TabletList.clear();

	vector<TTabletListUnit>::iterator it;

  if(codeStr.IsEmpty())
  {
    for (it = TotalTabletList.begin(); it < TotalTabletList.end(); it++)
    {
      TTabletListUnit aListUnit = *it;
      TabletList.push_back(aListUnit);
    }
  }
  else
  {
    for (it = TotalTabletList.begin(); it < TotalTabletList.end(); it++)
    {
      if (it->Name.Length() == codeStr.Length())
      {
        WideString CodeName =  it->Name;
        WideString Cstr = codeStr;
        if (_tcscmp(_tcslwr(CodeName),_tcslwr(Cstr))== 0)
        {
          TTabletListUnit aListUnit = *it;
          TabletList.push_back(aListUnit);
          continue;
        }
      }
      else
      {
        for(int i = 0 , z = 0 ; i < it->Name.Length() ; ++i)
        {
          bool BreakPoint = false;
          WideString CodeName =  it->Name.SubString(i+1,1);
          WideString Cstr = codeStr.SubString(z+1,1);
          if(_tcscmp(_tcslwr(CodeName), _tcslwr(Cstr)) == 0)
          {
             BreakPoint = true;
             if( z+1 == codeStr.Length() ) // 전부 일치
             {
               TTabletListUnit aListUnit = *it;
               TabletList.push_back(aListUnit);
               break;
             }
              else
                ++z;
            }
          }
        }
      }
  }

	SortByName_Ascending();
	ArrangeProductList();
}
//---------------------------------------------------------------------------
WideString __fastcall TProductSearchForm::GetSelectedProductCode(void)
{
	WideString productCode = ProductListStringGrid->Cells[0][ProductListStringGrid->Row];
	return productCode;
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::OkBitBtnClick(TObject *Sender)
{
	if (FOnClickOK)
  {
    WideString FileName = GetProductDataFileName(TabletSelectName);
    TProductData tempProductData;
    ReadProductData(FileName, tempProductData, MachineParams, MachineSetupData);
    FOnClickOK(Sender);
    NFALaserinfo.SendDLLCommand = CMD_LASER_RECIPE_SELECT;
  }
	this->Close();
}
//---------------------------------------------------------------------------

void __fastcall TProductSearchForm::CancelBitBtnClick(TObject *Sender)
{
	if (FOnClickCancel) FOnClickCancel(Sender);
	this->Close();
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ScrollImageMouseDown(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	if (!IsScrollImageMouseDown)
	{
		ScrollImageMouseDownPos.x = X;
		ScrollImageMouseDownPos.y = Y;
		ScrollImageMouseMovePos.x = X;
		ScrollImageMouseMovePos.y = Y;
		IsScrollImageMouseDown = true;
		StringGridMouseDownPos = ProductListStringGrid->Row;
		LastScrollTime = GetTickCount();
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ScrollImageMouseMove(TObject *Sender,
	TShiftState Shift, int X, int Y)
{
	if (Y < 0 || Y >= ScrollImage->Height) return;
	if (IsScrollImageMouseDown)
	{
		ScrollImageMouseMovePos.x = X;
		ScrollImageMouseMovePos.y = Y;
		int scrollCount = (Y - ScrollImageMouseDownPos.y) / 10;
		int newRow = StringGridMouseDownPos + scrollCount;
		if (newRow < 1) newRow = 1;
		else if (newRow >= ProductListStringGrid->RowCount) newRow = ProductListStringGrid->RowCount - 1;
		ProductListStringGrid->Row = newRow;
		if (scrollCount != 0)
		{
			for (int y = 0; y < ScrollImage->Height; y++)
			{
				byte *pBitmap = (byte *)ScrollImage->Picture->Bitmap->ScanLine[y];
				byte colorB = 0xFF - abs(y - ScrollImage->Height / 2 - scrollCount * 10) * 0x4F / (ScrollImage->Height / 2);
				byte colorG = 0x7F - abs(y - ScrollImage->Height / 2 - scrollCount * 10) * 0x1F / (ScrollImage->Height / 2);
				byte colorR = 0x7F - abs(y - ScrollImage->Height / 2 - scrollCount * 10) * 0x1F / (ScrollImage->Height / 2);
				if (y % 10 == 0)
				{
					colorB = colorG = colorR = 0;
				}
				for (int x = 0; x < ScrollImage->Width; x++)
				{
					pBitmap[x * 3] = colorB;
					pBitmap[x * 3 + 1] = colorG;
					pBitmap[x * 3 + 2] = colorR;
				}
			}
			ScrollImage->Repaint();
			LastScrollTime = GetTickCount();
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ScrollImageMouseUp(TObject *Sender,
	TMouseButton Button, TShiftState Shift, int X, int Y)
{
	IsScrollImageMouseDown = false;

	for (int y = 0; y < ScrollImage->Height; y++)
	{

		byte *pBitmap = (byte *)ScrollImage->Picture->Bitmap->ScanLine[y];
		byte colorB = 0xFF - abs(y - ScrollImage->Height / 2) * 0x4F / (ScrollImage->Height / 2);
		byte colorG = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
		byte colorR = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
		if (y % 10 == 0)
		{
			colorB = colorG = colorR = 0;
		}
		for (int x = 0; x < ScrollImage->Width; x++)
		{
			pBitmap[x * 3] = colorB;
			pBitmap[x * 3 + 1] = colorG;
			pBitmap[x * 3 + 2] = colorR;
		}
	}
	ScrollImage->Repaint();
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ScrollImageDblClick(TObject *Sender)
{
	/*
		if (ScrollImageMouseDownPos.y < ScrollImage->Height / 2)
			{
			ProductListStringGrid->Row = 1;
			}
			else
			{
			ProductListStringGrid->Row = ProductListStringGrid->RowCount - 1;
			}
	*/
}
//---------------------------------------------------------------------------

void __fastcall TProductSearchForm::ProductListStringGridSelectCell(
	TObject *Sender, int ACol, int ARow, bool &CanSelect)
{
	RefreshSelectedTablet(ARow);
}
//---------------------------------------------------------------------------


void __fastcall TProductSearchForm::ScrollTimerTimer(TObject *Sender)
{
  if(UVLaser.UVLaserStatus.NotChangeRecipeFlag)
  {
    OkBitBtn->Visible = false;
  }
  else
  {
    OkBitBtn->Visible = true;
  }

	if (IsScrollImageMouseDown)
	{
		if (GetTickCount() - LastScrollTime > 500)
		{
			if (ScrollImageMouseDownPos.y < ScrollImage->Height / 2)
			{
				if (ProductListStringGrid->Row > 1)
				{
					ProductListStringGrid->Row--;
				}
			}
			else
			{
				if (ProductListStringGrid->Row < ProductListStringGrid->RowCount - 1)
				{
					ProductListStringGrid->Row++;
				}
			}
			ScrollImageMouseDownPos.x = ScrollImageMouseMovePos.x;
			ScrollImageMouseDownPos.y = ScrollImageMouseMovePos.y;
			StringGridMouseDownPos = ProductListStringGrid->Row;
			LastScrollTime = GetTickCount();

			for (int y = 0; y < ScrollImage->Height; y++)
			{
				byte *pBitmap = (byte *)ScrollImage->Picture->Bitmap->ScanLine[y];
				byte colorB = 0xFF - abs(y - ScrollImage->Height / 2) * 0x4F / (ScrollImage->Height / 2);
				byte colorG = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
				byte colorR = 0x7F - abs(y - ScrollImage->Height / 2) * 0x1F / (ScrollImage->Height / 2);
				if (y % 10 == 0)
				{
					colorB = colorG = colorR = 0;
				}
				for (int x = 0; x < ScrollImage->Width; x++)
				{
					pBitmap[x * 3] = colorB;
					pBitmap[x * 3 + 1] = colorG;
					pBitmap[x * 3 + 2] = colorR;
				}
			}
			int radius = 40;
			for (int y = ScrollImageMouseDownPos.y - radius; y < ScrollImageMouseDownPos.y + radius; y++)
			{
				if (y < 0 || y >= ScrollImage->Height) continue;
				byte *pBitmap = (byte *)ScrollImage->Picture->Bitmap->ScanLine[y];
				for (int x = ScrollImageMouseDownPos.x - radius; x < ScrollImageMouseDownPos.x + radius; x++)
				{
					if (x < 0 || x >= ScrollImage->Width) continue;
					if (radius * radius > (y - ScrollImageMouseDownPos.y) * (y - ScrollImageMouseDownPos.y) + (x - ScrollImageMouseDownPos.x) * (x - ScrollImageMouseDownPos.x))
					{
						pBitmap[x * 3] = pBitmap[x * 3] - sqrt(radius * radius - (y - ScrollImageMouseDownPos.y) * (y - ScrollImageMouseDownPos.y) - (x - ScrollImageMouseDownPos.x) * (x - ScrollImageMouseDownPos.x)) * pBitmap[x * 3] / radius / 2;
						pBitmap[x * 3 + 1] = pBitmap[x * 3 + 1] - sqrt(radius * radius - (y - ScrollImageMouseDownPos.y) * (y - ScrollImageMouseDownPos.y) - (x - ScrollImageMouseDownPos.x) * (x - ScrollImageMouseDownPos.x)) * pBitmap[x * 3 + 1] / radius / 2;
						pBitmap[x * 3 + 2] = pBitmap[x * 3 + 2] - sqrt(radius * radius - (y - ScrollImageMouseDownPos.y) * (y - ScrollImageMouseDownPos.y) - (x - ScrollImageMouseDownPos.x) * (x - ScrollImageMouseDownPos.x)) * pBitmap[x * 3 + 2] / radius / 2;
					}
				}
			}
			ScrollImage->Repaint();
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ArrangeProductList(void)
{
	ProductListStringGrid->RowCount = 1;
	vector<TTabletListUnit>::iterator it;
	for (it = TabletList.begin(); it < TabletList.end(); it++)
	{
		ProductListStringGrid->RowCount++;
		ProductListStringGrid->Cells[0][ProductListStringGrid->RowCount - 1] = it->Name;
		ProductListStringGrid->Cells[1][ProductListStringGrid->RowCount - 1] = TabletKindStr(it->TabletKind);
		ProductListStringGrid->Cells[2][ProductListStringGrid->RowCount - 1] = TabletShapeStr(it->TabletShape);
		ProductListStringGrid->Cells[3][ProductListStringGrid->RowCount - 1] = FloatToStr(it->TabletSize);
		if (it->LastInspectionTime == 0)
		{
			ProductListStringGrid->Cells[4][ProductListStringGrid->RowCount - 1] = "";
		}
		else
		{
			ProductListStringGrid->Cells[4][ProductListStringGrid->RowCount - 1] = TDateTime(it->LastInspectionTime).DateString();
		}
	}

	if (ProductListStringGrid->RowCount > 1)
	{
		ProductListStringGrid->FixedRows = 1;
		ProductListStringGrid->Row = 1;
		ProductListStringGrid->Visible = true;
		ScrollImage->Enabled = true;

	}
	else
	{
		ProductListStringGrid->Visible = false;
		ScrollImage->Enabled = false;
	}
	RefreshSelectedTablet(ProductListStringGrid->Row);
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::RefreshSelectedTablet(int row)
{
  if(row == 0) return;
  
	WideString tabletName = ProductListStringGrid->Cells[0][row];
  TabletSelectName = tabletName;

  WideString productDir = ProgramPath.Product;
  WideString foundProductCode = TabletSelectName;
  TProductData tempProductData;
  WideString productFileName = WideString(productDir + "\\" + foundProductCode + "\\" + foundProductCode + ".dat");
  ReadLightProductData(productFileName, tempProductData);

  int MaxImageWidth;
  int MaxImageHeight;

  if(TabletSelectName != NULL)
  {
    if(_tcscmp(TabletSelectName ,L"Product Name") != 0 && !TabletSelectName.IsEmpty())
    {
      if(tempProductData.SubSamplingMode == 0)  // 확인 후 수정 필요
      {
        MaxImageWidth = SYSTEM_CAMERA_WIDTH;
        MaxImageHeight = SYSTEM_CAMERA_HEIGHT;
      }
      else if(tempProductData.SubSamplingMode == 1)
      {
        MaxImageWidth = SYSTEM_CAMERA_HD_WIDTH;
        MaxImageHeight = SYSTEM_CAMERA_HD_HEIGHT;
      }

      TabletTopImage->Picture->Bitmap->Width = MaxImageWidth;
      TabletTopImage->Picture->Bitmap->Height = MaxImageHeight;

      TabletBottomImage->Picture->Bitmap->Width = MaxImageWidth;
      TabletBottomImage->Picture->Bitmap->Height = MaxImageHeight;

      // For SELMA200, Rev by moon. (20180219) Camera Index
      if (!ExtractProductImage(tabletName, TabletTopImage->Picture->Bitmap, 1, SD1_2D_FRONT_FACE_CAMERA_INDEX))
      {
        TabletTopImage->Canvas->Brush->Color = clBlack;
        TabletTopImage->Canvas->FillRect(Rect(0, 0, MaxImageWidth, MaxImageHeight));
      }
      TabletTopImage->Repaint();
      if (!ExtractProductImage(tabletName, TabletBottomImage->Picture->Bitmap, 1, SD2_2D_FRONT_FACE_CAMERA_INDEX))
      {
        TabletBottomImage->Canvas->Brush->Color = clBlack;
        TabletBottomImage->Canvas->FillRect(Rect(0, 0, MaxImageWidth, MaxImageHeight));
      }
      TabletBottomImage->Repaint();
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByNamePanelClick(TObject *Sender)
{
	if (SortBy == SORT_BY_NAME)
	{
		if (SortAscendingOrder)
		{
			SortAscendingOrder = false;
			SortByName_Descending();
			SortByNamePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_09;
		}
		else
		{
			SortAscendingOrder = true;
			SortByName_Ascending();
			SortByNamePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_08;
		}
	}
	else
	{
		ClearSortingComponent();
		SortByNamePanel->Color = clBlue;
		SortByNamePanel->Font->Color = clWhite;
		SortByNamePanel->Font->Style = SortByNamePanel->Font->Style << fsBold;
		SortAscendingOrder = true;
		SortBy = SORT_BY_NAME;
		SortByName_Ascending();
		SortByNamePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_08;
	}
	ArrangeProductList();
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::ClearSortingComponent(void)
{
	SortByNamePanel->Color = clWhite;
	SortByNamePanel->Font->Color = clBlack;
	SortByNamePanel->Font->Style = SortByNamePanel->Font->Style >> fsBold;
	SortByNamePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_07;
	SortByKindPanel->Color = clWhite;
	SortByKindPanel->Font->Color = clBlack;
	SortByKindPanel->Font->Style = SortByKindPanel->Font->Style >> fsBold;
	SortByKindPanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_10;
	SortByShapePanel->Color = clWhite;
	SortByShapePanel->Font->Color = clBlack;
	SortByShapePanel->Font->Style = SortByShapePanel->Font->Style >> fsBold;
	SortByShapePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_04;
	SortBySizePanel->Color = clWhite;
	SortBySizePanel->Font->Color = clBlack;
	SortBySizePanel->Font->Style = SortBySizePanel->Font->Style >> fsBold;
	SortBySizePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_13;
	SortByInspTimePanel->Color = clWhite;
	SortByInspTimePanel->Font->Color = clBlack;
	SortByInspTimePanel->Font->Style = SortByInspTimePanel->Font->Style >> fsBold;
	SortByInspTimePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_01;
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByName_Ascending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->Name > (it2 + 1)->Name)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByName_Descending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->Name < (it2 + 1)->Name)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByKind_Ascending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletKind > (it2 + 1)->TabletKind)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByKind_Descending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletKind < (it2 + 1)->TabletKind)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByShape_Ascending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletShape > (it2 + 1)->TabletShape)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByShape_Descending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletShape < (it2 + 1)->TabletShape)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortBySize_Ascending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletSize > (it2 + 1)->TabletSize)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortBySize_Descending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->TabletSize < (it2 + 1)->TabletSize)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByInspTime_Ascending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->LastInspectionTime > (it2 + 1)->LastInspectionTime)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByInspTime_Descending(void)
{
	if (TabletList.size() < 2) return;
	vector<TTabletListUnit>::iterator it1, it2;
	for (it1 = TabletList.end() - 1; it1 >= TabletList.begin(); it1--)
	{
		for (it2 = TabletList.begin(); it2 < it1; it2++)
		{
			if (it2->LastInspectionTime < (it2 + 1)->LastInspectionTime)
			{
				swap(*it2, *(it2 + 1));
			}
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TProductSearchForm::SortByKindPanelClick(TObject *Sender)
{
	if (SortBy == SORT_BY_KIND)
	{
		if (SortAscendingOrder)
		{
			SortAscendingOrder = false;
			SortByKind_Descending();
			SortByKindPanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_12;
		}
		else
		{
			SortAscendingOrder = true;
			SortByKind_Ascending();
			SortByKindPanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_11;
		}
	}
	else
	{
		ClearSortingComponent();
		SortByKindPanel->Color = clBlue;
		SortByKindPanel->Font->Color = clWhite;
		SortByKindPanel->Font->Style = SortByKindPanel->Font->Style << fsBold;
		SortAscendingOrder = true;
		SortBy = SORT_BY_KIND;
		SortByKind_Ascending();
		SortByKindPanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_11;
	}
	ArrangeProductList();
}
//---------------------------------------------------------------------------

void __fastcall TProductSearchForm::SortByShapePanelClick(TObject *Sender)
{
	if (SortBy == SORT_BY_SHAPE)
	{
		if (SortAscendingOrder)
		{
			SortAscendingOrder = false;
			SortByShape_Descending();
			SortByShapePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_06;
		}
		else
		{
			SortAscendingOrder = true;
			SortByShape_Ascending();
			SortByShapePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_05;
		}
	}
	else
	{
		ClearSortingComponent();
		SortByShapePanel->Color = clBlue;
		SortByShapePanel->Font->Color = clWhite;
		SortByShapePanel->Font->Style = SortByShapePanel->Font->Style << fsBold;
		SortAscendingOrder = true;
		SortBy = SORT_BY_SHAPE;
		SortByShape_Ascending();
		SortByShapePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_05;
	}
	ArrangeProductList();
}
//---------------------------------------------------------------------------

void __fastcall TProductSearchForm::SortBySizePanelClick(TObject *Sender)
{
	if (SortBy == SORT_BY_SIZE)
	{
		if (SortAscendingOrder)
		{
			SortAscendingOrder = false;
			SortBySize_Descending();
			SortBySizePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_15;
		}
		else
		{
			SortAscendingOrder = true;
			SortBySize_Ascending();
			SortBySizePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_14;
		}
	}
	else
	{
		ClearSortingComponent();
		SortBySizePanel->Color = clBlue;
		SortBySizePanel->Font->Color = clWhite;
		SortBySizePanel->Font->Style = SortBySizePanel->Font->Style << fsBold;
		SortAscendingOrder = true;
		SortBy = SORT_BY_SIZE;
		SortBySize_Ascending();
		SortBySizePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_14;
	}
	ArrangeProductList();
}
//---------------------------------------------------------------------------


void __fastcall TProductSearchForm::TabletNameEditClick(TObject *Sender)
{
	TTntEdit *theEdit = (TTntEdit *)Sender;
	KeyboardForm->Text = theEdit->Text;
	if (KeyboardForm->ShowKeyboard() == mrOk)
	{
		theEdit->Text = KeyboardForm->Text;
	}

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

void __fastcall TProductSearchForm::SearchButtonClick(TObject *Sender)
{
	Search(TabletNameEdit->Text);
}
//---------------------------------------------------------------------------


void __fastcall TProductSearchForm::SortByInspTimePanelClick(
	TObject *Sender)
{
	if (SortBy == SORT_BY_INSP_TIME)
	{
		if (SortAscendingOrder)
		{
			SortAscendingOrder = false;
			SortByInspTime_Descending();
			SortByInspTimePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_03;
		}
		else
		{
			SortAscendingOrder = true;
			SortByInspTime_Ascending();
			SortByInspTimePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_02;
		}
	}
	else
	{
		ClearSortingComponent();
		SortByInspTimePanel->Color = clBlue;
		SortByInspTimePanel->Font->Color = clWhite;
		SortByInspTimePanel->Font->Style = SortBySizePanel->Font->Style << fsBold;
		SortAscendingOrder = false;
		SortBy = SORT_BY_INSP_TIME;
		SortByInspTime_Descending();
		SortByInspTimePanel->Caption = PRODUCTSEARCHFORM_PANEL_CAPTION_02;
	}
	ArrangeProductList();
}
//---------------------------------------------------------------------------

void __fastcall TProductSearchForm::DiscReSearchButtonClick(
	TObject *Sender)
{
	DiscSearch();
	Search("");
}
//---------------------------------------------------------------------------

void __fastcall UpdateLookupTable(WideString productCode)
{
	TProductData tempProductData;
	WideString productFileName = ProgramPath.Product + "\\" + productCode + "\\" + productCode + ".dat";
	ReadProductData(productFileName, tempProductData, MachineParams, MachineSetupData);

	TTabletListUnit aListUnit;
	aListUnit.Name = tempProductData.ProductName;
	aListUnit.TabletKind = tempProductData.TabletType;
	aListUnit.TabletShape = tempProductData.TabletShape;
	aListUnit.TabletSize = tempProductData.TabletLength;
	aListUnit.LastInspectionTime = tempProductData.LastInspectionTime.Val;

	WideString tableFileName = ProgramPath.Product + "\\LookupTable.dat";
	TIniFile *iniFile = new TIniFile(tableFileName);
	if (iniFile)
	{
		iniFile->WriteString(aListUnit.Name, "Product Name", aListUnit.Name);
		iniFile->WriteInteger(aListUnit.Name, "Tablet Kind", aListUnit.TabletKind);
		iniFile->WriteInteger(aListUnit.Name, "Tablet Shape", aListUnit.TabletShape);
		iniFile->WriteFloat(aListUnit.Name, "Tablet Size", aListUnit.TabletSize);
		iniFile->WriteFloat(aListUnit.Name, "Last Inspection Time", aListUnit.LastInspectionTime);
		delete iniFile;
	}
	else
	{
		ShowMessageFA(PRODUCTSEARCHFORM_MSG_01);
	}
}
//---------------------------------------------------------------------------
void __fastcall DeleteFromLookupTable(WideString productName)
{
	AnsiString tableFileName = ProgramPath.Product + "\\LookupTable.dat";
	TIniFile *iniFile = new TIniFile(tableFileName);
	if (iniFile)
	{
		iniFile->EraseSection(productName);
		delete iniFile;
	}
	else
	{
		ShowMessageFA(PRODUCTSEARCHFORM_MSG_01);
	}
}
//---------------------------------------------------------------------------


void __fastcall TProductSearchForm::TntFormActivate(TObject *Sender)
{
  SetScreenPosition(this);  
}
//---------------------------------------------------------------------------

