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


#ifndef	__NPROJECT__
#define	__NPROJECT__


		#include "project/project_factory_interface.h"
		#include "project/project_scene_instance.h"
		#include "project/project_script_unit.h"
		#include "project/project_layer.h"
		#include "core/resource_factories.h"
		#include "core/raster_font.h"
		#include "core/clock.h"
		#include "script/script_unit.h"
		#include "script/script_vm.h"
		#include "font/font_factory.h"
		#include "font/font_cache.h"


namespace GS {

	namespace Audio { struct IMixer; }
	namespace Render { class Renderer; }

	namespace Core {
		using Audio::IMixer;
		using Render::Renderer;

//
class	Project
{
protected:

		sResourceFactories factories;

		AutoList <ProjectSceneInstance *> instance_list;

		bool			prohibit_project_action;	///< Disable all instance creation and layer stack modifications.

		/// Check whether project action are allowed.
		bool			IsProjectActionAllowed(const char *f);

public:

		String			file_path;
		String			name, authors, description, company;

		Script::sVM		vm;

		sClock			clock;
		sFontCache		font_cache;

		//----------------------------------------------------------------------
		/// @short	Render flags.
enum	RenderFlag
{
	FlagNone			=	0,
	FlagDisableScript	=	(1 << 0),

	FlagDefault			=	FlagNone
};

enum	ProjectFlag
{
	ProjectFlagNone			=	0,
	ProjectFlagEnd			=	(1 << 0),
	ProjectFlagDebugPhysics	=	(1 << 1)
};

		BitField		flags;

		AutoList <ProjectLayer *> layer_list;

		void			Update(uint scene_update_flag);
		void			Render(Renderer &, RenderFlag = FlagDefault);
		//----------------------------------------------------------------------

		/// Draw profiler.
		void			DrawProfilerText(Renderer &, Render::RasterFont *font[2], float &x, float &y);

		//----------------------------------------------------------------------
		StringList		root_script_list, search_path;

		bool			CompileRootScripts();

		AutoPtr <ProjectScriptUnit> script_unit;

		void			UpdateScriptClock();
		//----------------------------------------------------------------------

		//----------------------------------------------------------------------
		AutoPtr <IProjectFactory> iproject_factory;

		ProjectSceneInstance *FindSceneInstance(const char *) const;
		ProjectSceneInstance *FindSceneInstance(const S3D::Scene *) const;
		ProjectSceneInstance *FindSceneInstance(const S2D::Scene *) const;

		ProjectSceneInstance *Instantiate(const char *name);
		ProjectSceneInstance *Instantiate(S3D::Scene *);
		ProjectSceneInstance *Instantiate(S2D::Scene *);

		void			Delete(ProjectSceneInstance *scene);

		/// Create a layer for a given project scene.
		ProjectLayer	*AddLayer(ProjectSceneInstance *, float zorder = 0.5);

		bool			IsActive(const ProjectSceneInstance &inst) const { return inst.active; }
		void			Activate(ProjectSceneInstance &, bool activate);

		/// Return the number of instantiated layer in the display stack.
		uint			GetInstanceCount() const { return instance_list.GetCount(); }
		/// Get scene instance list.
		const AutoList <ProjectSceneInstance *> &GetInstanceList() const { return instance_list; }
		/// Return the number of active layer in the display stack.
		uint			GetActiveCount() const;
		//----------------------------------------------------------------------

		void			ResetStatistics();

		void			New();

		bool			Open(bool project_mode = true);
		bool			Setup();
		void			Close();

		bool			FromMetaTag(NML::Tag &);
		NML::Tag		*AsMetaTag() const;

		Project(ResourceFactories *, IFontFactory *, Script::IVM * = 0);
virtual	~Project();
};

	} // Core
} // GS

//------------------------------------------------------------------------------
#define	__PROJECT_ACTION_SAFETY_CHECK(__RET__)	{	if	(!IsProjectActionAllowed(__FUNCTION__)) return __RET__;		}
#define	__PROJECT_ACTION_SAFETY_CHECK_RAW		{	if	(!IsProjectActionAllowed(__FUNCTION__)) return;		}


#endif	// __NPROJECT__
