#include <csl_edma2.h>
#include "image_control.h"
#include "environment.h"
#include "TPBcamera.h"

#pragma DATA_SECTION(nomalImageBuffer, ".sdram2_image");
#pragma DATA_ALIGN(nomalImageBuffer, 1024);
#pragma DATA_SECTION(DefectImageBuffer, ".sdram2_image");
#pragma DATA_ALIGN(DefectImageBuffer, 1024);
unsigned char nomalImageBuffer[TBB_IMAGE_BUFFER_SIZE];
unsigned char DefectImageBuffer[TBB_IMAGE_BUFFER_SIZE];
TImageInfo NomalImageInfo, defectImageInfo;
TTPBMonitorInsData TPBMonitorInsData;

#pragma DATA_SECTION(DummyImage, ".sdram2_image");
#pragma DATA_ALIGN(DummyImage, 1024);

unsigned char DummyImage[SYSTEM_CAMERA_WIDTH * SYSTEM_CAMERA_HEIGHT];


void InitImageInfo(void)
{
	ImageControl_ClearBuffer();
	AllocateImageBuffer(NFA_HALF_FIFO_SIZE*18);
}

void AllocateImageBuffer(int imageBlockSize)
{
	int bufferBlockIndex;
	unsigned char *image_base_addr;
	unsigned int currentImageOffset;
	unsigned int buffer_max_size;
	
	ImageControl_ClearBuffer();
	imageBlockSize = (imageBlockSize / 1024)+ 1;
	imageBlockSize = imageBlockSize*1024;

	image_base_addr = nomalImageBuffer;
	buffer_max_size = TBB_IMAGE_BUFFER_SIZE;
	currentImageOffset = 0;
	bufferBlockIndex = 0;	
	while((currentImageOffset + imageBlockSize < buffer_max_size) && (bufferBlockIndex < MAX_IMAGE_BLOCK_INDEX - 1))
	{
		NomalImageInfo.ImageBuffer[bufferBlockIndex] = image_base_addr + currentImageOffset;
		currentImageOffset += imageBlockSize;
		bufferBlockIndex++;
	}

	NomalImageInfo.BlockSize = imageBlockSize;
	NomalImageInfo.BlockCount = bufferBlockIndex;
	NomalImageInfo.currentIndex = 0;

	image_base_addr = DefectImageBuffer;
	buffer_max_size = TBB_IMAGE_BUFFER_SIZE;
	currentImageOffset = 0;
	bufferBlockIndex = 0;	
	while((currentImageOffset + imageBlockSize < buffer_max_size) && (bufferBlockIndex < MAX_IMAGE_BLOCK_INDEX - 1))
	{
		defectImageInfo.ImageBuffer[bufferBlockIndex] = image_base_addr + currentImageOffset;
		currentImageOffset += imageBlockSize;
		bufferBlockIndex++;
	}

	defectImageInfo.BlockSize = imageBlockSize;
	defectImageInfo.BlockCount = bufferBlockIndex;
	defectImageInfo.currentIndex = 0;
}

int ImageControlGetCapturedFrameCount(int type)
{
	int i = 0;
	int validFrameCount = 0;
	if(type == 0)
	{
		for(i = 0; i <NomalImageInfo.BlockCount;i++)
		{
			if((NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD) || (NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_GOOD_IMAGE_LOAD))
				validFrameCount++;
		}
	}
	else
	{
		//불량버퍼 구현자리
		for(i = 0; i <NomalImageInfo.BlockCount;i++)
		{
			if((NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD))
				validFrameCount++;
		}
	}
	return validFrameCount;
}

unsigned char* ImageControlGetFirstValidFrameBuffer(int type)
{
	int i;
	if(type==0)
	{
		for(i =NomalImageInfo.uploadIndex; i < NomalImageInfo.BlockCount;i++)
		{
			if((NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD) || (NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_GOOD_IMAGE_LOAD))
			{	
				NomalImageInfo.Status[i] = TPB_IMAGEBUFFER_STATUS_IMAGE_LOAD;
				NomalImageInfo.uploadIndex = i;
				return NomalImageInfo.ImageBuffer[i];
			}
		}
		for(i = 0 ; i <NomalImageInfo.uploadIndex ; i++ )
		{
			if((NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD) || (NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_GOOD_IMAGE_LOAD))
			{	
				NomalImageInfo.Status[i] = TPB_IMAGEBUFFER_STATUS_IMAGE_LOAD;
				NomalImageInfo.uploadIndex = i;
				return NomalImageInfo.ImageBuffer[i];
			}			
		}
	}
	else
	{
		for(i =NomalImageInfo.uploadIndex; i < NomalImageInfo.BlockCount;i++)
		{
			if(NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD)
			{	
				NomalImageInfo.Status[i] = TPB_IMAGEBUFFER_STATUS_IMAGE_LOAD;
				NomalImageInfo.uploadIndex = i;
				return NomalImageInfo.ImageBuffer[i];
			}
		}
		for(i = 0 ; i <NomalImageInfo.uploadIndex ; i++ )
		{
			if(NomalImageInfo.Status[i] == TPB_IMAGEBUFFER_STATUS_DEFECT_IMAGE_LOAD)
			{	
				NomalImageInfo.Status[i] = TPB_IMAGEBUFFER_STATUS_IMAGE_LOAD;
				NomalImageInfo.uploadIndex = i;
				return NomalImageInfo.ImageBuffer[i];
			}		
		}
	}
}

void ImageControl_ClearBuffer(void)
{
	memset(nomalImageBuffer, 0, TBB_IMAGE_BUFFER_SIZE);
	memset(DefectImageBuffer, 0, TBB_IMAGE_BUFFER_SIZE);
	memset(NomalImageInfo,0,sizeof(NomalImageInfo)); 
	memset(defectImageInfo,0,sizeof(defectImageInfo)); 

}
