#include "MW4Headers.hpp"

#include <GOSScript\GOSScriptHeaders.hpp>
#include <GameOS\ToolOS.hpp>
#include "FileDialog.hpp"
#include <Stuff\Stuff.hpp>

char * FileDialog::src_dir = NULL;
char * FileDialog::search_string = NULL;
char * FileDialog::dialog_name = NULL;
	
char * FileDialog::indicated_file = NULL;
char * FileDialog::full_path = NULL;
char * FileDialog::this_dir = NULL;
const char * FileDialog::valid_drives = NULL;
	
int FileDialog::selected_drive = 0;
int FileDialog::number_files = 0;
int FileDialog::number_drives = 0;
int FileDialog::number_directories = 0;
int FileDialog::max_filename_length = 256;
char ** FileDialog::filenames = NULL;
char ** FileDialog::drivenames = NULL;
int FileDialog::lit = -1;
int FileDialog::hscroll_pos = 0;




FileDialog::FileDialog(char * name, char * search, char * dir)
{
	dialog_name = (char *) gos_Malloc(256);
	search_string = (char *) gos_Malloc(256);
	strcpy(search_string,search);
	strcpy(dialog_name,"Open ERF");
	src_dir = (char *) gos_Malloc(256);
	this_dir = (char *) gos_Malloc(256);
//	indicated_file = (char *) gos_Malloc(256);
	indicated_file = NULL;
	full_path = (char *) gos_Malloc(256);
	src_dir[0] = '.';
	src_dir[1] = '\\';
	src_dir[2] = 0;
	strcpy(src_dir,dir);
	filenames = NULL;
	drivenames = NULL;
	lit = -1;
//	*indicated_file=0;
	hscroll_pos = 0;

	gosScript_RegisterVariable("selected_drive",&selected_drive,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("lit",&lit,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("search_string",&search_string,GOSVAR_STRING,0, NULL);
	gosScript_RegisterVariable("dialog_name",&dialog_name,GOSVAR_STRING,0, NULL);
	gosScript_RegisterVariable("hscroll_pos",&hscroll_pos,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("indicated_file",&indicated_file,GOSVAR_STRING,0, NULL);
	gosScript_RegisterVariable("valid_drives",&filenames,GOSVAR_STRING,26, NULL);
	gosScript_RegisterVariable("drivenames",&drivenames,GOSVAR_STRING,32, NULL);
	gosScript_RegisterVariable("filenames",&filenames,GOSVAR_STRING,1024, NULL);
	gosScript_RegisterVariable("src_dir",&src_dir,GOSVAR_STRING,0, NULL);
	gosScript_RegisterVariable("this_dir",&this_dir,GOSVAR_STRING,0, NULL);
	gosScript_RegisterVariable("ChangeDrive",&ChangeDrive,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("InitializeFileDialog",&InitializeFileDialog,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("ReceivedFileFromDialog",&ReceivedFileFromDialog,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("number_files",&number_files,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("number_drives",&number_drives,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("number_directories",&number_directories,GOSVAR_INT,0, NULL);
	gosScript_RegisterVariable("max_filename_length",&max_filename_length,GOSVAR_INT,0, NULL);

}

FileDialog::~FileDialog()
{
	gosScript_UnregisterVariable("selected_drive");
	gosScript_UnregisterVariable("lit");
	gosScript_UnregisterVariable("search_string");
	gosScript_UnregisterVariable("dialog_name");
	gosScript_UnregisterVariable("hscroll_pos");
	gosScript_UnregisterVariable("indicated_file");
	gosScript_UnregisterVariable("valid_drives");
	gosScript_UnregisterVariable("drivenames");
	gosScript_UnregisterVariable("filenames");
	gosScript_UnregisterVariable("src_dir");
	gosScript_UnregisterVariable("this_dir");
	gosScript_UnregisterVariable("ChangeDrive");
	gosScript_UnregisterVariable("InitializeFileDialog");
	gosScript_UnregisterVariable("receivedFileFromDialog");
	gosScript_UnregisterVariable("number_files");
	gosScript_UnregisterVariable("number_drives");
	gosScript_UnregisterVariable("number_directories");
	gosScript_UnregisterVariable("max_filename_length");
	gos_Free(dialog_name);
	gos_Free(search_string);
	gos_Free(src_dir);
	gos_Free(this_dir);
	if( indicated_file )
		gos_Free(indicated_file);
	gos_Free(full_path);
}


char * FileDialog::Execute()
{
	SPEW(("daberger", "Script load should not be hardcoded"));
	gosScript_ExecuteScript("Content\\ShellScripts\\filedialog.script",0x2000,NULL);
	if (indicated_file == NULL)
		return NULL;
	else
	{
		strcpy(full_path,src_dir);
		strcat(full_path,indicated_file);
		return full_path;
	}
}

bool FileDialog::InitializeFileDialog(void * instance)
{
	if (filenames)
	{
		for(int i=0; i < number_files; i++)
		{
			gos_Free((char *)filenames[i]);
		}
		gos_Free(filenames);
	}
	filenames = (char **) gos_Malloc(1024*sizeof(char *));

	if (drivenames)
	{
		for(int i=0; i < number_drives; i++)
		{
			gos_Free((char *)drivenames[i]);
		}
		gos_Free(drivenames);
	}

	char drives[256];
	number_drives = gos_GetValidDrives( drives, 256 ) / 4;
	drivenames = (char **) gos_Malloc(sizeof(char *) * number_drives);
	for(int i=0; i < number_drives; i++)
	{
		drivenames[i] = (char *) gos_Malloc(sizeof(char) * 4);
		strcpy(drivenames[i],&drives[i*4]);
	}



	char cur_dir[256];
	strcpy(cur_dir,src_dir);
	strcat(cur_dir,"*.*");

	number_files = number_directories = 0;
	char * tmp = gos_FindDirectories(cur_dir);
	gos_GetFullPathName(src_dir,src_dir);

	// strip all but last directory
	char * handy = &src_dir[strlen(src_dir)-2];
	while(handy != src_dir)
	{
		if (*handy != '\\')
			handy--;
		else
		{
			handy++;
			break;
		}
	}

	strcpy(this_dir,handy);
	if (this_dir[strlen(this_dir)-1] == '\\')
		this_dir[strlen(this_dir)-1] = 0;

	if (src_dir[strlen(src_dir)-1] !='\\')
	{
		strcat(src_dir,"\\");
	}

	while (tmp)
	{
		filenames[number_files] = (char *) gos_Malloc(strlen(tmp)+1);
		strcpy(filenames[number_files],tmp);
		number_files++;
		number_directories++;
		tmp = gos_FindDirectoriesNext();
	}
	gos_FindDirectoriesClose();
	qsort( filenames, number_files, sizeof(char *), SortString );

	strcpy(cur_dir,src_dir);
	strcat(cur_dir,search_string);

	tmp = gos_FindFiles(cur_dir);
	while (tmp)
	{
		filenames[number_files] = (char *) gos_Malloc(strlen(tmp)+1);
		strcpy(filenames[number_files],tmp);
		number_files++;
		tmp = gos_FindFilesNext();
	}
	gos_FindFilesClose();
	qsort( &filenames[number_directories], number_files-number_directories, sizeof(char *), SortString );

	// what drive are we currently on?
	for(i=0; i < number_drives; i++)
	{
		if (strnicmp(drivenames[i], cur_dir,3) == 0)
		{
			selected_drive = i;
			break;
		}
	}
	return true;

}

bool FileDialog::ReceivedFileFromDialog(void * instance)
{
	if (lit == -10)
	{
		if (src_dir[strlen(src_dir)-1] != '\\')
			strcat(src_dir,"\\");
		strcat(src_dir,"..");// change directories
		strcat(src_dir,"\\");
		lit = -1;
		return 0;
	}
	if (lit > -1 && lit < number_directories)
	{
		if (src_dir[strlen(src_dir)-1] != '\\')
			strcat(src_dir,"\\");
		strcat(src_dir,indicated_file);// change directories
		strcat(src_dir,"\\");
		lit = -1;
		return 0;
	}
	else
	{
		if (strrchr(indicated_file,'*'))
		{
			strcpy(search_string,indicated_file);
			InitializeFileDialog(NULL);
			return 0;
		}
		char tmp[1024];
		strcpy(tmp,src_dir);
		strcat(tmp,indicated_file);
		if (!gos_DoesFileExist(tmp))
		{
			// no file by that name!
			return 0;
		}
		else
		{
			// load the file!
			return 1;
		}
	}
}

//-----------------------------------------
// Compare two strings for ascending order
//-----------------------------------------
int FileDialog::SortString( const void* arg1, const void *arg2 )
{
	char * str1 =(char *) ((int *)arg1)[0];
	char * str2 =(char *) ((int *)arg2)[0];

	return stricmp(str1,str2);
}

char * FileDialog::GetDirectory()
{
	return FileDialog::src_dir;
}

bool FileDialog::ChangeDrive(void * instance)
{
	strcpy(src_dir,drivenames[selected_drive]);
	InitializeFileDialog(instance);
	return 1;
}
