// Include
#include "gamesrv.h"
#include "logprotocol.h"

#include <stdlib.h>
#include <time.h>

// Local definitions
#pragma warning( disable: 4244 )
#pragma warning( disable: 4127 )

// Global data
cRandomTable* cRandomTable::mpRandomTable = NULL;

// cRandomTable Constructor
cRandomTable::cRandomTable(void)
{
	mpRandomTable = this;

	table  = NULL;
	offset = 0;
	length = 0;
}

// ~cRandomTable Destructor
cRandomTable::~cRandomTable(void)
{
	Shutdown( );

	mpRandomTable = NULL;
}

// Initialize Method - 테이블 헤더와 최대크기 검사 필요함.
bool cRandomTable::Initialize( )
{
	FILE*  stream   = fopen( "./Script/Resource/randomtable.", "rb" );
	size_t numread  = 0;
	bool   retvalue = false;

	// rand function 시드값 초기화.
	srand( (unsigned)time( NULL ) );

	if ( stream != NULL )
	{
		WORD type;

		// 헤더정보 확인
		fread( &type, sizeof(type), 1, stream );

		if ( type == ((WORD) ('T' << 8) | 'R') )
		{
			// 테이블이 NULL 이 아닐결우 해제 및 초기화.
			if ( table != NULL )
			{
				GlobalFree( table );
				table = NULL;
			}
			// 테이블 오프셋 초기화.
			offset = 0;
			// 테이블 최대 크기 가져오기.
			fread( &length, sizeof(length), 1, stream );

			// 테이블 메모리 생성.
			table = (double*)GlobalAlloc( GPTR, sizeof(double)*length );

			if ( table != NULL )
			{
				// 테이블 가져오기 & 최대 크기와 비교.
				numread = fread( table, sizeof(double), length, stream );
				if ( numread != length )
				{
					GlobalFree( table );
					table = NULL;
				}
				else
				{
					// 테이블 오프셋 램덤설정.
					offset   = rand( ) % length;
					retvalue = true;
				}
			}
		}

		fclose( stream );
	}

	return retvalue;
}

// Shutdown Method
void cRandomTable::Shutdown( )
{
	if ( table != NULL )
	{
		GlobalFree( table );
		table = NULL;
	}
	length = 0;
	offset = 0;
}

// GetSeed Method
DWORD cRandomTable::GetSeed( )
{
	return rand( );
}

// Get Method
double cRandomTable::Get( )
{
	double value = 0;
	if ( table != NULL && offset < length )
	{
		value = *(table + offset);

		if ( ++offset >= length )
			offset = 0;
	}
	return value;
}

// Get Method
double cRandomTable::Get(DWORD& seed)
{
	double value = 0;
	if ( table != NULL )
	{
		// 최대 값보다 크거나 같을경우.
		if ( seed >= length ) seed %= length;

		value = *(table + seed);
		seed += 1;

		// 최대 값보다 커진경우..
		if ( seed >= length ) seed = 0;
	}
	return value;
}
