#include "DevLib.h"
/******************************************************************************
 * MenuSelectShip.cpp                                                         *
 ******************************************************************************
 * Project      : Futura (DevLib Demo)                                        *
 * License      : LGPL (full notice can be found at root directory)           *
 * Created by   : Arnaud Storq (norecess@devlib-central.org)                  *
 ******************************************************************************/
#include "MenuSelectShip.h"
#include "Application.h"

// ---------------------------------------------------------------------------- CREATE MENU SELECTSHIP
MenuSelectShip *MenuSelectShip::createMenuSelectShip( )
{
    return new MenuSelectShip( );
}

// ---------------------------------------------------------------------------- CONSTRUCTOR
MenuSelectShip::MenuSelectShip( )
{
    m_playerCount = 0;

    m_ship = 0;
    m_shipPlayer1 = Application::getInstance( )->getShips( ).at( m_ship );
    m_shipPlayer2 = 0;

    m_grip = 0;
    m_maxSpeed = 0;
    m_lenghtJump = 0;

    m_player = 0;

    m_fill = Texture::createTexture( false, 1, 1 );
    unsigned int *buffer = m_fill->lock( );
    *buffer = 0x80808080;
    m_fill->unlock( );

    string shipEnvmapFilename = Application::getInstance( )->getXML( )->getRoot( )->getChildElement( "menu" )->getChildElement( "shipEnvmap" )->getChildElement( )->getString( );
    m_shipEnvmap = Texture::createTexture( false, shipEnvmapFilename );

    m_isFinished = false;
}

// ---------------------------------------------------------------------------- DESTRUCTOR
MenuSelectShip::~MenuSelectShip( )
{
    delete m_fill;

    delete m_shipEnvmap;
}

// ---------------------------------------------------------------------------- KEY PRESS
void MenuSelectShip::keyPress( Key key )
{
    if ( key == KEY_LEFT )
    {
        m_ship--;

        if ( m_ship < 0 )
            m_ship = 0;
        else
            Application::getInstance( )->getClickSelect( )->play( );
    }

    if ( key == KEY_RIGHT )
    {
        m_ship++;

        if ( m_ship > 2 )
            m_ship = 2;
        else
            Application::getInstance( )->getClickSelect( )->play( );
    }

    if ( ( key == KEY_SPACE ) || ( key == KEY_RETURN ) || ( key == KEY_LCTRL ) )
    {
        Application::getInstance( )->getClickValidate( )->play( );
        
        if ( m_player == 0 )
        {
            if ( m_playerCount == 1 )
            {
                m_isFinished = true;
                return;
            }
                
            m_player++;
        }
        else
        {
            m_isFinished = true;
        }
    }

    Ship *ship = Application::getInstance( )->getShips( ).at( m_ship );
    if ( m_player == 0 )
        m_shipPlayer1 = ship;
    else
        m_shipPlayer2 = ship;
}

// ---------------------------------------------------------------------------- DISPLAY UPDATE
void MenuSelectShip::displayUpdate( )
{
    RenderSystem *rs = RenderSystemManager::getRenderSystem( );

    float time = Application::getInstance( )->getTime( );
    float elapsedTime = Application::getInstance( )->getElapsedTime( );

    Font *littleFont = Application::getInstance( )->getLittleFont( );
    Font *bigFont = Application::getInstance( )->getBigFont( );

    Ship *ship = 0;
    if ( m_player == 0 )
        ship = m_shipPlayer1;
    else
        ship = m_shipPlayer2;

    ship->setEnvmap( m_shipEnvmap );

    m_grip += ( ship->getGrip( ) - m_grip ) * 4.0f * elapsedTime;
    m_maxSpeed += ( ship->getMaxSpeed( ) - m_maxSpeed ) * 4.0f * elapsedTime;
    m_lenghtJump += ( ship->getLenghtJump( ) - m_lenghtJump ) * 4.0f * elapsedTime;
    
    // Clear Z-buffer 
    rs->clear( CLEAR_MODE_ZBUFFER );

    // Set matrix projection
    rs->setMatrixMode( MATRIX_MODE_PROJECTION );
    Matrix matrixProjection;
    matrixProjection.setPerspective(    0.00001f, // minimum Z-value
                                        1000.0f, // maximum Z-value
                                        45.0f, // focal
                                        ( (float) rs->getWidth( ) ) / ( (float) rs->getHeight( ) ) // ratio
                                        );
    rs->loadMatrix( matrixProjection );

    // Set view projection
    rs->setMatrixMode( MATRIX_MODE_MODELVIEW );	
    rs->loadIdentityMatrix( );

    rs->translateMatrix( sin( time * 0.7f ) * 0.009f, cos( time ) * 0.009f, -0.05f );
    rs->rotateMatrix( sin( time ) * 20.0f, 1.0f, 0.0f, 0.0f );
    rs->rotateMatrix( -90.0f + time * 30.0f, 0.0f, 1.0f, 0.0f );
    rs->rotateMatrix( cos( time * 0.8f ) * 20.0f, 0.0f, 0.0f, 1.0f );
    rs->scaleMatrix( ship->getScale( ), ship->getScale( ), ship->getScale( ) );

    // Set Z-buffer state
    rs->setRenderState( RS_ZBUFFER, RV_ZBUFFER_LESS );

    ship->render( );
    
    // Display title
    string title;
    if ( m_playerCount == 1 )
    {
        title = Application::getInstance( )->getLanguageNode( )->getChildElement( "selectShipAloneTitle" )->getChildElement( )->getString( );
    }
    else
    {
        if ( m_player == 0 )
            title = Application::getInstance( )->getLanguageNode( )->getChildElement( "selectShipPlayer1Title" )->getChildElement( )->getString( );
        else
            title = Application::getInstance( )->getLanguageNode( )->getChildElement( "selectShipPlayer2Title" )->getChildElement( )->getString( );
    }

    bigFont->render( ( rs->getWidth( ) - bigFont->getStringWidth( title ) ) / 2, rs->getHeight( ) / 12, title );

    // Display informations
    int x = rs->getWidth( ) / 12;
    int yCenter = rs->getHeight( ) / 4;
    int charHeight = littleFont->getCharacterHeight( );
    
    littleFont->render( x, yCenter, Application::getInstance( )->getLanguageNode( )->getChildElement( "name" )->getChildElement( )->getString( ) );
    littleFont->render( x, yCenter + charHeight, ship->getName( ) );
    
    littleFont->render( x, yCenter + charHeight * 3, Application::getInstance( )->getLanguageNode( )->getChildElement( "grip" )->getChildElement( )->getString( ) );
    displaySquares( x, yCenter + charHeight * 4, m_grip, charHeight );

    littleFont->render( x, yCenter + charHeight * 6, Application::getInstance( )->getLanguageNode( )->getChildElement( "maxSpeed" )->getChildElement( )->getString( ) );
    displaySquares( x, yCenter + charHeight * 7, m_maxSpeed, charHeight );

    littleFont->render( x, yCenter + charHeight * 9, Application::getInstance( )->getLanguageNode( )->getChildElement( "lenghtJump" )->getChildElement( )->getString( ) );
    displaySquares( x, yCenter + charHeight * 10, m_lenghtJump, charHeight );

    // Display instructions
    string instructions;
    if ( m_player == 0 )
        instructions = Application::getInstance( )->getLanguageNode( )->getChildElement( "instructionsPlayer1" )->getChildElement( )->getString( );
    else
        instructions = Application::getInstance( )->getLanguageNode( )->getChildElement( "instructionsPlayer2" )->getChildElement( )->getString( );

    littleFont->render( ( rs->getWidth( ) - littleFont->getStringWidth( instructions ) ) / 2, rs->getHeight( ) - rs->getHeight( ) / 8, instructions );
}

// ---------------------------------------------------------------------------- DISPLAY SQUARES
void MenuSelectShip::displaySquares( int x, int y, float value, int charHeight )
{
    int start = 0;
    int end = (int) ( value * 10.0f );
    for ( start = 0; start <= end * 2; ++start )
    {
        int posX = x + start * charHeight;
        int posY = y;

        m_fill->render( posX, posY, posX + charHeight - 2, posY + charHeight - 2 );
    }
    for ( ; start <= 10 * 2; ++start )
    {
        int posX = x + start * charHeight;
        int posY = y;

        Application::getInstance( )->getFade( )->render( posX, posY, posX + charHeight - 2, posY + charHeight - 2 );
    }
}

