/*---------------------------------------------------------------------------
 *	Import Headers
\*--------------------------------------------------------------------------*/

#include <sys\types.h>
#include <libetc.h>
#include <stdio.h>
#include "typedefs.h"
#include "malloc.h"
#include "cd.h"
#include "file.h"
#include "gpu.h"
#include "gen_draw.h"
#include "picture.h"
#include "specific.h"
#include "profile.h"
#include "..\game\text.h"

/*---------------------------------------------------------------------------
 *	Constants
\*--------------------------------------------------------------------------*/

#define LOG


#ifdef CD_LOAD
#define LOADBAR_SPEED	8	// cd-speed... (I hope)
#else
#define LOADBAR_SPEED	16	// pc speed (hoho)
#endif

#define LOADBAR_WIDTH	(384<<3)
#define LOADBAR_SHIFT	12
#define LOADBAR_HEIGHT	12
#define LOADBAR_X		((512-(LOADBAR_WIDTH>>3))/2)

#ifdef NTSC
	#if defined(PSX_SONY_DEMO_SHELL) || defined(TEST_SONY_DEMO_SHELL)
		#define	LOADBAR_Y		240-64
	#else
		#define	LOADBAR_Y		240-16
	#endif
#else
	#if defined(PSX_SONY_DEMO_SHELL) || defined(TEST_SONY_DEMO_SHELL)
		#define	LOADBAR_Y		256-48
	#else
		#define	LOADBAR_Y		256-32
	#endif
#endif

/*---------------------------------------------------------------------------
 *	Locals
\*--------------------------------------------------------------------------*/

static int LnLoadingBarFileSize;			// this is the TOTAL size for the level...
static int LnLoadingBarBytesRead;			// this is the amount of data loaded so far...
static volatile int LnLoadingBarCurWidth;	// this is the current loader-bar width
static int LnLoadingBarTargetWidth;		// this is the desired bar width
static volatile int LnLoadingBarMode;
static int LtLoadingBarEnabled;

static GouraudBarColourSet L_LoadingBarColourSet = {
	{ 48, 96,127, 80, 32},	// left red
	{  0,  0,  0,  0,  0},	// left green
	{ 48, 96,127, 80, 32},	// left blue
	{  0,  0,  0,  0,  0},	// right red
	{ 48, 96,127, 80, 32},	// right green
	{ 48, 96,127, 80, 32}	// right blue
};

/*---------------------------------------------------------------------------
 *	Macros
\*--------------------------------------------------------------------------*/

#ifdef LOG
#define Log_(format,args...) DebugOut(format "\n" , ## args)
#else
#define Log_(args...)
#endif

/*---------------------------------------------------------------------------
 *	Local Functions
\*--------------------------------------------------------------------------*/

static void LOAD_VSyncHandler(void)
{
	if (LnLoadingBarMode)
	{
		if (LnLoadingBarCurWidth < LnLoadingBarTargetWidth)
			LnLoadingBarCurWidth += LOADBAR_SPEED;
		else
			LnLoadingBarCurWidth = LnLoadingBarTargetWidth;

		if (LnLoadingBarCurWidth >= LOADBAR_WIDTH)
		{
			LnLoadingBarMode=0;
			LnLoadingBarCurWidth=LOADBAR_WIDTH;
		}

		if (LtLoadingBarEnabled)
		{
			GPU_BeginScene();

			S_DrawGouraudBar(LOADBAR_X, LOADBAR_Y, LOADBAR_WIDTH>>3, LnLoadingBarCurWidth>>3, &L_LoadingBarColourSet);

			GPU_EndScene();
			GPU_FlipNow();
		}
	}
}

/*---------------------------------------------------------------------------
 *	Public Functions
\*--------------------------------------------------------------------------*/

int LOAD_DrawEnable(int tEnable)
{
	int tOld = LtLoadingBarEnabled;

	LtLoadingBarEnabled=tEnable;
	return tOld;
}


void LOAD_Start(char* szPicFileName,int nBytesToLoad)
{
	if (szPicFileName)
		Log_("LOAD_Start(\"%s\",%d)",szPicFileName,nBytesToLoad);
	else
		Log_("LOAD_Start(NO_PIC, %d)",nBytesToLoad);

#ifdef PROFILE_ME
	GPU_EnableProfilerBar(FALSE);
#endif
	if (szPicFileName)
	{
		if (S_DisplayPicture(szPicFileName))						// display loading picture...
    			S_FadeUp();												// and fade it in if need be
	}

//	else
//	{
//		int nBuffer;							// clear both double buffers (is this necessary?)
//
//		for (nBuffer=2;nBuffer;--nBuffer)
//		{
//			S_InitialisePolyList();
//			S_ClearScreen();
//			S_OutputPolyList();
//			S_DumpScreen();
//		}
//	}

#ifdef PROFILE_ME
	GPU_EnableProfilerBar(TRUE);
#endif

	VSync(0);
	GPU_UseOrderingTables(GadwOrderingTables,1);
	GPU_EnableBGClear(FALSE);

	LnLoadingBarFileSize=nBytesToLoad;
	LnLoadingBarBytesRead=0;
	LnLoadingBarCurWidth=0;
	LnLoadingBarTargetWidth=0;
	LnLoadingBarMode=1;

	LOAD_DrawEnable(TRUE);

	VSYNC_Add(LOAD_VSyncHandler);
}



void LOAD_Stop(void)
{
	Log_("LOAD_Stop");

 /*	while (LnLoadingBarMode) 										// wait for it... :)
	{
#ifdef LOG
		putchar('.');
#endif
		VSync(0);
	}

	VSync(0);
#ifdef LOG
	putchar('\n');
#endif*/

   	LnLoadingBarCurWidth = LOADBAR_WIDTH-1;
	VSync(3);

	VSYNC_Remove(LOAD_VSyncHandler);
	GPU_EnableBGClear(TRUE);
	GPU_UseOrderingTables(GadwOrderingTables,OTSIZE);
}


void LOAD_Update(int nBytesRead)
{
	if (LnLoadingBarMode)
	{
		LnLoadingBarBytesRead += nBytesRead;
		if (LnLoadingBarBytesRead > LnLoadingBarFileSize)
			LnLoadingBarBytesRead = LnLoadingBarFileSize;

		if (LnLoadingBarBytesRead)
   		{
			u_int one;

//  			one = (LnLoadingBarFileSize << 8) >> LOADBAR_SHIFT;
//			LnLoadingBarTargetWidth = ((LnLoadingBarBytesRead<<8) / one);

			one = (LnLoadingBarFileSize<<8) / LnLoadingBarBytesRead;
			LnLoadingBarTargetWidth = (LOADBAR_WIDTH<<8) / one;

			if (LnLoadingBarTargetWidth >= LOADBAR_WIDTH)
   				LnLoadingBarTargetWidth = LOADBAR_WIDTH;
			else if (LnLoadingBarTargetWidth <= 0)
   				LnLoadingBarTargetWidth = 1;

//			printf("Max %d Cur %d BarMax %d Bardest %d\n",	LnLoadingBarFileSize,
//												LnLoadingBarBytesRead,
//												LOADBAR_WIDTH,
//												LnLoadingBarTargetWidth);
   		}
	}
}
