// This file is part of ThriceBall.
//
// Author: Kai Hillenbrand (AnTeevY)
// © Copyright, 2009 by Kai Hillenbrand, http://www.anteevy.de

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

#include "renderer.h"

void CRenderer::createCamera()
{
	std::cout << "ThriceBall Log: Create Camera" << std::endl;	// for the log

	m_pCamera = m_pSceneMgr->createCamera("MainCamera");
	m_pCamera->setNearClipDistance(5);

	// the node where the camera points at, always centered on the ball
	SceneNode *pointNode = m_pSceneMgr->getRootSceneNode()->createChildSceneNode("RotPointNode");

	// the node the camera is attached to and while is a child node of the rotation point node
	SceneNode *node = pointNode->createChildSceneNode("MainCameraNode", Vector3(0,30,20));
	node->attachObject(m_pCamera);

	m_pCamera->lookAt(pointNode->getPosition());
}

void CRenderer::createScene()
{	
	std::cout << "ThriceBall Log: Create Scene" << std::endl;	// for the log

	initNxOgre();
	
	// initialize variables
	m_bContRend = true;
	m_pInterface = new CInterface(this);	
	m_pPlayer = new CPlayer(this, m_pRenderSystem);
	m_pLevel = new CLevel(this, m_pScene, m_pRenderSystem);
	m_pAudio->setVolumes(m_iSoundVol, m_iMusVol);
	m_pAudio->playMusic(m_sLevelName);

	// set scene basics
	m_pSceneMgr->setAmbientLight(ColourValue(0.2f, 0.2f, 0.2f));
	m_pSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);

	createArrowPlane();			// create helper plane for the shoot direction arrow
	createCheckPointParticles();// create the particle flow on current checkpoint

	// load a level
	m_pLevel->loadLevel(m_sLevelName);
}

void CRenderer::createFrameListener()
{
	std::cout << "ThriceBall Log: Create Framelistener" << std::endl;	// for the log

	// create the frame listener which inherits from CBaseFrameListener
	m_pFrameListener = new CFrameListener(m_pWindow, m_pSceneMgr, this, m_pPlayer);
	m_pRoot->addFrameListener(m_pFrameListener);
	m_pFrameListener->showDebugOverlay(getDebugMode());
}

void CRenderer::createArrowPlane()
{
	std::cout << "ThriceBall Log: Create Arrow Plane" << std::endl;	// for the log

	// create the plane
	MovablePlane *plane = new MovablePlane("ArrowPlane");
	plane->d = 0;
	plane->normal = Vector3::UNIT_Y;
	Ogre::MeshManager::getSingleton().createPlane("ArrowPlaneMesh", 
		ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
		*plane, 1, 1, 1, 1, true, 1, 500, 500, Vector3::UNIT_Z);

	// create the plane entity
	Entity *planeEnt = m_pSceneMgr->createEntity("ArrowPlaneEnt", "ArrowPlaneMesh");
	planeEnt->setVisible(false);

	// create the plane node
	Ogre::SceneNode* planeNode = m_pSceneMgr->getRootSceneNode()->createChildSceneNode();
	planeNode->attachObject(planeEnt);
	planeNode->scale(1000, 1000, 1000);
	planeNode->translate(0,-5,0);
}

void CRenderer::initNxOgre()
{
	std::cout << "ThriceBall Log: Initialize NxOgre" << std::endl;	// for the log

	m_pWorld = NxOgre::World::createWorld();

	NxOgre::SceneDescription sceneDesc;
	sceneDesc.mGravity = NxOgre::Vec3(0, -9.8f, 0);
	sceneDesc.mName = "ThriceBall";

	m_pScene = m_pWorld->createScene(sceneDesc);
	
	m_pScene->getMaterial(0)->setStaticFriction(0.5);
	m_pScene->getMaterial(0)->setDynamicFriction(0.5);
	m_pScene->getMaterial(0)->setRestitution(0.6);

	//m_pScene->getScene()->setTiming();

	m_pRenderSystem = new OGRE3DRenderSystem(m_pScene);

	// PhysX remote debugger
	NxOgre::RemoteDebugger *pRD = m_pWorld->getRemoteDebugger();
	pRD->connect();
}

void CRenderer::createCheckPointParticles()
{
	std::cout << "ThriceBall Log: Create Checkpoint Particles" << std::endl;	// for the log

    ParticleSystem* pSys = m_pSceneMgr->createParticleSystem("CPParticles", "CPParticles");
    SceneNode *partNode = m_pSceneMgr->getRootSceneNode()->createChildSceneNode("CPParticlesNode");
    partNode->attachObject(pSys);
	// don't care about where the particles are, because the player class cares about that
}