/***********************************************************
 * God Mode On, Und[0]ne Devs < http://undonedevs.tk >
 * 2013 Pepe Romero < wizardpepe@gmail.com >
 * < https://bitbucket.org/undone_devs/god-mode-on >
 ***********************************************************/

#include "PlayState.h"
#include "LevelsState.h"
#include "MenuState.h"
#include "AchievState.h"

template<> PlayState* Ogre::Singleton<PlayState>::msSingleton = 0;

void PlayState::enter()
{
    // Se recupera el gestor de escena y la cámara.
    _root = Ogre::Root::getSingletonPtr();
    _sceneMgr = _root->getSceneManager("SceneManager");
    _materialMgr = Ogre::MaterialManager::getSingletonPtr();
    _meshMgr = Ogre::MeshManager::getSingletonPtr();
    _fontMgr = Ogre::FontManager::getSingletonPtr();
    _overlayMgr = Ogre::OverlayManager::getSingletonPtr();
    _camera = _sceneMgr->getCamera("PjCamera");
    _viewport = _root->getAutoCreatedWindow()->addViewport(_camera);

    // Pone los parámetros de inicio por defecto
    _movW = false;
    _movA = false;
    _movS = false;
    _movD = false;
    _completado = false;
    _puertaExiste = true;

    // Creación de datos Bullet
    // Creacion del modulo de debug visual de Bullet
    _debugDrawer = new OgreBulletCollisions::DebugDrawer();
    _debugDrawer->setDrawWireframe(true);
    Ogre::SceneNode *node = _sceneMgr->getRootSceneNode()->createChildSceneNode("debugNode", Ogre::Vector3::ZERO);
    node->attachObject(static_cast <Ogre::SimpleRenderable *>(_debugDrawer));

    // Creacion del mundo (definicion de los limites y la gravedad)
    Ogre::AxisAlignedBox worldBounds = Ogre::AxisAlignedBox(Ogre::Vector3(-1000,-1000,-1000), Ogre::Vector3(1000,1000,1000));
    Ogre::Vector3 gravity = Ogre::Vector3(0, -9.8, 0);

    _world = new OgreBulletDynamics::DynamicsWorld(_sceneMgr, worldBounds, gravity);
    _world->setDebugDrawer(_debugDrawer);
    _world->setShowDebugShapes(false);  // Muestra los collision shapes

    // Establecemos la técnica de sombras a usar
    _sceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

    // Creamos los elementos del HUD
    _sheet = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "Sheet");
    _escenarioHUD = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Text", "EscenarioHUD");
    _nivelHUD = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Text", "NivelHUD");
    _tiempoHUD = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Text", "TiempoHUD");
    _fondoHUD = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "FondoHUD");
    _objetoHUD = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "ObjetoHUD");

    _fondoHUD->setProperty("Image", "set:GodModeOnMenus image:FondoHUD");
    _fondoHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0,0),CEGUI::UDim(0,0)));
    _fondoHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0,1280),CEGUI::UDim(0,65)));

    _objetoHUD->setProperty("Image", "set:GodModeOnGui image:EsferaMadera");
    _objetoHUD->setVisible(false);
    _objetoHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0,1180),CEGUI::UDim(0,620)));
    _objetoHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0,77),CEGUI::UDim(0,76)));

    _escenarioHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0.02,0),CEGUI::UDim(0.02,0)));
    _escenarioHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0.98,0),CEGUI::UDim(0,37)));
    _escenarioHUD->setProperty("HorzFormatting", "LeftAligned");
    _escenarioHUD->setText("[font='astonish-20'][colour='FFFFFFFF']UNIVERSO 1/1");

    _tiempoHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0.48,0),CEGUI::UDim(0.02,0)));
    _tiempoHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0.30,0),CEGUI::UDim(0,37)));
    _tiempoHUD->setText("[font='astonish-20'][colour='FFFFFFFF']00:00");

    _nivelHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0.02,0),CEGUI::UDim(0.02,0)));
    _nivelHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0.96,0),CEGUI::UDim(0,37)));
    _nivelHUD->setProperty("HorzFormatting", "RightAligned");
    _nivelHUD->setText("[font='astonish-20'][colour='FFFFFFFF']NIVEL " + Ogre::StringConverter::toString(_nivel));

    _sheet->addChildWindow(_fondoHUD);
    _sheet->addChildWindow(_objetoHUD);
    _sheet->addChildWindow(_escenarioHUD);
    _sheet->addChildWindow(_tiempoHUD);
    _sheet->addChildWindow(_nivelHUD);

    // Establece el sheet
    CEGUI::System::getSingleton().setGUISheet(_sheet);

    // Creamos la escena con todos los elementos del nivel 1
    // Creamos los nodos
    _sceneNode = _sceneMgr->getRootSceneNode()->createChildSceneNode("sceneNode");
    _pj1Node = _sceneNode->createChildSceneNode("pj1Node");
    _puertaNode = _sceneNode->createChildSceneNode("puertaNode");
    _boton1Node = _sceneNode->createChildSceneNode("boton1Node");
    _trampasNode = _sceneNode->createChildSceneNode("trampasNode");
    _lightsNode = _sceneNode->createChildSceneNode("lightsNode");
    _cameraNode = _pj1Node->createChildSceneNode("cameraNode");
    _light1Node = _lightsNode->createChildSceneNode("light1Node");
    _bookNode = _sceneNode->createChildSceneNode("bookNode");

    // Creamos todas las entidades del nivel con sus propiedades
    _esc1Entity = _sceneMgr->createEntity("esc1Entity", "Escenario1.mesh");
    _esc2Entity = _sceneMgr->createEntity("esc2Entity", "Escenario2.mesh");
    _puertaEntity = _sceneMgr->createEntity("puertaEntity", "Puerta.mesh");
    _boton1Entity = _sceneMgr->createEntity("boton1Entity", "Cylinder.002.mesh");
    _pj1Entity = _sceneMgr->createEntity("pj1Entity", "Personaje1.mesh");
    _bookEntity = _sceneMgr->createEntity("bookEntity", "Plane.mesh");
    _light1Entity = _sceneMgr->createEntity("light1Entity", "RepresentLuz.mesh");
    _light1Light = _sceneMgr->createLight("light1Light");
    _esc1Entity->setVisible(true);
    _esc2Entity->setVisible(false);
    // Entidad solo para debug
    _light1Entity->setVisible(false);
    _light1Entity->setCastShadows(false);

    // Creación del OBJECT
    _object1 = new Object(_world);

    // Establecemos cada entidad en su nodo y su posición de inicio
    _sceneNode->attachObject(_esc1Entity);
    _sceneNode->attachObject(_esc2Entity);
    _puertaNode->attachObject(_puertaEntity);
    _boton1Node->attachObject(_boton1Entity);
    _cameraNode->attachObject(_camera);
    _light1Node->attachObject(_light1Entity);
    _light1Node->attachObject(_light1Light);
    //_sceneNode->attachObject(_light1Light);
    _pj1Node->attachObject(_pj1Entity);
    _light1Node->setPosition(0, 8.55f, 0);
    _bookNode->attachObject(_bookEntity);
    _bookNode->setPosition(-1.0f, 4.0f, 18.0f);

    // Datos bullet del personaje para su movimiento
    _movPJNode = _sceneNode->createChildSceneNode("movPJNode");
    _pjShape = new OgreBulletCollisions::SphereCollisionShape(0.5f);
    _pjRigidBody = new OgreBulletDynamics::RigidBody("rigidPJ", _world);
    _pjRigidBody->setShape(_movPJNode, _pjShape, 0.01, 0.95, 1500, Ogre::Vector3(0,0.3f,0), Ogre::Quaternion::IDENTITY);

    // Datos bullet del escenario
    _trimeshConverter = new OgreBulletCollisions::StaticMeshToShapeConverter(_esc1Entity);
    OgreBulletCollisions::TriangleMeshCollisionShape *esc1Trimesh = _trimeshConverter->createTrimesh();
    OgreBulletDynamics::RigidBody *rigidesc1 = new OgreBulletDynamics::RigidBody("esc1RigidBody", _world);
    rigidesc1->setShape(_sceneNode, esc1Trimesh, 0.8, 0.95, 0, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);

    _trimeshConverter = new OgreBulletCollisions::StaticMeshToShapeConverter(_puertaEntity);
    _puertaTrimesh = _trimeshConverter->createTrimesh();
    _rigidpuerta = new OgreBulletDynamics::RigidBody("puertaRigidBody", _world);
    _rigidpuerta->setShape(_puertaNode, _puertaTrimesh, 0.8, 0.95, 0, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);

    _trimeshConverter = new OgreBulletCollisions::StaticMeshToShapeConverter(_boton1Entity);
    OgreBulletCollisions::TriangleMeshCollisionShape *boton1Trimesh = _trimeshConverter->createTrimesh();
    OgreBulletDynamics::RigidBody *rigidboton1 = new OgreBulletDynamics::RigidBody("boton1RigidBody", _world);
    rigidboton1->setShape(_sceneNode, boton1Trimesh, 0.8, 0.95, 0, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);

    // Establecemos los parámetros de la cámara
    _camera->setNearClipDistance(0.01f);
    _camera->setFarClipDistance(100);
    _camera->setAspectRatio((_viewport->getActualWidth() * 1.0f) / (_viewport->getActualHeight() * 1.0f));
    _camera->setPosition(-0.17f, 4.24f, 0.18f); _camera->lookAt(-0.17, 4.24f, 1.18f);   // Cámara en 1a persona
    //_camera->setPosition(-2.5f, 5.0f, -4.5f); _camera->lookAt(0.0f, 4.0f, 8.0f);      // Cámara en 3a persona
    //_camera->setPosition(5, 5, 5); _camera->lookAt(0, 2, 0);                          // Cámara de personaje en pantalla

    // Carga datos específicos del nivel
    switch(LevelsState::getSingletonPtr()->getNivel()){
        case 1:
            cargaNivel1();
            break;
        case 2:
            cargaNivel2();
            break;
        case 3:
            cargaNivel3();
            break;
        default:
            break;
    }

    // No salimos del juego, todavía
    _exitGame = false;

    // Comienza a contar el tiempo del nivel
    _tiempoN = new Ogre::Timer();
    _tiempoN->reset();
}

void PlayState::cargaNivel1()
{
    _nivel = 1;
    _tiempoObjetivo = 35;
}

void PlayState::cargaNivel2()
{
    _nivel = 2;
    _tiempoObjetivo = 30;

    _trampaF1 = _sceneMgr->createEntity("trampaF1", "TrampaFuego.mesh");
    _trampaF2 = _sceneMgr->createEntity("trampaF2", "TrampaFuego.001.mesh");
    _trampaF3 = _sceneMgr->createEntity("trampaF3", "TrampaFuego.002.mesh");
    _trampaC1 = _sceneMgr->createEntity("trampaC1", "TrampaCristal.mesh");
    _trampaC2 = _sceneMgr->createEntity("trampaC2", "TrampaCristal.001.mesh");
    _trampaC3 = _sceneMgr->createEntity("trampaC3", "TrampaCristal.002.mesh");
    _trampaC4 = _sceneMgr->createEntity("trampaC4", "TrampaCristal.003.mesh");
    _trampaC5 = _sceneMgr->createEntity("trampaC5", "TrampaCristal.004.mesh");

    _trampasNode->attachObject(_trampaF1);
    _trampasNode->attachObject(_trampaF2);
    _trampasNode->attachObject(_trampaF3);
    _trampasNode->attachObject(_trampaC1);
    _trampasNode->attachObject(_trampaC2);
    _trampasNode->attachObject(_trampaC3);
    _trampasNode->attachObject(_trampaC4);
    _trampasNode->attachObject(_trampaC5);
}

void PlayState::cargaNivel3()
{
    _nivel = 3;
    _tiempoObjetivo = 31;

    _trampaF1 = _sceneMgr->createEntity("trampaF1", "TrampaFuego.mesh");
    _trampaF2 = _sceneMgr->createEntity("trampaF2", "TrampaFuego.001.mesh");
    _trampaF3 = _sceneMgr->createEntity("trampaF3", "TrampaFuego.002.mesh");
    _trampaF4 = _sceneMgr->createEntity("trampaF4", "TrampaFuego.003.mesh");
    _trampaF5 = _sceneMgr->createEntity("trampaF5", "TrampaFuego.004.mesh");
    _trampaF6 = _sceneMgr->createEntity("trampaF6", "TrampaFuego.005.mesh");
    _trampaF7 = _sceneMgr->createEntity("trampaF7", "TrampaFuego.006.mesh");
    _trampaF8 = _sceneMgr->createEntity("trampaF8", "TrampaFuego.007.mesh");
    _trampaC1 = _sceneMgr->createEntity("trampaC1", "TrampaCristal.mesh");
    _trampaC2 = _sceneMgr->createEntity("trampaC2", "TrampaCristal.001.mesh");
    _trampaC3 = _sceneMgr->createEntity("trampaC3", "TrampaCristal.002.mesh");
    _trampaC4 = _sceneMgr->createEntity("trampaC4", "TrampaCristal.003.mesh");
    _trampaC5 = _sceneMgr->createEntity("trampaC5", "TrampaCristal.004.mesh");
    _trampaC6 = _sceneMgr->createEntity("trampaC6", "TrampaCristal.005.mesh");
    _trampaC7 = _sceneMgr->createEntity("trampaC7", "TrampaCristal.006.mesh");
    _trampaC8 = _sceneMgr->createEntity("trampaC8", "TrampaCristal.007.mesh");

    _trampasNode->attachObject(_trampaF1);
    _trampasNode->attachObject(_trampaF2);
    _trampasNode->attachObject(_trampaF3);
    _trampasNode->attachObject(_trampaF4);
    _trampasNode->attachObject(_trampaF5);
    _trampasNode->attachObject(_trampaF6);
    _trampasNode->attachObject(_trampaF7);
    _trampasNode->attachObject(_trampaF8);
    _trampasNode->attachObject(_trampaC1);
    _trampasNode->attachObject(_trampaC2);
    _trampasNode->attachObject(_trampaC3);
    _trampasNode->attachObject(_trampaC4);
    _trampasNode->attachObject(_trampaC5);
    _trampasNode->attachObject(_trampaC6);
    _trampasNode->attachObject(_trampaC7);
    _trampasNode->attachObject(_trampaC8);
}

void PlayState::exit()
{
    // Eliminar mundo dinamico y debugDrawer

    delete _world->getDebugDrawer();
    _world->setDebugDrawer(0);
    delete _world;
    delete _object1;

    Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("Nivel");
    _sceneMgr->clearScene();
    _root->getAutoCreatedWindow()->removeAllViewports();
    CEGUI::WindowManager::getSingletonPtr()->destroyAllWindows();
}

void PlayState::pause(){}
void PlayState::resume(){}

bool PlayState::frameStarted(const Ogre::FrameEvent& evt)
{
    Ogre::Vector3 vt(0,0,0);
    Ogre::Real deltaT = evt.timeSinceLastFrame;

    _world->stepSimulation(deltaT); // Actualizar simulacion Bullet
    actualizaHUD();
    movPlayer();
    movLibro();

    if(_nivel == 2) comprobacionObjetoDestruidoN2();
    else if(_nivel == 3) comprobacionObjetoDestruidoN3();

    comprobacionFinPuzzle();
    if(_exitGame && _completado) changeState(AchievState::getSingletonPtr());
    else if(_exitGame) changeState(LevelsState::getSingletonPtr());

    return true;
}

bool PlayState::frameEnded(const Ogre::FrameEvent& evt)
{
    Ogre::Real deltaT = evt.timeSinceLastFrame;
    _world->stepSimulation(deltaT); // Actualizar simulacion Bullet
    return true;
}

void PlayState::keyPressed(const OIS::KeyEvent &e)
{
    switch(e.key){

        // Movimiento de personaje
        case OIS::KC_W:
            _movW = true;
            break;
        case OIS::KC_A:
            _movA = true;
            break;
        case OIS::KC_S:
            _movS = true;
            break;
        case OIS::KC_D:
            _movD = true;
            break;

        // DEBUG
        case OIS::KC_P:
            break;

        // Cambio de universo
        case OIS::KC_E:
            if(_esc1Entity->getVisible() == false){
                /*_esc1Entity->setVisible(true);
                _esc2Entity->setVisible(false);*/
            }
            else{
                /*_esc1Entity->setVisible(false);
                _esc2Entity->setVisible(true);*/
            }
            break;

        // Salir al menu ingame
        case OIS::KC_ESCAPE:
            _exitGame = true;
            break;

        default:
            break;
    }
}

void PlayState::keyReleased(const OIS::KeyEvent &e){
    switch(e.key){

        // Deja de moverse el personaje
        case OIS::KC_W:
            _movW = false;
            break;
        case OIS::KC_A:
            _movA = false;
            break;
        case OIS::KC_S:
            _movS = false;
            break;
        case OIS::KC_D:
            _movD = false;
            break;

        default:
            break;
    }
}

void PlayState::mouseMoved(const OIS::MouseEvent &e)
{

    // Giro hacia la derecha o izquierda del personaje (teniendo en cuenta la sensibilidad)
    _pj1Node->rotate(Ogre::Quaternion(Ogre::Degree(-e.state.X.rel * 0.3f), Ogre::Vector3(0, 1, 0)), Ogre::Node::TS_LOCAL);

    // Movimiento de cámara hacia arriba o hacia abajo (teniendo en cuenta la sensibilidad), calculando los límites de la cámara
    float desplazamiento = e.state.Y.rel * 0.3f;

    if(((_camera->getDirection().y < -0.96f) && (desplazamiento > 0.0f)) || ((_camera->getDirection().y > 0.96f) && (desplazamiento < 0.0f)))
        std::cout << "";
    else
        _camera->rotate(Ogre::Quaternion(Ogre::Degree(desplazamiento), Ogre::Vector3(1, 0, 0)));

    // Cambio de objetos con rueda del ratón
    if(e.state.Z.rel > 0) // Rueda hacia arriba
    {
        _object1->siguienteObjeto();
        if(!_object1->objetoCogido())
            _object1->crearObjeto();

    }
    else if(e.state.Z.rel < 0) // Rueda hacia abajo
    {
        _object1->siguienteObjeto();
        if(!_object1->objetoCogido())
            _object1->crearObjeto();
    }

}

void PlayState::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
    switch(id){
        case 0:
            // Botón izquierdo
            // Cogemos el objeto si no tenemos nada cogido.
            if(!_object1->objetoCogido())
            {
                _object1->cogerObjeto();
            }
            // Soltamos el objeto si ya lo tenemos cogido.
            else
            {
                _object1->lanzarObjeto();
            }
            break;

        case 1:
            // Botón derecho
            _object1->siguienteMaterial();
            break;

        default:
            break;
    }

}

void PlayState::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id){}

PlayState* PlayState::getSingletonPtr()
{
    return msSingleton;
}

PlayState& PlayState::getSingleton()
{
    assert(msSingleton);
    return *msSingleton;
}

void PlayState::movPlayer()
{
    // Movimiento del Player al pulsar WASD del teclado

    float velocidad = 8.0f;
    int keysPulsadas = 0;
    Ogre::Vector3 movimientoLinear = Ogre::Vector3::ZERO;

    // Desactiva el movimiento linear
    _pjRigidBody->enableActiveState();
    _pjRigidBody->setLinearVelocity(movimientoLinear);

    if(_movW) keysPulsadas++;
    if(_movA) keysPulsadas++;
    if(_movS) keysPulsadas++;
    if(_movD) keysPulsadas++;

    if(keysPulsadas>0)
        velocidad /= keysPulsadas;

    if(_movW) movimientoLinear.z += velocidad;
    if(_movA) movimientoLinear.x += velocidad;
    if(_movS) movimientoLinear.z -= velocidad;
    if(_movD) movimientoLinear.x -= velocidad;

    // Actualiza la posición en base al movimiento
    _pjRigidBody->enableActiveState();
    _pjRigidBody->setLinearVelocity(_pj1Node->getOrientation() * movimientoLinear);

    // Actualiza la posicion del jugador y la cámara con respecto a la posición de movimiento
    _pj1Node->setPosition(_movPJNode->getPosition());
    _movPJNode->setOrientation(_pj1Node->getOrientation());

}

void PlayState::comprobacionFinPuzzle()
{

    Ogre::AxisAlignedBox BoundingBoxFin1 = _bookEntity->getWorldBoundingBox();
    Ogre::AxisAlignedBox BoundingBoxPersonaje = _pj1Entity->getWorldBoundingBox();

    // Comprobación de fin de nivel
    if((BoundingBoxPersonaje.intersects(BoundingBoxFin1)==true)){
        AchievState::getSingletonPtr()->nivelCompletado(_nivel, _tiempoN->getMilliseconds()/1000, _tiempoObjetivo);
        _completado = true;
        _exitGame = true;
    }

    // Comprobaciones de puerta abierta
    if(_sceneMgr->hasEntity("esfera") || _sceneMgr->hasEntity("caja")){
        Ogre::AxisAlignedBox BoundingBoxBoton1 = _boton1Entity->getWorldBoundingBox();
        Ogre::AxisAlignedBox BoundingBoxObjeto1 = _sceneMgr->getSceneNode("object1Node")->getAttachedObject(0)->getWorldBoundingBox();

        if(BoundingBoxObjeto1.intersects(BoundingBoxBoton1)==true){
            // Elimina la entidad puerta si existe
            if(_puertaExiste){
                if(_sceneMgr->hasEntity("puertaEntity")) _sceneMgr->destroyEntity("puertaEntity");
                delete _rigidpuerta;
                _puertaExiste = false;
            }
        }
        else{
            // Vuelve a crear la entidad si no existe
            if(!_puertaExiste){
                _puertaEntity = _sceneMgr->createEntity("puertaEntity", "Puerta.mesh");
                _puertaNode->attachObject(_puertaEntity);
                _rigidpuerta = new OgreBulletDynamics::RigidBody("puertaRigidBody", _world);
                _rigidpuerta->setShape(_puertaNode, _puertaTrimesh, 0.8, 0.95, 0, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);
                _puertaExiste = true;
            }
        }

    }
    else{
        // Vuelve a crear la entidad si no existe
        if(!_puertaExiste){
            _puertaEntity = _sceneMgr->createEntity("puertaEntity", "Puerta.mesh");
            _puertaNode->attachObject(_puertaEntity);
            _rigidpuerta = new OgreBulletDynamics::RigidBody("puertaRigidBody", _world);
            _rigidpuerta->setShape(_puertaNode, _puertaTrimesh, 0.8, 0.95, 0, Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY);
            _puertaExiste = true;
        }
    }

}

void PlayState::comprobacionObjetoDestruidoN2()
{

    if(_sceneMgr->hasEntity("esfera") || _sceneMgr->hasEntity("caja")){
        Ogre::AxisAlignedBox BBTrampaF1 = _trampaF1->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF2 = _trampaF2->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF3 = _trampaF3->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC1 = _trampaC1->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC2 = _trampaC2->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC3 = _trampaC3->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC4 = _trampaC4->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC5 = _trampaC5->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBObjeto1 = _sceneMgr->getSceneNode("object1Node")->getAttachedObject(0)->getWorldBoundingBox();

        // Colisiones de madera con fuego
        if((BBObjeto1.intersects(BBTrampaF1)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF2)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF3)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();

        // Colisiones de cristal con trampa
        if((BBObjeto1.intersects(BBTrampaC1)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC2)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC3)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC4)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC5)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
    }

}

void PlayState::comprobacionObjetoDestruidoN3()
{

    if(_sceneMgr->hasEntity("esfera") || _sceneMgr->hasEntity("caja")){
        Ogre::AxisAlignedBox BBTrampaF1 = _trampaF1->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF2 = _trampaF2->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF3 = _trampaF3->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF4 = _trampaF4->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF5 = _trampaF5->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF6 = _trampaF6->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF7 = _trampaF7->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaF8 = _trampaF8->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC1 = _trampaC1->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC2 = _trampaC2->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC3 = _trampaC3->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC4 = _trampaC4->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC5 = _trampaC5->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC6 = _trampaC6->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC7 = _trampaC7->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBTrampaC8 = _trampaC8->getWorldBoundingBox();
        Ogre::AxisAlignedBox BBObjeto1 = _sceneMgr->getSceneNode("object1Node")->getAttachedObject(0)->getWorldBoundingBox();

        // Colisiones de madera con fuego
        if((BBObjeto1.intersects(BBTrampaF1)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF2)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF3)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF4)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF5)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF6)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF7)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaF8)==true) && (_object1->getMaterialActual()==0)) _object1->destruirObjeto();

        // Colisiones de cristal con trampa
        if((BBObjeto1.intersects(BBTrampaC1)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC2)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC3)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC4)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC5)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC6)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC7)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
        else if((BBObjeto1.intersects(BBTrampaC8)==true) && (_object1->getMaterialActual()==1)) _object1->destruirObjeto();
    }

}

void PlayState::actualizaHUD()
{
    // Actualiza el tiempo
    _tiempoHUD->setText("[font='astonish-20'][colour='FFFFFFFF']" + formateaTiempo(_tiempoN->getMilliseconds()));
    _nivelHUD->setText("[font='astonish-20'][colour='FFFFFFFF']NIVEL " + Ogre::StringConverter::toString(_nivel));

    // Actualiza la imagen del objeto cogido
    switch(_object1->getObjetoActual()){
        case 0:
            if(_object1->getMaterialActual() == 0)
                _objetoHUD->setProperty("Image", "set:GodModeOnGui image:EsferaMadera");
            else if(_object1->getMaterialActual() == 1)
                _objetoHUD->setProperty("Image", "set:GodModeOnGui image:EsferaCristal");

            _objetoHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0,1180),CEGUI::UDim(0,620)));
            _objetoHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0,77),CEGUI::UDim(0,76)));
            break;
        case 1:
            if(_object1->getMaterialActual() == 0)
                _objetoHUD->setProperty("Image", "set:GodModeOnGui image:CajaMadera");
            else if(_object1->getMaterialActual() == 1)
                _objetoHUD->setProperty("Image", "set:GodModeOnGui image:CajaCristal");

            _objetoHUD->setPosition(CEGUI::UVector2(CEGUI::UDim(0,1180),CEGUI::UDim(0,620)));
            _objetoHUD->setSize(CEGUI::UVector2(CEGUI::UDim(0,90),CEGUI::UDim(0,87)));
            break;
        default:
            break;
    }

    if(_object1->objetoCogido())
        _objetoHUD->setVisible(true);
    else
        _objetoHUD->setVisible(false);
}

Ogre::String PlayState::formateaTiempo(int segundos)
{
    Ogre::String tiempoFormateado = "";
    int minutos = 0;

    segundos /= 1000;
    minutos = segundos / 60;
    segundos = segundos % 60;

    if(minutos<10) tiempoFormateado += "0";
    tiempoFormateado += Ogre::StringConverter::toString(minutos) + ":";
    if(segundos<10) tiempoFormateado += "0";
    tiempoFormateado += Ogre::StringConverter::toString(segundos);

    return tiempoFormateado;
}

void PlayState::movLibro()
{
    _bookNode->yaw(Ogre::Radian(0.005f), Ogre::SceneNode::TS_LOCAL);
}
