#ifndef _IMAGE_CONTROL_H_
#define _IMAGE_CONTROL_H_

#include "spb_system.h"
#include "processing.h"

#define MAX_IMAGE_BLOCK_INDEX			256		// IMAGE_BUFFER_SIZE / IMAGE_BLOCK_SIZE 보다는 크게.. 

#define IMAGE_BUFFER_SIZE		(150 * 640 * 480)
#define IMAGE_BLOCK_SIZE2		(ACAM_CAMERA_WIDTH * ACAM_CAMERA_HEIGHT)
#define FIFO_INT_TRANSFER_SIZE	(24 * 1024)

#define IMAGE_BUFFER_COUNT	4

extern unsigned char ImageBuffer1[IMAGE_BUFFER_SIZE];
extern unsigned char ImageBuffer2[IMAGE_BUFFER_SIZE];
extern unsigned char ImageBuffer3[IMAGE_BUFFER_SIZE];
extern unsigned char ImageBuffer4[IMAGE_BUFFER_SIZE];
extern unsigned char DummyImage[4][SYSTEM_CAMERA_HD_WIDTH * SYSTEM_CAMERA_HD_HEIGHT];
extern unsigned char InvalidImage[SYSTEM_CAMERA_HD_WIDTH * SYSTEM_CAMERA_HD_HEIGHT];

#define DEFECT_QUEUE_SIZE		256		// MAX_IMAGE_BLOCK_INDEX 보다 같거나 크게..
#define DEFECT_QUEUE_MASK		255

#define IMAGE_CONTROL_MODE_NONE					0
#define IMAGE_CONTROL_MODE_FIFO					1
#define IMAGE_CONTROL_MODE_PROCESSING			2


#define IC_CALIB_STATE_NONE					0
#define IC_CALIB_STATE_ON_CAPTURE			1
#define IC_CALIB_STATE_CAPTURE_COMPLETE		2
#define IC_CALIB_STATE_ERROR				3

#define REALTIME_IMAGE_WIDTH	SYSTEM_CAMERA_WIDTH / 4
#define REALTIME_IMAGE_HEIGHT	SYSTEM_CAMERA_HEIGHT / 4
#define REALTIME_IMAGE_SIZE 	(REALTIME_IMAGE_WIDTH * REALTIME_IMAGE_HEIGHT)

#define MAX_REALTIME_BUFFER_SIZE	IMAGE_BUFFER_SIZE / REALTIME_IMAGE_SIZE

extern unsigned char *RealtimeImageBuffer;
extern unsigned int RealtimeImageStartQueue;
extern unsigned int RealtimeImageEndQueue;
extern unsigned int ImageControlInterval;

extern unsigned short DefectQueueList[DEFECT_QUEUE_SIZE];
extern int DefectQueueStart, DefectQueueEnd;

extern TDefectData_SPB DefectDataList[MAX_IMAGE_BLOCK_INDEX][IMAGE_BUFFER_COUNT];

typedef struct
{
	int ImageControlMode;
	int BlockSize;
	int BlockCount;
	int Allocated;
	unsigned char *ImageBuffer[MAX_IMAGE_BLOCK_INDEX];
} TImageInfo;

extern TImageInfo ImageInfo[IMAGE_BUFFER_COUNT];

typedef struct
{
//	int Filled[MAX_IMAGE_BLOCK_INDEX];
	int ImageState[MAX_IMAGE_BLOCK_INDEX];
	int ImageInspectState[MAX_IMAGE_BLOCK_INDEX][IMAGE_BUFFER_COUNT];
	int TabletNumber[MAX_IMAGE_BLOCK_INDEX];
//	unsigned int TabletIndex[MAX_IMAGE_BLOCK_INDEX];
	int ImageCount;
	int CaptureImageIndex;
//	int DefectImageIndex;
	int DefectUploadIndex;
	int ProcessingBufferFindingIndex;
	unsigned char *ImageBuffer[MAX_IMAGE_BLOCK_INDEX][IMAGE_BUFFER_COUNT];
	unsigned char *DummyBuffer[IMAGE_BUFFER_COUNT];
} TProcessingImageInfo;

typedef struct
{
	int FIFOModeStart[IMAGE_BUFFER_COUNT];
	int FIFOModeEnd[IMAGE_BUFFER_COUNT];
	unsigned char FIFOState[MAX_IMAGE_BLOCK_INDEX][IMAGE_BUFFER_COUNT];
	unsigned char *ImageBuffer[MAX_IMAGE_BLOCK_INDEX][IMAGE_BUFFER_COUNT];
	unsigned char *DummyBuffer[IMAGE_BUFFER_COUNT];
	int MaxFrameCount[IMAGE_BUFFER_COUNT];
} TCalibrationImageInfo;


extern TProcessingImageInfo ProcessingImageInfo;

extern unsigned int lastCaptureStartTime; // temp

void AllocateImageBuffer(int bufferIndex, int imageBlockSize);
void ClearImageBuffer(int bufferIndex);
unsigned char* GetFirstImageBuffer(int bufferIndex);
unsigned char* GetLastImageBuffer(int bufferIndex);
void ProceedToNextBufferIndex(int bufferIndex);
//int GetFilledBufferIndexCount(int bufferIndex);
int GetBufferIndexLimit(int bufferIndex);
int GetImageBlockSize(int bufferIndex);
void RemoveFirstImageBlock(int bufferIndex);

//unsigned char* GetProcessingImageBuffer(int bufferIndex);
unsigned char* GetProcessingImageBufferPtr(int camIndex, int frameIndex);
unsigned char* GetOverlappedProcessingImageBuffer(int bufferIndex);
unsigned char* ImageControl_CalibMode_GetLastFrameBuffer(int bufferIndex);
void ImageControl_CalibMode_DecreaseToNextValidFrame(int bufferIndex);

static inline void ProcessingImageBuffer_Clear(int imageIndex)
{
	ProcessingImageInfo.ImageState[imageIndex] = IMAGE_STATE_EMPTY;
}

static inline void ProcessingImageBuffer_MarkCaptured(int imageIndex)
{
	ProcessingImageInfo.ImageState[imageIndex] = IMAGE_STATE_CAPTURED;
}

static void ProcessingImageBuffer_MarkDefect(int imageIndex)
{
	ProcessingImageInfo.ImageState[imageIndex] = IMAGE_STATE_DEFECT;
	DefectQueueList[DefectQueueEnd] = imageIndex;
	DefectQueueEnd = (DefectQueueEnd + 1) & DEFECT_QUEUE_MASK; 	
	if (DefectQueueEnd == DefectQueueStart)	// overflow
	{
		ProcessingImageInfo.ImageState[DefectQueueList[DefectQueueStart]] = IMAGE_STATE_EMPTY;
		DefectQueueStart = (DefectQueueStart + 1) & DEFECT_QUEUE_MASK; 	
	}
}


#endif

