/*
	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:   GuiBuyShip_Buy
// Purpose:      Handles the actual buying part of the buy ship screen. Relies
//               on the ship selection widget for which ship to buy.
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

#include "GuiBuyShip_Buy.h"

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

Name:     GuiBuyShip_Buy::GuiBuyShip_Buy()
Purpose:  Constructor.
Params:   Pointer to the game. Pointer to the ship selection widget.
Returns:  n/a

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

GuiBuyShip_Buy::GuiBuyShip_Buy( Game * game , GuiBuyShip_Select * shipSelecter )
{
    // Save the pointer to the game:

    this->game = game;

    // Save the pointer to the ship selection widget

    this->shipSelecter = shipSelecter;

    // Set the position of the buy button

    buttonBuy.setLabel("Buy");
    buttonBuy.setSize(192,32);
    buttonBuy.setPosition(this->position_x + 8, this->position_y + 284);

    // Set the zoom for both mesh viewers:

    meshViewer1.setZoom(1.2f);
    meshViewer2.setZoom(1.2f);

    // Set the pitch and yaw for the second mesh viewer:

    meshViewer2.setYaw(1);
    meshViewer2.setPitch(2);
}

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

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

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

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

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

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

        // Send the mouse moved event to the button:

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

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

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

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

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

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

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

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

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

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

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

void GuiBuyShip_Buy::mouseReleased( int x , int y , GLWindow::MouseButton button )
{
    //--------------------------------------------------------------------------
    // Get the player from the game:
    //--------------------------------------------------------------------------

    Player * player = game->getPlayer();

    //--------------------------------------------------------------------------
    // See if the mouse is over the buy button:
    //--------------------------------------------------------------------------

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

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

            GameObject_Ship * playerShip = (GameObject_Ship*) player->getShipHook()->getObject();

            //------------------------------------------------------------------
            // Get the ship currently selected by the ship selection widget:
            //------------------------------------------------------------------

            GameObject_Ship * ship = shipSelecter->getSelectedShip();

            //------------------------------------------------------------------
            // See if the players ship exists firstly
            //------------------------------------------------------------------

            if ( playerShip != 0 && ship != 0)
            {
                // Make sure the player has enough money to buy the ship:

                if ( player->getCredits() >= ship->getCost() )
                {
                    //----------------------------------------------------------
                    // Player has enough money to buy ship: confirm action
                    //----------------------------------------------------------

                    bool buy = GuiScreen::showQuestionDialog
                    (
                        "Confirm ship purchase",
                        "Are you sure you want to buy this ship ? ",
                        "All cargo and upgrades will be lost on current ship."
                    );

                    // See if the player confirmed the action:

                    if ( buy )
                    {
                        // Save the player ships scene:

                        GameObjectScene * scene = playerShip->getScene();

                        // Remove the players ship from its scene but don't delete:

                        scene->removeObject(playerShip);

                        // Give the player the new ship:

                        * playerShip = * ship;

                        // Add the new ship the player has into the scene:

                        scene->addObject(playerShip);

                        // Deduct the cost from the players credits:

                        player->setCredits( player->getCredits() - ship->getCost() );

                        // Tell the user action is complete:

                        GuiScreen::showMessageDialog
                        (
                            "Ship purchased",
                            "Congratulations on your new ship purchase!"
                        );
                    }
                }
                else
                {
                    //----------------------------------------------------------
                    // Player hasn't enough money to buy ship
                    //----------------------------------------------------------

                    GuiScreen::showMessageDialog
                    (
                        "Cannot buy ship",
                        "You do not have enough credits."
                    );
                }

            }   // end if player ship exists

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

            buttonBuy.mouseReleased(x,y,button);

        }   // end if button is depressed

    }   // end if mouse released over button
}

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

Name:     GuiBuyShip_Buy::windowRedrawing()
Purpose:  Redraw event for the buy ship widget.
Params:   none
Returns:  n/a

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

void GuiBuyShip_Buy::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 currently selected ship from the ship selection widget:
    //--------------------------------------------------------------------------

    GameObject_Ship * ship = shipSelecter->getSelectedShip();

    if ( ship == 0 ) return;

    //--------------------------------------------------------------------------
    // Get the big and small fonts from the font manager:
    //--------------------------------------------------------------------------

    GLFont * fontB = GLFontManager::getFont_big();
    GLFont * fontS = GLFontManager::getFont_main();

    //--------------------------------------------------------------------------
    // Keep a small string buffer to hold numbers and that here:
    //--------------------------------------------------------------------------

    char buffer[512];

    //--------------------------------------------------------------------------
    // Show the general ship information:
    //--------------------------------------------------------------------------

    // Show the title for this:

    fontB->drawString("General",8,8,16,1,1,1);

    // Show the ship class:

    sprintf_s( buffer, 512 , "Class:             %1s" , ship->getName() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        40.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the ships shield strenght:

    sprintf_s( buffer, 512 , "Shield strenght:   %1.2f units" , ship->getMaxHealth() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        52.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the ships weight:

    sprintf_s( buffer, 512 , "Weight:            %1.2f kg" , ship->getMass() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        64.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show its cargo capacity:

    sprintf_s( buffer, 512 , "Cargo capacity:    %1i units" , ship->getCargoCapacity() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        76.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f
    );

    //--------------------------------------------------------------------------
    // Show the ships engine information
    //--------------------------------------------------------------------------

    // Show the title for this:

    fontB->drawString("Engines",8,100,16,1,1,1);

    // Show the ships shield strenght:

    sprintf_s( buffer, 512 , "Top Speed:         %1.2f kmph" , ( ship->getMaxSpeed() * 60 * 60 ) / 1000.0f );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        132.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f
    );

    // Show the ships acceleration:

    sprintf_s( buffer, 512 , "Acceleration:      %1.2f m/s2" , ship->getAcceleration() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        144.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the hyperspace range of the ship:

    sprintf_s( buffer, 512 , "Hyperspace range:  %1.2f ly" , ship->getHyperspaceRange() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        156.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    //--------------------------------------------------------------------------
    // Show the ships weapon information
    //--------------------------------------------------------------------------

    // Show the title for this:

    fontB->drawString("Weapons",8,180,16,1,1,1);

    // Show the ships laser strenght:

    sprintf_s( buffer, 512 , "Laser strenght:    %1.2f mw" , ship->getLaser()->getStrenght() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        212.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the ships laser cooling capacity:

    sprintf_s( buffer, 512 , "Laser cooling:     %1.2f mw/s" , ship->getLaser()->getCoolingAmount() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        224.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the capacity of the ship to hold missiles

    sprintf_s( buffer, 512 , "Missile capacity:  %1i missiles" , ship->getMaxMissiles() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        236.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Show the capacity of the ship to hold emp bombs

    sprintf_s( buffer, 512 , "Emp bomb capacity: %1i emp bombs" , ship->getMaxEmpBombs() );

    fontS->drawString
    (
        buffer	,
        8.0f	,
        248.0f	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f
    );

    //--------------------------------------------------------------------------
    // Draw a rule underneath all this information:
    //--------------------------------------------------------------------------

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

    //--------------------------------------------------------------------------
    // Draw the mesh viewers that show the players ship
    //--------------------------------------------------------------------------

    meshViewer1.setMesh( ship->getMesh() );
    meshViewer1.setSize( 128 , 128       );
    meshViewer1.setPosition( 328 , 8 );
    meshViewer1.windowRedrawing();

    meshViewer2.setMesh( ship->getMesh() );
    meshViewer2.setSize( 128 , 128       );
    meshViewer2.setPosition( 328 , 140   );
    meshViewer2.windowRedrawing();

    //--------------------------------------------------------------------------
    // Draw the buy button:
    //--------------------------------------------------------------------------

    buttonBuy.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 + 284		) );
        glTexCoord2f(1,0);  glVertex2f( float( this->position_x + 216 + 32 ) , float( this->position_y + 284		) );
        glTexCoord2f(1,1);  glVertex2f( float( this->position_x + 216 + 32 ) , float( this->position_y + 284 + 32	) );
        glTexCoord2f(0,1);  glVertex2f( float( this->position_x + 216      ) , float( this->position_y + 284 + 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 , 512 , "Cr %1.2f" , money );

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


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

Name:     GuiBuyShip_Buy::lostFocus()
Purpose:  Lost focus event
Params:   none
Returns:  n/a

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

void GuiBuyShip_Buy::lostFocus()
{
    // Cause all the button to loose focus:

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