// These functions need to be implemented to run gosScript without GameOS or GamePlatform
//
#include "Script.hpp"
#if (DISTRIBUTED_GOSSCRIPT == 1)
#include <GameOS\GameOS.hpp>
#include <GameOS\ToolOS.hpp>
#include <windows.h>
#pragma comment( lib, "winmm.lib" )

struct gos_Heap
{
public:
	gos_Heap();
	~gos_Heap();
};

gos_Heap * ClientHeap;
gos_Heap * DefaultHeap;

DWORD gCurrentHeapStackLevel = 0;

//
// The only variables used by scripts in the Environment are :
//
// screenWidth			// Normaly 800 in Crimson Skies
// screenHeight			// Normaly 600 in Crimson Skies
//
gosEnvironment  Environment;
void _stdcall GetGameOSEnvironment(char * lpCmd)
{
	lpCmd;
}

//
// This routine executes and renders gosScripts.
//
// It must be called three times in the application main loop
//
//	DoScriptUpdate(0xffff)		// This is the main 'execute scripts' - this does all the logic involved in scripts
//
//	DoScriptUpdate(0x0000)		// Before the main game updates the display
//	DoScriptUpdate(0x1000)		// After the game updates the display
//
void (__stdcall * DoScriptUpdate)(int)=0;

//
// This is set when Modal script are executed
//
DWORD	ModalScripts=0;			// ModalScripts

//
// When this is true the scripts will show visual debugging information
//
extern DWORD	gEnableScriptRegions;

//
// If scripts generate errors, this can be set to the script file and line with the errors
//
char* gosErrorFile;
DWORD gosErrorLine;

//
// When set to 1 exit the game
//
DWORD Terminate=0;
//
// Time when APP started
//
DWORD StartTime=0;




//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// *************************   Machine Information API  *********************** //
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

//
// Returns machine information, valid for THE CURRENT FRAME ONLY
//
DWORD __stdcall gos_GetMachineInformation( MachineInfo mi, int Param1, int Param2, int Param3 )
{
	mi; Param1; Param2; Param3;
	return NULL;
}

//
//
// Localization API's
//
//


//
// Opens a DLL and returns a handle
//
DWORD __stdcall gos_OpenResourceDLL( const char* FileName )
{
	FileName;
	return NULL;
}

//
// Use to close a resource DLL
//
void __stdcall gos_CloseResourceDLL( DWORD Handle )
{
	Handle;
}

//
// Returns a string from a resource (or a place holder if string not defined)
//
// This returns a pointer to an internal GameOS 1K buffer. It is only valid until the next call to gos_GetResourceString
//
char* __stdcall gos_GetResourceString( DWORD Handle, DWORD Id )
{
	Handle; Id;
	return NULL;
}

//
// Returns a void * to block of memory stored in the resource .dll. Resources
// that are stored in this fashion must be a "custom" resource and their resource type
// string must match that of the 2nd parameter. 
//
// If the resource cannot be found, a NULL is returned. 
// 
// If the resource is found, size is set to the size of resource in
// bytes and the resource data is copied into a freshly allocated memory block from the
// currently designated heap. It is the responsibility of the client application to
// release this memory when it is no longer needed.
//
void* __stdcall gos_GetResourceData( DWORD Handle, char * type, DWORD id, size_t * size )
{
	Handle; type; id; size;
	return NULL;
}











//
//
// 3D Font API's
//
//
HGOSFONT3D __stdcall gos_LoadFont( const char* FontFile, DWORD StartLine, int CharCount, DWORD textureHandle )
{
	FontFile; StartLine; CharCount; textureHandle;
	return 0;
}
void __stdcall gos_DeleteFont( HGOSFONT3D Fonthandle )
{
	Fonthandle;
}
void __stdcall gos_TextSetAttributes( HGOSFONT3D Handle, DWORD Foreground, float Size, bool WordWrap, bool Proportional, bool Bold, bool Italic, DWORD wrapType )
{
	Handle; Foreground; Size; WordWrap; Proportional; Bold; Italic; wrapType;
}
void __stdcall gos_TextSetRegion( int Left, int Top, int Right, int Bottom )
{
	Left; Top; Right; Bottom;
}
void __stdcall gos_TextSetPosition( int XPosition, int YPosition )
{
	XPosition; YPosition;
}
void __stdcall gos_TextGetPrintPosition( int* XPosition, int* YPosition )
{
	XPosition; YPosition;
}
void __stdcall gos_TextStringLength( DWORD* Width, DWORD* Height, const char *Message, ... )
{
	Width; Height; Message;
}
void __stdcall gos_TextDrawBackground( int Left, int Top, int Right, int Bottom, DWORD Color )
{
	Left; Top; Right; Bottom; Color;
}
void __stdcall gos_TextDraw( const char *Message, ... )
{
	Message;
}




//
//
// Video playback API's
//
//
void __stdcall gosVideo_GetResourceInfo( HGOSVIDEO video, gosVideo_ResourceInfo * gvri)
{
	video; gvri;
}
void __stdcall gosVideo_DestroyResource(HGOSVIDEO* video)
{
	video;
}
void __stdcall gosVideo_Command( HGOSVIDEO video, enum gosVideo_Command vc, float x, float y)
{
	video; vc; x; y;
}
void __stdcall gosVideo_SetPlayMode(HGOSVIDEO video, enum gosVideo_PlayMode gvpm)
{
	video; gvpm;
}
void __stdcall gosVideo_CreateResource(HGOSVIDEO* video, char * path)
{
	video; path;
}

void __stdcall gosVideo_CreateResourceAsTexture(HGOSVIDEO* video, DWORD * texture, char * path)
{
	video; texture; path;
}





//
//
// Audio playback API's
//
//
void __stdcall gosAudio_GetResourceInfo(HGOSAUDIO hgosaudio, gosAudio_ResourceInfo * ga_ri)
{
	hgosaudio; ga_ri;
}
void __stdcall gosAudio_DestroyResource( HGOSAUDIO * resource)
{
	resource;
}
void __stdcall gosAudio_AllocateChannelSliders(int Channel, DWORD properties)
{
	Channel; properties;
}
void __stdcall gosAudio_GetChannelSlider(int Channel, enum gosAudio_Properties ga_p, float * value, float * value1, float * value2)
{
	Channel; ga_p; value; value1; value2;
}
void __stdcall gosAudio_SetChannelSlider(int Channel, enum gosAudio_Properties ga_p, float value, float value1, float value2)
{
	Channel; ga_p; value; value1; value2;
}
gosAudio_PlayMode __stdcall gosAudio_GetChannelPlayMode(int Channel)
{
	Channel;
	return gosAudio_Stop;
}
void __stdcall gosAudio_AssignResourceToChannel(int Channel, HGOSAUDIO hgosaudio)
{
	Channel; hgosaudio;
}
void __stdcall gosAudio_CreateResource( HGOSAUDIO * hgosaudio, enum gosAudio_ResourceType ga_rt,  const char * file_name, gosAudio_Format * ga_wf, void * data, int size)
{
	hgosaudio; ga_rt; file_name; ga_wf; data; size;
}
void __stdcall gosAudio_SetChannelPlayMode(int Channel, enum gosAudio_PlayMode ga_pm)
{
	Channel; ga_pm;
}



//
//
// Disk file access
//
//
void __stdcall gos_GetFile( const char* FileName, BYTE** MemoryImage, DWORD* Size )
{
	FileName; MemoryImage; Size;
}
void __stdcall gos_OpenFile( HGOSFILE* file, const char* FileName, gosEnum_FileWriteStatus fwstatus )
{
	file; FileName; fwstatus;
}
DWORD __stdcall gos_WriteFile( HGOSFILE file, const void* buf, DWORD size )
{
	file; buf; size;
	return 0;
}
void __stdcall gos_CloseFile(HGOSFILE file)
{
	file;
}
bool __stdcall gos_DoesFileExist( const char* FileName )
{
	FileName;
	return 0;
}




//
//
// Keybord input
//
//
DWORD __stdcall gos_GetKey()
{
	return 0;
}
gosEnum_KeyStatus __stdcall gos_GetKeyStatus(gosEnum_KeyIndex index)
{
	index;
	return KEY_FREE;
}
void __stdcall gos_KeyboardFlush()
{
}



//
//
// Mouse input
//
//
void __stdcall gos_GetMouseInfo( float* pXPosition, float* pYPosition, int* pXDelta, int* pYDelta, int* pWheelDelta, DWORD* pButtonsPressed )
{
	pXPosition; pYPosition; pXDelta; pYDelta; pWheelDelta; pButtonsPressed;
}




//
//
// 3D Rendering API's
//
//
void __stdcall gos_SetupViewport( bool FillZ, float ZBuffer, bool FillBG, DWORD BGColor, float top, float left, float bottom, float right, bool ClearStencil, DWORD StencilValue )
{
	FillZ; ZBuffer; FillBG; BGColor; top; left; bottom; right; ClearStencil; StencilValue;
}
void __stdcall gos_SetRenderState( gos_RenderState RenderState, int Value )
{
	RenderState; Value;
}
void __stdcall gos_DrawQuads( gos_VERTEX* Vertices, int NumVertices )
{
	Vertices; NumVertices;
}
void __stdcall gos_DrawLines( gos_VERTEX* Vertices, int NumVertices )
{
	Vertices; NumVertices;
}
bool __stdcall gos_RecreateTextureHeaps()
{
	return 0;
}
void __stdcall gos_DestroyTexture( DWORD Handle )
{
	Handle;
}
void __stdcall gos_LockTexture( DWORD Handle, DWORD MipMapSize, bool ReadOnly, TEXTUREPTR* TextureInfo )
{
	Handle; MipMapSize; ReadOnly; TextureInfo;
}

//
// Converts from 32bpp source to subrect of n-bpp dest, bypassing intermediate 32bpp buffer
//
void __stdcall gos_ConvertTextureRect( DWORD Handle, DWORD DestLeft, DWORD DestTop, DWORD *Source, DWORD SourcePitch, DWORD Width, DWORD Height )
{
	Handle; DestLeft; DestTop; Source; SourcePitch; Width; Height;
}

void __stdcall gos_UnLockTexture( DWORD Handle )
{
	Handle;
}
DWORD __stdcall gos_NewEmptyTexture( gos_TextureFormat Format, char const* Name, DWORD Width, DWORD Hints )
{
	Format; Name; Width; Hints;
	return 0;
}
void __stdcall gos_PushRenderStates()
{
}
void __stdcall gos_PopRenderStates()
{
}


//
// Adds a menu item to the ^Break debugger.
//
// This allows games to enable or disable game features using the debugger.
//
// If no items have been added to this menu it will not appear. Otherwise the
// menu item will appear under the last drop down menu with the same title
// as the game. ie: Assassin.
//
// Name			is the name of the menu entry (if " " a blank line is added to the menu)
// CheckMark	is a routine that should return true if the menu should have a check next to it (active)
// Activated	is a routine that is callled when the user select this menu item
// Greyed		is a routine that if it returns true the item will be greyed and will not be able to be selected
//
void __stdcall AddDebuggerMenuItem( char* Name, bool(__stdcall *CheckMark)(), void(__stdcall *Activated)(), bool(__stdcall *Greyed)(), DWORD(__stdcall *Callback)( char* Name, DWORD MenuFunction) )
{
	Name; CheckMark; Activated; Greyed;	Callback;
}


//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// **************************	   MEMORY API	   **************************** //
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

//
// By default, any gos_Malloc's or new's made by the client application will be dropped
// into this heap: the ParentClientHeap. Use ParentClientHeap to explicitly tell the Memory Manager
// to place allocated memory into client memory. 
//
extern HGOSHEAP ParentClientHeap;

//
// When including GamePlatform, new and delete will map directly to gos_Malloc and gos_Free
//
// new also has an optional second parameter which specifies the heap to allocate from.
//

//
// Not filling in the heap parameter on gos_Malloc's tells the Memory Manager to allocate memory in
// the heap currently on top of the heap stack.
//
void* __stdcall gos_Malloc( size_t bytes, HGOSHEAP Heap )
{
	Heap;
	return malloc(bytes);
}

void __stdcall gos_Free( void* ptr )
{
	free(ptr);
}

//
// Not filling in the heap parameter on new's tells the Memory Manager to allocate memory in
// the heap currently on top of the heap stack.
//
void* __cdecl operator new (size_t size, HGOSHEAP Heap)
{
	Heap;
	return malloc(size);
}

//
// Allows an application to create a named memory heap.
//
// The DWORD returned is a heap number that can be the second parameter passed to new or gos_Malloc.
//
// If MaximumSize is specified, GameOS will assert when more than that number of bytes is allocated.
//
// The memory heaps and current sizes are visible in the GameOS debugger.
//
HGOSHEAP __stdcall gos_CreateMemoryHeap( char* HeapName, DWORD MaximumSize, HGOSHEAP parentHeap)
{
	HeapName; MaximumSize; parentHeap;
	return NULL;
}

//
// Allows the application to destroy a previously created memory heap.
// Note that, at shutdown, the default heap is destroyed automatically.
//
// o Destroying a heap destroys all its children as well
// o Setting shouldBeEmpty to false silences the deallocation of memory
//   still assigned to the heap or its children. We don't encourage this
//   as it can result in non-NULLed pointers within the client code.
//
void __stdcall gos_DestroyMemoryHeap( HGOSHEAP Heap, bool shouldBeEmpty )
{
	Heap; shouldBeEmpty;
}

//
// Sets the current heap being used by new and delete (and any gos_Mallocs that don't specifiy a heap)
//
// The 'default heap' for all client memory is caught by ClientHeap.
//
void __stdcall gos_PushCurrentHeap( HGOSHEAP Heap )
{
	Heap;
}

HGOSHEAP __stdcall gos_GetCurrentHeap()
{
	return NULL;
}


void __stdcall gos_PopCurrentHeap()
{
}

//
// Read in a BMP file and return a 32bit memory surface containing it.
//
//
// pBitmap contains the BMP file
// Size is the length of the BMP file
//
//
void * DecodeBMP( const char* FileName, BYTE* Data, DWORD DataSize, DWORD* TextureWidth, DWORD* TextureHeight, bool TextureLoad, void *pDestSurf )
{
	FileName; Data; DataSize; TextureWidth; TextureHeight; TextureLoad; pDestSurf;
	return NULL;
}

void * DecodePNG( const char* FileName, BYTE* Data, DWORD DataSize, DWORD* TextureWidth, DWORD* TextureHeight, bool TextureLoad, void *pDestSurf)
{
	FileName; Data; DataSize; TextureWidth; TextureHeight; TextureLoad; pDestSurf;
	return NULL;
}

void * DecodeTGA( const char* FileName, BYTE* Data, DWORD DataSize, DWORD* TextureWidth, DWORD* TextureHeight, bool TextureLoad, void *pDestSurf)
{
	FileName; Data; DataSize; TextureWidth; TextureHeight; TextureLoad; pDestSurf;
	return NULL;
}

void * DecodeJPG( const char* FileName, BYTE* Data, DWORD DataSize, DWORD* TextureWidth, DWORD* TextureHeight, bool TextureLoad, void *pDestSurf)
{
	FileName; Data; DataSize; TextureWidth; TextureHeight; TextureLoad; pDestSurf;
	return NULL;
}












//
//****************************************************************************************************************
//
//
// Code below here should be 'ok' - you will have to merge this with your game logic.
//
// You should not need to add anything to this code to get scripts to run though.
//
//
//





//
// Called during 'modal' scripts to update the display and run the script logic loop
//
DWORD __stdcall RunGameOSLogic()
{
//
// Run any game logic
//
	Environment.DoGameLogic();
//
// Run the scripts game logic
//
	DoScriptUpdate(0xffff);
//
// Update the screen from scripts (before game logic)
//
	DoScriptUpdate(0x0000);
//
// If main game needs to update the screen, do it here
//
	if( !ModalScripts )
		Environment.UpdateRenderers();
//
// Update the screen from scripts (after game logic)
//
	DoScriptUpdate(0x1000);
//
//
//
	return Terminate;
}




//
// Called to signify the application should exit at the end of the logic loop
//
void __stdcall gos_TerminateApplication()
{
	Terminate=1;
}
//
// Error handling functions
//
void __stdcall InternalFunctionSpew( const char *Group, const char *Message, ... )
{
	Group; Message;
}
int __stdcall InternalFunctionStop( const char *Message, ... )
{
	Message;
	_asm int 3;
	return 0;
}
int __stdcall InternalFunctionPause( const char *Message, ... )
{
	Message;
	_asm int 3;
	return 0;
}
int _fastcall ErrorHandler( int Flags, char* Text )
{
	Flags; Text;
	_asm int 3;
	return 0;
}
//
// Used to get information about the machine (Script use this to decide on a texel offset)
//
DWORD __stdcall gos_GetMachineInformation( MachineInfo mi )
{
	mi;
	return 0;
}
//
// Called to terminate a program
//
void __stdcall ExitGameOS()
{
	_exit(1);
}









//
// Map this to rand()
//
int __stdcall gos_rand()
{
	return rand();
}
//
// Returns the time in seconds since the start of the application
//
double __stdcall gos_GetElapsedTime( int )
{
	return (timeGetTime()-StartTime)/1000.0;
}





//
//
// Windows entry point (required so will compile as a windows program)
//
//
int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
{
	nCmdShow; hPrevInst; hInst;
//
// Setup some variables
//
	ModalScripts=0;
	gEnableScriptRegions=0;				// Set to 1 to enable debugging in scripts
	Terminate=0;
	StartTime=timeGetTime();
//
// Clear environment to defaults
//
	memset( &Environment, 0, sizeof(Environment) );
//
// Get application to fill in it's defaults
//
	GetGameOSEnvironment( lpCmdLine );
//
// Setup a window and D3D here
//


//
// Now system is seutp, run game logic init
//
	Environment.InitializeGameEngine();
//
// Now the main loop
//
	do
	{
		RunGameOSLogic();
	} while( !Terminate );
//
// Clean up the game code
//
	Environment.TerminateGameEngine();
//
// Clean up game shell (never returns)
//
	ExitGameOS();
	return 0;
}


DWORD __stdcall gos_LZCompress( BYTE* dest, BYTE* src, DWORD srcLen )
{
	dest; src; srcLen;
	return 0;
}
//
//
// LZ Decompression routine, returns length to decompressed output in dest buffer
//
//
DWORD __stdcall gos_LZDecompress( BYTE* dest, BYTE* src, DWORD srcLen )
{
	dest; src; srcLen;
	return 0;
}

//////////////////////////////////////////////////////////////////////////
//								MISC						
//////////////////////////////////////////////////////////////////////////

//
// Gets a pointer to text data in the windows clip board (NULL=No text)
//
DWORD __stdcall gos_GetClipboardText( char* Buffer, DWORD BufferSize );
{
	Buffer; BufferSize;
	return 0;
}

//
// Sets the windows clipboard to the current text string
//
void __stdcall gos_SetClipboardText( char* Text );
{
	Text;
}

//
// Set text entry caret screen position (Used to enable the localization IME pop-up at the correct place)
//
void _stdcall gos_PositionIME( DWORD x, DWORD y, DWORD baseColor=0xffffffff, DWORD borderColor=0xff000000, BYTE symbolTranslucence=0xA0, BYTE symbolSize=24, BYTE symbolPlacement=0, DWORD symbolColor = 0 );
{
	x;y;baseColor;borderColor;symbolTranslucence; symbolSize; symbolPlacement; symbolColor;
}

//
// Opens/closes IME programatiically if IME is enabled
//
void _stdcall gos_ToggleIME(bool onOff)
{
	onOff;
}

void _stdcall gos_EnableIME( bool onOff )
{
	onOff;
}

// Set the IME's composition string to the value currently displayed in the edit box.
void _stdcall gos_FinalizeStringIME()
{
}


char* __stdcall gos_DescribeKey( DWORD Key )
{
	key;
	return NULL;
}



// 
// JOYSTICK-RELATED
//

//
// The various outputs that can be examined by GameOS.
//
typedef enum GOSJoystickAxis
{
	JOY_XAXIS = 0,
	JOY_YAXIS = 1,
	JOY_ZAXIS = 2,
	JOY_THROTTLE = 2,
	JOY_RXAXIS = 3,
	JOY_RYAXIS = 4,
	JOY_RZAXIS = 5,
	JOY_RUDDER = 5,
	JOY_SLIDER1 = 6,
	JOY_SLIDER2 = 7,
	JOY_HAT1 = 8,
	JOY_POV1 = 8,
	JOY_HAT2 = 9,
	JOY_POV2 = 9,
	JOY_HAT3 = 10,
	JOY_POV3 = 10,
	JOY_HAT4 = 11,
	JOY_POV4 = 11,
	JOY_MAX = 12
};


//
// Information returned about each joystick
//
struct gosJoystick_Info
{
	const char*	lpstrName;				// the brand and model name
	DWORD		bAxisValid:JOY_MAX;		// yes/no bitflags.
	DWORD  		nAxes:4;				// number of availab axes
	DWORD  		nButtons:5;				// number of available buttons
	DWORD  		nSliders:4;				// number of slidesr
	DWORD  		nPOVs:4;				// number of point of view hats
	DWORD  		bIsPolled:1;			// whether or not this stick is polled
	DWORD 		bIsForceFeedback:1;
											// 1 spare bit
};

//
// Return the total number of joysticks detected when the application started.
//  This API may take up to 100ms to comlete, so should be called on a 'Refresh button' in an options screen.
//  When a joystick is unplugged during gameplay, you need to call this API to have GameOS 're-detect' it.
//  This will also detect any new joysticks plugged into the computer since the application started.
//
DWORD __stdcall gosJoystick_CountJoysticks( bool ReDetect=1 )
{
	return 0;
}

//
// Return joystick <index>'s details in structure <gji>
//
void __stdcall gosJoystick_GetInfo( DWORD index, gosJoystick_Info* gji )
{
	index; gji;
}

//
// Turn the polling of joystick <index> on or off. howOften variable details the
// frequency of polling. A 'howOften' of .5 will poll twice per second, for
// example.	By default, it polls at 30Hz.
//
void __stdcall gosJoystick_SetPolling( DWORD index, bool yesNo, float howOften=0.03333f )
{
	index; yesNo; howOften;
}

//
// Return the current value of a particular joystick's particular axis. The
// value is mapped internally to range between -1.0f and 1.0f.
// except for POV which are at -1 when at rest, a %clockwise when engaged
//
float __stdcall gosJoystick_GetAxis( DWORD index, GOSJoystickAxis axis )
{
	index; axis;
	return 0.0f;
}


//
// Return a value (FALSE unpressed, TRUE pressed) for the button <button> on joystick <index>.
//
bool __stdcall gosJoystick_ButtonStatus( DWORD index, DWORD button )
{
	index; button;
	return false;
}


#endif
