/*!
	@file
	@author     Albert Semenov
	@date       08/2008
*/
#include "Precompiled.h"
#include "DemoKeeper.h"
#include "Base/Main.h"

#ifdef MYGUI_OGRE_PLATFORM

	#include "Ogre/RenderBox/RenderBox.h"

namespace demo
{
	static std::vector<wraps::RenderBox*> mRenderBoxes;
}

#endif // MYGUI_OGRE_PLATFORM

namespace demo
{

	void DemoKeeper::setupResources()
	{
		base::BaseManager::setupResources();
		addResourceLocation(getRootMedia() + "/Demos/Demo_Gui");
		addResourceLocation(getRootMedia() + "/Common/Scene");
		addResourceLocation(getRootMedia() + "/Common/Demos");
	}

	void DemoKeeper::createScene()
	{
		base::BaseDemoManager::createScene();
		createDefaultScene();
		const MyGUI::VectorWidgetPtr& root = MyGUI::LayoutManager::getInstance().loadLayout("HelpPanel.layout");
		if (root.size() == 1)
			root.at(0)->findWidget("Text")->castType<MyGUI::TextBox>()->setCaption(
				"Demonstration of using different widgets and styles (something like Ogre Demo_Gui).");

		mMainPanel = new MainPanel();
		mMainPanel->eventAction = MyGUI::newDelegate(this, &DemoKeeper::notifyEventAction);
		mMainPanel->addObject("FrameWindow");
		mMainPanel->addObject("Horizontal Scrollbar");
		mMainPanel->addObject("Vertical Scrollbar");
		mMainPanel->addObject("TextBox");
		mMainPanel->addObject("ImageBox");
		mMainPanel->addObject("Render to Texture");

		mEditorWindow = new EditorWindow();

		MyGUI::Gui::getInstance().eventFrameStart += MyGUI::newDelegate(this, &DemoKeeper::notifyFrameStart);
	}

	void DemoKeeper::destroyScene()
	{
		MyGUI::Gui::getInstance().eventFrameStart -= MyGUI::newDelegate(this, &DemoKeeper::notifyFrameStart);

		removeRenderBoxes();
		destroyWindows();

		delete mEditorWindow;
		mEditorWindow = nullptr;
		delete mMainPanel;
		mMainPanel = nullptr;
	}

	void DemoKeeper::destroyWindows()
	{
		delete mInformationWindow;
		mInformationWindow = nullptr;

		delete mColourWindow;
		mColourWindow = nullptr;
	}

	void DemoKeeper::createWindows()
	{
		destroyWindows();

		mInformationWindow = new InformationWindow(mEditorWindow->getView());
		mColourWindow = new ColourWindow(mEditorWindow->getView());
	}

	static int getRand(int _min, int _max)
	{
		if (_max < _min)
			std::swap(_max, _min);
		int range = _max - _min;
		if (range == 0)
			return 0;
		int result = ::rand() % range;
		if (result < 0)
			result = -result;
		return _min + result;
	}

	void DemoKeeper::notifyEventAction(MainPanel::TypeEvents _action, size_t _index)
	{
		if (_action == MainPanel::EventQuit)
		{
			quit();
		}
		else if (_action == MainPanel::EventNew)
		{
			removeRenderBoxes();
			destroyWindows();
			mEditorWindow->clearView();
		}
		else if (_action == MainPanel::EventLoad)
		{
			createWindows();
		}
		else if (_action == MainPanel::EventCreate)
		{
			MyGUI::Widget* view = mEditorWindow->getView();
			const MyGUI::IntCoord& coord = view->getClientCoord();

			if (_index == 0)
			{
				const MyGUI::IntSize size(80, 80);
				MyGUI::Window* window = view->createWidget<MyGUI::Window>(
					MyGUI::WidgetStyle::Overlapped,
					"WindowCS",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				window->setCaption("Frame");
				window->setMinSize(size);
			}
			else if (_index == 1)
			{
				const MyGUI::IntSize size(180, 15);
				MyGUI::ScrollBar* scroll = view->createWidget<MyGUI::ScrollBar>(
					"ScrollBarH",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				scroll->setScrollRange(200);
				scroll->setScrollPosition(10);
				scroll->setScrollPage(1);
				scroll->setScrollViewPage(20);
			}
			else if (_index == 2)
			{
				const MyGUI::IntSize size(15, 180);
				MyGUI::ScrollBar* scroll = view->createWidget<MyGUI::ScrollBar>(
					"ScrollBarV",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				scroll->setScrollRange(200);
				scroll->setScrollPosition(10);
				scroll->setScrollPage(1);
				scroll->setScrollViewPage(20);
			}
			else if (_index == 3)
			{
				const MyGUI::IntSize size(80, 26);
				MyGUI::TextBox* text = view->createWidget<MyGUI::TextBox>(
					"TextBox",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				text->setCaption("TextBox");
			}
			else if (_index == 4)
			{
				const MyGUI::IntSize size(50, 50);
				MyGUI::ImageBox* image = view->createWidget<MyGUI::ImageBox>(
					"ImageBox",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				image->setImageTexture("HelpIcon.png");
			}
			else if (_index == 5)
			{
				const MyGUI::IntSize size(150, 150);
				MyGUI::Window* window = view->createWidget<MyGUI::Window>(
					MyGUI::WidgetStyle::Overlapped,
					"WindowC",
					MyGUI::IntCoord(
						getRand(0, coord.width - size.width),
						getRand(0, coord.height - size.height),
						size.width,
						size.height),
					MyGUI::Align::Default);
				window->setCaption("Render");
				MyGUI::Canvas* canvas = window->createWidget<MyGUI::Canvas>(
					"Canvas",
					MyGUI::IntCoord(0, 0, window->getClientCoord().width, window->getClientCoord().height),
					MyGUI::Align::Stretch);

				createRenderBox(canvas);
			}
		}
	}

	void DemoKeeper::removeRenderBoxes()
	{
#ifdef MYGUI_OGRE_PLATFORM
		for (auto& mRenderBox : mRenderBoxes)
			delete mRenderBox;
		mRenderBoxes.clear();
#endif // MYGUI_OGRE_PLATFORM
	}

	void DemoKeeper::createRenderBox(MyGUI::Canvas* _canvas)
	{
#ifdef MYGUI_OGRE_PLATFORM
		wraps::RenderBox* box = new wraps::RenderBox();
		box->setCanvas(_canvas);
		box->setViewport(getCamera());
		box->setBackgroundColour(MyGUI::Colour::Black);
		mRenderBoxes.push_back(box);
#endif // MYGUI_OGRE_PLATFORM
	}

	void DemoKeeper::createDefaultScene()
	{
#ifdef MYGUI_OGRE_PLATFORM
		try
		{
			Ogre::Entity* entity = getSceneManager()->createEntity("Mikki.mesh", "Mikki.mesh", MyGuiResourceGroup);
			mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode();
			mNode->attachObject(entity);
		}
		catch (Ogre::FileNotFoundException&)
		{
			return;
		}

		try
		{
			Ogre::MeshManager::getSingleton().createPlane(
				"FloorPlane",
				MyGuiResourceGroup,
				Ogre::Plane(Ogre::Vector3::UNIT_Y, 0),
				1000,
				1000,
				1,
				1,
				true,
				1,
				1,
				1,
				Ogre::Vector3::UNIT_Z);

			Ogre::Entity* entity = getSceneManager()->createEntity("FloorPlane", "FloorPlane", MyGuiResourceGroup);
			entity->setMaterialName("Ground", MyGuiResourceGroup);
			mNode->attachObject(entity);
		}
		catch (Ogre::FileNotFoundException&)
		{
		}
#endif // MYGUI_OGRE_PLATFORM
	}

	void DemoKeeper::notifyFrameStart(float _time)
	{
#ifdef MYGUI_OGRE_PLATFORM
		if (mNode)
			mNode->yaw(Ogre::Radian(Ogre::Degree(_time * 10)));
#endif // MYGUI_OGRE_PLATFORM
	}

} // namespace demo

MYGUI_APP(demo::DemoKeeper)
