#include "Demo3.hpp"
#include "configure.hpp"
#include "mof/EventScheduler.hpp"
#include "mof/mofInput.hpp"
#include "mof/mofGraphics.hpp"
#include "mof/Application.hpp"
#include "mof/utilities.hpp"
#include "mof/widgets.hpp"
#include <mof/Texture.hpp>
#include "mof/Font.hpp"
#include "resource.hpp"
#include <mof/streams.hpp>
#include <mof/FactoryMethod.hpp>
#include <boost/bind.hpp> 
#include <memory> 
#include "widget/createMenuView.hpp"
#include "widget/createFrame.hpp"
#include <mof/ConsoleIO.hpp>
#include <mof/FactoryMethod.hpp>
#include <mof/script/LuaInterpreter.hpp>
#include "script/MyEnvironment.hpp"

#include "mof/sound/SoundDevice.hpp"

using namespace mof::widget;
using namespace boost;

//{{{ impl
struct my_scene::impl
{
	
	std::shared_ptr<mof::script::LuaInterpreter> interpreter_;
	std::shared_ptr<mof::script::Environment> environment_;
	std::shared_ptr<mof::InputReceiver> m_pInputReceiver;
	mof::EventScheduler m_scheduler;

	impl()
	{
	}
	
	~impl()
	{
	}

};
//}}}	
//{{{ constructor
my_scene::my_scene(const std::vector<mof::tstring>& args)
	: pimpl_(new impl)
{
	if (args.size() < 2) throw std::invalid_argument("no script name");
	mof::Application::InputMode mode = mof::Application::input_mode();
	if (mode == mof::Application::INPUT_MODE_DEVICE) {
       	pimpl_->m_pInputReceiver = std::shared_ptr<mof::InputReceiver>(mof::InputDevice::getInputReceiver());
	}
	else if (mode == mof::Application::INPUT_MODE_LOGGING) {
       	pimpl_->m_pInputReceiver = std::make_shared<mof::LoggingInputReceiver>((TCHAR*)_T("inputLog.txt"));
	}
	else if (mode == mof::Application::INPUT_MODE_LOGGED) {
       	pimpl_->m_pInputReceiver = std::make_shared<mof::LoggedInputReceiver>((TCHAR*)_T("inputLog.txt"));
	}
	pimpl_->m_scheduler.addEvent
	(
		new mof::InputEventCondition(mof::InputReceiver::ESCAPE, pimpl_->m_pInputReceiver),
		[] {mof::Application::quit();}
	);


	pimpl_->environment_ = std::make_shared<script::MyEnvironment>(pimpl_->m_pInputReceiver);
	pimpl_->interpreter_ = std::make_shared<mof::script::LuaInterpreter>(pimpl_->environment_, args[1]);
	for (int i = 2; i < args.size(); ++i) {
		pimpl_->interpreter_->start(args[i]);
	}
    mof::GraphicsDevice::setAlphaBlendingMode(mof::GraphicsDevice::BLENDING_MODE_ALPHA);
   

};
//}}}
//{{{ destructor
my_scene::~my_scene()
{
}
//}}} 
//{{{ update
void my_scene::update()
{
  	pimpl_->m_scheduler.update();
   	pimpl_->m_pInputReceiver->update();

	pimpl_->interpreter_->update(pimpl_->environment_);
	pimpl_->environment_->update();
}
//}}}
//{{{ draw
void my_scene::draw() const
{
	mof::Rectangle<int> cr = mof::GraphicsDevice::getClientRegion();
    mof::VertexXYZRHWC vertices[] = 
    {
    	mof::VertexXYZRHWC(mof::Vector2D(0 , 0) , mof::createColor(50 , 50 , 120)) ,
    	mof::VertexXYZRHWC(mof::Vector2D(cr.getWidth() , 0) , mof::createColor(50 , 50 , 120)) ,
    	mof::VertexXYZRHWC(mof::Vector2D(0 , cr.getHeight()) , mof::createColor(0 , 0 , 60)) ,
    	mof::VertexXYZRHWC(mof::Vector2D(cr.getWidth() , cr.getHeight()) , mof::createColor(0 , 0 , 60))
    };
    mof::GraphicsDevice::setTexture(NULL);
    mof::GraphicsDevice::drawVertexArray(vertices[0] , vertices[3] , mof::PRIMITIVE_TYPE_TRIANGLESTRIP );
   	mof::GraphicsDevice::clearZBuffer();

	pimpl_->environment_->draw();
}
//}}}


