#include <xtl.h>
#include "xbinput.h"
#include "app.h"
int stateChanged = 0;
#include <string>
#include <vector>
using namespace std;
extern int screenGeneralOptionsGG;
struct fileDisplay {
	string name;
	string path;
	bool isAGame;
	bool isARoot;
	bool isADirectory;
	bool topLevel;
	int soundTrack;
	int song;
	int archive;
};
extern vector<fileDisplay> fileList;
extern int FileMenuSelected;
extern void setVertex();
extern std::string SAVE_PATH;
extern int screenGenralOptionsGG;
extern IDirect3DVertexBuffer8 *VertexBuffer;
extern IDirect3DVertexBuffer8 *AnimatedVertexBuffer;
extern IDirect3DVertexBuffer8 *StationaryAnimatedVertexBuffer;
extern IDirect3DVertexBuffer8 *VertexBufferPreview;
extern IDirect3DVertexBuffer8 *VertexBufferImage;
extern IDirect3DVertexBuffer8 *VertexBufferPreviewGP;
extern IDirect3DVertexBuffer8 *VertexBufferMP;
extern IDirect3DVertexBuffer8 *VertexBufferMPL;
extern IDirect3DVertexBuffer8 *VertexBufferPreviewBorder;
extern IDirect3DVertexBuffer8 *VertexBufferPreviewB;
extern IDirect3DVertexBuffer8 *VertexBufferPreview2;
extern IDirect3DVertexBuffer8 *VertexBufferLinear;
extern IDirect3DVertexBuffer8 *VertexBufferResize;
extern IDirect3DVertexBuffer8 *VertexBufferController;
extern IDirect3DVertexBuffer8 *VertexBufferOptions;
extern "C" unsigned char fnamest[512];
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
extern CustomVertex VertexList[4];
extern CustomVertex VertexListPreview[4];
extern CustomVertex VertexListImage[4];
extern CustomVertex VertexListPreviewGP[4];
extern CustomVertex VertexListPreviewB[4];
extern CustomVertex VertexListPreviewBorder[4];
extern CustomVertex VertexListPreview2[4];
extern CustomVertex VertexListLinear[4];
extern CustomVertex VertexListResize[4];
extern CustomVertex VertexListController[4];
extern void stopRumble();
extern CustomVertex VertexListOptions[4];
extern int screenOptions;
extern int screenResize;
extern int screenResizeP;
extern int screenResizeI;
extern int screenResizePB;
extern int screenResizeJ;
extern int screenResizeG;
extern int screenResizeB;
extern int screenResizeA;
extern int screenResizeA2;
extern int screenOptionsM;
extern int screenResizeS;
extern int screenControllerOptions;
extern int screenCheatOptions;
extern LPDIRECTSOUNDBUFFER     lpPrimaryBuffer;
extern int SoundEnabled;
extern void makeVertexListLinear();
extern void pauseMusic();

extern int screensoundOptions;
extern int screenSoundOptions;
extern int screenLightGunOptions;
extern int screenGeneralOptions;
extern int screenGUIOptions;
extern void setHeight(int v);
// Global instance of custom gamepad devices
extern int DisableMenuSounds;
extern void playEffect(int i);
extern  void writeConfig();
extern XBGAMEPAD g_Gamepads[4];
extern int vSpace;
extern int saveStateLoad;
extern int saveStateSave;

extern unsigned char ftemp[512];
unsigned char tempsave[512];
extern void xboxScreenshotState(const char* filename);
void SaveSlot(int slot) {
    for(int i = 0; i < 512; i++) fnamest[i] = '\0';
	
	std::string t2 = SAVE_PATH;
	

	//dprintf("Save Slot base: %s\n", t2.c_str());
	std::string a2 = fileList[FileMenuSelected].name;
	a2[a2.size()-4] = '\0';
	a2[a2.size()-3] = '\0';
	a2[a2.size()-2] = '\0';
	a2[a2.size()-1] = '\0';
	std::string g = a2.c_str();
	t2 = t2 + g;



	if(slot == 0) t2 = t2 + "\\slot0\\";
	if(slot == 1) t2 = t2 + "\\slot1\\";
	if(slot == 2) t2 = t2 + "\\slot2\\";
	if(slot == 3) t2 = t2 + "\\slot3\\";
	if(slot == 4) t2 = t2 + "\\slot4\\";
	if(slot == 5) t2 = t2 + "\\slot5\\";
	if(slot == 6) t2 = t2 + "\\slot6\\";
	if(slot == 7) t2 = t2 + "\\slot7\\";
	if(slot == 8) t2 = t2 + "\\slot8\\";
	if(slot == 9) t2 = t2 + "\\slot9\\";

	//dprintf("t2 now: %s\n", t2.c_str());
	


	//dprintf("Save Slot base: %s\n", t2.c_str());
	std::string a3 = fileList[FileMenuSelected].name;
	a3[a3.size()-3] = 'z';
	a3[a3.size()-2] = 's';
	a3[a3.size()-1] = 't';
	t2 = t2 + a3;
	
	for(int i = 0; i < 512; i++) fnamest[i] = '\0';
	fnamest[0] = t2[0];
	for(int i = 1; i < 512+1; i++) {
		if(t2[i-1] == '\0') {
			fnamest[i] = t2[i-1];
			break;
		}
		else {
			fnamest[i] = t2[i-1];
		}
	}

	//dprintf("End of Save SLot. fnamest is: %s\n", fnamest);
} 


//menuColor[FullNameColor];
////menuColor[FolderColor];
//menuColor[GameNameColor];
//menuColor[GameNameSelectedColor]
//menuColor[MenuOption]


extern unsigned char * keys;
extern int firstVidRender;
extern int FlickerFilter;
extern "C" {
extern unsigned char FPSAtStart;
extern  unsigned char FPSOn;
extern unsigned char RevStereo;
extern unsigned char SPCDisable;
extern unsigned char RewindStates;// = how many states 0 - 25
extern unsigned char RewindFrames;// = how many half seconds between rewind states 0 - 40
extern unsigned int per2exec;
extern unsigned int cfgper2exec;
extern void Setper2exec();
extern int Bper2exec ;
extern int Bcfgper2exec ;


}

extern  int HardwareFilter;
extern unsigned char SoftwareFilter;
extern  int FlickerFilter;
extern  int ShowFPS;
extern  int Soften;
int guiOptionStateSelected = 0;
extern void setFlickerSoft();
extern int LowPassFilter;
extern int SoundFrequency;
extern int SoundInterpolation;
extern int SurroundSound;

extern "C" {
extern void SetReverseStereo();
extern void SetSPCEnable();
extern void setFrequency();
extern void setLowPassFilter();
extern void setSoundInterpolation();
extern void setSurroundSound();
}

extern int zLeftIT;
extern int zTopIT;


extern int DisableMenuSounds;

extern "C" {
	extern unsigned char ForceROMTiming;
	extern unsigned char pl3contrl;
	extern unsigned char pl4contrl;
}

extern int Disable34;
extern int DisableSaveStates;

extern void processOptions();

extern int inGame;

extern int HighRes;

extern float XBINPUT_DEADZONE;


extern "C" {
	extern int aCount;
}

bool useNoState = false;

void loadStateImage() {
	std::string a2 = (char*)&fnamest[1];
	a2[a2.size()-3] = 'p';
	a2[a2.size()-2] = 'n';
	a2[a2.size()-1] = 'g';

	if(TexStatePreview) {
		TexStatePreview->Release();
		TexStatePreview = NULL;
	}

	if( FAILED(D3DXCreateTextureFromFileEx(Device, (LPCSTR)a2.c_str(),
		D3DX_DEFAULT, D3DX_DEFAULT, 1, 0, D3DFMT_R5G6B5  , D3DPOOL_MANAGED,
		D3DX_FILTER_LINEAR , D3DX_FILTER_NONE, 0, NULL, NULL, &TexStatePreview))) {

		useNoState = true;
	}
	else {
		useNoState = false;
	}
}


int processStateOptions() {
   if(g_Gamepads[0].Event == XBGAMEPAD_B) {
      if(DisableMenuSounds == 0) playEffect(1);
      screenGeneralOptions = 0;
	  screenGeneralOptionsGG = 0;
	  screenGUIOptions = 0;
      screenOptions     = 1;
	  screenResize = 0;
	  screenResizeP = 0;
	  screenResizeI = 0;
	  screenResizePB = 0;
	  screenResizeJ = 0;
	  screenResizeG = 0;
	  screenResizeB = 0;
	  screenResizeA = 0;
	  screenResizeA2 = 0;
	  screenOptionsM = 0;
	  screenResizeS = 0;
	  screenControllerOptions = 0;
	  saveStateLoad = 0;
	  saveStateSave = 0;
	  //writeConfig();
      return 0;          
   } 
   
   if (g_Gamepads[0].Event == XBGAMEPAD_DPAD_DOWN)  {  
		if(DisableMenuSounds == 0) playEffect(0);	
		guiOptionStateSelected++;
		if(guiOptionStateSelected > 9) guiOptionStateSelected = 0;
		SaveSlot(guiOptionStateSelected);
		loadStateImage();
   }

   if (g_Gamepads[0].Event == XBGAMEPAD_DPAD_UP)  {  
		if(DisableMenuSounds == 0) playEffect(0);	
		guiOptionStateSelected--; 
		if(guiOptionStateSelected < 0) guiOptionStateSelected = 9;   
		SaveSlot(guiOptionStateSelected);
		loadStateImage();
   }  

   if(g_Gamepads[0].Event == XBGAMEPAD_A) {
	   //if(DisableMenuSounds == 0) playEffect(2);

	   if(saveStateSave == 1) {	
		   if(!DisableSaveStates){  
			    SaveSlot(guiOptionStateSelected); 
				std::string a2 = (char*)&fnamest[1];
				a2[a2.size()-3] = 'p';
				a2[a2.size()-2] = 'n';
				a2[a2.size()-1] = 'g';
				//dprintf("Going to save a savestate screenshot: %s\n", a2.c_str());
			    xboxScreenshotState((const char*)a2.c_str());
			    keys[KeySaveState] = 1; 
		   } 
		   ////dprintf("Just triggered save on fnamest: %s\n", fnamest);
		   LoopMode = 8; 
		   lpPrimaryBuffer->Play(0,0,DSBPLAY_LOOPING);
		   SoundEnabled = 1; 	
		   screenOptions = 0; 
		   setVertex();
		  // Device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
		  // Device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
		   g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_A] = 0;
		   pauseMusic();
		   aCount = 0;
		   //bCount = 0;
		   //startHDMode();
		   saveStateLoad = 0;
			saveStateSave = 0;
			screenOptions = 0;
			screenGeneralOptions = 0;
			return 1;
	   }


	   if(saveStateLoad == 1) {	
		   if(!DisableSaveStates){ SaveSlot(guiOptionStateSelected); keys[KeyLoadState] = 1; stopRumble();} 
		   LoopMode = 8; 
		   lpPrimaryBuffer->Play(0,0,DSBPLAY_LOOPING);
		   SoundEnabled = 1; 	
		   screenOptions = 0; 
		   setVertex();
		  // Device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
		  //Device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
		   pauseMusic();
		   g_Gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_A] = 0;
		   aCount = 0;
		   saveStateLoad = 0;
			saveStateSave = 0;
			screenOptions = 0;
			screenGeneralOptions = 0;
			return 1;
	   }



	   saveStateLoad = 0;
	   saveStateSave = 0;
	   screenOptions = 0;
	   screenGeneralOptions = 0;
	   return 1;
   }

   return 0;
} 


extern int FontSetColour(unsigned int colour);
extern int FontText(WCHAR *,int,int, int);

//*************************************************************************
//DRAW
int yState = 0;
int drawState_Count = 0;

void drawStateText(char* text) {
     DWORD color = menuColor[MenuOption];
     
	// WCHAR text2345678_[80]={0};
	// wsprintfW(text2345678_,  L"Option Selected: %d, ShowFPS: %d", controllerConfigSelected, B[0].Button_ShowFPS);
	// FontSetColour(0xffff00);
	// FontText(text2345678_,50,300, 600);
	 
	 
	 
	 if(drawState_Count == guiOptionStateSelected) color = menuColor[MenuOptionSelected]; 
     
     //Draw the text string
     WCHAR text23456789[80]={0};
	 //wsprintfW(text2345678_, (LPCWSTR)text);

	 for(int i = 0; i < 1000; i++) {
		 if(text[i] == '\0') {
			text23456789[i] = '\0';
			break;
		 }
		 text23456789[i] = text[i];
	 }
	 FontSetColour(color);
	 FontText(text23456789,400+zLeftIT,yState+zTopIT, 600);
	 yState += vSpace;
     drawState_Count++;
}

void drawG_StateText(char* text) {
     DWORD color = menuColor[MenuOption];
     
	// WCHAR text2345678_[80]={0};
	// wsprintfW(text2345678_,  L"Option Selected: %d, ShowFPS: %d", controllerConfigSelected, B[0].Button_ShowFPS);
	// FontSetColour(0xffff00);
	// FontText(text2345678_,50,300, 600);
	 
	 
	 
	 if(drawState_Count == guiOptionStateSelected) color = menuColor[MenuOptionSelected]; 
     
     //Draw the text string
     WCHAR text23456789[80]={0};
	 //wsprintfW(text2345678_, (LPCWSTR)text);

	 for(int i = 0; i < 1000; i++) {
		 if(text[i] == '\0') {
			text23456789[i] = '\0';
			break;
		 }
		 text23456789[i] = text[i];
	 }
	 FontSetColour(color);
	 FontText(text23456789,150+zLeftIT,yState+zTopIT, 600);
	 //yState += 20;
     //drawState_Count++;
}
extern int sWidth;

#include <sstream>

extern int FontSmallText(WCHAR *,int,int, int);
void drawStateOptions() {
		/*WCHAR text2345[280]={0};
		wsprintfW(text2345,L"Press \"B\" to exit.");
		FontSetColour(0xffff00);
		FontSmallText(text2345,sWidth/2,70, 600);	*/

		if(saveStateLoad == 1) {
			WCHAR atext2345[280]={0};
			wsprintfW(atext2345,L"Select a slot to load a game from.");
			FontSetColour(0xffff00);
			FontSmallText(atext2345,sWidth/2,(480-90), 600);	
		}
		else {
			WCHAR atext2345[280]={0};
			wsprintfW(atext2345,L"Select a slot to save the game to.");
			FontSetColour(0xffff00);
			FontSmallText(atext2345,sWidth/2,(480-90), 600);
		}
	    drawState_Count = 0;

		//xO = 150;
		//	yO = 120;
        yState = 120;



		drawG_StateText("Slot 1"); drawStateText("");  
		drawG_StateText("Slot 2"); drawStateText("");  
		drawG_StateText("Slot 3"); drawStateText("");  
		drawG_StateText("Slot 4"); drawStateText("");  
		drawG_StateText("Slot 5"); drawStateText("");  
		drawG_StateText("Slot 6"); drawStateText("");  
		drawG_StateText("Slot 7"); drawStateText("");  
		drawG_StateText("Slot 8"); drawStateText("");  
		drawG_StateText("Slot 9"); drawStateText("");  
		drawG_StateText("Slot 10"); drawStateText("");  

}