/*
 *  OgreTest.cpp
 *  OgreNibDemo
 *
 *  Created by Will Thimbleby on 08/02/2006.
 *  Copyright 2006 __MyCompanyName__. All rights reserved.
 *
 */

//#include "OgreTest.h"


#include "Ogre.h"
#include "OgreConfigFile.h"
#include "OgreOSXWindow.h"
#include "OgreGLRenderSystem.h"
#include "ExampleFrameListener.h"

using namespace Ogre;

Root *mRoot;
SceneNode* headNode;
Entity *headEntity;
Light* mainLight;
Camera *mCamera;
RenderWindow *mWindow;


bool renderOgreFrame()
{
	return Ogre::Root::getSingleton().renderOneFrame();
}

void endOgre()
{
	delete mRoot;
}

void resetStatistics()
{
	mWindow->resetStatistics();
}

void setupResources(std::string mResourcePath)
{
	// Load resource paths from config file
	ConfigFile cf;
	cf.load(mResourcePath + "/resources.cfg");

	// Go through all sections & settings in the file
	ConfigFile::SectionIterator seci = cf.getSectionIterator();

	String secName, typeName, archName;
	while (seci.hasMoreElements())
	{
		secName = seci.peekNextKey();
		ConfigFile::SettingsMultiMap *settings = seci.getNext();
		ConfigFile::SettingsMultiMap::iterator i;
		for (i = settings->begin(); i != settings->end(); ++i)
		{
			typeName = i->first;
			archName = i->second;
			ResourceGroupManager::getSingleton().addResourceLocation(mResourcePath + "/" + archName, typeName, secName);
		}
	}
}

bool setupOgre(bool autoCreateWindow, const char *cResourcePath)
{
	// Setup OGRE
	std::string mResourcePath = cResourcePath;
	mRoot = new Root(mResourcePath + "/plugins.cfg", mResourcePath + "/ogre.cfg", mResourcePath + "/Ogre.log");
	
	setupResources(mResourcePath);
	
	if(autoCreateWindow)
	{
		if(!mRoot->showConfigDialog())
			return false;
	}
	
	// Initialise
	mWindow = mRoot->initialise(autoCreateWindow);
	
	return true;
}

void createOgreWorld()
{
	SceneManager *mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
	
	// Set default mipmap level (NB some APIs ignore this)
	TextureManager::getSingleton().setDefaultNumMipmaps(5);
	
	
	// Create camera
	mCamera = mSceneMgr->createCamera("PlayerCam");

	// Position it at 500 in Z direction
	mCamera->setPosition(Vector3(0,0,500));
	// Look back along -Z
	mCamera->setNearClipDistance(5);
		
	
	// Load resources
	// Initialise, parse scripts etc
	ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	
	
	// Set ambient light
	mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

	// Create a skydome
	mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

	// Create a light
	Light* l = mSceneMgr->createLight("MainLight");
	// Accept default settings: point light, white diffuse, just set position
	// NB I could attach the light to a SceneNode if I wanted it to move automatically with
	//  other objects, but I don't
	l->setPosition(20,80,50);

	// Define a floor plane mesh
	Plane p;
	p.normal = Vector3::UNIT_Y;
	p.d = 200;
	MeshManager::getSingleton().createPlane(
		"FloorPlane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
		p, 200000, 200000, 20, 20, true, 1, 50, 50, Vector3::UNIT_Z);

	// Create an entity (the floor)
	Entity *ent = mSceneMgr->createEntity("floor", "FloorPlane");
	ent->setMaterialName("Examples/RustySteel");
	// Attach to child of root node, better for culling (otherwise bounds are the combination of the 2)
	mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

	// Add a head, give it it's own node
	SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	ent = mSceneMgr->createEntity("head", "ogrehead.mesh");
	headNode->attachObject(ent);

	// Create the camera node & attach camera
	SceneNode* camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	camNode->attachObject(mCamera);

	// Put in a bit of fog for the hell of it
	mSceneMgr->setFog(FOG_EXP, ColourValue::White, 0.0002);
	
	
	//setup viewport
	Viewport* vp = mWindow->addViewport(mCamera);
	vp->setBackgroundColour(ColourValue(0,0,0));
	// Alter the camera aspect ratio to match the viewport
	mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
	
	
	// add frame listener
	ExampleFrameListener *mFrameListener = new ExampleFrameListener(mWindow, mCamera, false, true);
	mFrameListener->showDebugOverlay(true);
	mRoot->addFrameListener(mFrameListener);
}
