/*
	Rogue Trader.
	Copyright (c) 2007, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################
//
//
// Class Name:   GuiRepair
// Purpose:      This widget handles the repairing of the players ship.
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

#include "GuiRepair.h"

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::GuiRepair()
Purpose:  Constructor. Initialises the widget.
Params:   Game to which the player belongs
Returns:  n/a

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

GuiRepair::GuiRepair( Game * game )
{
    // Save the pointer to the game

    this->game = game;

    // Setup the repair button:

    repairButton.setPosition( this->position_x + 8 , this->position_y + 424 );
    repairButton.setSize( 192 , 32 );
    repairButton.setLabel("Repair ship");
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::mouseMoved()
Purpose:  Mouse moved event for the widget
Params:   new mouse position
Returns:  none

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void GuiRepair::mouseMoved( int x , int y )
{
    //--------------------------------------------------------------------------
    // See if the mouse is over the repair button:
    //--------------------------------------------------------------------------

    if (
            x >= repairButton.getPositionX()
            &&
            y >= repairButton.getPositionY()
            &&
            x <  repairButton.getPositionX() + repairButton.getSizeX()
            &&
            y <  repairButton.getPositionY() + repairButton.getSizeY()
        )
    {
        // If the button is not in focus then send the gained focus event:

        if ( repairButton.getFocus() == false )
        {
            repairButton.setFocus(true);
            repairButton.gainedFocus(x,y);
        }

        // Send the mouse moved event to the button:

        repairButton.mouseMoved(x,y);
    }
    else
    {
        // If the button has focus then make it loose it:

        if ( repairButton.getFocus() == true )
        {
            repairButton.setFocus(false);
            repairButton.lostFocus();
        }
    }
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::mousePressed()
Purpose:  Mouse pressed event for this widget.
Params:   Mouse position, button pressed
Returns:  none

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void GuiRepair::mousePressed( int x , int y , GLWindow::MouseButton button )
{
    // See if the mouse is over the repair button:

    if (
            x >= repairButton.getPositionX()
            &&
            y >= repairButton.getPositionY()
            &&
            x <  repairButton.getPositionX() + repairButton.getSizeX()
            &&
            y <  repairButton.getPositionY() + repairButton.getSizeY()
        )
    {
        // Send the mouse pressed event to the repair button:

        repairButton.mousePressed(x,y,button);
    }
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::mouseReleased()
Purpose:  Mouse released event for this widget.
Params:   Mouse position, button pressed
Returns:  none

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void GuiRepair::mouseReleased( int x , int y , GLWindow::MouseButton button )
{
    // See if the mouse is over the repair button:

    if (
            x >= repairButton.getPositionX()
            &&
            y >= repairButton.getPositionY()
            &&
            x <  repairButton.getPositionX() + repairButton.getSizeX()
            &&
            y <  repairButton.getPositionY() + repairButton.getSizeY()
        )
    {
        //----------------------------------------------------------------------
        // If the mouse was released over the button when it was depressed then
        // try to repair the players ship:
        //----------------------------------------------------------------------

        if ( repairButton.isDepressed() )
        {
            // Get the players ship first:

            GameObject_Ship * ship = (GameObject_Ship*) game->getPlayer()->getShipHook()->getObject();

            // See if the players ship exists firstly

            if ( ship )
            {
                // Get the max health and damage of the ship:

                float health    = ship->getHealth();
                float maxHealth = ship->getMaxHealth();
                float damage    = maxHealth - health;

                // Get the cost to repair:

                float cost = mlDecimalRound(Game::REPAIR_COST * damage,2);

                // Get the players money

                float money = (float) game->getPlayer()->getCredits();

                // See if the players ship has taken any damage first:

                if ( damage > 0 )
                {
                    // See if player has enough money to repair

                    if ( money >= cost )
                    {
                        // Can repair: subtract cost from money

                        money -= cost;

                        // Update the players credits:

                        game->getPlayer()->setCredits(money);

                        // Set the players ship to max health:

                        ship->setHealth(maxHealth);

                        // Play the repair sound

                        SoundSystem::playSound( SoundManager::getSndRepair() );

                        // Tell the player the repair was successful

                        GuiScreen::showMessageDialog("Ship repaired","Ship successfuly repaired.");
                    }
                    else
                    {
                        // Not enough money to repair. tell player.

                        GuiScreen::showMessageDialog("Cannot repair ship","You do not have enough credits.");
                    }
                }
                else
                {
                    // No damage: tell the player

                    GuiScreen::showMessageDialog("Cannot repair ship","Your ship already in the best possible shape.");
                }

            }   // end if player ship exists

            // Send the mouse released event to the repair button:

            repairButton.mouseReleased(x,y,button);

        }   // end if button is depressed

    }   // end if mouse released over button
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::windowRedrawing()
Purpose:  Redraw event for the repair widget.
Params:   none
Returns:  n/a

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void GuiRepair::windowRedrawing()
{
    //--------------------------------------------------------------------------
    // Clear the widget background to black:
    //--------------------------------------------------------------------------

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glColor4f(0,0,0,1);

    glBegin(GL_QUADS);

        glVertex2f( float( this->position_x					) , float( this->position_y                 ) );
        glVertex2f( float( this->position_x + this->size_x  ) , float( this->position_y                 ) );
        glVertex2f( float( this->position_x + this->size_x  ) , float( this->position_y + this->size_y  ) );
        glVertex2f( float( this->position_x                 ) , float( this->position_y + this->size_y  ) );

    glEnd();

    //--------------------------------------------------------------------------
    // Get the players ship: abort if the player no longer has a ship
    //--------------------------------------------------------------------------

    GameObject_Ship * ship = (GameObject_Ship*)game->getPlayer()->getShipHook()->getObject();

    // Abort if players ship is gone:

    if ( ship == 0 ) return;

    // Get the amount of damage the player has taken the max health of the ship:

    float maxHealth = ship->getMaxHealth();
    float damage    = maxHealth - ship->getHealth();

    //--------------------------------------------------------------------------
    // Get the games big font:
    //--------------------------------------------------------------------------

    GLFont * font = GLFontManager::getFont_big();

    //--------------------------------------------------------------------------
    // Show how much damage the player has obtained:
    //--------------------------------------------------------------------------

    // Draw the damage text first

    font->drawString
    (
        "Damage taken"						,
        float( this->position_x + 6		)	,
        float( this->position_y + 16	)	,
        16.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Draw a white outline around the damage bar:

    glColor3f(1,1,1);

    glRecti
    (
        this->position_x + 8	,
        this->position_y + 48	,
        this->position_x + 465	,
        this->position_y + 88
    );

    // Draw another black box inside this as the main bar fill

    glColor3f(0,0,0);

    glRecti
    (
        this->position_x + 10	,
        this->position_y + 50	,
        this->position_x + 463	,
        this->position_y + 86
    );

    // Figure how wide the damage bar should be based on the ships current health:

    int width = int( ( damage / maxHealth ) *  455 );

    // Draw the damage bar:

    if ( width > 0 )
    {
        glColor3f(1,0,0);

        glRecti
        (
            this->position_x + 10			,
            this->position_y + 50			,
            this->position_x + 22 + width	,
            this->position_y + 86
        );
    }

    // Draw the damage percent:

    char buffer[32]; sprintf_s( buffer , 32 , "%1.0f %%" , ( damage / maxHealth ) * 100.0f );

    GLFont * fontSmall = GLFontManager::getFont_main();

    fontSmall->drawString
    (
        buffer																			,
        float( int( this->position_x + 22 + ( 443 / 2.0f ) - strlen(buffer) * 4 )	)	,
        float( int( this->position_y + 64 )											)	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    //--------------------------------------------------------------------------
    // Show the cost of reparing the damage
    //--------------------------------------------------------------------------

        //----------------------------------------------------------------------
        // Draw the reapir icon:
        //----------------------------------------------------------------------

        // Enable texturing:

        glEnable(GL_TEXTURE_2D);

        // Enable alpha blending:

        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

        // Bind the repair icon texture first:

        GLTextureManager::getTexRepair()->bind();

        // Draw the icon centered vertically:

        glBegin(GL_QUADS);

            glColor4f(1,1,1,1);

            glTexCoord2f(0,0);  glVertex2f( float( this->position_x + 8			) , float( this->position_y + 96      )	);
            glTexCoord2f(1,0);  glVertex2f( float( this->position_x + 8 + 32	) , float( this->position_y + 96	  )	);
            glTexCoord2f(1,1);  glVertex2f( float( this->position_x + 8 + 32	) , float( this->position_y + 96 + 32 )	);
            glTexCoord2f(0,1);  glVertex2f( float( this->position_x + 8			) , float( this->position_y + 96 + 32 )	);

        glEnd();

        //----------------------------------------------------------------------
        // Print the cost of the repairs
        //----------------------------------------------------------------------

        float cost = mlDecimalRound( damage * Game::REPAIR_COST , 2 );

        sprintf_s( buffer , 32 , "Repair cost: Cr %1.2f" , cost );

        font->drawString
        (
            buffer								,
			float( this->position_x + 64	)	,
            float( this->position_y + 104	)	,
            16.0f	,
            1.0f	,
            1.0f	,
            1.0f	
        );

    //--------------------------------------------------------------------------
    // Draw a rule below the damage bar
    //--------------------------------------------------------------------------

    rule.setSize(470,4);
    rule.setPosition(8,136);
    rule.windowRedrawing();

    //--------------------------------------------------------------------------
    // Show the players ship:
    //--------------------------------------------------------------------------

    meshViewer.setPosition(4,144);
    meshViewer.setSize(470,256);

    meshViewer.setMesh( ship->getMesh() );
    meshViewer.windowRedrawing();

    //--------------------------------------------------------------------------
    // Draw a rule above the repair button
    //--------------------------------------------------------------------------

    rule.setSize(470,4);
    rule.setPosition(8,412);
    rule.windowRedrawing();

    //--------------------------------------------------------------------------
    // Draw the repair button:
    //--------------------------------------------------------------------------

    repairButton.windowRedrawing();

    //--------------------------------------------------------------------------
    // Show the credits icon:
    //--------------------------------------------------------------------------

    // Enable texturing:

    glEnable(GL_TEXTURE_2D);

    // Enable alpha blending:

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

    // Bind the repair icon texture first:

    GLTextureManager::getTexMoney()->bind();

    // Draw the icon centered vertically:

    glBegin(GL_QUADS);

        glColor4f(1,1,1,1);

        glTexCoord2f(0,0);  glVertex2f( float( this->position_x + 216		) , float( this->position_y + 424		)	);
        glTexCoord2f(1,0);  glVertex2f( float( this->position_x + 216 + 32	) , float( this->position_y + 424		)	);
        glTexCoord2f(1,1);  glVertex2f( float( this->position_x + 216 + 32	) , float( this->position_y + 424 + 32	)	);
        glTexCoord2f(0,1);  glVertex2f( float( this->position_x + 216		) , float( this->position_y + 424 + 32	)	);

    glEnd();

    //--------------------------------------------------------------------------
    // Show how much money the player has
    //--------------------------------------------------------------------------

    // Get how much money the player has

    float money = (float) game->getPlayer()->getCredits();

    // Print this to a buffer

    sprintf_s( buffer , 32 , "Cr %1.2f" , money );

    font->drawString
    (
        buffer								,
        float( this->position_x + 256	)	,
        float( this->position_y + 432	)	,
        16.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );
}

/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Name:     GuiRepair::lostFocus()
Purpose:  Lost focus event for the repair widget.
Params:   none
Returns:  none

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/

void GuiRepair::lostFocus()
{
    // Cause the repair button to go out of focus:

    if ( repairButton.getFocus() )
    {
        repairButton.setFocus(false);
        repairButton.lostFocus();
    }
}

