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

#include <ogre.h>

#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
   {
	try{
	// Creation de l'objet root
	Ogre::Root* root=new Ogre::Root();

	// Creation de l'objet RenderWindow
	if(!root->restoreConfig()){	// Test si un fichier de config existe deja
		if(!root->showConfigDialog()){ // Test si, suite a l'affichage de la boite de dialogue, l'utilisateur a appuyer sur OK ou Annuler
			delete root;
			return -1; // On ressort avec un code d'erreur, car l'affichage ne peut etre creer
		}
	}
	Ogre::RenderWindow* pRenderWindow=NULL;
	pRenderWindow=root->initialise(true,"Tutoriel 2 App");
	// Creation du gestionnaire de scene
	Ogre::SceneManager* pSceneManager=NULL;
	pSceneManager=root->createSceneManager(Ogre::ST_GENERIC,"SceneManager generic");

	// Creation des ressources
	// Code en dur
	//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/models","FileSystem","General");
	//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/tests","FileSystem","General");
	//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/programs","FileSystem","General");
	//Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/textures","FileSystem","General");
	//Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	
	// Code plus souple avec un fichier de script de configuration
	Ogre::ConfigFile cf;
	cf.load("resources.cfg");

	Ogre::ConfigFile::SectionIterator si=cf.getSectionIterator();

	Ogre::String secNom, typeArch, cheminArch;
	while(si.hasMoreElements()){
		secNom = si.peekNextKey();
		Ogre::ConfigFile::SettingsMultiMap *settings = si.getNext();
		Ogre::ConfigFile::SettingsMultiMap::iterator it;
		
		for (it=settings->begin(); it!=settings->end();++it){
			typeArch = it->first;
			cheminArch = it->second;
			Ogre::ResourceGroupManager::getSingleton().addResourceLocation(cheminArch,typeArch,secNom);
		}
	}
	Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

	// Creation d'une scene, voir tutoriel 1
	Ogre::Entity* pEntity=pSceneManager->createEntity("Ogre Head","OgreHead.mesh");
	Ogre::SceneNode* pNode=pSceneManager->getRootSceneNode()->createChildSceneNode("Node");
	pNode->attachObject(pEntity);

	// Creation de la camera
	Ogre::Camera* pCamera=pSceneManager->createCamera("Camera");
	pCamera->setPosition(Ogre::Vector3(0,50,200));
	pCamera->lookAt(Ogre::Vector3(0,0,0));

	// Creation du Viewport
	Ogre::Viewport* pViewport = pRenderWindow->addViewport(pCamera);
	pViewport->setBackgroundColour(Ogre::ColourValue(0,0,0.3));
	pCamera->setAspectRatio(Ogre::Real(pViewport->getActualWidth()) / Ogre::Real(pViewport->getActualHeight()));

	// Affichage à l'écran
	//pSceneManager->setAmbientLight(Ogre::ColourValue(0,0,0));

	// Boucle de rendu

	// Une très mauvaise idée si l'on ne veut pas boucler sans fin !!!
	// root->startRendering();

	// Une première approche pour ce tutoriel, mais il y aura mieux ...
	Ogre::InputReader* pInputReader=Ogre::PlatformManager::getSingleton().createInputReader();
	pInputReader->initialise(pRenderWindow,true,false);
	while(1){
		MSG msg;
		while(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE)){
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		root->_updateAllRenderTargets();
		pInputReader->capture();
		if(pInputReader->isKeyDown(Ogre::KC_ESCAPE))
			break;
	}

	// Nettoyage de l'objet Ogre: celui-ci se charge de détruire les entités, les caméras ...
	delete root;
	}catch(Ogre::Exception e){
		#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			MessageBox(NULL,e.getFullDescription().c_str(),
				"Erreur d'initialisation de l'objet Root",MB_OK|MB_ICONERROR|MB_TASKMODAL);
		#else
			std::cerr << "Une exception a été levée: " << e.getFullDescription().c_str() << std::endl;
		#endif
	}
    return 0;
}

#ifdef __cplusplus
}
#endif