/*
 * $Id: h,v 1.1 2008-04-08 21:28:30 kybav1 Exp $
 *
 * Description  : One line description of file.
 * Author       : Vaclav Kyba <mail/Jabber: vaseo1@gmail.com>  <ICQ: 98576293>
 *
 * Purpose      :
 *     Long description of what the file is for.
 */

#ifndef __SCENEMODULE_H__
#define __SCENEMODULE_H__

#include "module.h"
#include "scenemanager.h"
#include "VrutApi.h"


namespace VRUT
{
	///Module with access to scene manager
	class VRUT_CORE_API SceneModule : public Module
	{
	protected:
		///Scene ID
		SCENE_ID sceneID;
		///Parameter identifier for \c sceneID
		Parameter::ParameterIdentifier sceneIDParamID;
		///Scene pointer
		smart_pointer_v2<Scene> scene;

		bool sceneIDAutoFromNodeMode;
		bool sceneIDAutoMode;

		virtual void processEvent(Event *evt)
		{
			Module::processEvent(evt);
			switch (evt->type)
			{
			case Event::EVT_PARAM_SET:
				if (((EventParamSet*)evt)->paramIdentifier == sceneIDParamID)
				{
					wxString valueRest;

					if (((EventParamSet*)evt)->value.StartsWith(wxT("AutoFromNodeMode "), &valueRest))
					{
						sceneIDAutoFromNodeMode = valueRest.IsSameAs(wxT("1"));
						// stop event propagation
					}
					else if (((EventParamSet*)evt)->value.StartsWith(wxT("AutoMode "), &valueRest))
					{
						sceneIDAutoMode = valueRest.IsSameAs(wxT("1"));
						// stop event propagation
					}
					else
					{
						UPDATE_PARAM_FROM_EVENT_ID(sceneIDParamID, sceneID, evt);
						KERNEL->sceneManager->GetScene(scene, sceneID);
					}
				}
				break;
			case Event::EVT_SCENE_ADDED:
				if (((EventSceneAdded*)evt)->sceneID == sceneID)
					KERNEL->sceneManager->GetScene(scene, sceneID);
				break;
			case Event::EVT_SCENE_REMOVED:
				if (((EventSceneRemoved*)evt)->sceneID == sceneID)
					KERNEL->sceneManager->GetScene(scene, sceneID);
				break;
			case Event::EVT_SCENE_NODE_SELECTED:
				if (!sceneIDAutoFromNodeMode)
					break;

				if (((EventSceneNodeSelected*)evt)->sceneID != sceneID)
				{
					SetSceneID(((EventSceneNodeSelected*)evt)->sceneID);
					KERNEL->sceneManager->GetScene(scene, ((EventSceneNodeSelected*)evt)->sceneID);
				}
				break;
			case Event::EVT_RENDER_WIN_FOCUSED:
			{
				if (!sceneIDAutoMode)
					break;				
				/*
				GLWindow* win = KERNEL->renderManager->GetGLWindow(((EventRenderWinFocused*)evt)->windowID);

				if (win == NULL)
					break;

				RenderModule *renderModule = win->GetRenderModule();
				if (renderModule == NULL)
					break;

				SCENE_ID newSceneID = renderModule->GetSceneID();
				*/

				SCENE_ID newSceneID = ((EventRenderWinFocused*)evt)->sceneID;

				if ((newSceneID != SCENE_ID_NONE) && (newSceneID != sceneID))
				{
					SetSceneID(newSceneID);
					KERNEL->sceneManager->GetScene(scene, newSceneID);
				}
				break;
			}
			default:
				break;
			}
		}

	public:
		///Class constructor
		SceneModule(const MODULE_ID & _id, const wxString & _name, unsigned _type, Kernel * _kernel, const wxString &layoutFileName=wxT("")) : Module(_id, _name, (_type | MODULE_TYPE_SCENE), _kernel), sceneID(SCENE_ID_NONE), sceneIDAutoFromNodeMode(false), sceneIDAutoMode(false)
		{
			REGISTER_LISTENER(Event::EVT_SCENE_ADDED);
			REGISTER_LISTENER(Event::EVT_SCENE_REMOVED);

			REGISTER_LISTENER(Event::EVT_SCENE_NODE_SELECTED);
			REGISTER_LISTENER(Event::EVT_RENDER_WIN_FOCUSED);

#ifndef VRUT_HPC
			// set parameters window's layout
			if (!layoutFileName.empty())
			{
				Parameter::ParameterIdentifier layoutParamID;
				wxString layoutFileNameTmp(layoutFileName);
				PARAM_GUI_SET_LAYOUT(layoutParamID, wxT("layout"), layoutFileNameTmp, wxT("Parameters window's layout"));
			}
#endif
			SetSceneID(sceneID);
			KERNEL->sceneManager->GetScene(scene, sceneID);
		}

		///Class destructor
		virtual ~SceneModule()  {}

		///Get associated scene ID
		SCENE_ID GetSceneID() const
		{
			return sceneID;
		}

		///Set sceneID and update combobox
		void SetSceneID(SCENE_ID _sceneID)
		{
			sceneID = _sceneID;
			REGISTER_PARAM_GUI_SCENEID(sceneIDParamID, wxT("sceneID"), sceneID, wxT("Scene ID"));
		}
	};
}

#endif // __SCENEMODULE_H__
