#include <xtl.h>
#include "XBInput.h"
#include "app.h"
#include "FileMenu.h"
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int gamesFound;
int scrollCount = 0;
class FileMenu FileMenu;
int selected = 1;
float scaleZ2 = 0;
int extra = 0;
int b = 0;
vector<string> d2;
extern int romMove;
extern bool initMovie(char* name);
extern "C" int dprintf(char *format, ...);
extern std::string INI_PATH;
int zipChanged = 0;
#include "undocumented.h"
extern int HideFileExtension;
//extern unsigned char savePartition;
  extern int zTopBR;
extern int zLeftBR;
int rWidth = 190;
  extern int zTopV;
  extern int musicMode;
extern   int oldScreenShot ;
extern int zLeftV;
  extern int zTopSM;
extern int zLeftSM;



  extern int zTopGM;
extern int zLeftGM;

 extern int zTopCD;
extern int zLeftCD;

  extern int zTopMM;
extern int zLeftMM;

  extern int zTopBF;
extern int zLeftBF;

extern int zTopGT;
extern int zLeftGT;

extern int zTopIT;
extern int zLeftIT;
extern XBGAMEPAD g_Gamepads[4];

extern std::string ARTWORK_SHOTS_1_PATH;
extern std::string ARTWORK_SHOTS_2_PATH;
extern std::string ARTWORK_SHOTS_3_PATH;
extern std::string ARTWORK_SHOTS_4_PATH ;
extern std::string ARTWORK_SHOTS_5_PATH; 
extern std::string ARTWORK_SHOTS_6_PATH; 
extern std::string ARTWORK_SHOTS_7_PATH; 
extern std::string ARTWORK_SHOTS_8_PATH; 
extern std::string VIDEO_PATH;

extern int zTopCC;
extern int zLeftCC;

#include <string>
using namespace std;

struct fileDisplay {
	string name;
	string path;
	bool isAGame;
	bool isARoot;
	bool isADirectory;
	bool topLevel;
	int soundTrack;
	int song;
	int archive;
};
vector<fileDisplay> fileList;
int FileMenuSelected = 0;

int maxGames = 13;


#include "zunzip.h"

extern int HDMode;
extern int ShowZipContents;
extern int HideFileExtension;
WCHAR textOld[512];
int showZipName = 0;





struct archiveContents {
	string parentPath;
	vector<std::string> archiveList;
};

archiveContents archive;
int archiveGameSelected = 0;


int getZipFileName(char* filename, char* zipfile) {
	unzFile file = unzOpen(zipfile);
	if(file == NULL) {
		return 0;
	}

    unzGoToFirstFile(file);
    unz_file_info info;
    //while(port == UNZ_OK)
    //{
    char name[132];
    unzGetCurrentFileInfo(file, &info, name, 128, NULL,0, NULL,0);
	

    //if ( strrchr(name, '.' ) )
    strcpy( filename, name );
    
	unzClose(file);
    return 1;
	
	//port = unzGoToNextFile(file);
    //}
    //if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) )
    //{
	//	//////dprintf("Closing zip file\n");
     //   unzClose(file);
    //    return 0;
   // }
}

void checkForCharacterRemoval(std::string &t) {
	////////dprintf("Passed in: %s\n", t.c_str());
	char buffer[1024];
	for(int i = 0; i < 1024; i++) buffer[i] = '\0';
	for(int i = 0; i < t.size(); i++) buffer[i] = t[i];
	
	if(HideFileExtension == 1) {
		////////dprintf("Hide File Extension for: %s\n", buffer);

		//test.zip
		//size = 8
		for(int i = 0; i < t.size(); i++) {
			if(buffer[i] == '\0') break;
			if((buffer[i] ==  '.' && buffer[i+1] == 'z' && buffer[i+2] == 'i' && buffer[i+3] == 'p' && buffer[i+4] == '\0') || 
				(buffer[i] == '.' && buffer[i+1] == 's' && buffer[i+2] == 'm' && buffer[i+3] == 'c' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 's' && buffer[i+2] == 'f' && buffer[i+3] == 'c' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 's' && buffer[i+2] == 'w' && buffer[i+3] == 'c' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'f' && buffer[i+2] == 'i' && buffer[i+3] == 'g' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'u' && buffer[i+2] == 'f' && buffer[i+3] == 'o' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'b' && buffer[i+2] == 'i' && buffer[i+3] == 'n' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == '0' && buffer[i+2] == '5' && buffer[i+3] == '8' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == '0' && buffer[i+2] == '7' && buffer[i+3] == '8' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'u' && buffer[i+2] == 's' && buffer[i+3] == 'a' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'e' && buffer[i+2] == 'u' && buffer[i+3] == 'r' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'j' && buffer[i+2] == 'a' && buffer[i+3] == 'p' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == '7' && buffer[i+2] == 'z' && buffer[i+3] == 'p' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+1] == 'j' && buffer[i+2] == 'm' && buffer[i+3] == 'a' && buffer[i+4] == '\0')	
				) {
					buffer[i] = '\0';
					////////dprintf("File Without Extension: %s\n", buffer);
					break;

				}
		}
	}

	if(HideFileExtension == 2) {
		////////dprintf("Strip extra characters from: %s\n", buffer);
		for(int i = 0; i < t.size(); i++) {
			if(buffer[i] == '\0') break;

			if(  

				((buffer[i] == '(') || (buffer[i] == '[') || 
				(buffer[i] == '.' && buffer[i+4] == '\0') ||
				(buffer[i] == '.' && buffer[i+2] == '\0'))
				) {

					if(!(buffer[i] == '.' && buffer[i+1] == '.' && buffer[i+2] == '.' && buffer[i+3] == '\0'))
					   buffer[i] = '\0';
					
					////////dprintf("Extra characters stripped: %s\n", buffer);
					break;
				}
		}
	}


	//int r = t.find_first_of("\0", 0);
	////////dprintf("First Null at: %d\n", r);

	//if(r != string::npos) {
	//	//////dprintf("Shrinking file\n");
	//	t = t.substr(0, r);
	//}
	std::string a = buffer;
	t = a;
	////////dprintf("Result equals: %s\n", t.c_str());
}

std::string zip;
void updateZipFilename() {
	if(fileList[FileMenuSelected].isAGame && ShowZipContents == 1) {
		char buffer[1024];
		for(int s = 0; s < 1024; s++) buffer[s] = '\0';
		std::string zipFile = fileList[FileMenuSelected].path;
		unzFile file = unzOpen(zipFile.c_str());
		if(file != NULL) {
			unzGoToFirstFile(file);
			unz_file_info info;
			char name[132];
			unzGetCurrentFileInfo(file, &info, name, 128, NULL,0, NULL,0);
			strcpy(buffer, name );
			unzClose(file); 
			zip = buffer;
		}
	}
}
extern int romBrowserCount;
extern int vSpace;
void drawFileList() {
	int yDB = 100;
	DWORD color = menuColor[GameNameColor];
	int start = 0;
	
	
	if(FileMenuSelected > (romBrowserCount/2) && (fileList.size() > romBrowserCount)) {
		start += (FileMenuSelected  - (romBrowserCount/2));
	}

	if((FileMenuSelected > ((fileList.size()-1) - (romBrowserCount/2))) && (fileList.size() > romBrowserCount)) {
		start = (fileList.size() - romBrowserCount);
	}

	for(int i = start; i <  start +romBrowserCount; i++) {
		if(i == fileList.size()) return;

		color = menuColor[GameNameColor];
		if(fileList[i].name[0] == '.') color = 0xffffffff;//white ...
		if(fileList[i].name[0] == '<') color =menuColor[FolderColor]; 

		std::string t = fileList[i].name;
		
		if(fileList[i].isAGame) 
			checkForCharacterRemoval(t);
		
		if(i ==FileMenuSelected) { 
			color = menuColor[GameNameSelectedColor];
			WCHAR atext2345[1024]={0};
			for(int r = 0; r < 1024; r++) {
				if((t.c_str())[r] == '\0') {
					atext2345[r] = '\0';
					break;
				}
				atext2345[r] = (t.c_str())[r];
			}
			FontSetColour(color);
			FontText(atext2345,105+ zLeftBR, yDB+20+ zTopBR, rWidth);

			//Now draw the full name;
			if(ShowZipContents == 1 && (fileList[FileMenuSelected].isAGame)) {
				checkForCharacterRemoval(zip);
				for(int r = 0; r < 1024; r++) {
					if(zip[r] == '\0') {
						atext2345[r] = '\0';
						break;
					}
					atext2345[r] = zip[r];
				}	
			}
			FontSetColour(menuColor[FullNameColor]);
			FontSmallText(atext2345,60,426+ zTopBF, 550);
		}
		else {
			WCHAR atext2345[1024]={0};
			for(int r = 0; r < 1024; r++) {
				if((t.c_str())[r] == '\0') {
					atext2345[r] = '\0';
					break;
				}
				atext2345[r] = (t.c_str())[r];
			}
			FontSetColour(color);
			FontText(atext2345,105+ zLeftBR, yDB+20+ zTopBR, rWidth);
		}
		yDB+= vSpace;
	}
}

bool operator<(const fileDisplay &l, const fileDisplay &r) {
			std::string a = l.name;
			std::string b = r.name;
			transform(a.begin(), a.end(), a.begin(), tolower);
			transform(b.begin(), b.end(), b.begin(), tolower);
			if(a < b) return true; else return false;
}


int favorites = 0;
vector<fileDisplay> favoriteList;
vector<fileDisplay> favoriteListTemp;
vector<fileDisplay> backup;
int backupSelected = 0;
int backupChanged = 0;

int empty = 0;
void buildFavorites() {
    favoriteList.clear();
	FILE* f;
	std::string t = INI_PATH;
	t = t + "favorites.ini";
	
	////dprintf("Going to open: %s\n", t.c_str());
	f = fopen(t.c_str(), "r");
	
	

	if(!f) {
		////dprintf("Favorites file does not exist\n");
		fileDisplay fg;
		std::string e = "No Favorites Found";
		fg.name = e;
		fg.path = e;
		fg.isARoot = false;
		fg.isADirectory = false;
		fg.isAGame = false;
		fg.topLevel = false;
	//	//dprintf("Going to add: %s\n", fg.name.c_str());
		favoriteList.push_back(fg);
		////dprintf("Just called push_back\n");
		fileList.clear();
		////dprintf("Just called cear\n");
		fileList = favoriteList;
		////dprintf("Just called fileList = favoritesList\n");
		favoriteList.clear();
		//dprintf("Just called favoriteList.clear()\n");
		FileMenuSelected = 0;
		////dprintf("favoriteList = Just added no game found: %s\n", favoriteList[0].name.c_str());
		////dprintf("fileList = Just added no game found: %s\n", fileList[0].name.c_str());
		empty = 1;
		return;
	}
	////dprintf("Favorites file found\n");
	empty = 0;
	while(true) {
		////dprintf("Reading favorites file\n");
		char line[1024];
		fgets(line,1024, f);
		//- = EOF
		if(line[0] == '-' ) { 
			////dprintf("Read a -. Going to sort.\n");
			sort(favoriteList.begin(), favoriteList.end());
			fileList.clear();
			fileList = favoriteList;
			favoriteList.clear();
			fclose(f); 
			FileMenuSelected = 0;
			if(fileList.size() == 0) {
				////dprintf("Read favorites but it was empty\n");
				fileDisplay fg;
				std::string e = "No Favorites Found";
				fg.name = e;
				fg.path = e;
				fg.isARoot = false;
				fg.isADirectory = false;
				fg.isAGame = false;
				fg.topLevel = false;
				fg.archive = 0;

				favoriteList.push_back(fg);
				fileList.clear();
				fileList = favoriteList;
				favoriteList.clear();
				FileMenuSelected = 0;
			}
			else {
				////dprintf("Favorites list from file is:\n");
				//for(int i = 0; i < fileList.size(); i++) {
					////dprintf("%s\n",    fileList[i].name.c_str());
				//}	
			}
			////dprintf("Read all the favorites from file. Returning.\n");
			return;
		}
	
		fileDisplay gfile;
		for(int z = 0; z < 1024; z++)  { if(line[z] == '\n') line[z] = '\0'; }
		std::string nm = line;
		gfile.name = nm;
		char p[1024];
		fgets(p,1024, f);	
		for(int z = 0; z < 1024; z++)  { if(p[z] == '\n')p[z] = '\0'; }
		std::string pt = p;
		gfile.path = p;
		gfile.isAGame = true;
		gfile.isARoot = false;
		gfile.isADirectory = false;
		gfile.topLevel = false;
		////dprintf("Adding in loop to favorites: %s\n",    gfile.name.c_str());
	
		std::string t = "No Favorites Found";
		
		int r = gfile.path.find(".7z", 0);
		if(r == string::npos) {
			gfile.archive = 0;
		}
		else {
			gfile.archive = 1;
		}

		if(gfile.name != t)
			favoriteList.push_back(gfile);
	}
}



void  removeFromFavorites() {
	////dprintf("Removing from favorites: %s\n",    fileList[FileMenuSelected].name.c_str());
	if(fileList.size() == 1 && FileMenuSelected == 0) {
		fileList.clear();
		fileDisplay fg;
		std::string e = "No Favorites Found";
		fg.name = e;
		fg.path = e;
		fg.isARoot = false;
		fg.isADirectory = false;
		fg.isAGame = false;
		fg.topLevel = false;
		fileList.push_back(fg);
		FileMenuSelected = 0;
		return;
	}
	if(fileList.size() > 1) {
		fileList.erase(fileList.begin()+FileMenuSelected);
	}
	if(FileMenuSelected > 0) FileMenuSelected--;
}

void addToFavorites() {
	////dprintf("Add to favorites: %s\n",    fileList[FileMenuSelected].name.c_str());
	fileDisplay gf;
	gf.name = fileList[FileMenuSelected].name;
	gf.path =  fileList[FileMenuSelected].path;
	gf.isARoot = false;
	gf.isADirectory = false;
	gf.isAGame = true;
	gf.topLevel = false;
	favoriteListTemp.push_back(gf);
	sort(favoriteListTemp.begin(), favoriteListTemp.end());
}

void restoreRomBrowser() {
	if(backupChanged == 1) {
		fileList.clear();
		fileList = backup;
		backup.clear();
		FileMenuSelected = backupSelected;
	}
}
void saveFavorites() {
   backupChanged = 1;
	backup = fileList;
	backupSelected = FileMenuSelected;

	////dprintf("Saving favorites\n");
	buildFavorites();
	////dprintf("After build favorites in saveFavorites\n");
	

	if(empty == 1) {
		////dprintf("Build was empty\n");
		FILE* f;
		std::string t =INI_PATH + "favorites.ini";
		f = fopen(t.c_str(), "w+");

		for(int i = 0; i < favoriteListTemp.size(); i++) {
			fprintf(f, "%s\n", favoriteListTemp[i].name.c_str());
			fprintf(f, "%s\n", favoriteListTemp[i].path.c_str());
		}
		fprintf(f, "%s\n", "-");
		fileList.clear();
		favoriteListTemp.clear();

		fclose(f);
		return;
	}

	////dprintf("Build was not empty\n");
	for(int i = 0; i < favoriteListTemp.size(); i++) {
		////dprintf("Adding new temps from favoritesTemp: %s\n",    favoriteListTemp[i].name.c_str());
		fileList.push_back(favoriteListTemp[i]);
	}
	////dprintf("Now favorites list is after adding any pending temps:\n");
	//for(int i = 0; i < fileList.size(); i++) {
		////dprintf("%s\n",    fileList[i].name.c_str());
	//}

	sort(fileList.begin(), fileList.end());
	FILE* f;
	std::string t = INI_PATH + "favorites.ini";
	f = fopen(t.c_str(), "w+");

	for(int i = 0; i < fileList.size(); i++) {
		  //  //dprintf("Writing favorites: %s\n",    fileList[i].name.c_str());
			
			std::string t = "No Favorites Found";
			if(fileList[i].name != t) {
				fprintf(f, "%s\n", fileList[i].name.c_str());
				fprintf(f, "%s\n", fileList[i].path.c_str());
			}
	}
	fprintf(f, "%s\n", "-");
	favoriteListTemp.clear();
	fclose(f);
	////dprintf("Returning from favorites save\n");
}

void saveFavoritesExit() {
	if(fileList.size() > 0) {
		if( !(fileList[0].isAGame)) { 
			fileList.clear(); 
			FILE* f;
			std::string t = INI_PATH + "favorites.ini";
			f = fopen(t.c_str(), "w+");
			fprintf(f, "%s\n", "-");
			fclose(f);
			return; 
		}
	}
	//dprintf("Saving favorites Exit\n");
	////dprintf("After build favorites in saveFavorites\n");

	sort(fileList.begin(), fileList.end());
	FILE* f;
	std::string t = INI_PATH + "favorites.ini";
	f = fopen(t.c_str(), "w+");
	for(int i = 0; i < fileList.size(); i++) {
		    //dprintf("Writing favorites: %s\n",    fileList[i].name.c_str());
			
			std::string t = "No Favorites Found";
			if(fileList[i].name != t) {
				fprintf(f, "%s\n", fileList[i].name.c_str());
				fprintf(f, "%s\n", fileList[i].path.c_str());
			}
	}
	fprintf(f, "%s\n", "-");
	fileList.clear();
	fclose(f);
	//dprintf("Returning from save favorites exit\n");
}
extern int musicPlayer;

std::string lastPath;
void searchDirectory(std::string pathToSearch, bool mountTopLevel) {
	lastPath = pathToSearch;

	//dprintf("Going to search directory: %s\n", pathToSearch.c_str());
	std::string path1 = pathToSearch;// + "*";
	std::string path2("*");
	std::string path = path1 + path2;
	fileList.clear();

	if(mountTopLevel) {
		fileDisplay f;
		f.name = "C:\\";
		f.path =  "C:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "E:\\";
		f.path = "E:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "F:\\";
		f.path = "F:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "G:\\";
		f.path = "G:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "DVD-ROM (Xbox Format)";
		f.path = "R:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "X:\\";
		f.path = "X:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "Y:\\";
		f.path = "Y:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);

		f.name = "Z:\\";
		f.path = "Z:\\";
		f.isARoot = false;
		f.isADirectory = true;
		f.isAGame = false;
		f.topLevel = false;
		fileList.push_back(f);
		return;
	}

	vector<fileDisplay> directories;
	int firstDirectory = 0;
	HANDLE find=NULL;
	WIN32_FIND_DATA wfd;
	memset(&wfd,0,sizeof(wfd));
	find=FindFirstFile(path.c_str(),&wfd);
	string tq;// = NULL;
	if (find ==INVALID_HANDLE_VALUE){ //Empty directory
		std::string root("...");
		fileDisplay f;
		f.name = root;
		f.archive = 0;
		std::string backPath = pathToSearch;
		//How many slashes are there
		int slash = 0;
		for(int i = 0; i < backPath.size(); i++) {
			if(backPath[i] == '\0') { 
				break;
			}
			else {
				if(backPath[i] == '\\')
					slash++;
			}
		}
		if(slash != 1) {
			f.topLevel = false;
			int slashTemp = 0;
			for(int i = 0; i < backPath.size(); i++) {
				if(backPath[i] == '\\') { 
					slashTemp++;
					if(slashTemp == (slash - 1)) {
						char buffer[1024];
						for(int m = 0; m < 1024; m++) buffer[m] = '\0';
						int s = 0;
						for(s = 0; s < i; s++) {
							buffer[s] = backPath[s]; 
						}
						buffer[s] = '\\';
						buffer[s+1] = '\0';
						tq = buffer;
						break;
					}
				}
			}
		}
		else {
			f.topLevel = true;	
		}
		f.path = tq;
		f.isAGame = false;
		f.isARoot = true;
		f.isADirectory = false;
		fileList.push_back(f); //Add the ..
		FindClose(find);
		return;

	}

	do {
		if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
			//Not a folder		 
			std::string fileFound(wfd.cFileName);
			fileDisplay f;
			f.name = fileFound;
			f.path = pathToSearch + fileFound;
			f.archive = 0;
			
			if(musicPlayer == 1 && musicMode == 1) {
				int r = fileFound.find(".nsf", 0);
				int r1 = fileFound.find(".spc", 0);
				int r2 = fileFound.find(".gym", 0);
				int r3 = fileFound.find(".vgm", 0);
				int r4 = fileFound.find(".gbs", 0);
				int r5 = fileFound.find(".NSF", 0);
				int r6 = fileFound.find(".SPC", 0);
				int r7 = fileFound.find(".GYM", 0);
				int r8 = fileFound.find(".VGM", 0);
				int r9 = fileFound.find(".GBS", 0);
				int r10 = fileFound.find(".vgz", 0);
				int r11 = fileFound.find(".VGZ", 0);
				if(r == string::npos && r1 == string::npos &&
					r2 == string::npos && r3 == string::npos && 
					r4 == string::npos &&
					r5 == string::npos && r6 == string::npos && 
					r7 == string::npos && r8 == string::npos && r9 == string::npos && 
					r8 == string::npos && r9 == string::npos && r10 == string::npos && 
					r11 == string::npos) {
						f.isAGame = false;
					}
					else {
						f.isAGame = true;
					}
			}
			else {
				int r = fileFound.find(".zip", 0);
				int r1 = fileFound.find(".smc", 0);
				int r2 = fileFound.find(".sfc", 0);
				int r3 = fileFound.find(".swc", 0);
				int r4 = fileFound.find(".fig", 0);
				int r5 = fileFound.find(".mgd", 0);
				int r6 = fileFound.find(".ufo", 0);
				int r7 = fileFound.find(".bin", 0);
				int r8 = fileFound.find(".058", 0);
				int r9 = fileFound.find(".078", 0);
				int r11 = fileFound.find(".usa", 0);
				int r12= fileFound.find(".eur", 0);
				int r13 = fileFound.find(".jap", 0);
				int ar = fileFound.find(".ZIP", 0);
				int ar1 = fileFound.find(".SMC", 0);
				int ar2 = fileFound.find(".SFC", 0);
				int ar3 = fileFound.find(".SWC", 0);
				int ar4 = fileFound.find(".FIG", 0);
				int ar5 = fileFound.find(".MGD", 0);
				int ar6 = fileFound.find(".UFO", 0);
				int ar7 = fileFound.find(".BIN", 0);
				int ar8 = fileFound.find(".058", 0);
				int ar9 = fileFound.find(".078", 0);
				int ar11 = fileFound.find(".USA", 0);
				int ar12= fileFound.find(".EUR", 0);
				int ar13 = fileFound.find(".JAP", 0);
				if(
					r == string::npos && r1 == string::npos && r2 == string::npos && r3 == string::npos && r4 == string::npos &&
					r5 == string::npos && r6 == string::npos && r7 == string::npos && r8 == string::npos && r9 == string::npos &&
					r11 == string::npos && r12 == string::npos && r13 == string::npos &&
					ar == string::npos && ar1 == string::npos && ar2 == string::npos && ar3 == string::npos && ar4 == string::npos &&
					ar5 == string::npos && ar6 == string::npos && ar7 == string::npos && ar8 == string::npos && ar9 == string::npos &&
					ar11 == string::npos && ar12 == string::npos && ar13 == string::npos) {
						f.isAGame = false;
					}
				else {
					f.isAGame = true;
				}
			}
			

			if(f.isAGame == false) {
				int r = fileFound.find(".7z", 0);
				//int r2 = fileFound.find(".rar", 0);
				if(r == string::npos) {
					f.isAGame = false;
				}
				else {
					f.isAGame = true;
					f.name += "p";
					f.archive = 1;
				}
			}
			
			
			//f.isAGame = true;
		
			if(f.isAGame) {
				f.isARoot = false;
				f.isADirectory = false;
				f.topLevel = false;
				fileList.push_back(f);
			}
		}
		else {
			std::string folderName(wfd.cFileName);
			folderName = "<" + folderName + ">"; 
			if(firstDirectory == 0) {
				std::string root("...");
				fileDisplay f;
				f.name = root;
				f.archive = 0;
				std::string backPath = pathToSearch;
				//How many slashes are there
				int slash = 0;
				for(int i = 0; i < backPath.size(); i++) {
					if(backPath[i] == '\0') { 
						break;
					}
					else {
						if(backPath[i] == '\\')
							slash++;
					}
				}
				if(slash != 1) {
					f.topLevel = false;
					int slashTemp = 0;
					for(int i = 0; i < backPath.size(); i++) {
						////dprintf("Loop start\n");
						if(backPath[i] == '\\') { 
							slashTemp++;
							if(slashTemp == (slash - 1)) {
								////dprintf("Last slash: %d\n", i);
								//backPath[i+1] = '\0';
								char buffer[1024];
								for(int m = 0; m < 1024; m++) buffer[m] = '\0';
								int s = 0;
								for(s = 0; s < i; s++) {
									buffer[s] = backPath[s]; 
									////dprintf("Just added: %c\n", buffer[s]);
								}
								//	////dprintf("Buffer Before slash: %s\n", buffer);
								buffer[s] = '\\';
								//	////dprintf("Buffer after slash: %s\n", buffer);
								buffer[s+1] = '\0';
								//	////dprintf("Buffer null: %s\n", buffer);
								tq =buffer;
								//backPath = tq;
								//	////dprintf("New BackPath tq: %s\n", tq.c_str());

								//i = backPath.size();
								break;
							}

						}
					}
				}
				else {
					f.topLevel = true;	
				}

				f.path =tq;
				f.isAGame = false;
				f.isARoot = true;
				f.isADirectory = false;

				directories.push_back(f); //Add the ..
				// ////dprintf("Just added root with a path of: %s\n", f.path.c_str());
				fileDisplay d;
				d.archive = 0;
				d.name = folderName;
				std::string folderNameNoBrackets(wfd.cFileName);
				d.path = pathToSearch +  folderNameNoBrackets + "\\";
				d.isAGame = false;
				d.isARoot = false;
				d.isADirectory = true;
				d.topLevel = false;
				directories.push_back(d); 
				// ////dprintf("Just added first directory with a path of: %s\n", d.path.c_str());
				firstDirectory = 1;
			}
			else {
				fileDisplay d;
				d.archive = 0;
				d.name = folderName;
				std::string folderNameNoBrackets(wfd.cFileName);
				d.path = pathToSearch +  folderNameNoBrackets + "\\";
				d.isAGame = false;
				d.isARoot = false;
				d.isADirectory = true;
				d.topLevel = false;
				directories.push_back(d); 
				//////dprintf("Just added a directory with a path of: %s\n", d.path.c_str());
			}
		}
	} while (FindNextFile(find,&wfd) !=0);

	if(fileList.size() != 0 && directories.size() == 0) {//roms no folders
		std::string root("...");
		fileDisplay f;
		f.archive = 0;
		f.name = root;

		std::string backPath = pathToSearch;

		//How many slashes are there
		int slash = 0;
		for(int i = 0; i < backPath.size(); i++) {
			if(backPath[i] == '\0') { 
				break;
			}
			else {
				if(backPath[i] == '\\')
					slash++;
			}
		}
		if(slash != 1) {
			f.topLevel = false;
			int slashTemp = 0;
			for(int i = 0; i < backPath.size(); i++) {
				if(backPath[i] == '\\') { 
					slashTemp++;
					if(slashTemp == (slash - 1)) {
						//backPath[i+1] = '\0';
						char buffer[1024];
						for(int m = 0; m < 1024; m++) buffer[m] = '\0';
						int s = 0;
						for(s = 0; s < i; s++) {
							buffer[s] = backPath[s]; 
						}
						buffer[s] = '\\';
						buffer[s+1] = '\0';
						tq = buffer;
						//backPath = tq;

						////dprintf("BackPath tq: %s\n", tq.c_str());

						break;
					}
				}
			}
		}
		else {
			f.topLevel = true;	
		}

		f.path = tq;
		f.isAGame = false;
		f.isARoot = true;
		f.isADirectory = false;

		fileList.push_back(f); //Add the ..
		sort(fileList.begin(), fileList.end());
		FindClose(find);
		return;
	}

	if(fileList.size() == 0 && directories.size() == 0) {//no roms no folders
		std::string root("...");
		fileDisplay f;
		f.archive = 0;
		f.name = root;
		std::string backPath = pathToSearch;
		//How many slashes are there
		int slash = 0;
		for(int i = 0; i < backPath.size(); i++) {
			if(backPath[i] == '\0') { 
				break;
			}
			else {
				if(backPath[i] == '\\')
					slash++;
			}
		}
		if(slash != 1) {
			f.topLevel = false;
			int slashTemp = 0;
			for(int i = 0; i < backPath.size(); i++) {
				if(backPath[i] == '\\') { 
					slashTemp++;
					if(slashTemp == (slash - 1)) {
						//backPath[i+1] = '\0';
						char buffer[1024];
						for(int m = 0; m < 1024; m++) buffer[m] = '\0';
						int s = 0;
						for(s = 0; s < i; s++) {
							buffer[s] = backPath[s]; 
						}
						buffer[s] = '\\';
						buffer[s+1] = '\0';
						tq = buffer;
						break;
					}
				}
			}
		}
		else {
			f.topLevel = true;	
		}

		f.path = tq;
		f.isAGame = false;
		f.isARoot = true;
		f.isADirectory = false;
		fileList.push_back(f); //Add the ..
		FindClose(find);
		return;
	}

	sort(fileList.begin(), fileList.end());
	sort(directories.begin(), directories.end());
	//Concatenate them into directories
	directories.insert(directories.end(), fileList.begin(), fileList.end());
	//Clear file list
	fileList.clear();
	fileList = directories;
	directories.clear();
	FindClose(find);
	return;
}

void drawListOfArchiveGames() {
	int yDB = 110;
	DWORD color;
	int start = 0;
	
	if(archiveGameSelected > 7 && (archive.archiveList.size() > 15)) {
		start += (archiveGameSelected  - 7);
	}

	if((archiveGameSelected > ((archive.archiveList.size()-1) - 7)) && (archive.archiveList.size() > 15)) {
		start = (archive.archiveList.size() - 15);
	}

	for(int i = start; i <  start +15; i++) {
		if(i == archive.archiveList.size()) return;
		if(i ==archiveGameSelected) color = 0xffff00; else color = 0xffffff; 
		WCHAR atext2345[1024]={0};

		std::string t = archive.archiveList[i];
		for(int r = 0; r < 1024; r++) {
			if((t.c_str())[r] == '\0') {
				atext2345[r] = '\0';
				break;
			}
			atext2345[r] = (t.c_str())[r];
		}
		FontSetColour(color);
		FontSmallText(atext2345,sWidth/2,yDB, 600);
		yDB+=20;
	}
}

void buildArchiveList(char *name) {
	
}

extern unsigned char rightAnalog;
extern unsigned char leftAnalog;
double slowArchive = 0;
extern float scrollSpeed;
extern int DisableSounds;
extern void playEffect(int i);
extern int archiveMode = 0;
void processArchiveList() {
	if(g_Gamepads[0].Event == XBGAMEPAD_B) { 
		if(DisableMenuSounds == 0) playEffect(1); 
		archiveMode = 0;
		return; 
	}

	if( g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) {
		if(slowArchive >= 1)  { 
			slowArchive = 0;
		}
		if(leftAnalog == 255)
			slowArchive = scrollSpeed;
		else
			slowArchive += ((float)leftAnalog/255.0f);
		archiveGameSelected-=((int)slowArchive); if(archiveGameSelected < 0) archiveGameSelected = 0;
	}


	if( g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]) {
		if(slowArchive >= 1) { 
			slowArchive = 0; 
		} 
		if(rightAnalog == 255)
			slowArchive = scrollSpeed;
		else
			slowArchive += ((float)rightAnalog/255.0f);
		archiveGameSelected+=((int)slowArchive); if(archiveGameSelected >= archive.archiveList.size()) archiveGameSelected = archive.archiveList.size() - 1;
	}


	if(g_Gamepads[0].Event == XBGAMEPAD_DPAD_UP) { 
		if(DisableMenuSounds == 0 && archiveGameSelected != 0) playEffect(0);
		archiveGameSelected--; if(archiveGameSelected < 0) archiveGameSelected = 0;
	}

	if(g_Gamepads[0].Event == XBGAMEPAD_DPAD_DOWN) { 
		if(DisableMenuSounds == 0 && (archiveGameSelected != (archive.archiveList.size() - 1))) playEffect(0);	
		archiveGameSelected++; if(archiveGameSelected >= archive.archiveList.size()) archiveGameSelected = archive.archiveList.size() - 1;	
	}

	if(g_Gamepads[0].Event == XBGAMEPAD_A) { 
		//extractArchive((char*)(fileList[FileMenuSelected].path.c_str()), archiveGameSelected);
		archiveMode = 0;
		return; 
	}



	return;
}
extern "C" {
extern void stopMovie();
}
extern int screenShotSlotAuto;
int wasThere = 0;

void analogScroll() {
	stopMovie();
	if(TexPreview) {
				TexPreview->Release();
				TexPreview = NULL;
		}
		useNoRom =true;
}


void releaseMP() {
	if(TexPreviewMedia) {
		TexPreviewMedia->Release();
		TexPreviewMedia = NULL;
	}
}

void switchMP(int i) {
	if(TexPreviewMedia) {
		TexPreviewMedia->Release();
		TexPreviewMedia = NULL;
	}

	std::string imagePath;

	imagePath = "D:\\media\\player\\redmetal.png";
	if(i == 0) imagePath = "D:\\media\\player\\redmetal.png";
	if(i == 1) imagePath = "D:\\media\\player\\greenindustrial.png";
	if(i == 2) imagePath = "D:\\media\\player\\blackpalm.png";
	if(i == 3) imagePath = "D:\\media\\player\\greenpalm.png";
	if(i == 4) imagePath = "D:\\media\\player\\dvd.png";
	
	D3DXCreateTextureFromFileEx(Device, 
					imagePath.c_str(), 
					D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file 
					D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
					1,            //MipLevels
					0,            //Usage, Is this to be used as a Render Target? 0 == No
					D3DFMT_A8R8G8B8, //32-bit with Alpha, everything should support this
					D3DPOOL_MANAGED,//Pool, let D3D Manage our memory
					D3DX_DEFAULT, //Filter:Default filtering
					D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
					0,            //Disable ColourKey
					NULL,         //SourceInfo, returns extra info if we want it (we don't)
					NULL,         //Palette:We're not using one
					&TexPreviewMedia);
					
		            
	  return;
}


extern float freeMemory();
extern bool videoRender;

void loadScreenshot() {
	
	if(fileList[FileMenuSelected].isAGame == false) { analogScroll();  return; }


	std::string a =  fileList[FileMenuSelected].name;
	
	
	std::string ext = ".zip"; 

	int r = a.find(".zip", 0);
	if(r == string::npos) { ext = ".smc"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".7zp"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".sfc"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".swc"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".fig"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".mgd"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".ufo"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".bin"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".058"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".078"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".usa"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".eur"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".jap"; r = a.find(ext, 0);}

	if(r == string::npos) { ext = ".SMC"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".SFC"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".SWC"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".FIG"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".MGD"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".UFO"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".BIN"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".058"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".078"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".USA"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".EUR"; r = a.find(ext, 0);}
	if(r == string::npos) { ext = ".JAP"; r = a.find(ext, 0);}

	if(r == string::npos) return;
	
	std::string b = a.substr(0, r);
	std::string c;
	std::string imagePath;

	string q = VIDEO_PATH;
	q += b;
	q += ".xmv";

	
	if(freeMemory() < 4) {
		//videoRender = false;
		useNoRom =true;
		initMovie((char*) q.c_str());
		return;
	}

	dprintf("Init movie start\n");
	if(initMovie((char*) q.c_str())) {
		dprintf("Init movie success\n");
		//useNoRom =true;
		//return;
	}
	dprintf("Init movie failed\n");
	

	
	ext = ".png";
	if(screenShotSlotAuto == 1) { 
		c = b + ext ;
		imagePath = ARTWORK_SHOTS_1_PATH + c;
	}
	else if(screenShotSlotAuto == 2) { 
		c = b + ext ; 
		imagePath = ARTWORK_SHOTS_2_PATH + c;
	}
	else if(screenShotSlotAuto == 3) { 
		c = b + ext ; 
		imagePath = ARTWORK_SHOTS_3_PATH + c;
	}
	else if(screenShotSlotAuto == 4) { 
		c = b + ext ; 
		imagePath = ARTWORK_SHOTS_4_PATH + c;
	}
	else if(screenShotSlotAuto == 5) { 
	    c = b + ext ; 
		imagePath = ARTWORK_SHOTS_5_PATH + c;
	}
	else if(screenShotSlotAuto == 6) { 
		c = b + ext ; 
		imagePath = ARTWORK_SHOTS_6_PATH + c;
	}
	else if(screenShotSlotAuto == 7) { 
		c = b + ext ; 
		imagePath =ARTWORK_SHOTS_7_PATH + c;
	}
	else { 
		c = b + ext ; 
		imagePath =ARTWORK_SHOTS_8_PATH + c;
	}


	FILE *f = fopen(imagePath.c_str(), "r");
	if(f) {
		fclose(f);
		if(TexPreview) {
			TexPreview->Release();
			TexPreview = NULL;
		}
		
		//////dprintf("Loading: %s\n", imagePath.c_str());
		D3DXCreateTextureFromFileEx(Device, 
					imagePath.c_str(), 
					D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file 
					D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
					1,            //MipLevels
					0,            //Usage, Is this to be used as a Render Target? 0 == No
					D3DFMT_A8R8G8B8, //32-bit with Alpha, everything should support this
					D3DPOOL_MANAGED,//Pool, let D3D Manage our memory
					D3DX_DEFAULT, //Filter:Default filtering
					D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
					0,            //Disable ColourKey
					NULL,         //SourceInfo, returns extra info if we want it (we don't)
					NULL,         //Palette:We're not using one
					&TexPreview );



					D3DSURFACE_DESC desc;
					TexPreview->GetLevelDesc( 0, &desc );
					DWORD dwTexWidth  = desc.Width;
					DWORD dwTexHeight = desc.Height;
					
					if(dwTexWidth > 512 || dwTexHeight > 512) {
						if(TexPreview) {
							TexPreview->Release();
							TexPreview = NULL;
						}
						useNoRom =true;
						return;
					}


					wasThere = 1;
		            useNoRom = false;
					return;
	}
	else {
		useNoRom =true;
		return;
	}
}



// screenShotSlotAuto = 1;
//	wasThere = 0;
void changePreview() {
	//for(int i = 0; i < 8; i++) {
		loadScreenshot();
		//if(useNoRom == false) //Found one so return
		//	return;
		//Otherwise look in the next slot
		//screenShotSlotAuto++;
	//}
	return;//no screenshots found
}


//wasThere=1
//screenshot = 2;
void changePreviewUp() {
	//if(videoRender)
	//	return;
	for(int i = 0; i < 7; i++) {
		dprintf("screenshot %i\n");
		loadScreenshot();
		if(useNoRom == false) {
			dprintf("found screenshot\n");
			return;
		}
		screenShotSlotAuto++;

		if(screenShotSlotAuto > 8)
			screenShotSlotAuto = 1;

		if(i == 6 && wasThere == 1) { useNoRom = false; return; }
	}
	
	if(TexPreview) {
			TexPreview->Release();
			TexPreview = NULL;
	}
	wasThere = 0;
	dprintf("no screenshot found\n");
	return;//no screenshots found
}

void changePreviewDown() {
	//if(videoRender)
	//	return;
	for(int i = 0; i < 7; i++) {
		loadScreenshot();
		if(useNoRom == false)
			return;
		screenShotSlotAuto--;
		if(screenShotSlotAuto < 1)
			screenShotSlotAuto = 8;
		if(i == 6 && wasThere == 1) { useNoRom = false; return; }
	}
	if(TexPreview) {
			TexPreview->Release();
			TexPreview = NULL;
	}
	wasThere = 0;
	return;//no screenshots found
}


HRESULT Mount(const char* szDrive, char* szDevice)
{
    char szSourceDevice[256];
    char szDestinationDrive[16];

    sprintf(szSourceDevice,"\\Device\\%s",szDevice);
    sprintf(szDestinationDrive,"\\??\\%s",szDrive);

    STRING DeviceName =
    {
        strlen(szSourceDevice),
        strlen(szSourceDevice) + 1,
        szSourceDevice
    };

    STRING LinkName =
    {
        strlen(szDestinationDrive),
        strlen(szDestinationDrive) + 1,
        szDestinationDrive
    };

    IoCreateSymbolicLink(&LinkName, &DeviceName);

    return S_OK;
}

HRESULT Unmount(const char* szDrive)
{
    char szDestinationDrive[16];
    sprintf(szDestinationDrive,"\\??\\%s",szDrive);

    STRING LinkName =
    {
        strlen(szDestinationDrive),
        strlen(szDestinationDrive) + 1,
        szDestinationDrive
    };

    IoDeleteSymbolicLink(&LinkName);
    
    return S_OK;
}


FileMenu::FileMenu()
{
	memset(this,0,sizeof(*this));
}

extern unsigned char romPath[260];
int FileMenu::init()
{
	//memset(this,0,sizeof(*this));
	//strcpy(currentPath,HOME "roms");
	
	return 0;
}

int FileMenu::scan()
{
	char path[260];

	memset(path,0,sizeof(path));

	// Scan for all the roms in the current directory:
	nameReset();

	
	sprintf(path,"%.240s\\*", currentPath); nameFind(path);
	//sprintf(path,"%.240s\\*.zip", currentPath); nameFind(path);
	//sprintf(path,"%.240s\\*.sfc",currentPath); nameFind(path);

	return 0;
}

unsigned int color = 0xffffff;
void FileMenu::exit()
{
	free(nameList);
	memset(this,0,sizeof(*this));
}



int x2 = 0;
int y2 = 0;
int lastChoice = 80;
WCHAR previous[80]={0};




bool useNoBox = true;

void freeTexture() {
	if(TexPreview) {
		TexPreview->Release();
		TexPreview = NULL;
	}
}

int FileMenu::render()
{
	drawFileList();
	return 0;
}

int FileMenu::scroll(int amount)
{
	return 0;
}

// Get the currently highlighted filename
int FileMenu::getFilePath(char *path)
{
	return 0;
}

// ----------------------------------------------------------------------
int FileMenu::nameReset()
{
	return 0;
}

int dF = 0;
int dD = 0;
	
int root = 0;
int d = 0;
int page = 0;
int pageMove = 0;

#include "iosupport.h"
#include "iso9660.h"


//CISO9660 m_iso9660 ;
//HANDLE m_cdrom ;
//CIoSupport m_io ;





int FileMenu::nameFind(char *path)
{
	return 0;
}

int FileMenu::nameAdd(char *entry)
{
	return 0;
}

int FileMenu::nameSizeUp()
{
	return 0;
}

int FileMenu::nameOffset(int index)
{
	return 0; // Unknown index
}
