//---------------------------------------------------------------------------
#ifndef Common_PCH
#define Common_PCH

#include "common.h"
#include "processing.h"
#include <Classes.hpp>
#include <Controls.hpp>

#define PROGRAM_REGISTRY_KEY                "Software\\FAElectronics\\ELMA100"

//#define MOTOR_SPEED_STEP_COUNT					10
//#define MOTOR_SPEED_STEP_COUNT					3					
#define MOTOR_SPEED_STEP_COUNT_FOR_PRODUCT		3

#define MS_TABLET_TYPE_COUNT			3
#define MS_TABLET_SHAPE_COUNT			4
#define MS_MOTOR_SPEED_STEP_COUNT		3

#define TABLET_TYPE_COUNT				4

#define TABLET_TYPE_UNKNOWN				0
#define TABLET_TYPE_UNCOATED			1
#define TABLET_TYPE_FILM_COATED         2
#define TABLET_TYPE_SUGAR_COATED        3
#define TABLET_TYPE_MULTI_LAYERED       4
#define TABLET_TYPE_OTHER				0xFF

#define TABLET_SHAPE_COUNT				4

#define TABLET_SHAPE_UNKNOWN			0
#define TABLET_SHAPE_CIRCLE				1
#define TABLET_SHAPE_OBLONG         	2
#define TABLET_SHAPE_OVAL        		3
#define TABLET_SHAPE_HEXAGON        	4
#define TABLET_SHAPE_TRIANGLE        	5
#define TABLET_SHAPE_SQUARE        		6
#define TABLET_SHAPE_OCTAGON        	7
#define TABLET_SHAPE_ETC				10

#define ENGRAVE_TYPE_UNKNOWN			0
#define ENGRAVE_TYPE_RELIEF				1
#define ENGRAVE_TYPE_INTAGLIO			2
#define ENGRAVE_TYPE_PRINT				3
#define ENGRAVE_TYPE_EMPTY				4

#define ENGRAVE_POS_UNKNOWN				0
#define ENGRAVE_POS_ONESIDE				1
#define ENGRAVE_POS_SAME				2
#define ENGRAVE_POS_DIFF				3

#define PRINT_BRIGHTNESS_UNKNOWN		0
#define PRINT_BRIGHTNESS_LIGHT			1
#define PRINT_BRIGHTNESS_DARK			2

#define LARGE_TABLET_CIRCLE_THICK			5.0
#define LARGE_TABLET_CIRCLE_LENGTH     		10.0
#define LARGE_TABLET_OBLONG_LENGTH     		13.0

#define TABLET_PROCESSING_STEP_NONE								0
#define TABLET_PROCESSING_STEP_CALIBRATION_REQUIRED				1
#define TABLET_PROCESSING_STEP_EXTRACT_CHARACTER_REQUIRED		2
#define TABLET_PROCESSING_STEP_FIRST_STUDY_REQUIRED				3
#define TABLET_PROCESSING_STEP_STUDY_REQUIRED					4
#define TABLET_PROCESSING_STEP_STUDY_COMPLETE					5

//#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_1		((float)3000 / 500 * 3 / 10 * 102 * 3.141592)		// 초당 회전 거리 (mm/s)
//#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_2		((float)1500 / 500 * 3 / 10 * 202 * 3.141592)		// 초당 회전 거리 (mm/s)

//#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_1		((float)102 * 3.141592 * 2)		// 초당 회전 거리 (mm/s)
//#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_2		((float)202 * 3.141592)		// 초당 회전 거리 (mm/s)
#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_1		((float)302 * 3.141592)		// 초당 회전 거리 (mm/s)
#define MOTOR_SPEED_TO_LENGTH_CONSTANT_DISC_2		((float)302 * 3.141592)		// 초당 회전 거리 (mm/s)

//#define RANGER_3D_BASE_SHUTTER_SPEED		316	// 100 us	(101us)
//#define RANGER_3D_BASE_SHUTTER_SPEED				310
//#define RANGER_3D_BASE_SHUTTER_SPEED				311
//#define RANGER_3D_BASE_SHUTTER_SPEED				260
#define RANGER_3D_BASE_SHUTTER_SPEED				288

//#define MOTOA_BASE_SPEED_DISC1       32
//#define MOTOA_BASE_SPEED_DISC2       16
//#define MOTOA_BASE_SPEED_DISC3       32

#define SUCTION_DISK_100P_RPM			54.0

#define SERVO_MOTOR_SPEED_TO_RPM_PARAM1			(25000000.0 / 3000 * 60)
#define SERVO_MOTOR_SPEED_TO_RPM_PARAM2			(25000000.0 / 3000 * 60)
#define SERVO_MOTOR_SPEED_TO_RPM_PARAM3			(25000000.0 / 3000 * 60)
#define SERVO_MOTOR_SPEED_TO_RPM_PARAM4			(25000000.0 / 3000 / 21 * 5 * 60)

#define SUCTION_DISK_DIAMETER						303
#define SUCTION_DISK_DISTANCE_Y						265
#define SUCTION_DISK_DISTANCE_BASE_X				sqrt(SUCTION_DISK_DIAMETER * SUCTION_DISK_DIAMETER - SUCTION_DISK_DISTANCE_Y * SUCTION_DISK_DISTANCE_Y)


#define MAX_CPB_DEFECT_SERIES_COUNT		30
#define MAX_DEFECT_SERIES_COUNT			(MAX_CPB_DEFECT_SERIES_COUNT + 2)

#define BACKUP_PROCESS_SPEED_FAST		0	//default
#define BACKUP_PROCESS_SPEED_NORMAL	1

//---------------------------------------------------------------------------
typedef struct
{
    AnsiString Root;
    AnsiString Hex;
    AnsiString Env;
    AnsiString Image;
    AnsiString Product;
    AnsiString Log;
	AnsiString Defect;
	AnsiString Temp;
} TProgramPath;
typedef struct
{
	int DefaultCPBProgramID;
	bool CPBEnabled[SYSTEM_CPB_COUNT];
    int CameraDistribution[SYSTEM_CPB_COUNT];
	int CPBSDRSizeType[SYSTEM_CPB_COUNT];
	unsigned char CPBClockKind[SYSTEM_CPB_COUNT];
    unsigned char CameraHardwarePosition[SYSTEM_SPB_CAMERA_MAX_COUNT];
    unsigned short ShutterSpeed[SYSTEM_SPB_CAMERA_MAX_COUNT];
//    unsigned short ShutterDelay[SYSTEM_SPB_CAMERA_MAX_COUNT];
    unsigned short GlobalCameraIndex[SYSTEM_SPB_CAMERA_MAX_COUNT];
    unsigned char CamMask;
} TSPBInfo;

typedef struct
{
	int MotorSpeedList[MS_TABLET_TYPE_COUNT][MS_TABLET_SHAPE_COUNT][MAX_SERVO_MOTOR_COUNT][MS_MOTOR_SPEED_STEP_COUNT];
    int DiscCenterPos[SYSTEM_TOTAL_CAMERA_COUNT];
	int CameraResolution[SYSTEM_TOTAL_CAMERA_COUNT];
	int CameraBrightnessEvalValue[4];
} TMachineParams;

typedef struct
{
	int ShutterSpeed[SYSTEM_TOTAL_CAMERA_COUNT];	
} TInitialValues;
/*
typedef struct
{
	int BaseSpeed;
	int AccTime;
	int DecTime;
	bool IsPositiveDirection;
} TServoMotorInfo;
*/
typedef struct
{
	unsigned char Disk1InverterSpeed;
	unsigned char Disk2InverterSpeed;
	char dummyChar[2];
	unsigned int ServoMotorSpeed[MAX_SERVO_MOTOR_COUNT];
	int SpeedIndex;
} TMachineOperationInfo;


/*
class TSystemInfor
{
private:
public:
	__fastcall TSystemInfor();
	TSPBInfo SPBInfo[SYSTEM_SPB_COUNT];
	TCameraMapInfo CameraMapInfo[SYSTEM_TOTAL_CAMERA_COUNT];
//    int ShutterSpeed[SYSTEM_TOTAL_CAMERA_COUNT];
//    float Resolution[SYSTEM_TOTAL_CAMERA_COUNT];
//    unsigned int LEDOnMask[SYSTEM_TOTAL_CAMERA_COUNT];
	int SpeedIndex;

	bool __fastcall LoadData(AnsiString fileName);
	bool __fastcall SaveData(AnsiString fileName);
};
*/

#define STUDY_STEP_NONE						0
#define STUDY_STEP_FEATURE_EXTRACTED		1
#define STUDY_STEP_STUDY_COMPLETE			2

#define MAX_TABLET_LAYER_COUNT				16

typedef struct
{
    int MaxSpeedTrainingMode;
	int ManualMaxSpeed;
    int ManualModeSensorIndex;
    int ManualModeSensorActiveRatio;

//    int EmptySensorIndex;
    int EmptySensorActiveRatio;
//    int FullSensorIndex;
    int FullSensorActiveRatio;
	int SuctionDisk1InverterSpeed;
	int SuctionDisk2InverterSpeed;
	unsigned char AirKnifeSpeed;
	int StartSpeed;
	int LampKind;
} TMachineRunOption;

typedef struct
{
	AnsiString ProductCode;
	AnsiString ProductName;
	AnsiString LOTName;
	int TabletType;
	int TabletShape;
	int StudyStep;
	double TabletLength;
	double TabletWidth;
	double TabletThick;
	double TabletSideThick;
	int EngraveType;
	int EngravePos;
	int PrintBrightness;
	int BoundaryLeft[SYSTEM_TOTAL_CAMERA_COUNT];
	int BoundaryTop[SYSTEM_TOTAL_CAMERA_COUNT];
	int BoundaryRight[SYSTEM_TOTAL_CAMERA_COUNT];
	int BoundaryBottom[SYSTEM_TOTAL_CAMERA_COUNT];
	int ShutterSpeed[SYSTEM_TOTAL_CAMERA_COUNT];
	int ProcessingStep;
	AnsiString TabletColorCode;
	AnsiString PrintColorCode;
	int MotorSpeedList[MAX_SERVO_MOTOR_COUNT][MOTOR_SPEED_STEP_COUNT_FOR_PRODUCT];
	int ProductionCount;
	TDateTime LastInspectionTime;
	bool PlateTablet;
	int TabletLayerCount;
	TColor MultiLayeredTabletColor[MAX_TABLET_LAYER_COUNT];
	int ThresholdFor3D[SYSTEM_TOTAL_CAMERA_COUNT];

	int StudiedSensor1Length;
	int StudiedSensor2Length;
	int StudiedSensorIntervalA;
	int StudiedSensorIntervalB;
	double NCMotorPos[MAX_STEP_MOTOR_COUNT];
	int PartialCaptureMode;
	int RotatingGuideKind;
	int FixedGuideKind;
	int VerticalGate2Kind;
	bool Arrange;
	int SymmetricLineCount;
	TMachineRunOption MachineRunOption;
	int LampKind;
} TProductData;

typedef struct
{
	AnsiString OperatorName;
    AnsiString LOTName;
	int TotalTabletCount;
	int GoodTabletCount;
	int DefectTabletCount;
	int UnInsTabletCount;
	
	// unins detail
	int SPBProcessingNCTabletCount;
	int SPBTOTabletCount;
	int SPBUnInsTabletCount;
	int DisapperedTabletCount;
	int InsertedTabletCount;
	int LateTabletCount;
	int EarlyTabletCount;
    // defect detail

	unsigned int ElapsedTime;
} TInspectionResultData;

#define INSPECTION_REPORT_VERSION			100

typedef struct
{
	int Version;
	char IsPrintedTablet;
	char dummyChar[3];

	char dummyChar2[248];
} TTabletInspectReportHeader;

typedef struct
{
	int TotalTabletCount;
	int GoodTabletCount;
	int DefectTabletCount;
	int UnInsTabletCount;

	// unins detail
	int SPBProcessingNCTabletCount;
	int SPBTOTabletCount;
	int SPBUnInsTabletCount;
	int DisappearedTabletCount;
	int InsertedTabletCount;
	int LateTabletCount;
	int EarlyTabletCount;
	unsigned int ElapsedTime;
	unsigned int reserved;

    double InspectionStartTime;
    double InspectionEndTime;

    int ProductionCount;
    int DefectDataCount;
    int ClosedTabletCount;
	// 76 bytes
    char ProductName[64];
    char OperatorName[32];

    char IsReIns;
	char dummyChar1[3];
    int UnPrintTabletCount;
    int WrongNumberTabletCount;
    int NumberUndefTabletCount;
    int CaptureNotReadyTabletCount;
    int BufferFullTabletCount;
    int CaptureTimoutTabletCount;
    int ProcessingTimoutTabletCount;
    int CPBFullTabletCount;
	int ProcessingErrorTabletCount;

	int UnInsTabletPositionCount;
	int UnInsBrightnessDropCount;
	int UnInsBrightnessChaseCount;
	int Sensor1MisFeedingTabletCount;
	int Sensor2MisFeedingTabletCount;
	int Sensor1MultiTabletCount;
	int Sensor2MultiTabletCount;
	int UnIntendedUninsTabletCount;
	int CounterSensorTabletCount;
	int MisejectActiveCount;
	int GoodTabletLostCount;
	int MisejectTabletInsertCount;
	int MisejectDefectTabletCount;
	int MisejectUnInsTabletCount;
	int FRMisMatchTabletCount;
	char dummyChar2[752];
} TTabletInspectReport;

typedef struct
{
	int ColorGrade;
	int FrontNormalDirtyGrade;
	int FrontPrintDirtyGrade;
	int FrontStainGrade;
	int FrontEdgeGrade;
	int OptionFrontStickingGrade;
	int SideDirtyGrade;
	int SideStainGrade;
	int SideEdgeGrade;
	int OptionBreakingGrade;
	int OptionPrintMarkGrade;
	int PrintEraseGrade;
	int PrintSpreadGrade;

	int FrontEdgeDirtyGrade;
	int FrontColorDirtyGrade;
	int SideHeightGrade;
	// 64 bytes
	int SideColorDirtyGrade;
	int ThreeDHeightMinusLimit;
	int ThreeDHeightPlusLimit;

	int FrontNormalDirtySize;
	int FrontEdgeDirtySize;
	int FrontStainSize;
	int FrontEdgeSize;
	int FrontColorDirtySize;
	int SideDirtySize;
	int SideStainSize;
	int SideHeightSize;
	int OptionBreakingSize;
	int OptionFrontStickingSize;
	int SideColorDirtySize;
	// 120 bytes
	char dummyChar[136];
} TTabletInspectGradeData;  // for report


typedef struct
{
	bool DSMEnabled;
//	bool OldDataCompress;
//	double BMPMaintainTime;
	double ReduceTime[3];
	int PrimeLotCount[3];
	int PrimeLotMaxDefectCount[3];
	int TrivialLotMaxDefectCount[3];
	int MinDiskSpaceRatio;
	bool DSMAlwaysOn;
	TDateTime DSMStartTime;
	TDateTime DSMEndTime;
} TDSMInfo;

void __fastcall SetGrayPalette(Graphics::TBitmap *theBitmap);
void __fastcall Set3DPalette(Graphics::TBitmap *theBitmap);
double __fastcall Motor_RPM_To_MMPS(int rpm);

bool __fastcall ReadMachineSetupData(AnsiString fileName, TMachineSetupData &machineSetupData);
void __fastcall WriteMachineSetupData(AnsiString fileName, TMachineSetupData &machineSetupData);
bool __fastcall ReadMachineParams(AnsiString fileName, TMachineParams &machineParams);		// pc saved params
bool __fastcall WriteMachineParams(AnsiString fileName, TMachineParams &machineParams);		// pc saved params
bool __fastcall ReadCameraMapData(AnsiString fileName, TCameraMapInfo *cameraMapInfo);
bool __fastcall WriteCameraMapData(AnsiString fileName, TCameraMapInfo *cameraMapInfo);
bool __fastcall ReadSPBSystemSetupData(AnsiString fileName, TSPBSystemSetupData *spbSystemSetupData,
	TCameraMapInfo *cameraMapInfo);
bool __fastcall WriteSPBSystemSetupData(AnsiString fileName, TSPBSystemSetupData *spbSystemSetupData);
//bool __fastcall ReadServoMotorInfo(AnsiString fileName, TServoMotorInfo *servoMotorInfo);
//void __fastcall WriteServoMotorInfo(AnsiString fileName, TServoMotorInfo *servoMotorInfo);
bool __fastcall ReadMachineOperationInfo(AnsiString fileName, TMachineOperationInfo &machineOperationInfo, TMachineSetupData &machineSetupData);		// read recent operation info
void __fastcall WriteMachineOperationInfo(AnsiString fileName, TMachineOperationInfo &machineOperationInfo);		// write recent operation info
bool __fastcall ReadDSMInfo(AnsiString fileName, TDSMInfo &dsmInfo);
void __fastcall WriteDSMInfo(AnsiString fileName, TDSMInfo &dsmInfo);

bool __fastcall ReadProductData(AnsiString fileName, TProductData &productData, TMachineParams &machineParams,
	TMachineSetupData &machineSetupData);
bool __fastcall WriteProductData(AnsiString fileName, TProductData &productData);
bool __fastcall IsLargeTablet(TProductData &productData);

bool __fastcall SetProgramPath(TProgramPath &path);

bool __fastcall LoadGradeData(AnsiString gradeFileName, TTabletGradeData &GradeData);
bool __fastcall SaveGradeData(AnsiString gradeFileName, TTabletGradeData &GradeData);

bool __fastcall LoadStudyData(AnsiString studyFileName, TTabletStudyResultData &StudyData);
bool __fastcall SaveStudyData(AnsiString studyFileName, TTabletStudyResultData &StudyData);

void __fastcall MakeTabletCharacterData(TProductData *productData, TTabletCharacter *tabletCharacter, TMachineParams *machineParams);

bool __fastcall SaveShutterSpeedInfo(AnsiString fileName, AnsiString colorCodeName, TColor bgrColor, int *shutterSpeedList, unsigned int validCameraMask);
AnsiString __fastcall LoadShutterSpeedInfo(AnsiString fileName, AnsiString colorCodeName, TColor bgrColor, int *shutterSpeedList, unsigned int validCameraMask);
AnsiString __fastcall Load3DParameterInfo(AnsiString fileName, AnsiString colorCodeName, TColor bgrColor, int *exposureTimeList, int *thresholdList, unsigned int validCameraMask);

WideString __fastcall GetDefectSeriesStr(int series);

WideString __fastcall TabletKindStr(int tabletKind);
WideString __fastcall TabletShapeStr(int tabletShape);
WideString __fastcall TabletEngraveKindStr(int engraveKind);
WideString __fastcall TabletEngravePosStr(int engravePos);
WideString __fastcall LampKindStr(int lampKind);

bool __fastcall ReadUserMachineEnvData(AnsiString fileName, TUserMachineEnv &userMachineEnv);
bool __fastcall WriteUserMachineEnvData(AnsiString fileName, TUserMachineEnv &userMachineEnv);

void __fastcall InitCommon_PC(void);
int __fastcall DefectSizePixelToMili(int pixel);
int __fastcall GetDefaultGuideKind(int guideIndex, double tabletWidth);
int __fastcall GetDefaultVGateKind(int gateIndex, double tabletWidth);
int __fastcall GetDefaultAirKnifeSpeed(void);
int __fastcall GetDefaultSuctionSpeed(TProductData &productData, int &suctionSpeed1, int &suctionSpeed2);
void __fastcall GetDefaultNCPosition(TProductData &productData, double *ncMotorPos, double interlockAValue);

void __fastcall ImageConversion_3D(Graphics::TBitmap *DestBitmap, int destWidth, int destHeight, byte *srcBitmap, int srcWidth, int srcHeight);

int __fastcall GetMSTabletTypeIndex(int tabletType);
int __fastcall GetMSTabletShapeIndex(int tabletShape);

unsigned short Generate_CRC16(unsigned char *data, int len);

void __fastcall CopyProductData(TProductData &dest, TProductData &src);

extern int BackupSpeedMode;
#endif
