#pragma once
#include "Gos.h"

#pragma warning ( disable : 4200 )

struct Gos1TLVertex
{
	float x,y,z,rhw;
	DWORD argb,frgb;
	float u,v;
	enum { VertexType = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1 };
};

enum Gos1AlphaBlend
{
	Gos1AlphaBlend_OneZero=1,
	Gos1AlphaBlend_OneOne,
	Gos1AlphaBlend_AlphaInvAlpha,
	Gos1AlphaBlend_OneInvAlpha
};

// An enumeration of the various commands to the Video playback API. 
enum Gos1Video_Command
{
	Gos1Video_SeekTime = 1, 			// Seek to a frame or timestamp in hVideo
	Gos1Video_SetCoords	= 2,		// Set the destination coordinates of <hVideo> via <dwOriginX/Y>
	Gos1Video_SetScale = 4,			// Change the scale of <hVideo> on the fly via <fScaleOfX/Y>
	Gos1Video_Volume = 8,			// Set the volume of the multiVideo
	Gos1Video_Panning = 16			// Set the pan of the multiVideo
};

//////////////////////////////////////////////////////////////////////////////////
// An enumeration of the various states the video playback can be in.
enum Gos1Video_PlayMode
{
	Gos1Video_PlayOnceHide,		// The Video is currently playing (will hide when done)
	Gos1Video_PlayOnceHold,		// The Video is currently playing (will hold when done)
	Gos1Video_Loop,				// The Video is currently in continuous play mode
	Gos1Video_Stop,				// The Video is stopped
	Gos1Video_Pause,				// The Video has been paused
	Gos1Video_Continue			// SET ONLY: continue a paused Video
};

//////////////////////////////////////////////////////////////////////////////////
// This structure is used to send and receive information about a particular video 
// resource. Each command (above) requires specific info to be initialized in the 
// structure below in order to properly carry out that command. For this data, 
// consult the comments listed under the appropriate command (listed above).
typedef struct _Gos1Video_Info
{
	char *					lpstrPath;		// string specified path to data
	Gos1Video_PlayMode		ePlayMode;		// the play mode (see above)
	Gos1Video_PlayMode		ePlayStatus;	// the play mode (see above)
	DWORD					dwOriginX;		// x coord on dest. surf for video
	DWORD					dwOriginY;		// y coord on dest. surf for video
	float					fScaleOfX;		// ratio of displayed to orgininal width
	float					fScaleOfY;		// ratio of displayed to orgininal height
	float					fDurationSec;	// read-only duration of video (hundredth of a second)
	float					fSoFarSec;		// current play position (hundredth of a second)
	unsigned char *			lpData;			// RGB data
	DWORD					dwSurfaceWidth;	// read-only width of video surface
	DWORD					dwSurfaceHeight;// read-only height of vidoe surface
	DWORD					dwPitch;		// read-only pitch of video surface
	DWORD					dwWidth;		// read-only width of video
	DWORD					dwHeight;		// read-only height of vidoe
} Gos1Video_ResourceInfo;





typedef enum Gos1Audio_ResourceType
{
	Gos1Audio_CachedFile,			// Pull a WAV file from disk, parse it, and copy the raw sound data into system memory
	Gos1Audio_UserMemory,			// Use a preloaded WAV already in the client's system memory. Note: This memory must remain intact until this resource is destroyed
	Gos1Audio_UserMemoryDecode,		// Use a preloaded WAV already in the client's system memory. Note: Unlike UserMemory, UserMemoryDecode deciphers the waveformat itself.
	Gos1Audio_UserMemoryPlayList,	// Play a series of same-format WAVs back to back, played from memory-mapped WAVs
	Gos1Audio_StreamedFile,			// Leave the sound data on disk, streaming only the data when needed. Note: only volume and pan affect streamed files
	Gos1Audio_StreamedMusic
};

typedef struct _Gos1Audio_Format
{     
	WORD  wFormatTag;				// Waveform-audio format type. 1=PCM, 2=Microsoft ADPCM.
	WORD  nChannels; 				// 1=Mono, 2=Stereo.
    DWORD nSamplesPerSec;			// Sample rate, 11025Hz, 22050Hz or 44100Hz. 
	DWORD nAvgBytesPerSec;          // Normally, nBlockAlign * nSamplesPerSec
	WORD  nBlockAlign; 				// Normally, wBitsPerSample / 8 * nChannels
    WORD  wBitsPerSample;			// Bits per sample for the wFormatTag format type. If wFormatTag is 1 (PCM), then wBitsPerSample should be equal to 8 or 16.  
	WORD  cbSize;					// Size, in bytes, of extra format information appended to the end of the WAVEFORMATEX structure. For PCM's, this should be set to 0. For ADPCM, this should be set to 32.
} Gos1Audio_Format; 

enum Gos1Audio_PlayMode
{
	Gos1Audio_PlayOnce,				// Play the channel's resource once and then end
	Gos1Audio_Loop,					// Continually play the channel's resource, looping after each iteration
	Gos1Audio_Pause,					// Pause the sound, a Continue will resume the sound from where it was paused
	Gos1Audio_Continue,				// SET ONLY: continue a sound that was paused.
	Gos1Audio_Stop,					// Silence the channel and stop processing the resource
};



typedef struct _Gos1Audio_ResourceInfo
{
	char *					lpstrPath;		// the path or name of the resource queried
	Gos1Audio_ResourceType	eType;			// see above
	Gos1Audio_Format			sFormat;		// 1 = PCM, 2 = ADPCM
	DWORD					dwSizeInBytes;	// size of the data portion of the WAV
	float					fDuration;		// in seconds
} Gos1Audio_ResourceInfo;



typedef struct
{
//
// Application title and version number
//
	char*	applicationName;		// "TestApp" or "Pong"
	char*	version;				// Default is "00.00.00.0000"
	char*	registryVersion;		// If present, will be used to create a sub folder in the registry (ie: v1.1, v1.2)
	char*	directoryPath;			// If program path end in this directory, move up levels (ie: "\\Code\\AssassinEditor" or "\\Tools\\PixelWhIP"). "!" will force GameOS NOT to change directory at all (Including DEBUG/RELEASE/PROFILE....)
	bool	allowMultipleApps;		// Allows the game to be run more than once on a single system (network testing)
	DWORD	MegMemoryRequired;		// Megabytes of virtual memory required to run game (default is 64Meg)
//
// Current screen mode (application can check, but may change from frame to frame)
//
	int		screenWidth;			// 640
	int		screenHeight;			// 480
	int		bitDepth;				// 16 or 32
	int		FullScreenDevice;		// 0=Primary, 1=2nd video card (ie: 3Dfx) etc...
	int		Renderer;				// 0=Try hardware, fallback to software, 1=RGB, 2=Refrast, 3=Blade
	bool	fullScreen;				// Application start running full screen or in a window?
	bool	disableZBuffer;			// When true no Z buffer surface will be created
	bool	AntiAlias;				// When true full screen antialiasing will be enabled if possible
	bool	RenderToVram;			// When true Blade applications will render directly to video memory (speed-up if no alpha is used)
	bool	Stencil;				// When true an 8 bit stencil buffer will be enabled if possible
	bool	TripleBuffer;			// When true, full screen modes will be triple buffered, else double buffered
	bool	MaxRefreshRate;			// When true, full screen modes will use the maximum card refresh rate, else 60hz.
	int		DirtyRectangle;			// Bit 0=Enabled, Bit 1=Save Z buffer rectangles too, Bit 2=Save directly in system memory (don't try video memory).
	int		DisableLowEndCard;		// When set to 1 and video cards in VideoCard.cpp with the LowEndCard flag set will have hardware acceleration disabled
	DWORD	MinimumTextureMemory;	// If this value is !=0 it specifies the minimum TEXTURE memory required otherwise hardware acceleration is disabled
//
// Keys used by GameOS (Use 0 to disable them, or see keycodes later in this header)
//
	DWORD	Key_FullScreen;			// Default is KEY_F4	(Enter/exit full screen mode)
	DWORD	Key_SwitchMonitors;		// Default is KEY_F5	(Change video cards - nvidia/voodoo etc...)
	DWORD	Key_Exit;				// Default is KEY_ESC	(Exit full screen mode or exit game)
//
// Debugging settings
//
	char*	debugLog;				// File to dump info to, or "debugger" to the debug console
	char*	spew;					// List of groups to dump to debuglog - eg: GameOS_Texture, GameOS_DirectDraw
	bool	TimeStampSpew;			// adds the current time stamp to all spews
	DWORD	memoryTraceLevel;		// How many levels of stack to walk when tracing memory allocations
//
// Game related functions
//
	float	MaxTimeDelta;			// Maximum time delta in seconds allowed between calls to gos_GetElapsedTime(); (Typical value = 1.0f)
	float	MinimumTimeDelta;		// If the time delta is greater than MaxTimeDelta, return this time to the application. (Typical value = 1.0f/30.0f)
//
// Sound-related application information
//
	bool	soundDisable;			// false = disable all sound, true = enable all sound
	bool	soundHiFi;				// true = 44Khz sound, false = 22KHz
	int		soundDevice;			// 0 = primary/default, # = device enum
	int		soundChannels;			// Default number of sound channels, for example 8
//
// Network settings
//
	bool	NetworkGame;			// Is this game going to be network aware?
	union {
	BYTE	NetworkGUID[16];		// This is the DirectPlay GUID that must be unique for the game
	GUID	GameGUID;				// Note that this union allows access as GUID but byte order will changing depending on initialization
	};								// All initialization of this code should use GameGUID from now on
	DWORD	NetworkMaxPlayers;		// The maximum number of players allowed in this game.
	BYTE	NetGameInfo[16];		// Information about the current network game (this can be enumerated from other network games before you join them)
	char* (__stdcall *DecodeGameInfo)(void*Data);	// GameOS will call this routine if present to decode the 16 bytes of network game information.
	char*	ZoneMatchServerIP;      // Typical value is ZoneMatch.zone.com
	bool	NetServerMigration;		// When true, the server player can quit and the game will continue (another machine will become the server)
//
// Controller settings
//
	bool ButtonsAsKeys;				// when true, gos_GetKey will return events for controller button presses
	bool allowDoubleClicks;			// make double-click messages available to the application (default is false)
//
// Raid Database settings
//
	char* RaidFilePath;				//	The path where the exception files for your project should be stored. They will be referred to by hyperlink in the bug description.
	char* RaidCustomFields;			//  A string containing key-value pairs of Raid Database column name and the value for that record. the column must be of type var-char with a width of 32 (standard raid list)
	char* RaidDataSource;			//  The raid data source name (can be retrieved from your odbc control panel or the registry once an rdq has been opened on your machine.
//
//
//
//
// These are legacy and will be deleted
//
	DWORD	NetworkMinPlayers;		// The minimum number of player required to start a game
	DWORD	AllowJoinInProgress;	// When true 'join in progress' is enabled for this network game
	DWORD	Texture_S_256;			// Number of 256*256 Solid texture heap pages
	DWORD	Texture_S_128;			// Number of 128*128 Solid texture heap pages
	DWORD	Texture_S_64;			// Number of   64*64 Solid texture heap pages
	DWORD	Texture_S_32;			// Number of   32*32 Solid texture heap pages
	DWORD	Texture_S_16;			// Number of   16*16 Solid texture heap pages
	DWORD	Texture_K_256;			// Number of 256*256 Keyed texture heap pages
	DWORD	Texture_K_128;			// Number of 128*128 Keyed texture heap pages
	DWORD	Texture_K_64;			// Number of   64*64 Keyed texture heap pages
	DWORD	Texture_K_32;			// Number of   32*32 Keyed texture heap pages
	DWORD	Texture_K_16;			// Number of   16*16 Keyed texture heap pages
	DWORD	Texture_A_256;			// Number of 256*256 Alpha texture heap pages
	DWORD	Texture_A_128;			// Number of 128*128 Alpha texture heap pages
	DWORD	Texture_A_64;			// Number of   64*64 Alpha texture heap pages
	DWORD	Texture_A_32;			// Number of   32*32 Alpha texture heap pages
	DWORD	Texture_A_16;			// Number of   16*16 Alpha texture heap pages

// Now functions GameOS can call in the application
//
// Returns a string containing game data
//  This is called during error routines, so NO errors must be able to occur in this routine.
//  Do not assume DirectX or your memory heap etc.. are valid.
//
	char* (__stdcall *GetGameInformation)();		
//
// Called ONCE only, after GameOS has been setup, just before main loop starts
//  All memory should be allocated and all structures should be cleared
//
	void (__stdcall *InitializeGameEngine)();
//
// Called each main loop, game should move 'one tick' if DoTimedGameLogic is not set
//  Do not update the display, just do the game logic.
//
	void (__stdcall *DoGameLogic)();
//
// Called each main loop, game should update it's sound and video renderers.
//  This is the only time draw or sound functions within the game are valid.
//  These are not allowed during DoGameLogic so renders may be skipped during
//  heavy loads or during 'fast playback' of a logfile.
//
	void (__stdcall *UpdateRenderers)(); 
//
// GameOS will call this once it comes out of the main loop, before it shuts down
//  No display updating should be attempted. This should be used to free all memory.
//
	void (__stdcall *TerminateGameEngine)(); 
//
//
//
//
// Applications can use thie to 'hook into' the gos_GetFile function.
//
// This allows you to 'catch' all the gos_GetFile calls. If you wish to have a compressed file system,
// or manage your own content directories, this API will allow you to catch all the access to the disk
// that GameOS does. All texture reading and gosScript file access goes through this API. If this hook
// function is 0 (default) then the calls will go to gos_GetFile. If you put the address of your own
// function there, GameOS will jump to that function. GameOS will check for gos_GetFIle being called
// again during this function and allow it to read from the disk normally.
//
	void (__stdcall *HookGetFile)( const char* FileName, BYTE** MemoryImage, DWORD* Size );

// Other file API calls available to hook

	bool (__stdcall *HookDoesFileExist)( const char* FileName);

} Gos1Environment;




typedef enum Gos1Enum_KeyDeviceType
{
	KEYDEV_KEYBOARD = 0x00000000,
	KEYDEV_JOYSTICK = 0x01000000,
};

enum { KEYDEV_MASK = 0xff000000 };

typedef enum Gos1Setting
{
	Gos1SetMouseCursor,					// 0=Disable cursor (default), 1=Enable cursor (Hardware if possible)
	Gos1SetSkipRender,						// When this is set to 1 there will be no rendering for the current frame. Can be used to skip frames when behind.
	Gos1SetNextGameLogicTime,				// Value is the number of Milliseconds between the last GameLogic and the next. GameOS will 'spin' until this time is met.
	Gos1SetTriggerBrowser,					// Value is a (char*) pointing to an address ie: "http:\\microsoft.com"
	Gos1SetLoseFocusBehavior,				// 0=Slow to 10Hz (default), 1=Pause game, 2=Run at full speed
	Gos1SetIgnoreMaxUV,					// 1=Disable the maximum U,V message assert. This is for apps in development that have u,v's larger than the card can handle
	Gos1SetIgnoreVSYNC,					// When 1 and in full sreen mode, GameOS will use BLT not FLIP. This means the game is not limited by the refresh rate.
	Gos1SetCaptureScreen,					// 1=Grab BMP screen shot, 0=Grab JPG screen shot
};

inline Gos1Audio_PlayMode Gos1Audio_GetChannelPlayMode( int Channel )
{
	bool playing;
	bool looping;
	int seekPosition;

	GosAudio::Get( Channel, GosAudio::PlayState, &playing, &looping, &seekPosition );
	if( playing )
		return looping ? Gos1Audio_Loop : Gos1Audio_PlayOnce;
	else
		return seekPosition ? Gos1Audio_Pause : Gos1Audio_Stop;
}

struct Gos1SurfaceDesc
{
	DWORD	dwWidth;
	DWORD	dwHeight;
	DWORD	dwSize;
	DWORD	lPitch;
	void	*lpSurface;
};


char* Gos1DescribeKey( DWORD Key );
DWORD Gos1EnableSetting( Gos1Setting Setting, DWORD Value );
void Gos1Video_GetResourceInfo( GosVideo *pVideo, Gos1Video_ResourceInfo* gvi );
void Gos1Video_Command( GosVideo *pVideo, enum Gos1Video_Command vc, float x, float y = 0.0f );
void Gos1Video_SetPlayMode( GosVideo *pVideo, enum Gos1Video_PlayMode gvpm );
void Gos1Audio_GetResourceInfo( GosSound *pSound, Gos1Audio_ResourceInfo* sri );
void Gos1Audio_AllocateChannelSliders( int Channel, DWORD properties);
void Gos1Lock( GosTexture *pTexture, LPRECT lpDestRect, Gos1SurfaceDesc *pDesc, DWORD dwFlags, HANDLE hEvent );

inline int Gos1InfoTextureSize() { return 256; } // temporary!
extern Gos1Environment Environment;
extern Gos1SurfaceDesc BackBufferddsd;

