#ifndef __FBA_H__
#define __FBA_H__

#include <XBApp.h>
#include <XBFont.h>
#include <XBHelp.h>
#include <XBMesh.h>
#include <XBUtil.h>
#include <xgraphics.h>
#include <wchar.h>
#include <vector>		
#include <string>
#include <map>


//#include <string.h>
//#include <stdlib.h>
//#include <stdarg.h>

#include "burn.h"
#include "version.h"

// custom class includes
#include "GamepadConfig.h"
#include "IoSupport.h"
#include "roms.h"
#include "stringset.h"

#define BZIP_MAX (4)
// drv.cpp
extern int bDrvOkay;						// 1 if the Driver has been initted okay, and it's okay to use the BurnDrv functions
extern char szAppRomPaths[4][260];
int DrvInit(int nDrvNum);
int DrvExit();

extern CXBFont     m_Font;                 // Font for text display
 

// zipfn.cpp
struct ZipEntry {
	char* szName;
	unsigned int nLen;
	unsigned int nCrc;
};
int ZipOpen(char* szZip);
int ZipClose();
int ZipGetList(struct ZipEntry** pList, int* pnListCount);
int ZipLoadFile(unsigned char* Dest, int nLen, int* pnWrote, int nEntry);

#define ZIP_LIST_FREE(List, nListCount)			\
{												\
	if (List) {									\
		for (int i = 0; i < nListCount; i++) {	\
			if (List[i].szName) {				\
				free(List[i].szName);			\
				List[i].szName = NULL;			\
			}									\
		}			   							\
		free(List);								\
	}											\
	List = NULL;								\
	nListCount = 0;								\
};



// bzip.cpp
extern char *szBzipName[BZIP_MAX * 4 + 1];	// RomPaths
extern int nBzipError;						// Non-zero if there is a problem with the opened romset
extern StringSet BzipText;					// Text which describes any problems with loading the zip
extern StringSet BzipDetail;				// Text which describes in detail any problems with loading the zip
int BzipOpen(bool);
int BzipClose();
int BzipInit();
int BzipExit();


// screen strech struct

struct SScreenScale{
	int xoffset; 
	int yoffset; 
	int xsize;
	};

// Controller routines

// dinp.cpp
//int DinpInit(HINSTANCE hInst,HWND hPassWnd);
int DinpExit();
int DinpStart();							// Call before checking for Input in a frame
int DinpState(int nCode);
int DinpFind();
int DinpAxis(int i, int nAxis);

struct GameInp {
	unsigned char* pVal;					// Destination for the Input Value
	unsigned char nVal;						// The Input Value
	unsigned char nType;					// 0=binary (0,1) 1=analog (0x01-0xFF) 2=dip switch 3=contstant
	unsigned char nInput;					// 0=undefined, 1=constant value, 2=on/off switch, 3/4/5=joystick axis (analog), 6/7=slider
	unsigned char nConst;					// the constant value
	unsigned short nCode;					// the input code (for digital)
	unsigned char nJoy;						// the joystick number
	unsigned char nAxis;					// the joystick axis number
	unsigned short nSlider[2];				// Keys to use for slider
	short nSliderSpeed;						// speed which keys move the slider
	int nSliderValue;						// Current position of the slider
	short nSliderCenter;					// Speed the slider should center itself (high value = slow)
};

int InputInit();
int InputExit();
int InputMake(bool bCopy);					// Take inputs
int InputTick();

extern struct GameInp* GameInp;
extern unsigned int nGameInpCount;
int GameInpInit();
int GameInpExit();
char* InpToDesc(struct GameInp* pgi);
int GameInpBlank(int bDipSwitch);
int GameInpDefault();
int GameInpWrite(FILE* h);
int GameInpRead(char* szVal, bool bOverWrite);

// Player Default Controls
extern int nPlayerDefaultControls[4];

// gamc.cpp
int GamcMisc(struct GameInp* pgi, char* szi, int nPlayer);
int GamcAnalogKey(struct GameInp* pgi, char* szi, int nPlayer, int nSlide);
int GamcAnalogJoy(struct GameInp* pgi, char* szi, int nPlayer, int nJoy, int nSlide);
int GamcXboxPlayer(struct GameInp* pgi, char* szi, int nPlayer, int nDevice);
int GamcXArcade(struct GameInp* pgi, char* szi, int nPlayer, int nDevice);
int GamcPlayerHotRod(struct GameInp* pgi, char* szi, int nPlayer, int nSide, int nSlide);

// DSound routines

// Audio Output plugin
struct AudOut {
	int (*BlankSound)();
	int (*SoundCheck)();
	int (*SoundInit)();
	int (*SoundPlay)();
	int (*SoundStop)();
	int (*SoundExit)();
	int (*SoundSetVolume)();
	int (*SoundDeInit)();
};

int AudSoundInit();
int AudSoundExit();
int AudSoundPlay();
int AudSoundStop();
int AudBlankSound();
int AudSoundCheck();
int AudSoundSetVolume();
int AudSoundDeInit();

extern int nAudSampleRate;          // sample rate
extern int nAudSegCount;          	// Segs in the pdsbLoop buffer
extern int nAudSegLen;            	// Seg length in samples (calculated from Rate/Fps)
extern short *nAudNextSound;       	// The next sound seg we will add to the sample loop
extern unsigned char bAudOkay;    	// True if DSound was initted okay
extern unsigned char bAudPlaying;	// True if the Loop buffer is playing
extern long nDSoundVol;
extern int (*DSoundGetNextSound) (int bDraw); // Callback used to request more sound
extern int nAppVirtualFps;					// virtual fps
 
 

int DspInit();
int DspExit();
int DspDo(short* Wave, int nCount);

//
extern int VidInit();
extern int VidExit();
extern int VidFrame();
extern int VidRender();
extern int VidMemLen;
extern int nScrnWidth; 
extern int nScrnHeight;


// stretch code
extern void VidXboxDoStrech(void);			
extern void VidXboxLoadScreenData(void);
extern void VidXboxSaveScreenData(void);
//drv.cpp


//misc

extern void LoadingRomMsg(void);
extern int isPAL50;
// screen strech

extern int bStretchMode;
extern SScreenScale d3dScale;
	 
extern CConfiguration m_Config;

#define QUOTE_MAX (128)						// Maximum length of "quoted strings"
int QuoteRead(char** pszQuote, char** pszEnd, char* szSrc);					// Read a quoted string from szSrc and point to the end

char *LabelCheck(char* s, char* szLabel);
#define SKIP_WS(s) for (;;) { if (*s != ' ' && *s != '\t') break; s++; }	// skip whitespace
int ConfigAppLoad();		// char* lpszName = NULL
int ConfigAppSave();
#endif