#include "app.h"
#include "FileMenu.h"

char LoopQuit=0;
static FILE *DebugFile=NULL;
int LoopMode=0;
bool down;
void pauseMusic();

void resumeMusic();

void updateSound();
int initMusic();

void effectInit();
void updateEffect();
void playEffect();
void stopEffect();
extern "C" {
extern unsigned char En2xSaI;
extern unsigned char Surround;
}
extern unsigned char SoftwareFilter;

extern float getVolume();
extern void setVolume(float v);

extern "C" void zstart();

extern int render;


void getSNESInput() {
	
     

    
	//if (Inp.held[8]==1 ) {  render = 0; buttonPressed = 8; } 
	//if (Inp.held[9]==1 ) { render = 1; buttonPressed = 9; } 
	//if (Inp.held[10]==1 ) { render = 2; buttonPressed = 10; } 
	//if (Inp.held[11]==1 ) { render = 3; buttonPressed = 11; } 
}

extern "C" void loadIni();

int LoopInit()
{
	int ret=0;

	
    loadIni();
	// Init Direct3D:
	ret=DirectInit(); if (ret) return 1;
	InputInit();
    initMusic();


	effectInit();

	ret=EmuInit(); if (ret) return 1;
	FileMenu.init();

	return 0;
}

void LoopExit()
{
	FileMenu.exit();
	EmuExit();
	//DSoundExit(); DSoundSeg=0;
	InputExit();
	DirectExit();

	if (DebugFile) fclose(DebugFile);
	DebugFile=NULL;
}

// ----------------------------------------------------------------

int DoGame()
{
	//EmuFrame();

	if (Inp.held[7]==1) { resumeMusic(); LoopMode=2; LoopCode(); } // Right thumb = Toggle Menu

	return 0;
}
// ----------------------------------------------------------------

int buttonPressed = 0;
bool fastScroll = false;

bool a = false;
bool b = false;
bool c = false;
bool gameRunning = false;

extern "C" unsigned char fname[512];
extern "C" unsigned char fnames[512];
extern "C" unsigned char fnamest[512];

int threadIsValid = 1;
int screenResize = 0;

DWORD WINAPI ThreadFunc( LPVOID lpParam )  {
   zstart();
   threadIsValid = 0;
   return 0;
}

void startThread() {
    DWORD dwThreadId, dwThrdParam = 1; 
    HANDLE hThread; 

	
    hThread = CreateThread( 
        NULL,                        // (this parameter is ignored)
        0,                           // use default stack size  
        ThreadFunc,                  // thread function 
        &dwThrdParam,                // argument to thread function 
        0,                           // use default creation flags 
        &dwThreadId);                // returns the thread identifier 
}



float zTop = 0;
float zLeft = 0;

float zBottom = 0;
float zRight = 0;


void setTexture() {
	Device->SetTexture(0,TexScreen);
	        Device->SetStreamSource(0,VertexBufferLinear,sizeof(CustomVertex));
	        Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);

			//GUIQuit = 0;
			Device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
			Device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

			// Note: The hardware requires CLAMP for linear textures
			Device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
			Device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

}
bool optionScreen = 0;


extern char RomName[260];


int MenuUpdate()
{

	if (Inp.axis[3]>= 0x2000 && screenResize != 1) setVolume(getVolume() + 10.0f); // Up
	if (Inp.axis[3]<=-0x2000 && screenResize != 1) setVolume(getVolume() - 10.0f);

	if(Inp.button[11]>30) { screenResize = 1; return 0; }

    if (Inp.held[9]==1) { Surround ^= 1; }
    if (Inp.held[10]==1) { SoftwareFilter = (SoftwareFilter + 1) & 0x03; }





	if(screenResize == 1) {
		if(Inp.held[8]==1) {
		    screenResize = 0;
			LoopMode = 2;
			FILE* f;
	        f = fopen("D:\\ini\\ZsnexBox.ini", "w");
	
			if(f) {
				fprintf(f, "zLeft=%f\n", zLeft);
				fprintf(f, "zRight=%f\n", zRight);
				fprintf(f, "zTop=%f\n", zTop);
				fprintf(f, "zBottom=%f\n", zBottom);

			    fclose(f);
			}


			return 0;
		}
	
	   if (Inp.axis[1]>= 0x2000) zTop+=0.05f; // Up
	   if (Inp.axis[1]<=-0x2000) zTop-=0.05f; // Down
	   if (Inp.axis[0]<=-0x2000) zLeft-=0.05f; // Left
	   if (Inp.axis[0]>= 0x2000) zLeft+=0.05f; // Right
	
	   if (Inp.axis[3]>= 0x2000) zBottom+=0.05f; // Up
	   if (Inp.axis[3]<=-0x2000) zBottom-=0.05f; // Down
	   if (Inp.axis[2]<=-0x2000) zRight-=0.05f; // Left
	   if (Inp.axis[2]>= 0x2000) zRight+=0.05f; // Right
	   
	
	    return 0; 
	
	}



	if(LoopMode != 8) {
		screenResize = 0;
		int	delta=0;
		if (Inp.repeat[0]) {  playEffect();	delta-=0x100; menuChanged=true;	fastScroll = false;	buttonPressed =	0; } 
		if (Inp.repeat[1]) {  playEffect();	delta+=0x100; menuChanged=true;	fastScroll = false;	  buttonPressed	= 1; } 


		//if (Inp.held[0]) {  delta-=0x100;	menuChanged=true; fastScroll = true; buttonPressed = 0;	} 
		//if (Inp.held[1]) {  delta+=0x100;	menuChanged=true; fastScroll = true;   buttonPressed = 1; }	

		a =	false;
		fastScroll = false;
		if (Inp.button[14]>30) {   a = true;  b	= true;	menuChanged=true; fastScroll = true; delta-=0x100; }
		if (Inp.button[15]>30) {	a =	true;  b = true;  menuChanged=true;	fastScroll = true; delta+=0x100;  }

		if (a == false)	{
			if (b == true) {
				b =	false;
				menuChanged	= true;
			}
		}





		if (delta) FileMenu.scroll(delta);

		

		if (Inp.held[8]==1 && screenResize != 1) // A, X or Start
		{

			/*
			FileMenu.getFilePath(RomName);
			//D:\roms\_<1>
			//scan()
			dprintf("Romname: %s\n", RomName);
            dprintf("Current Path: %s\n", FileMenu.currentPath);
			if(RomName[8] == '_' && RomName[9] == '<') {
				for(int i = 8; i < 1024; i++) {
					dprintf("%s", RomName[i]);
					if(RomName[i] == '\0') {
						FileMenu.currentPath[i] = RomName[i];
						break;
					}
					else {
						FileMenu.currentPath[i] = RomName[i];
					}
				}
               dprintf("Scanning\n");
			   FileMenu.scan();
			   dprintf("After scan\n");
			   return 0;
			}
            */

			Device->SetTexture(0,TexScreen);
	        Device->SetStreamSource(0,VertexBufferLinear,sizeof(CustomVertex));
	        Device->SetVertexShader(D3DFVF_CUSTOMVERTEX);

			//GUIQuit = 0;
			Device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
			Device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

			// Note: The hardware requires CLAMP for linear textures
			Device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
			Device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

			pauseMusic();
			//gameRunning = true;
			//RomFree();
			FileMenu.getFilePath(RomName);
			//RomLoad();
			LoopMode=8; // Go to game
            

            





			dprintf("Before fname set\n");
   
   
			fname[0] = 'D';
			fname[1] = 'D';
			fname[2] = ':';
			fname[3] = '\\';
			fname[4] = 'r';
			fname[5] = 'o';
			fname[6] = 'm';
			fname[7] = 's';
			fname[8] = '\\';



			for(int i = 8; i < 1024; i++) {
				if(RomName[i] == '\0') {
					fname[i+1] = RomName[i];
					break;
				}
				else {
					fname[i+1] = RomName[i];
				}
			}

			fnames[0] = 'D';
			fnames[1] = 'D';
			fnames[2] = ':';
			fnames[3] = '\\';
			fnames[4] = 's';
			fnames[5] = 'r';
			fnames[6] = 'a';
			fnames[7] = 'm';
			fnames[8] = '\\';


            int i2;
			for(i2 = 8; i2 < 1024; i2++) {
				if(RomName[i2] == '\0') {
					fnames[i2+1] = RomName[i2];
					break;
				}
				else {
					fnames[i2+1] = RomName[i2];
				}
			}
            fnames[i2] = 'm';
			fnames[i2-1] = 'r';
			fnames[i2-2] = 's';
			
			dprintf("After fname set: %s\n", fname);

      
			fnamest[0] = 'D';
			fnamest[1] = 'D';
			fnamest[2] = ':';
			fnamest[3] = '\\';
			fnamest[4] = 's';
			fnamest[5] = 'a';
			fnamest[6] = 'v';
			fnamest[7] = 'e';
			fnamest[8] = '\\';


            int i3;
			for(i3 = 8; i3 < 1024; i3++) {
				if(RomName[i3] == '\0') {
					fnames[i3+1] = RomName[i3];
					break;
				}
				else {
					fnamest[i3+1] = RomName[i3];
				}
			}
            fnamest[i3] = 't';
			fnamest[i3-1] = 's';
			fnamest[i3-2] = 'z';

            zstart();
			//startThread();

			//while(threadIsValid == 1) {
			   
			//}
			//threadIsValid = 1;

			dprintf("After zstart()\n");
			LoopMode = 2;
			resumeMusic();
			//zstop();
		}
	}
     
	
	if (Inp.held[2]==1 ) {  buttonPressed = 2; } 
	if (Inp.held[3]==1 ) { buttonPressed = 3; } 
	if (Inp.held[4]==1 ) { buttonPressed = 4; } 
	if (Inp.held[5]==1 ) { buttonPressed = 5; } 
	if (Inp.held[6]==1 ) { buttonPressed = 6; } 
	if (Inp.held[7]==1 ) { buttonPressed = 7; } 
	if (Inp.held[8]==1 ) {  nFilter = 0; buttonPressed = 8; } 
	if (Inp.held[9]==1 ) { nFilter = 1; buttonPressed = 9; } 
	if (Inp.held[10]==1 ) { nFilter = 2; buttonPressed = 10; } 
	if (Inp.held[11]==1 ) { nFilter = 3; buttonPressed = 11; } 
	if (Inp.held[12]==1 ) { scaleZ+=0.5; buttonPressed = 12; } 
	if (Inp.held[13]==1 ) { scaleZ-=0.5; nFilter = 5; buttonPressed = 13; } 
	if (Inp.held[14]==1 ) { buttonPressed = 14; } 
	if (Inp.held[15]==1 ) { buttonPressed = 15; } 

	if (Inp.held[7]==1 && LoopMode == 8) {
		
		//GUIQuit = 1;
		gameRunning = false;
	    resumeMusic();
		LoopMode=2; // Right thumb = Toggle Menu
	}
	return 0;
}
extern int screenResize;

int MenuRender()
{
	
	//WCHAR text[80]={0};
	//wsprintfW(text,L"%.40S v1.0",AppName);
	//FontSetColour(0x60c0ff);
	//FontText(text,420,359);

	WCHAR text2[80]={0};
	wsprintfW(text2,L"Games Found: %d",gamesFound);
	FontSetColour(0x00ff40);
	FontText(text2,112,412, 600);

	/*
	WCHAR text23[80]={0};
	wsprintfW(text23,L"leftX: %f",leftX);
	FontSetColour(0x60c0ff);
	FontText(text23,295,200);

	WCHAR text234[80]={0};
	wsprintfW(text234,L"rightX: %f",rightX);
	FontSetColour(0x60c0ff);
	FontText(text234,295,220);

	WCHAR text2345[80]={0};
	wsprintfW(text2345,L"topY: %f",topY);
	FontSetColour(0x60c0ff);
	FontText(text2345,295,240);

	WCHAR text23456[80]={0};
	wsprintfW(text23456,L"bottomY: %f",bottomY);
	FontSetColour(0x60c0ff);
	FontText(text23456,295,260);

	WCHAR text234567[80]={0};
	wsprintfW(text234567,L"scaleZ: %f",scaleZ);
	FontSetColour(0x60c0ff);
	FontText(text234567,295,280);

	WCHAR text2345678[80]={0};
	wsprintfW(text2345678,L"selected: %d",selected);
	FontSetColour(0x60c0ff);
	FontText(text2345678,295,300);
	*/

	if(SoftwareFilter == 0) {
		WCHAR text23456789_[80]={0};
 	   wsprintfW(text23456789_,L"Software Filter:   None");
	   FontSetColour(0xffffff);
	   FontText(text23456789_,355,350, 600);

	   WCHAR text23456789[80]={0};
 	   wsprintfW(text23456789,L"Software Filter:");
	   FontSetColour(0xffff00);
	   FontText(text23456789,355,350, 600);

	   
	}

	if(SoftwareFilter== 1) {
	   WCHAR text23456789_[80]={0};
 	   wsprintfW(text23456789_,L"Software Filter:   Super Eagle");
	   FontSetColour(0xffffff);
	   FontText(text23456789_,355,350, 600);

	   WCHAR text23456789[80]={0};
 	   wsprintfW(text23456789,L"Software Filter:");
	   FontSetColour(0xffff00);
	   FontText(text23456789,355,350, 600);

	   
	}

	if(SoftwareFilter == 2) {
		WCHAR text23456789_[80]={0};
 	   wsprintfW(text23456789_,L"Software Filter:   2xSaI");
	   FontSetColour(0xffffff);
	   FontText(text23456789_,355,350, 600);

	   WCHAR text23456789[80]={0};
 	   wsprintfW(text23456789,L"Software Filter:");
	   FontSetColour(0xffff00);
	   FontText(text23456789,355,350, 600);

	   
	}

	if(SoftwareFilter == 3) {
		WCHAR text23456789_[80]={0};
 	   wsprintfW(text23456789_,L"Software Filter:   Super 2xSaI");
	   FontSetColour(0xffffff);
	   FontText(text23456789_,355,350, 600);

	   WCHAR text23456789[80]={0};
 	   wsprintfW(text23456789,L"Software Filter:");
	   FontSetColour(0xffff00);
	   FontText(text23456789,355,350, 600);

	   
	}

	if(Surround == 1) {
		WCHAR text2345678_[80]={0};
		wsprintfW(text2345678_,L"Surround Sound: On");
		FontSetColour(0xffffff);
		FontText(text2345678_,355,375, 600);

		WCHAR text2345678[80]={0};
		wsprintfW(text2345678,L"Surround Sound:");
		FontSetColour(0xffff00);
		FontText(text2345678,355,375, 600);

		
	}
	else {
        WCHAR text2345678_[80]={0};
		wsprintfW(text2345678_,L"Surround Sound: Off");
		FontSetColour(0xffffff);
		FontText(text2345678_,355,375, 600);

		WCHAR text2345678[80]={0};
		wsprintfW(text2345678,L"Surround Sound:");
		FontSetColour(0xffff00);
		FontText(text2345678,355,375, 600);
	}

	WCHAR text234567[80]={0};
	wsprintfW(text234567,L"Start Game");
	FontSetColour(0xffff00);
	FontText(text234567,355,402, 600);

	WCHAR text2345678[80]={0};
	wsprintfW(text2345678,L"Screen");
	FontSetColour(0xffff00);
	FontText(text2345678,480,402, 600);


	nFilter = 1;
	if(nFilter == 5) {
		WCHAR textF1[80]={0};
		Device->SetTextureStageState(0, D3DTSS_MIPFILTER,D3DTEXF_NONE);
		wsprintfW(textF1,L"Filter: None");
		FontSetColour(0xffff00);
		FontText(textF1,435,405, 600);
	}
	if(nFilter == 0) {
		Device->SetTextureStageState(0, D3DTSS_MAGFILTER,D3DTEXF_POINT );
		Device->SetTextureStageState(0, D3DTSS_MINFILTER,D3DTEXF_POINT );
		WCHAR textF[80]={0};
		wsprintfW(textF,L"Filter: Point");
		FontSetColour(0xffff00);
		FontText(textF,435,405, 600);

	}


	

	if(nFilter == 1) {
		Device->SetTextureStageState(0, D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
		Device->SetTextureStageState(0, D3DTSS_MINFILTER,D3DTEXF_LINEAR);
		//WCHAR textF[80]={0};
		//wsprintfW(textF,L"Filter: Linear");
		//FontSetColour(0xffff00);
		//FontText(textF,435,405);
	}
	if(nFilter == 2) {
		Device->SetTextureStageState(0, D3DTSS_MAGFILTER,D3DTEXF_ANISOTROPIC);
		Device->SetTextureStageState(0, D3DTSS_MINFILTER,D3DTEXF_ANISOTROPIC);
		WCHAR textF[80]={0};
		wsprintfW(textF,L"Filter: Anisotropic");
		FontSetColour(0xffff00);
		FontText(textF,435,405, 600);
	}
	if(nFilter == 3) {
		Device->SetTextureStageState(0, D3DTSS_MAGFILTER,D3DTEXF_QUINCUNX);
		Device->SetTextureStageState(0, D3DTSS_MINFILTER,D3DTEXF_QUINCUNX);
		WCHAR textF[80]={0};
		wsprintfW(textF,L"Filter: Quincunx");
		FontSetColour(0xffff00);
		FontText(textF,435,405, 600);
	}
	if(nFilter == 4) {
		Device->SetTextureStageState(0, D3DTSS_MAGFILTER,D3DTEXF_GAUSSIANCUBIC);
		Device->SetTextureStageState(0, D3DTSS_MINFILTER,D3DTEXF_GAUSSIANCUBIC);
		WCHAR textF[80]={0};
		wsprintfW(textF,L"Filter: Gaussiancubic");
		FontSetColour(0xffff00);
		FontText(textF,435,405, 600);
	}


	FileMenu.render();

	return 0;
}

// ----------------------------------------------------------------



 int ModeUpdate()
{
	if (Inp.held[14] && Inp.held[15] && Inp.held[12]==1) LoopQuit=1; // L+R+black to quit:
	if (Inp.button[4]>30 && Inp.button[5]>30) LoopQuit=1; // Start and back to quit

	if (LoopMode==8) { DoGame(); return 0; }

	//if (DSoundNext) memset(DSoundNext,0,DSoundSeg<<2);

	if (LoopMode==2) { FileMenu.scan(); LoopMode++; return 0; }
	if (LoopMode==3) { MenuUpdate(); return 0; }
	if (LoopMode==4) { LightCalUpdate(); return 0; }
    if (LoopMode==9) return 0;
	LoopMode=2; // Unknown mode, go to rom menu
	return 0;
}


int ModeRender()
{
	DirectScreen();
	//MenuRender();
	if (LoopMode==3 && screenResize != 1) MenuRender();
	if (LoopMode==4) LightCalRender();

	return 0;
}

int UpdateSound()
{

	//DSoundUpdate();
	//while (DSoundUpdate()) { Sleep(1); }
	//while (DSoundUpdate()==0) { }
	return 0;
}

extern "C" int ZsnesInputUpdate();

int LoopCode()
{
	LoopQuit = 0;
	// Main loop:
	while (!LoopQuit)
	{
		resumeMusic();
		InputUpdate();
        //ZsnesInputUpdate();

		DirectClear(0);
		ModeUpdate();
		ModeRender();
		DirectPresent();
		//UpdateSound();
        

		updateSound();
		updateEffect();

	}

	return 0;
}

// -------------------------------------------------------------------------------------

extern "C" int dprintf(char *format, ...)
{
	return 0;
	char *name=NULL;
	va_list val=NULL;

#ifdef _XBOX
	name="d:\\zout.txt";
#else
	name="zout.txt";
#endif

	if (DebugFile==NULL) DebugFile=fopen(name,"wt");
	if (DebugFile==NULL) return 1;

	va_start(val,format);
	vfprintf(DebugFile,format,val);
	fflush(DebugFile);

	va_end(val);
	return 0;
}
