#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>
#include <fat.h>
#include <wiiuse/wpad.h>

#include "easywbfs.h"
#include "wbfs.h"
#include "tools.h"

s32 Compare_discHdr(const void *a, const void *b)
{
	struct discHdr *hdr1 = (struct discHdr *)a;
	struct discHdr *hdr2 = (struct discHdr *)b;

	char *s1 = hdr1->title;
	char *s2 = hdr2->title;

	s32 ret;
	
	while (*s1 && *s2)
	{
		ret = toupper(*(u8*)s1) - toupper(*(u8*)s2);
		if (ret != 0)
		{
			return ret;
		}
		s1++;
		s2++;
	}
	return 0;
}

struct discHdr *gameList[2] = { NULL , NULL };
u32 gameCnt[2] = { 0 , 0 };
bool done[2] = { false , false };

struct discHdr *getGameHeader(u32 index)
{
	if (wbfsdevice == 0 || index >= gameCnt[wbfsdevice-1] || done[wbfsdevice-1] == false) return NULL;
	
	return &gameList[wbfsdevice-1][index];
}

char *getGameTitle(u32 index)
{
	if (wbfsdevice == 0)
	{
		return "This shouldn't happen";
	}
	if (done[wbfsdevice-1] == false )
	{
		return "Press A to mount WBFS";
	}
	if (index >= gameCnt[wbfsdevice-1])
	{
		return "Error mounting WBFS";
	}
	
	return getGameHeader(index)->title;
}

s32 getGameCount()
{
	if (done[wbfsdevice-1] == false)
	{
		return 0;
	}
	return gameCnt[wbfsdevice-1];
}

s32 Try_WBFS_Init()
{
	if (wbfsdevice == 0) return 0;
	if (done[wbfsdevice-1]) return 0;
	s32 ret;

	if (wbfsdevice == 1)
	{
		ret = WBFS_Init(WBFS_DEVICE_USB, 1);
	} else
	{
		ret = WBFS_Init(WBFS_DEVICE_SDHC, 1);
	}
	return ret;
}

s32 initGameList()
{
	if (wbfsdevice == 0) return 0;
	if (done[wbfsdevice-1]) return 0;
	struct discHdr *buffer = NULL;

	u32 cnt, len;
	s32 ret;

	gameCnt[wbfsdevice-1] = 0;
	
	/* Free memory */
	if (gameList[wbfsdevice-1])
		free(gameList[wbfsdevice-1]);

	ret = WBFS_Open();
	if (ret != 0)
	{
		//printf("Error: WBFS_Open fail\n");
		return ret;
	}

	/* Get list length */
	ret = WBFS_GetCount(&cnt);
	if (ret < 0)
	{
		//printf("Error: WBFS_GetCount fail\n");
		return ret;
	}

	/* Buffer length */
	len = sizeof(struct discHdr) * cnt;

	/* Allocate memory */
	buffer = (struct discHdr *)allocate_memory(len);
	if (!buffer)
	{
		return -1;
	}
	/* Clear buffer */
	memset(buffer, 0, len);

	/* Get header list */
	ret = WBFS_GetHeaders(buffer, cnt, sizeof(struct discHdr));
	if (ret < 0)
	{
		//printf("Error: WBFS_GetHeaders fail\n");
		goto err;
	}		

	qsort(buffer, cnt, sizeof(struct discHdr), Compare_discHdr);

	/* Set values */
	gameList[wbfsdevice-1] = buffer;
	gameCnt[wbfsdevice-1]  = cnt;
	done[wbfsdevice-1] = true;

	return 0;

err:
	/* Free memory */
	if (buffer)
		free(buffer);

	return ret;
}

