#include "sys/xboxkrnl.h"
#include "string.h"
#include "xbox.h"
#include <fb.h>
#include "ntfile.h"
#include "pconfig.h"
#include "debug.h"
#include <stdlib.h>
	#include "Hermes.h"
	#include "H_Conv.h"
#include "VideoHelpers.h"


#define statusreg1 (*((volatile unsigned char*)(0xfd6013da)))

extern CONFIGENTRY *entry;

extern HermesHandle converter;
extern HermesFormat *form;

inline void waitretrace()
{

   	// Wait vertical retrace
   	while(statusreg1&0x08) ;
   	// Wait refresh
	while(!(statusreg1&0x08)) ;
}
		

inline void Fade(PUCHAR Image, int Amount)
{
	int i;
	//66331200  -22
	unsigned char *c = Image;
	for(i=0;i<640*480*4;i++)
	{
		
		if(*c + Amount < 0)
			*c = (unsigned char)0;
		else
			if(*c + Amount > 255)
				*c = (unsigned char)255;
			else
				*c += (unsigned char)Amount;
		c++;
	}
}

void SplitBlur(PUCHAR Image, int Amount)
{

	int n,s,e,w,x,y,ro,go,bo;
	PUCHAR Lin1, Lin2;
	PUCHAR pc;

	if(Amount == 0)
		return;
	//point to the first pixel
	pc = Image;

	//for each row
	for(y=0;y<480;y++)
	{
		
		//our "north row" (or the row of the top "ghost")
		n=y+Amount;
		while(n>476) //hackjob
			n=480-4;
			//n=480-n;

		//south row (bottom "ghost")
		s=y-Amount;
		while(s<0)
			s=0+4;
			//s=480+s;

		//get pointers to the starts of each of these rows
		Lin1 = (Image + (640*4*s));
		Lin2 = (Image + (640*4*n));
		
		//for each pixel in the current line
		for(x=0;x<640*4;x+=4)
		{
			//east ghost
			e=x+(Amount*4);
			while(e > 640*4)
				e=640*4-4;
				//e=(640*4)-e;
			
			//west ghost
			w=x-(Amount*4);
			while(w<0)
				w=0+4;
				//w=(640*4)+w;
			
			//sum the ghosts' overlap at this point to determine the color for this
			//point
			
			ro=(Lin1[w+2]+Lin1[e+2]+Lin2[w+2]+Lin2[e+2]) >> 2;
			go=(Lin1[w+1]+Lin1[e+1]+Lin2[w+1]+Lin2[e+1]) >> 2;
			bo=(Lin1[w+0]+Lin1[e+0]+Lin2[w+0]+Lin2[e+0]) >> 2;

			//write the color
			pc[2]=ro;
			pc[1]=go;
			pc[0]=bo;

			//next point
			pc+=4;
		}
	}
}

		



void DoSplashEffect(unsigned char *Framebuffer, unsigned char *Image)
{
	PUCHAR Buffer;

	int keyframes=8;
	int kftimes[8] ={        24, 8, 24,   4, 16, 16,   16, 8};
	int kffade[9] = {-255,  -32, 0,  0, -64,  0,  0, -255, -255};
	int kfsplit[9] = { 32,    0, 0,  0,  12,  0,  0,   64, 64};
	//int kfsplit[6] = { 5,  5, 5, 5, 5, 5};
	int kfc,c;

	
	Buffer = (PVOID)malloc(640*480*4);

	for(kfc=0;kfc<keyframes;kfc++)
	{
		for(c=0;c<kftimes[kfc];c++)
		{
			memcpy(Buffer, Image, 640*480*4);
			//C = A + (B-A) * k
			//A=start value
			//B=end value
			//k=(time/endtime)
			SplitBlur(Buffer,(int)(kfsplit[kfc] + (kfsplit[kfc+1]-kfsplit[kfc]) * ((float)c/(float)kftimes[kfc])));
			Fade(Buffer,(int)(kffade[kfc] + (kffade[kfc+1]-kffade[kfc]) * ((float)c/(float)kftimes[kfc])));
			waitretrace();
			memcpy(Framebuffer,Buffer,640*480*4);

		}
	}
	

}

void DoSplash()
{
	PUCHAR Image = 0;
	PUCHAR FileImage = 0;
	JPEG jpgImage;
	HermesFormat *img;
	//PUCHAR TempPtr = 0;


	img = Hermes_FormatNew(24,0xFF0000,0x00FF00,0x0000FF,0,0);
	if(!img)
	{
		Die("Could not initialize img format");
	}
	
	// 32 Bit
	Image = (PVOID)malloc(640*480*4);

	///FileImage = LoadFile(entry->szSplashFile, 640*480*3);
	//
	
	if(!LoadJpeg("P:\\phoenix2d_logo1.jpg", &jpgImage))
	{
		Die("Could not load logo");
	}

	FileImage = jpgImage.pBitmapData;
	
	if (FileImage)
	{
		
		// Convert 24->32 bit depth
		
		
		if(!Hermes_ConverterRequest(converter, img, form))
		{
			Die("Could not request converter");
		}

		if(!Hermes_ConverterCopy(converter,	//converter
					FileImage,	//source
					0,0,		//source x,y
					jpgImage.nWidth,jpgImage.nHeight,	//source w,h
					jpgImage.nWidth*jpgImage.nBytesPerPixel,		//source pitch
					Image,		//dest
					0,0,		//dest x,y
					640,480,	//dest w,h
					640*4))		//dest pitch
		{
			Die("Could not convert image to 32 bit 640x480!");
		}
		
		DoSplashEffect(fb_get(), Image);
		
	}
	
	free(Image);
	free(FileImage);
	
	Hermes_FormatFree(img);
	
}

