#pragma once
//===========================================================================//
// File:	 gosScriptHeaders.hpp											 //
// Project:  gosScript				                                         //
// Contents: External API													 //
//---------------------------------------------------------------------------//
// Date      Who    Modification                                             //
// 08/05/99  JTR	Added a lot of documentation							 //
//																			 //
//---------------------------------------------------------------------------//
// Copyright (C) 1999 Microsoft Corp.						                 //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//



//
// Handles to the internal script structure
//
typedef struct _SCRIPT* HGOSSCRIPT;

//
// The following handles client application to script communication in the form
// of a single API and a number of enum'd commands
//
// The enum specifies the different commands that can be send from a C/C++ client
// application to the script while gosScript_Command actually sends the message
//
// EXAMPLE:
//	   int value = 1;
//     gosScript_Command(myScript, "o_listbox.m_update", gosScript_Cmd_ChangeValue, &value)
//
//     The above code immediately changes the value of o_listbox.m_update to 1.
//
enum gosScript_Cmd
{
	gosScript_Cmd_INIT,				// send a GUI_INIT to an object
	gosScript_Cmd_MAILBOX,			// send a GUI_MAILBOX to an object
	gosScript_Cmd_FOCUS,			// send a GUI_FOCUS to an object
	gosScript_Cmd_UNFOCUS,			// send a GUI_UNFOCUS to an object
	gosScript_Cmd_ACTIVATE,			// send a GUI_ACTIVATE to an object
	gosScript_Cmd_DEACTIVATE,		// send a GUI_DEACTIVATE to an object
	gosScript_Cmd_ChangeValue		// change a variable's value in an object (now you're playing with power, careful!)
};

extern void _stdcall gosScript_Command( HGOSSCRIPT hHandle, const char* variableOrObjectName, gosScript_Cmd cmd, void* parameter );



//
// In order to execute any script, the script processor must first be initialized.
// During the initialization phase, the parser sets up various tables and hooks
// into the GameOS' main loop. Once this is complete, the client application can
// begin making calls to gosScript_ExecuteScript.
//
// There is very little memory and CPU-usage overhead associated with leaving the 
// script processor running; it is generally acceptable to call gosScript_Initialize- 
// Processor once in the client application's initialization routines and then call
// gosScript_ShutdownProcessor when the client application is closing down.
//
extern void __stdcall gosScript_InitializeProcessor( int defaultFramerate = 60, void (_stdcall *ModalScriptLogic)(void) = 0 );
extern void __stdcall gosScript_ShutdownProcessor();



//
// To execute a script, the client application must call gosScript_ExecuteScript 
// with the name of file containing the script as well as a priority level at
// which the script will be run.
//
// Quite simply, the priority levels are as follows:
//
// 0x0000 - 0x0fff:	The script will render before the client application's UpdateDisplay
// 0x1000 - 0x1fff: The script renders after the client application's UpdateDisplay
// 0x2000 - 0x2fff: Execute the script in a "modal" fashion, game logic will cease until
//					the script has ended.
//
// An optional parameter, "instance," allows the user to run a script that sees only
// globally defined variables and variables defined in scripts of the same instance.
// This is an ideal way of differentiating registered script variables of the same name.
// One could, for example, create a C++ class that, upon construction, runs a script with
// the instance parameter equal to it the class instance's "this" pointer. To make that
// class' registered variable visible to that script (and that script only), fill in 
// "instance" parameter of gosScript_RegisterVariable/gosScript_RegisterCallback with the
// same "this" pointer.	Now a script exists that is directly tied to an instance of a 
// class!
// 
// Regardless of what priority a script is, or whatever its instance, it can be ended and
// uncached by simply calling gosScript_EndScript with the proper script handle.
//
extern HGOSSCRIPT __stdcall gosScript_ExecuteScript( const char* ScriptFileName, int Priority, void* instance=0 );
extern bool __stdcall gosScript_EndScript( HGOSSCRIPT Handle );
extern bool __stdcall gosScript_EndAllScripts(void);

//
// Pause a currently loaded script. Region-checking and GUI_EXECUTE will not be enabled.
// If drawMeThough is set to true, the GUI_DRAW will be called whether or not the script
// is paused.
//
extern bool _stdcall gosScript_PauseScript( HGOSSCRIPT Handle, bool drawMeThough = false );

//
// Resume processing and drawing a paused script.
//
extern bool _stdcall gosScript_ContinueScript( HGOSSCRIPT Handle );


//
//Find the script handle given the script name and instance.  Name should be specified without
//the extension and without @signs@ around it. If handle is NULL, the script couldn't be found.
//
extern HGOSSCRIPT _stdcall gosScript_GetScriptHandle( const char* pszScriptName, int Instance );

//
// Once a script is loaded and executing, the client can get and set the priority
// of the script at will. Simply furnish the functions below with the handle to
// the script in question, and fire it off. See above for how script priorities are
// interpreted.
//
int __stdcall gosScript_GetScriptPriority( HGOSSCRIPT Handle );
void __stdcall gosScript_SetScriptPriority( HGOSSCRIPT Handle, int Priority );



//
// C/C++ programs can communicate indirectly with scripts through the use of
// registered variables. To register a C/C++ variable with gosScript, simply
// call the gosScript_RegisterVariable function with the proper parameters.
//
// The first parameter is the character string by which the variable will be
// referred to within the scripting language. Two dollar signs are prepended
// and appended to this name within scripts to signify that it is a registered
// variable. For example, "myVariableInC" becomes "$$myVariableInC$$."
//
// Next, the address of the variable must be supplied. This is pretty 
// straightforward except that gosScript isn't designed to handle multi-dimensional
// arrays.
//
// Only a few basic types of variables may be shared with a gosScript, because
// gosScript doesn't require many variable types to function. In the event that
// a client needs anything to share anything besides an int or a string, please
// contact jreicher@microsoft.com; sharing other variable types can be fairly
// tricky. 
//
// If the variable being shared is a one dimensional array, the array's size
// must be supplied. If the variable is not an array, simply supply 0.
//
// To make the variable visible only to scripts of a particular instance, set the
// instance of the registered variable to match it.
//
typedef enum gosEnum_VarType
{
	GOSVAR_UNKNOWN=0, 
	GOSVAR_INT,				// thoroughly tested JTR 08/05/99
	GOSVAR_STRING, 			// thoroughly tested JTR 08/05/99
	GOSVAR_POSITION, 
	GOSVAR_BITMAP, 
	GOSVAR_OBJECT, 
	GOSVAR_FONT, 
	GOSVAR_SOUND,
	GOSVAR_CUBE,
	GOSVAR_MOVIE,
	GOSVAR_GAF, 
	GOSVAR_PANE, 
	GOSVAR_FONT3D, 
	GOSVAR_FLOAT,
	GOSVAR_LIST

};

//
// Position structure, to decode GOSVAR_POSITION variables through a callback (location is a POSITION)
//
typedef struct
{
	int	x;
	int	y;
	int	z;
} gosScript_POSITION;

//
// Cube structure, to decode GOSVAR_CUBE variables through a callback (region is a CUBE)
//
typedef struct
{
	gosScript_POSITION p1;
	gosScript_POSITION p2;
} gosScript_CUBE;



void __stdcall gosScript_RegisterVariable( const char* name, void* address, gosEnum_VarType vt, int arraysize, void* instance = 0 );
void __stdcall gosScript_UnregisterVariable( const char* name, void* instance = 0);

//
// To remove all registered variables/callbacks attributed to a particular instance, 
// simply call the function below with the proper instance pointer. If instance is NULL,
// all globally registered (instance == NULL) variables will be unregistered.
//
void __stdcall gosScript_UnregisterAll(void * instance);



// 
// gosScript scripts can "call back" into actuall C++ code through the registration of
// gosScript_RegisterCallback. The format for C/C++ is standardized and follows the
// format: "int <func_name>(void * instance, int args, void * arg[16])." When a callback
// is executed, the "instance" parameter is filled in with whatever instance the callback
// was registered with, as well as the number of parameters, followed by pointers to 
// the parameters themselves. As the variables are referenced with pointers, the value 
// held in them can be changed within the C/C++ callback.
// 
// The gosEnum_VarType parameter is always GOSVAR_INT. This parameter will be removed soon, as it is
// superfluous.
//
// Remember to supply the proper instance when you gosScript_UnregisterCallback.
//
typedef  int ( _stdcall * GOSSCRIPTCALLBACK)( void* instance, int args, void * arg[16] );
void __stdcall gosScript_RegisterCallback( const char* name, GOSSCRIPTCALLBACK address, gosEnum_VarType vt, int arraysize, void * instance = 0 );
void __stdcall gosScript_UnregisterCallback( const char* name, void* instance = 0 );









//
// While this is not likely to be an oft-used function, it has been supplied in the
// event that a client wants create their own front-end to the GAF compressor.
enum gosGAF_Type
{
	gosGAF_DeltaFromFirst,
	gosGAF_DeltaFromLast
};

int _stdcall gosScript_BuildGAFResource( char* orig_path, char* dst_name, gosGAF_Type);

