//---------------------------------------------------------------------------
// For SELMA200, 20180223, moon, 변경사항 없음
//---------------------------------------------------------------------------
#include <inifiles.hpp>
#pragma hdrstop

#include "AbstractDB.h"
#include "Environment.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

TDefectDataDB DefectDataDB;

//---------------------------------------------------------------------------
__fastcall TDefectDataDB::TDefectDataDB()
{
	FProductCode = "";
	FLotCode = "";
	DataList = new TList;
	DataValidList = new TList;
}
//---------------------------------------------------------------------------
__fastcall TDefectDataDB::~TDefectDataDB()
{
	ClearList();
	delete DataList;
	delete DataValidList;
}
//---------------------------------------------------------------------------
bool __fastcall TDefectDataDB::ConnectTable(WideString productCode, WideString lotCode,bool Inspectionstatus,bool ReadAllData)
{  /*
	if (FProductCode == productCode && FLotCode == lotCode)
	{
		return true;
	}
	else*/
	{
		AnsiString defectDir = GetDefectDataPath(productCode, lotCode);
		if (!DirectoryExists(defectDir))
		{
			ForceDirectories(defectDir);
		}
		TIniFile *iniFile = new TIniFile(defectDir + "\\DBInfor.ini");

		int dataCount;
		if (iniFile)
		{
			dataCount = iniFile->ReadInteger("Information", "Data Count", -1);
			delete iniFile;
		}
		else
		{
			return false;
		}

		if (dataCount == -1)
		{
			int fileCount = 0;
			int imageIndex = 0;
			while (true)
			{
				AnsiString containerFileName = GetDefectDataContainerFileName(imageIndex, productCode, lotCode);
				if (!FileExists(containerFileName)) break;
				TFileContainer fileContainer;
				fileContainer.Open(containerFileName);
				if (fileContainer.GetContainFileCount() < DEFECT_DATA_CONTAINER_SIZE)
				{
					fileCount += fileContainer.GetContainFileCount();
					break;
				}
				else
				{
					imageIndex += DEFECT_DATA_CONTAINER_SIZE;
					fileCount += DEFECT_DATA_CONTAINER_SIZE;
				}
			}
			FDataCount = fileCount;

			iniFile = new TIniFile(defectDir + "\\DBInfor.ini");
			if (iniFile)
			{
				iniFile->WriteInteger("Information", "Data Count", FDataCount);
				delete iniFile;
			}
			else
			{
				return false;
			}
/*
			int fileCount = 0;
			if (DirectoryExists(defectDir))
			{
				TSearchRec sr;
				int iAttributes = faAnyFile & (~faDirectory);

				if (FindFirst(defectDir + "\\*.dat", iAttributes, sr) == 0)
				{
					do
					{
						fileCount++;
					} while (FindNext(sr) == 0);
					FindClose(sr);
				}
			}
			FDataCount = fileCount;

			iniFile = new TIniFile(defectDir + "\\DBInfor.ini");
			if (iniFile)
			{
				iniFile->WriteInteger("Information", "Data Count", FDataCount);
				delete iniFile;
			}
			else
			{
				return false;
			}
*/
		}
		else
		{
			FDataCount = dataCount;
		}

		FProductCode = productCode;
		FLotCode = lotCode;
    
		ClearList();
		LoadData(Inspectionstatus,ReadAllData);
	}

	return true;
}
//---------------------------------------------------------------------------
bool __fastcall TDefectDataDB::GetDefectData(TDefectData_PC *aDefectData, int defectDataIndex)
{
	/*if (defectDataIndex < 0 || defectDataIndex >= DataList->Count)
	{
		return false;
	}*/

  int ConvertDefDataIndex =  defectDataIndex - StandardFDataCount;

  if (defectDataIndex < 0  || ConvertDefDataIndex <= -1)// 카운트 제한 기능 수정으로 기존 기능은 사용불가
	{
		return false;
	}

	bool *dataValid = (bool *)DataValidList->Items[ConvertDefDataIndex];//defectDataIndex
	TDefectData_PC *theDefectData = (TDefectData_PC *) DataList->Items[ConvertDefDataIndex];
	if (!*dataValid)
	{
		if (ReadDefectData(theDefectData, defectDataIndex))
		{
			*dataValid = true;
		}
	}
	*aDefectData = *theDefectData;
	return true;
}
//---------------------------------------------------------------------------
bool __fastcall TDefectDataDB::ReadDefectData(TDefectData_PC *aDefectData, int defectDataIndex)
{
	bool returnValue = true;

	TFileContainer DefectDataContainer;
	AnsiString defectContainerFileName = GetDefectDataContainerFileName(defectDataIndex, FProductCode, FLotCode);
	DefectDataContainer.Open(defectContainerFileName, true, DEFECT_DATA_CONTAINER_SIZE);
	AnsiString dataName = "Data" + IntToStr(defectDataIndex + 1) + ".dat";

	if (DefectDataContainer.FileContains(dataName))
	{
		TDefectFileData defectFileData;
		if (DefectDataContainer.ExtractData(dataName, &defectFileData, sizeof(TDefectFileData)))
		{
			if (defectFileData.DefectDataHeader.Version == CURRENT_DEFECT_DATA_VERSION)
			{
				memcpy(aDefectData, &defectFileData.DefectData, sizeof(TDefectData_PC));
			}
			else
			{
				memset(aDefectData, 0, sizeof(TDefectData_PC));
				returnValue = false;
			}
		}
		else
		{
			memset(aDefectData, 0, sizeof(TDefectData_PC));
			returnValue = false;
		}
	}
	else
	{
		memset(aDefectData, 0, sizeof(TDefectData_PC));
		returnValue = false;
	}

/*
	AnsiString defectDir = GetDefectDataPath(FProductCode, FLotCode);
	AnsiString fileName = defectDir + "\\Data" + IntToStr(defectDataIndex + 1) + ".dat";
	if (FileExists(fileName))
	{
		TFileStream *fileStream = new TFileStream(fileName, fmOpenRead);
		if (fileStream)
		{
			TDefectDataHeader defectDataHeader;
			fileStream->Read(&defectDataHeader, sizeof(TDefectDataHeader));
			if (defectDataHeader.Version == CURRENT_DEFECT_DATA_VERSION)
			{
				fileStream->Read(aDefectData, sizeof(TDefectData_PC));
			}
			else
			{
				memset(aDefectData, 0, sizeof(TDefectData_PC));
				returnValue = false;
			}
			delete fileStream;
		}
		else
		{
			memset(aDefectData, 0, sizeof(TDefectData_PC));
			returnValue = false;
		}
	}
	else
	{
		memset(aDefectData, 0, sizeof(TDefectData_PC));
		returnValue = false;
	}
*/
	return returnValue;
}
//---------------------------------------------------------------------------
bool __fastcall TDefectDataDB::WriteDefectDataCount(void)
{
	AnsiString defectDir = GetDefectDataPath(FProductCode, FLotCode);
	TIniFile *iniFile = new TIniFile(defectDir + "\\DBInfor.ini");
	if (iniFile)
	{
		iniFile->WriteInteger("Information", "Data Count", FDataCount);
		delete iniFile;
	}
	else
	{
		return false;
	}
	return true;
}
//---------------------------------------------------------------------------
void __fastcall TDefectDataDB::ClearList(void)
{
	while (DataList->Count)
	{
		TDefectData_PC *aDefectData = (TDefectData_PC *) DataList->First();
		DataList->Remove(aDefectData);
		delete aDefectData;
	}

	while (DataValidList->Count)
	{
		bool *dataValid = (bool *) DataValidList->First();
		DataValidList->Remove(dataValid);
		delete dataValid;
	}
}
//---------------------------------------------------------------------------
void __fastcall TDefectDataDB::LoadData(bool Inspectionstatus,bool ReadAllData)
{
   int EndIndex = 0;
  
  if(Inspectionstatus)
    EndIndex = 101;
  else
  {
    if(ReadAllData)
    {
      EndIndex = FDataCount;
    }
    else
      EndIndex = 5001;
  }


	for (int defectDataIndex =  0; defectDataIndex < EndIndex; defectDataIndex++)
	{
		TDefectData_PC *aDefectData = new TDefectData_PC;
		DataList->Add(aDefectData);
		bool *dataValid = new bool;
		*dataValid = false;
		DataValidList->Add(dataValid);

		/*
		if (DefectDataDB.ReadDefectData(aDefectData, defectDataIndex))
		{
			DataList->Add(aDefectData);
		}
		else
		{
			memset(aDefectData, 0, sizeof(TDefectData_SPB));
			DataList->Add(aDefectData);
		}
		*/
	}
}
//---------------------------------------------------------------------------
int __fastcall TDefectDataDB::AddDefectData(TDefectData_PC *aDefectData)
{
	TFileContainer DefectDataContainer;
	AnsiString defectContainerFileName = GetDefectDataContainerFileName(FDataCount, FProductCode, FLotCode);
	DefectDataContainer.Open(defectContainerFileName, true, DEFECT_DATA_CONTAINER_SIZE);
	AnsiString dataName = "Data" + IntToStr(FDataCount + 1) + ".dat";

	TDefectFileData defectFileData;
	memset(&defectFileData.DefectDataHeader, 0, sizeof(TDefectDataHeader));
	defectFileData.DefectDataHeader.Version = CURRENT_DEFECT_DATA_VERSION;
	memcpy(&defectFileData.DefectData, aDefectData, sizeof(TDefectData_PC));
	DefectDataContainer.SaveData(dataName, ECM_NONE, &defectFileData, sizeof(TDefectFileData));
/*
	AnsiString saveDir = GetDefectDataPath(FProductCode, FLotCode);
	AnsiString saveDataFileName = saveDir + "\\Data" + IntToStr(FDataCount + 1) + ".dat";
	TFileStream *fileStream = new TFileStream(saveDataFileName, fmCreate);
	if (fileStream)
	{
		TDefectDataHeader defectDataHeader;
		memset(&defectDataHeader, 0, sizeof(TDefectDataHeader));
		defectDataHeader.Version = CURRENT_DEFECT_DATA_VERSION;
		fileStream->Write(&defectDataHeader, sizeof(TDefectDataHeader));
		fileStream->Write(aDefectData, sizeof(TDefectData_PC));
		delete fileStream;
	}
*/
/*
	TDefectData_PC *newDefectData = new TDefectData_PC;
	*newDefectData = *aDefectData;
	DataList->Add(newDefectData);
	bool *dataValid = new bool;
	DataValidList->Add(dataValid);
*/
	FDataCount++;
	WriteDefectDataCount();

    
	return FDataCount - 1;
}
//---------------------------------------------------------------------------
bool __fastcall TDefectDataDB::CleanDefectData(void)
{
/*
	AnsiString saveDir = GetDefectDataPath(FProductCode, FLotCode);
	for (int defectDataIndex = 0; defectDataIndex < FDataCount; defectDataIndex++)
	{
		AnsiString saveDataFileName = saveDir + "\\Data" + IntToStr(defectDataIndex + 1) + ".dat";
		if (FileExists(saveDataFileName))
		{
			DeleteFile(saveDataFileName.c_str());
		}
	}
*/
	for (int defectDataIndex = 0; defectDataIndex < FDataCount; defectDataIndex += DEFECT_DATA_CONTAINER_SIZE)
	{
		AnsiString defectContainerFileName = GetDefectDataContainerFileName(defectDataIndex, FProductCode, FLotCode);
		if (FileExists(defectContainerFileName))
		{
			DeleteFile(defectContainerFileName.c_str());
		}
	}

	ClearList();
	FDataCount = 0;
	WriteDefectDataCount();
	return true;
}
//---------------------------------------------------------------------------

