/***********************************************************
 * 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 "AchievState.h"
#include "MenuState.h"

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

AchievState::AchievState()
{
    // Pone todos los logros bloqueados por defecto
    this->_achlogroN1 = false;
    this->_achlogroN2 = false;
    this->_achlogroN3 = false;
    this->_achlogroTodosN = false;
    this->_achlogroN1T = false;
    this->_achlogroN2T = false;
    this->_achlogroN3T = false;
    this->_achlogroTodosNT = false;
}

void AchievState::enter()
{
    _root = Ogre::Root::getSingletonPtr();

    _sceneMgr = _root->getSceneManager("SceneManager");
    _camera = _sceneMgr->getCamera("PjCamera");
    _viewport = _root->getAutoCreatedWindow()->addViewport(_camera);

    _exitGame = false;

    // Crea un window con un background
    _sheet = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "Sheet");
    _background = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "MenuBackground");
    _background->setProperty("Image", "set:GodModeOnMenus image:MainGenerico");
    _sheet->addChildWindow(_background);

    // Carga mouse
    _mouse = CEGUI::MouseCursor::getSingletonPtr();
    _mouse->setImage("GodModeOnGui", "MouseCursor");
    _mouse->setVisible(true);
    _mouse->show();

    // Crea los botones
    _buttonBack = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Text", "ButtonBack");
    _descripcionLogro = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Text", "DescripcionLogro");
    _logroN1 = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN1");
    _logroN2 = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN2");
    _logroN3 = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN3");
    _logroTodosN = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroTodosN");
    _logroN1T = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN1T");
    _logroN2T = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN2T");
    _logroN3T = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroN3T");
    _logroTodosNT = CEGUI::WindowManager::getSingleton().createWindow("GodModeOn/Image", "LogroTodosNT");

    // Carga los botones de la escena
    _buttonBack->setPosition(CEGUI::UVector2(CEGUI::UDim(0.03,0),CEGUI::UDim(0.90,0)));
    _buttonBack->setSize(CEGUI::UVector2(CEGUI::UDim(0,138),CEGUI::UDim(0,37)));
    _buttonBack->setText("[font='astonish-30'][colour='FFA2A1A1']VOLVER");

    if(logroDesbloqueado("LogroN1"))
        _logroN1->setProperty("Image", "set:GodModeOnGui image:LogroN1");
    else
        _logroN1->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN1->setPosition(CEGUI::UVector2(CEGUI::UDim(0.075,0),CEGUI::UDim(0.20,0)));
    _logroN1->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroN2"))
        _logroN2->setProperty("Image", "set:GodModeOnGui image:LogroN2");
    else
        _logroN2->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN2->setPosition(CEGUI::UVector2(CEGUI::UDim(0.30625,0),CEGUI::UDim(0.20,0)));
    _logroN2->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroN3"))
        _logroN3->setProperty("Image", "set:GodModeOnGui image:LogroN3");
    else
        _logroN3->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN3->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5375,0),CEGUI::UDim(0.20,0)));
    _logroN3->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroTodosN"))
        _logroTodosN->setProperty("Image", "set:GodModeOnGui image:LogroTodosN");
    else
        _logroTodosN->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroTodosN->setPosition(CEGUI::UVector2(CEGUI::UDim(0.76875,0),CEGUI::UDim(0.20,0)));
    _logroTodosN->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroN1T"))
        _logroN1T->setProperty("Image", "set:GodModeOnGui image:LogroN1T");
    else
        _logroN1T->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN1T->setPosition(CEGUI::UVector2(CEGUI::UDim(0.075,0),CEGUI::UDim(0.50,0)));
    _logroN1T->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroN2T"))
        _logroN2T->setProperty("Image", "set:GodModeOnGui image:LogroN2T");
    else
        _logroN2T->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN2T->setPosition(CEGUI::UVector2(CEGUI::UDim(0.30625,0),CEGUI::UDim(0.50,0)));
    _logroN2T->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroN3T"))
        _logroN3T->setProperty("Image", "set:GodModeOnGui image:LogroN3T");
    else
        _logroN3T->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroN3T->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5375,0),CEGUI::UDim(0.50,0)));
    _logroN3T->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    if(logroDesbloqueado("LogroTodosNT"))
        _logroTodosNT->setProperty("Image", "set:GodModeOnGui image:LogroTodosNT");
    else
        _logroTodosNT->setProperty("Image", "set:GodModeOnGui image:LogroBloqueado");
    _logroTodosNT->setPosition(CEGUI::UVector2(CEGUI::UDim(0.76875,0),CEGUI::UDim(0.50,0)));
    _logroTodosNT->setSize(CEGUI::UVector2(CEGUI::UDim(0,200),CEGUI::UDim(0,200)));

    _descripcionLogro->setPosition(CEGUI::UVector2(CEGUI::UDim(0.0,0),CEGUI::UDim(0.80,0)));
    _descripcionLogro->setSize(CEGUI::UVector2(CEGUI::UDim(1.0,0),CEGUI::UDim(0,37)));
    _descripcionLogro->setProperty("HorzFormatting", "HorzCentred");
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']");

    // Añade los botones a la escena
    _background->addChildWindow(_buttonBack);
    _background->addChildWindow(_descripcionLogro);
    _background->addChildWindow(_logroN1);
    _background->addChildWindow(_logroN2);
    _background->addChildWindow(_logroN3);
    _background->addChildWindow(_logroTodosN);
    _background->addChildWindow(_logroN1T);
    _background->addChildWindow(_logroN2T);
    _background->addChildWindow(_logroN3T);
    _background->addChildWindow(_logroTodosNT);

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

void AchievState::exit()
{
    _sceneMgr->clearScene();
    _root->getAutoCreatedWindow()->removeAllViewports();
    CEGUI::WindowManager::getSingletonPtr()->destroyAllWindows();
}

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

bool AchievState::frameStarted(const Ogre::FrameEvent& evt)
{
    return true;
}

bool AchievState::frameEnded(const Ogre::FrameEvent& evt)
{
    if (_exitGame)
        return false;
    return true;
}

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

    case OIS::KC_ESCAPE:
        handle_MouseClick_WindowBack();
        break;
    default:
        break;
    }
}

void AchievState::keyReleased(const OIS::KeyEvent &e){}

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

    // Actualiza el mouse
    CEGUI::Vector2 vec2Mouse = CEGUI::Vector2(e.state.X.abs, e.state.Y.abs);
    _mouse->setPosition(vec2Mouse);

    // Gestión de mouse sobre botones
    if(_buttonBack->isHit(vec2Mouse)) handle_MouseEnter_WindowBack();
    else handle_MouseLeaves_WindowBack();

    // Gestión de mouse sobre botones de logros
    if(_logroN1->isHit(vec2Mouse)) handle_MouseEnter_LogroN1();
    else if(_logroN2->isHit(vec2Mouse)) handle_MouseEnter_LogroN2();
    else if(_logroN3->isHit(vec2Mouse)) handle_MouseEnter_LogroN3();
    else if(_logroTodosN->isHit(vec2Mouse)) handle_MouseEnter_LogroTodosN();
    else if(_logroN1T->isHit(vec2Mouse)) handle_MouseEnter_LogroN1T();
    else if(_logroN2T->isHit(vec2Mouse)) handle_MouseEnter_LogroN2T();
    else if(_logroN3T->isHit(vec2Mouse)) handle_MouseEnter_LogroN3T();
    else if(_logroTodosNT->isHit(vec2Mouse)) handle_MouseEnter_LogroTodosNT();
    else handle_MouseLeaves_WindowLogro();

    // Muestra el mouse al terminar
    _mouse->setImage("GodModeOnGui", "MouseCursor");
}

void AchievState::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id){

    // Posición del mouse
    CEGUI::Vector2 vec2Mouse = CEGUI::Vector2(e.state.X.abs, e.state.Y.abs);

    switch(id){
        case 0: // Botón izquierdo

            // Gestión de clicks de botones
            if(_buttonBack->isHit(vec2Mouse)) handle_MouseClick_WindowBack();

            break;

        default:
            break;
    }
}

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

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

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

bool AchievState::handle_MouseClick_WindowBack()
{
    changeState(MenuState::getSingletonPtr());
    return true;
}

bool AchievState::handle_MouseEnter_WindowBack()
{
    _buttonBack->setText("[font='astonish-30'][colour='FFFFFFFF']VOLVER");
    return true;
}

bool AchievState::handle_MouseLeaves_WindowBack()
{
    _buttonBack->setText("[font='astonish-30'][colour='FFA2A1A1']VOLVER");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN1()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 1.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN2()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 2.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN3()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 3.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroTodosN()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA TODOS LOS NIVELES DEL JUEGO.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN1T()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 1 POR DEBAJO DE 35 SEGUNDOS.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN2T()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 2 POR DEBAJO DE 30 SEGUNDOS.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroN3T()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA EL NIVEL 3 POR DEBAJO DE 31 SEGUNDOS.");
    return true;
}

bool AchievState::handle_MouseEnter_LogroTodosNT()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']TERMINA TODOS LOS NIVELES DEL JUEGO POR DEBAJO DE SUS RESPECTIVOS TIEMPOS OBJETIVO.");
    return true;
}

bool AchievState::handle_MouseLeaves_WindowLogro()
{
    _descripcionLogro->setText("[font='astonish-20'][colour='FFFFFFFF']");
    return true;
}

void AchievState::nivelCompletado(const int nivel, const int segundos, const int segundosObjetivo)
{
    // Logros de nivel y tiempo
    if(nivel==1){
        this->_achlogroN1 = true;
        if(segundos<=segundosObjetivo) this->_achlogroN1T = true;
    }
    else if(nivel==2){
        this->_achlogroN2 = true;
        if(segundos<=segundosObjetivo) this->_achlogroN2T = true;
    }
    else if(nivel==3){
        this->_achlogroN3 = true;
        if(segundos<=segundosObjetivo) this->_achlogroN3T = true;
    }

    // Logro de todos los niveles completados
    if((this->_achlogroN1 == true) && (this->_achlogroN2 == true) && (this->_achlogroN3 == true))
        this->_achlogroTodosN = true;

    // Logro de todos los niveles completados dentro del tiempo objetivo
    if((this->_achlogroN1T == true) && (this->_achlogroN2T == true) && (this->_achlogroN3T == true))
        this->_achlogroTodosNT = true;
}

bool AchievState::logroDesbloqueado(const Ogre::String logro)
{
    if(logro=="LogroN1") return this->_achlogroN1;
    else if(logro=="LogroN2") return this->_achlogroN2;
    else if(logro=="LogroN3") return this->_achlogroN3;
    else if(logro=="LogroTodosN") return this->_achlogroTodosN;
    else if(logro=="LogroN1T") return this->_achlogroN1T;
    else if(logro=="LogroN2T") return this->_achlogroN2T;
    else if(logro=="LogroN3T") return this->_achlogroN3T;
    else if(logro=="LogroTodosNT") return this->_achlogroTodosNT;
    else return false;
}
