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

#include "DiskSpaceManager.h"
#include "Common_PC.h"
#include "Environment.h"

#define MAX_ERROR_LOG_COUNT				1000

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

#pragma package(smart_init)

bool IsOlderFile(TFileTimeUnit lhs, TFileTimeUnit rhs)
{
	return (lhs.FileTime < rhs.FileTime);
}

bool IsOlder(TDefectLotInfo lhs, TDefectLotInfo rhs)
{
	return (lhs.Time < rhs.Time);
}
//---------------------------------------------------------------------------
__fastcall TDefectLotInfo::TDefectLotInfo(AnsiString lotName, double time)
{
	LotName = lotName;
	Compressed = false;
	Time.Val = time;
}
//---------------------------------------------------------------------------
__fastcall TDefectProductInfo::TDefectProductInfo(AnsiString productName, AnsiString rootPath, AnsiString productDataPath)
{
	Analyzed = false;
	FReduced = false;
	ProductName = productName;
	ProductPath = rootPath + "\\" + productName;
	ResultDir = productDataPath + "\\Result";
	ITReduceLot = NULL;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TDefectProductInfo::GetCurrentReducingLotName(void)
{
	if (ITReduceLot == NULL || ITReduceLot == LotList.end())
	{
		return "";
	}
	else
	{
		return ITReduceLot->LotName;
	}
}
//---------------------------------------------------------------------------
void __fastcall TDefectProductInfo::Analyze(void)
{
	LotList.clear();
	TSearchRec sr;
	int iAttributes = faAnyFile;
	if (FindFirst(ProductPath + "\\*.*", iAttributes, sr) == 0)
	{
		do
		{
			if (sr.Name == "." || sr.Name == "..") continue;
			if ((sr.Attr & faDirectory))
			{
				// get inspection time
				double inspectionEndTime;
				AnsiString inspectionReportFileName = ResultDir + "\\" + sr.Name + ".dat";
				if (FileExists(inspectionReportFileName))
				{
          NFA_INSPECTION_REPORT_STRUCT Report;
          bool Result = Read_InspectionReportData(inspectionReportFileName,Report);

          if(Result)
          {
            inspectionEndTime = Report.Data.InspectionEndTime;
          }
          else
          {
            inspectionEndTime = FileDateToDateTime(sr.Time).Val;
          }
				}
				else
				{
					inspectionEndTime = FileDateToDateTime(sr.Time).Val;
				}

				LotList.push_back(TDefectLotInfo(sr.Name, inspectionEndTime));
			}
		} while (FindNext(sr) == 0);
		FindClose(sr);
	}
	// sort lot list
	LotList.sort(IsOlder);
	Analyzed = true;

	ReduceBegin();
}
//---------------------------------------------------------------------------
void __fastcall TDefectProductInfo::ReduceBegin(void)
{
	if (LotList.size() == 0)
	{
		ITReduceLot = NULL;
	}
	else
	{
		ITReduceLot = LotList.begin();
	}
	FReduced = false;
}
//---------------------------------------------------------------------------
void __fastcall TDefectProductInfo::ReduceOneLot(void)
{
	if (ITReduceLot == NULL || ITReduceLot == LotList.end())
	{
		FReduced = true;
	}
	else
	{
		// compress current lot
		// check time
		int primeLotCount;
		int maxDefectCount;
		int currentLotPosition = 0;
		list<TDefectLotInfo>::iterator it;
		for (it = LotList.begin(); it != LotList.end(); it++, currentLotPosition++)
		{
			if (it == ITReduceLot) break;
		}
		if (ITReduceLot->Time < ReduceBaseTime[2])
		{
			int primeLotCount = PrimeLotCount[2];
			if (currentLotPosition <= primeLotCount)
			{
				maxDefectCount = PrimeLotMaxDefectCount[2];
			}
			else
			{
				maxDefectCount = TrivialLotMaxDefectCount[2];
			}
		}
		else if (ITReduceLot->Time < ReduceBaseTime[1])
		{
			int primeLotCount = PrimeLotCount[1];
			if (currentLotPosition <= primeLotCount)
			{
				maxDefectCount = PrimeLotMaxDefectCount[1];
			}
			else
			{
				maxDefectCount = TrivialLotMaxDefectCount[1];
			}
		}
		else if (Now().Val - 1 > ITReduceLot->Time)	// 최소 하루 전
		{
			int primeLotCount = PrimeLotCount[0];
			if (currentLotPosition <= primeLotCount)
			{
				maxDefectCount = PrimeLotMaxDefectCount[0];
			}
			else
			{
				maxDefectCount = TrivialLotMaxDefectCount[0];
			}
		}
		else
		{
			maxDefectCount = -1;
		}

		if (maxDefectCount == -1)	// don't delete anything
		{
			ITReduceLot++;
		}
		else if (maxDefectCount == 0)	// delete everything
		{
			AnsiString lotPath = ProductPath + "\\" + ITReduceLot->LotName;
			TSearchRec sr;
			int iAttributes = faAnyFile;
			if (FindFirst(lotPath + "\\*.*", iAttributes, sr) == 0)
			{
				do
				{
					if (sr.Name == "." || sr.Name == "..") continue;
					DeleteFile(lotPath + "\\" + sr.Name);
				} while (FindNext(sr) == 0);
				FindClose(sr);
			}
			list<TDefectLotInfo>::iterator itRemove = ITReduceLot;
			ITReduceLot++;
			RemoveDir(lotPath);
			LotList.erase(itRemove);
		}
		else
		{
			// count files
			AnsiString lotPath = ProductPath + "\\" + ITReduceLot->LotName;
			TIniFile *iniFile = new TIniFile(lotPath + "\\DBInfor.ini");
			int fileCount = 0;

			if (iniFile)
			{
				fileCount = iniFile->ReadInteger("Information", "Data Count", -1);
				delete iniFile;
			}
			else
			{
				fileCount = -1;
			}

			if (fileCount == -1)
			{
				fileCount = 0;
				int imageIndex = 0;
				while (true)
				{
					AnsiString containerFileName = GetDefectDataContainerFileName(imageIndex, ProductName, ITReduceLot->LotName);
					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;
					}
				}

				TIniFile *iniFile = new TIniFile(lotPath + "\\DBInfor.ini");

				if (iniFile)
				{
					iniFile->WriteInteger("Information", "Data Count", fileCount);
					delete iniFile;
				}
			}

			if (fileCount == 0)
			{
				list<TDefectLotInfo>::iterator itRemove = ITReduceLot;
				ITReduceLot++;
				RemoveDir(lotPath);
				LotList.erase(itRemove);
			}
			else
			{
				if (fileCount < maxDefectCount)
				{
					// nothing to delete
				}
				else
				{
				/*
					double currentMaintainNumber = fileCount / (double)(maxDefectCount * 2);
					double increaseFactor = fileCount / (double)(maxDefectCount);
					int nextMaintainNumber = (int)currentMaintainNumber;
					int newIndex = 0;
					for (int fileIndex = 0; fileIndex < fileCount; fileIndex++)
					{
						AnsiString dataFileName = lotPath + "\\Data" + IntToStr(fileIndex + 1) + ".dat";
						AnsiString imageBMPFileName = lotPath + "\\Image" + IntToStr(fileIndex + 1) + ".bmp";
						AnsiString imageJPGFileName = lotPath + "\\Image" + IntToStr(fileIndex + 1) + ".jpg";
						if (fileIndex == nextMaintainNumber && newIndex < maxDefectCount)
						{
							AnsiString newDataFileName = lotPath + "\\Data" + IntToStr(newIndex + 1) + ".dat";
							AnsiString newImageBMPFileName = lotPath + "\\Image" + IntToStr(newIndex + 1) + ".bmp";
							AnsiString newImageJPGFileName = lotPath + "\\Image" + IntToStr(newIndex + 1) + ".jpg";
							if (FileExists(dataFileName) && !FileExists(newDataFileName))
							{
								RenameFile(dataFileName, newDataFileName);
							}
							if (FileExists(imageBMPFileName) && !FileExists(newImageBMPFileName))
							{
								RenameFile(imageBMPFileName, newImageBMPFileName);
							}
							if (FileExists(imageJPGFileName) && !FileExists(newImageJPGFileName))
							{
								RenameFile(imageJPGFileName, newImageJPGFileName);
							}
							newIndex++;
							currentMaintainNumber += increaseFactor;
							nextMaintainNumber = (int)currentMaintainNumber;
						}
						else
						{
							if (FileExists(dataFileName)) DeleteFile(dataFileName);
							if (FileExists(imageBMPFileName)) DeleteFile(imageBMPFileName);
							if (FileExists(imageJPGFileName)) DeleteFile(imageJPGFileName);
						}
					}
					int newDataCount = newIndex;
				*/

					double currentMaintainNumber = fileCount / (double)(maxDefectCount * 2);
					double increaseFactor = fileCount / (double)(maxDefectCount);
					int nextMaintainNumber = (int)currentMaintainNumber;
					int newIndex = 0;

					int removeFileIndex = fileCount - 1;
					while (true)
					{
						if (removeFileIndex < maxDefectCount) break;
						AnsiString dataContainerFileName = GetDefectDataContainerFileName(removeFileIndex, ProductName, ITReduceLot->LotName);
						AnsiString imageContainerFileName = GetDefectImageContainerFileName(removeFileIndex, ProductName, ITReduceLot->LotName);
						if (!FileExists(dataContainerFileName) && !FileExists(imageContainerFileName))
						{
							removeFileIndex = (removeFileIndex / DEFECT_DATA_CONTAINER_SIZE) * DEFECT_DATA_CONTAINER_SIZE - 1;
						}
						else
						{
							if ((removeFileIndex / DEFECT_DATA_CONTAINER_SIZE) * DEFECT_DATA_CONTAINER_SIZE >= maxDefectCount)
							{
								// delete file
								if (FileExists(dataContainerFileName))
								{
									DeleteFile(dataContainerFileName);
								}
								if (FileExists(imageContainerFileName))
								{
									DeleteFile(imageContainerFileName);
								}
								removeFileIndex = (removeFileIndex / DEFECT_DATA_CONTAINER_SIZE) * DEFECT_DATA_CONTAINER_SIZE - 1;
							}
							else
							{
								if (FileExists(dataContainerFileName))
								{
									TFileContainer fileContainer;
									fileContainer.Open(dataContainerFileName);
									fileContainer.RemoveFromLast(removeFileIndex + 1 - maxDefectCount);
								}
								if (FileExists(imageContainerFileName))
								{
									TFileContainer fileContainer;
									fileContainer.Open(imageContainerFileName);
									fileContainer.RemoveFromLast(removeFileIndex + 1 - maxDefectCount);
								}
								removeFileIndex = maxDefectCount - 1;
							}
						}
					}

					int newDataCount = removeFileIndex + 1;

					AnsiString lotPath = ProductPath + "\\" + ITReduceLot->LotName;
					TIniFile *iniFile = new TIniFile(lotPath + "\\DBInfor.ini");

					if (iniFile)
					{
						iniFile->WriteInteger("Information", "Data Count", newDataCount);
						delete iniFile;
					}
				}
				ITReduceLot++;
			}
		}

	}
}
//---------------------------------------------------------------------------
double __fastcall TDefectProductInfo::GetOldestLotTime(void)
{
	if (LotList.size() == 0)
	{
		return Now().Val;
	}
	else
	{
		return LotList.front().Time.Val;
	}
}
//---------------------------------------------------------------------------
AnsiString __fastcall TDefectProductInfo::GetOldestLotName(void)
{
	if (LotList.size() == 0)
	{
		return "";
	}
	else
	{
		return LotList.front().LotName;
	}
}
//---------------------------------------------------------------------------
void __fastcall TDefectProductInfo::RemoveOldestLot(void)
{
	if (LotList.size() > 0)
	{
		TDefectLotInfo deleteLot = LotList.front();

		AnsiString lotPath = ProductPath + "\\" + deleteLot.LotName;
		TSearchRec sr;
		int iAttributes = faAnyFile;
		if (FindFirst(lotPath + "\\*.*", iAttributes, sr) == 0)
		{
			do
			{
				if (sr.Name == "." || sr.Name == "..") continue;
				DeleteFile(lotPath + "\\" + sr.Name);
			} while (FindNext(sr) == 0);
			FindClose(sr);
		}
		RemoveDir(lotPath);
		LotList.pop_front();
	}
}
//---------------------------------------------------------------------------
__fastcall TDSMThread::TDSMThread(bool CreateSuspended)
	: TThread(CreateSuspended)
{
	FDrive = 1;		// 'A' drive
//	DSMOption.CompressOldData = false;
	DSMOption.ReduceOldData = false;
//	DSMOption.BMPMaintainTime = TDateTime(30);	// 30 days
	DSMOption.ReduceTime[0] = TDateTime(0);	// 0 days
	DSMOption.ReduceTime[1] = TDateTime(100);	// 100 days
	DSMOption.ReduceTime[2] = TDateTime(365); // 365 days
	DSMOption.PrimeLotCount[0] = 2;
	DSMOption.PrimeLotCount[1] = 2;
	DSMOption.PrimeLotCount[2] = 2;
	DSMOption.PrimeLotMaxDefectCount[0] = -1;
	DSMOption.PrimeLotMaxDefectCount[1] = 1000;
	DSMOption.PrimeLotMaxDefectCount[2] = 100;
	DSMOption.TrivialLotMaxDefectCount[0] = 1000;
	DSMOption.TrivialLotMaxDefectCount[1] = 0;
	DSMOption.TrivialLotMaxDefectCount[2] = 0;
	DSMOption.MinDiskSpaceRatio = 10;
	DSMOption.ForcedCompressTime = TDateTime(1);	// 1 day
	DSMState = DSM_STATE_IDLE;

	FLogPath = "";	
}
//---------------------------------------------------------------------------
__fastcall TDSMThread::~TDSMThread()
{

}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::InitializeProcess(void)
{
	MakeProductFolderList();
	RDState = RD_STATE_BEGIN;
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::Execute()
{
	list<TDefectProductInfo>::iterator itDefectProductInfo;
	list<TDefectProductInfo>::iterator itForcedCompress;
	bool diskSizeChanged = false;
	bool freeSpaceLeak = false;
	bool logFileRetrenched = false;
  bool EjectLogFileRetrenched = false;

	InitializeProcess();

	if (ProductList.size() == 0)
	{
		itDefectProductInfo = NULL;
		itForcedCompress = NULL;
	}
	else
	{
		itDefectProductInfo = ProductList.begin();
		itForcedCompress = ProductList.begin();
	}
	

	while (!Terminated)
	{
		if (DSMAlwaysOn || (DSMStartTime < Now().CurrentTime() && Now().CurrentTime() < DSMEndTime))
		{
			// check disk free space
			__int64 freeSpace = DiskFree(FDrive);
			FreeDiskSpace = freeSpace / 1024 / 1024;
			if (itDefectProductInfo == NULL && (FreeDiskSpace * 100 / TotalDiskSpace < DSMOption.MinDiskSpaceRatio))
			{
				freeSpaceLeak = true;
			}
			else
			{
				freeSpaceLeak = false;
			}

			if (itDefectProductInfo != NULL)
			{
				// process one product
				if (!itDefectProductInfo->Analyzed)
				{
					// check size
					ProcessingProduct = itDefectProductInfo->ProductName;
					DSMState = DSM_STATE_CALC_PRODUCT_SIZE;
					itDefectProductInfo->Analyze();
					itDefectProductInfo->ReduceBaseTime[0] = Now() - DSMOption.ReduceTime[0];
					itDefectProductInfo->ReduceBaseTime[1] = Now() - DSMOption.ReduceTime[1];
					itDefectProductInfo->ReduceBaseTime[2] = Now() - DSMOption.ReduceTime[2];
					itDefectProductInfo->PrimeLotCount[0] = DSMOption.PrimeLotCount[0];
					itDefectProductInfo->PrimeLotCount[1] = DSMOption.PrimeLotCount[1];
					itDefectProductInfo->PrimeLotCount[2] = DSMOption.PrimeLotCount[2];
					itDefectProductInfo->PrimeLotMaxDefectCount[0] = DSMOption.PrimeLotMaxDefectCount[0];
					itDefectProductInfo->PrimeLotMaxDefectCount[1] = DSMOption.PrimeLotMaxDefectCount[1];
					itDefectProductInfo->PrimeLotMaxDefectCount[2] = DSMOption.PrimeLotMaxDefectCount[2];
					itDefectProductInfo->TrivialLotMaxDefectCount[0] = DSMOption.TrivialLotMaxDefectCount[0];
					itDefectProductInfo->TrivialLotMaxDefectCount[1] = DSMOption.TrivialLotMaxDefectCount[1];
					itDefectProductInfo->TrivialLotMaxDefectCount[2] = DSMOption.TrivialLotMaxDefectCount[2];
				}

				if (DSMOption.ReduceOldData && !itDefectProductInfo->Reduced)
				{
					if (RDState == RD_STATE_BEGIN)
					{
						itDefectProductInfo->ReduceBegin();
						RDState = RD_STATE_PROCESS;
					}
					DSMState = DSM_STATE_REDUCE_LOT;
					ProcessingProduct = itDefectProductInfo->ProductName;
					ProcessingLot = itDefectProductInfo->CurrentReducingLotName;
					itDefectProductInfo->ReduceOneLot();
					diskSizeChanged = true;
				}
				else		// compressed and reduced
				{
					itDefectProductInfo++;
					if (itDefectProductInfo == ProductList.end())
					{
						if (diskSizeChanged)	// 현재로서는 의미없음
						{
							itDefectProductInfo = ProductList.begin();
							diskSizeChanged = false;
						}
						else
						{
							itDefectProductInfo = NULL;
						}
					}
					RDState = RD_STATE_BEGIN;
				}
			}
			else if (freeSpaceLeak)
			{
				list<TDefectProductInfo>::iterator it, victim;
				double victimTime;
				if (ProductList.size() == 0)
				{
					freeSpaceLeak = false;
				}
				else
				{
					// forced remove
					victim = ProductList.begin();
					victimTime = victim->GetOldestLotTime();
					for (it = ProductList.begin(); it != ProductList.end(); it++)	// search victim
					{
						if (it->GetOldestLotTime() < victimTime)
						{
							victim = it;
							victimTime = victim->GetOldestLotTime();
						}
					}
					DSMState = DSM_STATE_FORCED_REMOVE;
					ProcessingProduct = victim->ProductName;
					ProcessingLot = victim->GetOldestLotName();
					// remove victim
					victim->RemoveOldestLot();
				}
			}
			else if (!logFileRetrenched)
			{
				RetrenchLogFiles();
				logFileRetrenched = true;
			}
      else if(!EjectLogFileRetrenched)
      {
        RetrenchEjectLogFiles();
        EjectLogFileRetrenched = true;
      }
			DSMState = DSM_STATE_IDLE;
//		FreeSpaceRatio = (double) FreeDiskSpace / TotalDiskSpace;
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::RetrenchLogFiles(void)
{
	AnsiString errLogFilePath = FLogPath + "\\Error Log";
	// count files
	TSearchRec sr;
	list<TFileTimeUnit> fileTimeList;

	fileTimeList.clear();
	int iAttributes = faAnyFile;
	int fileCount = 0;
	if (FindFirst(errLogFilePath + "\\*.log", iAttributes, sr) == 0)
	{
		do
		{
			TFileTimeUnit aFileTimeUnit;
			aFileTimeUnit.FileName = errLogFilePath + "\\" + sr.Name;
			aFileTimeUnit.FileTime = FileDateToDateTime(sr.Time);
			fileTimeList.push_back(aFileTimeUnit);
			fileCount++;
		} while (FindNext(sr) == 0);
		FindClose(sr);
	}

	fileTimeList.sort(IsOlderFile);
	while (fileCount > MAX_ERROR_LOG_COUNT)
	{
		TFileTimeUnit aFileTimeUnit = fileTimeList.front();
		fileTimeList.pop_front();
		if (FileExists(aFileTimeUnit.FileName))
		{
			DeleteFile(aFileTimeUnit.FileName);
		}
	}
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::RetrenchEjectLogFiles(void)
{
  // Check Product Folder
	AnsiString errLogFilePath = ProgramPath.Root + "\\HCB Monitoring";

	TSearchRec sr;
  list<AnsiString> ProductList;
  list<AnsiString> LotList;
  list<TFileTimeUnit> fileTimeList;

  if (FindFirst(errLogFilePath+"\\*.*", faAnyFile, sr) == 0)
	{
		do
		{
      if(sr.Name == "." || sr.Name == "..") continue;
      else if(sr.Attr == faDirectory)
      {
        ProductList.push_back(sr.Name);
      }
		} while (FindNext(sr) == 0);
		FindClose(sr);
	}

  // Check Lot Folder
  if(ProductList.size() < 1)
  {
    return;
  }
  else
  {
    list<AnsiString>::iterator iter;
    for(iter = ProductList.begin(); iter != ProductList.end(); ++iter )
    {
      if (FindFirst(errLogFilePath + "\\"+*iter+"\\*.*", faAnyFile, sr) == 0)
      {
        do
        {
          if(sr.Name == "." || sr.Name == "..") continue;
          else if(sr.Attr == faDirectory)
          {
            LotList.push_back(errLogFilePath + "\\"+*iter+"\\"+sr.Name);
          }
        } while (FindNext(sr) == 0);
        FindClose(sr);
      }
    }

  }

  // Check Log Folder
  if(LotList.size() < 1)
  {
    return;
  }
  else
  {
    list<AnsiString>::iterator iter;
    for(iter = LotList.begin(); iter != LotList.end(); ++iter )
    {
      if (FindFirst(*iter+"\\*.*", faAnyFile, sr) == 0)
      {
        do
        {
          if(sr.Name == "." || sr.Name == "..") continue;
          else if(sr.Attr == faDirectory)
          {
            TFileTimeUnit aFileTimeUnit;
            aFileTimeUnit.FileName = *iter + "\\"+ sr.Name;
            aFileTimeUnit.FileTime = FileDateToDateTime(sr.Time);
            fileTimeList.push_back(aFileTimeUnit);
          }
        } while (FindNext(sr) == 0);
        FindClose(sr);
      }
    }
  }

  if(fileTimeList.size() < 1)
  {
    return;
  }
  else
  {
    try
    {
      list<TFileTimeUnit>::iterator iter;
      for(iter = fileTimeList.begin(); iter != fileTimeList.end(); ++iter )
      {
        double LimitDay = Now().Val - 60;

        if( (*iter).FileTime.Val < LimitDay )
        {
          RemoveWholeDir( (*iter).FileName);
        }
      }
    }
    catch(...)
    {
    }
  }
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::RemoveWholeDir(AnsiString folderName)
{
	TSearchRec sr;
	int iAttributes = faAnyFile;
	if (FindFirst(folderName + "\\*.*", iAttributes, sr) == 0)
	{
		do
		{
			if (sr.Name == "." || sr.Name == "..") continue;
			if (sr.Attr & faDirectory)
			{
				RemoveWholeDir(folderName + "\\" + sr.Name);
			}
			else
			{
					DeleteFile(folderName + "\\" + sr.Name);
			}

		} while (FindNext(sr) == 0);
		FindClose(sr);

		RemoveDir(folderName);

	}
}
//--------------------------------------------------------------------------
void __fastcall TDSMThread::MakeProductFolderList(void)
{
	ProductList.clear();

	TSearchRec sr;
	int iAttributes = faAnyFile;
	if (FindFirst(FDefectPath + "\\*.*", iAttributes, sr) == 0)
	{
		do
		{
			if (sr.Name == "." || sr.Name == "..") continue;
			if ((sr.Attr & faDirectory))
			{
				ProductList.push_back(TDefectProductInfo(sr.Name, FDefectPath, FProductDataRoot + "\\" + sr.Name));
			}
		} while (FindNext(sr) == 0);
		FindClose(sr);
	}
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::SetDefectPath(AnsiString folder)
{
	// 생성 후 thread가 동작하기 전에 바로 설정해 주어야 한다.
	FDefectPath = folder;
	AnsiString driveStr = ExtractFileDrive(FDefectPath);
	FDrive = driveStr[1] - 'A' + 1;
	__int64 diskSpace = DiskSize(FDrive);
	TotalDiskSpace = diskSpace / 1024 / 1024;
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::SetLogPath(AnsiString folder)
{
	// 생성 후 thread가 동작하기 전에 바로 설정해 주어야 한다.
	FLogPath = folder;
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::SetProductDataRoot(AnsiString folder)
{
	// 생성 후 thread가 동작하기 전에 바로 설정해 주어야 한다.
	FProductDataRoot = folder;
}
//---------------------------------------------------------------------------
void __fastcall TDSMThread::SetParams(
	double reduceTime0, double reduceTime1, double reduceTime2,
	int PrimeLotCount0, int PrimeLotCount1, int PrimeLotCount2,
	int primeLotMaxDefectCount0, int primeLotMaxDefectCount1, int primeLotMaxDefectCount2,
	int trivialLotMaxDefectCount0, int trivialLotMaxDefectCount1, int trivialLotMaxDefectCount2,
	int minDiskSpaceRatio, bool dsmAlwaysOn,bool mainformDiskSpaceEnabled, TDateTime dsmStartTime, TDateTime dsmEndTime)
{
	DSMOption.ReduceOldData = true;
	DSMOption.ReduceTime[0] = TDateTime(reduceTime0);
	DSMOption.ReduceTime[1] = TDateTime(reduceTime1);
	DSMOption.ReduceTime[2] = TDateTime(reduceTime2);
	DSMOption.PrimeLotCount[0] = PrimeLotCount0;
	DSMOption.PrimeLotCount[1] = PrimeLotCount1;
	DSMOption.PrimeLotCount[2] = PrimeLotCount2;
	DSMOption.PrimeLotMaxDefectCount[0] = primeLotMaxDefectCount0;
	DSMOption.PrimeLotMaxDefectCount[1] = primeLotMaxDefectCount1;
	DSMOption.PrimeLotMaxDefectCount[2] = primeLotMaxDefectCount2;
	DSMOption.TrivialLotMaxDefectCount[0] = trivialLotMaxDefectCount0;
	DSMOption.TrivialLotMaxDefectCount[1] = trivialLotMaxDefectCount1;
	DSMOption.TrivialLotMaxDefectCount[2] = trivialLotMaxDefectCount2;
	DSMOption.MinDiskSpaceRatio = minDiskSpaceRatio;
	DSMOption.ForcedCompressTime = TDateTime(1);	// 1 day
	DSMAlwaysOn = dsmAlwaysOn;
  MainformDiskSpaceEnabled = mainformDiskSpaceEnabled;
	DSMStartTime = dsmStartTime;
	DSMEndTime = dsmEndTime;
}
//---------------------------------------------------------------------------



