#include "syslib.h"
#include "timer.h"

#define ERROR_QUEUE_MAX_SIZE			256

typedef struct
{
	unsigned int 	inputPosition;					/* 데이터를 넣을 위치 */
	unsigned int 	removePosition;					/* 데이터를 뺄 위치 */
	TErrorUnit		errorUnit[ERROR_QUEUE_MAX_SIZE];
} TErrorQueue;

TErrorQueue 	ErrorQueue;

void ErrorQueue_Init(void);
TErrorCode ErrorQueue_Put(TErrorUnit *errorUnit, int count, int clientIndex);
int ErrorQueue_IsEmpty(void);
int ErrorQueue_IsFull(void);
int ErrorQueue_Count(void);
void ErrorQueue_Clear(void);
int ErrorQueue_Get(unsigned int* buf, int max);

//---------------------------------------------------------------------------
void ErrorQueue_Init(void)
{
	ErrorQueue_Clear();
}
//---------------------------------------------------------------------------
TErrorCode ErrorQueue_Put(TErrorUnit *errorUnit, int count, int clientIndex)
{
	int i;
	TErrorUnit *unit;
	TErrorCode rtn = ERROR_CODE_NONE;
	unsigned int nextInputPosition;
	unit = errorUnit;

	for (i = 0; i < count; i++)
	{
		nextInputPosition = ErrorQueue.inputPosition + 1;
		if (nextInputPosition >= ERROR_QUEUE_MAX_SIZE)
		{
			nextInputPosition = 0;
		}
		if (nextInputPosition == ErrorQueue.removePosition)	// queue is full.
		{
			rtn = ERROR_CODE_OVERFLOW;
			break;
		}
		memcpy(&ErrorQueue.errorUnit[ErrorQueue.inputPosition], unit, sizeof(TErrorUnit));
		ErrorQueue.inputPosition = nextInputPosition;
		unit++;
	}
	return rtn;
}
//---------------------------------------------------------------------------
void ErrorQueue_Remove(int count)
{
	unsigned int nextRemovePosition;
	int removeCount;
	if (count <= ErrorQueue_Count())
	{
		removeCount = count;
	}
	else
	{
		removeCount = ErrorQueue_Count();
	}

	nextRemovePosition = ErrorQueue.removePosition + removeCount;
	if (nextRemovePosition >= ERROR_QUEUE_MAX_SIZE)
	{
		nextRemovePosition -= ERROR_QUEUE_MAX_SIZE;
	}
	ErrorQueue.removePosition = nextRemovePosition;
}
//---------------------------------------------------------------------------
int ErrorQueue_IsEmpty(void)
{
    return ErrorQueue.inputPosition == ErrorQueue.removePosition;
}
//---------------------------------------------------------------------------
int ErrorQueue_IsFull(void)
{
	unsigned int nextInputPosition;
	
	nextInputPosition = ErrorQueue.inputPosition + 1;
	if (nextInputPosition >= ERROR_QUEUE_MAX_SIZE)
	{
		nextInputPosition = 0;
	}
    return nextInputPosition == ErrorQueue.removePosition;
}
//---------------------------------------------------------------------------
int ErrorQueue_Count(void)
{
	if (ErrorQueue.removePosition > ErrorQueue.inputPosition)
	{
		return (ErrorQueue.inputPosition + ERROR_QUEUE_MAX_SIZE) - ErrorQueue.removePosition;
	}
	else
	{
		return ErrorQueue.inputPosition - ErrorQueue.removePosition;
	}
}
//---------------------------------------------------------------------------
void ErrorQueue_Clear(void)
{
	ErrorQueue.inputPosition = ErrorQueue.removePosition = 0;
}
//---------------------------------------------------------------------------
int ErrorQueue_Get(unsigned int* buf, int maxCount)
{
	int i, count, currentPosition;
	TErrorUnit *unit;
	
	count = ErrorQueue_Count();
	if (count > 0)
	{
		if (count >= maxCount) count = maxCount;
		unit = (TErrorUnit *) buf;
		currentPosition = ErrorQueue.removePosition;
		for (i = 0; i < count; i++)
		{
			memcpy(unit, &ErrorQueue.errorUnit[currentPosition], sizeof(TErrorUnit));
			currentPosition++;
			if (currentPosition >= ERROR_QUEUE_MAX_SIZE)
			{
				currentPosition = 0;
			}
			unit++;
		}

	}
	return count;
}
//---------------------------------------------------------------------------
TErrorCode ErrorUnit_Put(unsigned short troubleBoard, unsigned short type, unsigned int code, 
	unsigned int value1, unsigned int value2, unsigned int value3)
{
	TErrorUnit tempunit;

	tempunit.troubleBoard = troubleBoard;
	tempunit.type = type;
	tempunit.code = code;
	tempunit.time = Board1MSTmr;
	tempunit.value[0] = value1;
	tempunit.value[1] = value2;
	tempunit.value[2] = value3;

	return ErrorQueue_Put(&tempunit, 1, -1);
}

//---------------------------------------------------------------------------
int SysLibInit(void)
{
	ErrorQueue_Init();
	return 1;
}
//---------------------------------------------------------------------------
