/*
-----------------------------------------------------------------------------
Filename:    graviator_client.cpp
-----------------------------------------------------------------------------


This source file is generated by the
   ___                   _              __    __ _                  _ 
  /___\__ _ _ __ ___    /_\  _ __  _ __/ / /\ \ (_)______ _ _ __ __| |
 //  // _` | '__/ _ \  //_\\| '_ \| '_ \ \/  \/ / |_  / _` | '__/ _` |
/ \_// (_| | | |  __/ /  _  \ |_) | |_) \  /\  /| |/ / (_| | | | (_| |
\___/ \__, |_|  \___| \_/ \_/ .__/| .__/ \/  \/ |_/___\__,_|_|  \__,_|
      |___/                 |_|   |_|                                 
      Ogre 1.7.x Application Wizard for VC9 (August 2010)
      http://code.google.com/p/ogreappwizards/
-----------------------------------------------------------------------------
*/

#include "graviator_client.h"

#include "client\hud\ClientHudResources.h"

#include <OgreException.h>
#include <OgreConfigFile.h>
#include <OgreCamera.h>
#include <OgreViewport.h>
#include <OgreSceneManager.h>
#include <OgreRenderWindow.h>
#include <OgreWindowEventUtilities.h>






//-------------------------------------------------------------------------------------
graviator_client::graviator_client(void):
	mRoot(0),
	mPluginsCfg(Ogre::StringUtil::BLANK),
	mResourcesCfg(Ogre::StringUtil::BLANK),
	mShutDown(false)
	
{
}
//-------------------------------------------------------------------------------------
graviator_client::~graviator_client(void)
{
	ClientHUDResources::destroy();
	delete mRoot;
}

bool graviator_client::go(void)
{

#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif

	mRoot = new Ogre::Root(mPluginsCfg);
	Ogre::ConfigFile cf;
	cf.load(mResourcesCfg);

	Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
	Ogre::String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
		Ogre::ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)

		{
			typeName = i->first;
			archName = i->second;
			Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
				archName, typeName, secName);
		}
	}

	if(!(mRoot->restoreConfig() || mRoot->showConfigDialog()))
	{
		return false;
	}

	mWindow = mRoot->initialise(true, "Graviator");

	Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(3);
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

//-------------------------------------------------------------------------------------
	OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    mWindow->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

    mOISInputManager = OIS::InputManager::createInputSystem( pl );

    mKeyboard = static_cast<OIS::Keyboard *>(mOISInputManager->createInputObject(OIS::OISKeyboard, true ));
    mMouse = static_cast<OIS::Mouse *>(mOISInputManager->createInputObject(OIS::OISMouse, true ));

    mMouse->setEventCallback(this);

    mRoot->addFrameListener(this);

//-------------------------------------------------------------------------------------

	ClientStateSharedElements *sharedElements = new ClientStateSharedElements;
	sharedElements->root = mRoot;
	sharedElements->window = mWindow;
	sharedElements->mouse = mMouse;
	sharedElements->keyboard = mKeyboard;
	mStateManager = new ClientStateManager(sharedElements, LOBBY_STATE);

//-------------------------------------------------------------------------------------

	while(true)
	{

		// Pump window messages for nice behaviour
		Ogre::WindowEventUtilities::messagePump();
		
		if(!mStateManager->update())
			mShutDown = true;
		
		if(mWindow->isClosed())
			return false;

		// Render a frame
		Sleep(10);
		if(!mRoot->renderOneFrame()) 
			return false;

	}

	return true;
}


bool graviator_client::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
	if (mWindow->isClosed()) return false;
    if (mShutDown) return false;
    mKeyboard->capture();
    mMouse->capture();
   
	if(!processUnbufferedInput(evt)) return false;
	
	return true;
}


bool graviator_client::mouseMoved(const OIS::MouseEvent &arg )
{
	return mStateManager->mouseMoved(arg);
}



bool graviator_client::processUnbufferedInput(const Ogre::FrameEvent &evt)
{
    return mStateManager->processUnbufferedInput(evt);
}


//-------------------------------------------------------------------------------------



#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
    int main(int argc, char *argv[])
#endif
    {
        // Create application object
        graviator_client app;

        try {
            app.go();
        } catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " <<
                e.getFullDescription().c_str() << std::endl;
#endif
        }

        return 0;
    }

#ifdef __cplusplus
}
#endif
