/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NSQUIRRELVM__
#define __NSQUIRRELVM__


		#include "squirrel.h"
		#include "script/script_vm.h"
		#include "script/script_object.h"


namespace GS {
	namespace Script {
		class SquirrelVM;

//
struct	SquirrelObject : public Object
{
		HSQOBJECT	object;
		SquirrelObject(SquirrelVM &, HSQOBJECT);
		~SquirrelObject();
};

/*
	@short	Squirrel based virtual machine.
	@author	Emmanuel Julien (ejulien@nworks.fr)
*/
class	SquirrelVM : public IVM
{
protected:

		HSQUIRRELVM	vm;

		int			call_arg_count;

public:

		/// Get VM name.
		const char	*GetName() const { return "Squirrel"; }

		/// Get VM call stack.
		void		GetCallStack(AutoList <CallStackEntry *> &);

/*!
	@name	Squirrel specific API.
	@{
*/
		HSQUIRRELVM	VM() const { return vm; }

		/// Set event hook table.
virtual	void		SetDebugInterface(IDebug *, bool enable_step_hook = false);

		/// Dump VM call stack.
static	void		DumpCallStack(HSQUIRRELVM, const char *desc, String *msg = 0);

		/// Push null value onto the stack.
virtual	bool		PushNull();
		/// Push property onto the stack.
virtual	bool		PushVariant(const Variant &);
		/// Get Squirrel value from stack.
virtual	bool		GetVariantFromStack(int stack_index, Variant &);
		/// Get a reference to a stack object.
		Object		*GetObjectFromStack(int stack_index);
/// @}

		/// Get a reference to a VM object.
virtual	Object		*GetObjectFromName(const char *name, const Object *context = 0);

		/// Setup a function call in the VM.
virtual	bool		SetupFunctionCall(const char *func, const Object *function_object = 0, const Object *search_context = 0);
		/// Set function call context.
virtual	bool		SetFunctionCallContext(const Variant &);
		/// Push function call null argument.
virtual	bool		PushNullArgument();
		/// Push function call argument.
virtual	bool		PushArgument(const Variant &);
		/// Execute a function call in the VM.
virtual	bool		DoFunctionCall(Variant *return_value = 0);

		/// Invalidate all references to a user object.
virtual	int			InvalidateNativeReference(void *) { return 0; }

		/// Compile a script.
virtual	bool		Compile(const char *source, uint size, const Object *context = 0, const char *sourcename = 0);

		/// Create a table object.
virtual	Object *CreateTable();
		/// Set a VM variable.
virtual	bool		Set(const char *name, const Variant &, const Object *context = 0);
		/// Get a VM variable.
virtual	bool		Get(const char *name, Variant &, const Object *context = 0);

		/// Create a script array.
virtual	Object		 *CreateArray();
		/// Append a VM variable to an array.
virtual	bool		Append(const Variant &, const Object *context = 0);

		/// Is the VM open.
virtual	bool		IsOpen() const { return asbool(vm); }

virtual	bool		Open();
virtual	void		Close();

		SquirrelVM();
virtual	~SquirrelVM();
};

	} // Script
} // GS


#endif	// __NSQUIRRELVM__
