#include <fb.h>
#include <stdlib.h>
#include <BootUSB.h>
#include <string.h>
#include <sys/xboxkrnl.h>
#include <sys/types.h>
#include <sys/nttypes.h>


#include "bitmapfont.h"
#include "pconfig.h"
#include "debug.h"
#include "VideoHelpers.h"

#include <Hermes.h>
#include <H_Conv.h>

extern CONFIGENTRY *entry;

#define MAX_BIOS_FILES 512
char szBioses[MAX_BIOS_FILES][50];

extern HermesHandle converter;
extern HermesHandle clearer;
extern HermesFormat *form;

extern int cx;
extern int cy;

DWORD *LoadBG()
{
	HermesFormat *img;
	PUCHAR FileImage = 0;
	JPEG jpgImage;
	DWORD *bg;

	printk("loading bg\n");
	bg = malloc(640*480*4);
	if(!bg)
		return 0;

	img = Hermes_FormatNew(24,0xFF0000,0x00FF00,0x0000FF,0,0);
	if(!img)
		Die("Could not initialize img Format\n");


	if(!LoadJpeg("P:\\bg.jpg", &jpgImage))
	{
		Die("Could not load bg.jpg");
	}
	
	FileImage = jpgImage.pBitmapData;
	
	if (FileImage)
	{
		
		// Convert 24->32 bit depth
		if(!Hermes_ConverterRequest(converter, img, form))
		{
			Die("Could not initialize 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
					bg,		//dest
					0,0,		//dest x,y
					640,480,	//dest w,h
					640*4))		//dest pitch
		{
			Die("Could not convert image to 32 bit 640x480!");
		}
	}
	else
	{
		Die("Could not get jpeg buffer");
	}
	return bg;
	
}


int GetFiles(char *path)
{
	IO_STATUS_BLOCK IoStatusBlock;
	FILE_DIRECTORY_INFORMATION *FileInformation;
	HANDLE hFile = 0;
	ANSI_STRING FileMask;
	ANSI_STRING FileName;
	FILE_INFORMATION_CLASS FileInformationClass = FileDirectoryInformation;
	OBJECT_ATTRIBUTES Attributes;
	int nFirst = TRUE;

	int fcount=0;
	int i;

	for(i = 0; i < MAX_BIOS_FILES; i ++) szBioses[i][0] = 0;
			
	RtlInitAnsiString(&FileMask,"*");
			
	RtlInitAnsiString(&FileName,path);
	Attributes.RootDirectory = ObDosDevices;
	Attributes.ObjectName = &FileName;
	Attributes.Attributes = OBJ_CASE_INSENSITIVE;

	
	if(!NT_SUCCESS(NtCreateFile(&hFile, FILE_LIST_DIRECTORY,
				&Attributes, &IoStatusBlock,
				NULL, FILE_ATTRIBUTE_NORMAL,
				FILE_SHARE_READ, FILE_OPEN, FILE_DIRECTORY_FILE
				))) {
		Die("\n\n\nError : NtCreateFile\n");

	}
	
	FileInformation = malloc(sizeof(FILE_DIRECTORY_INFORMATION));

	if(!FileInformation)
		Die("Could not allocate FileInformation");
	
	
	memset(FileInformation,0x0,sizeof(FILE_DIRECTORY_INFORMATION));	

	nFirst=true;
	fcount = 0;
	
	while(NT_SUCCESS(NtQueryDirectoryFile(hFile, NULL, NULL, NULL,
			&IoStatusBlock, FileInformation, sizeof(FILE_DIRECTORY_INFORMATION),
			FileInformationClass, &FileMask, nFirst)))
	{

		if(fcount >= MAX_BIOS_FILES) break;
		if(nFirst)
			nFirst = FALSE;


		if(FileInformation->FileAttributes & FILE_ATTRIBUTE_NORMAL)
		{
			
//			szBioses[fcount] = malloc(strlen(FileInformation->FileName+1));
			if(!(szBioses[fcount]))
			{
				Die("Could not allocate space for filename");
			}
			
			strcpy(szBioses[fcount], FileInformation->FileName);
			fcount++;
		}
		
		
		memset(FileInformation,0x0,sizeof(FILE_DIRECTORY_INFORMATION));

	}

	NtClose(hFile);

	free(FileInformation);

	printk("Found %d files\n",fcount);
	for(i=0; i < MAX_BIOS_FILES;i++) {
		if(szBioses[i][0]) {
			printk("%d %s\n",i,szBioses[i]);
		}
	}

	return fcount;
}

void Dash()
{
	FONT f;
	DWORD *FB = NULL;
	DWORD *DB = NULL;
	DWORD *bg = NULL;
	int filecount;

	int selected=0;
	int before=0;
	int after=0;
	int before2=0;
	int after2=0;


	printk("loading font\n");
	if(!bfInit("P:\\font.jpg",&f))
	{
		Die("Unable to load font");
	}

	
	bg = LoadBG();
	if(!bg)
	{
		Die("Unable to load bg");
	}

	printk("intializing framebuffers\n");
	
	FB = (DWORD *)(fb_get());
	DB = malloc(640*480*4);

	if(!DB)
	{
		Die("Unable to get double buffer");
	}

	printk("Getting file list\n");
	filecount = GetFiles("P:\\Bioses\\");

	if(!filecount)
	{
		Die("No file in bios directory!");
	}
	
	printk("\nAll systems 5 by 5.\n");
	printk("We are green across the board!\n");
	printk("Now entering dash interface.....\n");	
	
	while(1)
	{


		memcpy(DB,bg,640*480*4);
		bfPutStr("Phoenix",&f,DB,640*4, (int)320.0-(f.w*3.5) ,5,1.0);
		bfPutStr("Bios loader",&f,DB,640*4, (int)(320.0-((f.w*0.5)*5.5)) ,f.h,0.5);
		bfPutStr("v1.3.5 INTERNAL!",&f,DB,640*4,(int)(320.0-((f.w*0.45)*8)), f.h+(f.h*0.5) ,0.45);

		
		if(selected==0)
		{
			before = filecount-1;
			before2 = filecount-2;
		}
		else if(selected==1)
		{
			before = 0;
			before2 = filecount-1;
		}
		else
		{
			before = selected - 1;
			before2 = selected - 2;
		}

		if(selected==filecount-1)
		{
			after=0;
			after2=1;
		}
		else if(selected==filecount-2)
		{
			after=filecount-1;
			after2=0;
		}
		else
		{
			after = selected+1;
			after2 = selected+2;
		}
			
#define pos  300
#define mid 0.5
#define first 0.3
#define second 0.25

	bfPutStr(szBioses[before2],&f,DB,640*4, (int)(320.0-((f.w*second)*(strlen(szBioses[before2])/2))) , (int)(pos-(f.h*first)-(f.h*second)), second);
	bfPutStr(szBioses[before],&f,DB,640*4, (int)(320.0-((f.w*first)*(strlen(szBioses[before])/2))) , (int)(pos-(f.h*first)), first);
	bfPutStr(szBioses[selected],&f,DB,640*4, (int)(320.0-((f.w*mid)*(strlen(szBioses[selected])/2))) , pos, mid);
	bfPutStr(szBioses[after],&f,DB,640*4, (int)(320.0-((f.w*first)*(strlen(szBioses[after])/2))) , (int)(pos+(f.h*mid)), first);
	bfPutStr(szBioses[after2],&f,DB,640*4, (int)(320.0-((f.w*second)*(strlen(szBioses[after2])/2))) , (int)(pos+(f.h*mid)+(f.h*first)), second);


		
		memcpy(FB,DB,640*480*4);
		
		
		USBGetEvents();
		if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_BLACK) == 1) {
			bfClear(FB,0,0,640,480,640*4,0x00,0x00,0x00,0xFF);
			printk("Quick Rebooting\n");
			HalReturnToFirmware(3); ////RebootHard
		}
		if (risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_WHITE) == 1) {
			memset(DB,0,640*480*4);
			bfPutStr("Reloading List",&f,DB,640*4, (int)320.0-(f.w*12) ,10,1.0);
			memcpy(FB,DB,640*480*4);
			printk("Refreshing bios list");
			filecount = GetFiles("P:\\Bioses\\");
			selected = 0;
		}
		if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_UP) == 1)
		{
			if(selected) {
				selected--;				
			}
			else
			{
				selected = filecount-1;
			}
			
		}
		
		if (risefall_xpad_BUTTON(TRIGGER_XPAD_PAD_DOWN) == 1)
		{
			if(selected < (filecount - 1)) {
				selected++;		
			}
			else
			{
				selected = 0;
			}

		}
		if(risefall_xpad_BUTTON(TRIGGER_XPAD_KEY_A) == 1)
		{
			sprintf(entry->szRom,"P:\\Bioses\\%s",szBioses[selected]);
			bfClear(FB,0,0,640,480,640*4,0x00,0x00,0x00,0xFF);
			printk("Selected Bios %s\n",entry->szRom);
			break;
		}
	}

	free(bg);		
	printk("freeing font\n");
	bfFree(&f);

}
