/*
	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:   GuiTrade_Buy
// Purpose:      Widget which handles the buying of goods in a space station.
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

#include "GuiTrade_Buy.h"

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

Name:     GuiTrade_Buy::GuiTrade_Buy
Purpose:  Constructor.
Params:   Pointer to the game
Returns:  n/a

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

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

    this->game = game;

    // Set the last selected trade item to -1


}

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

Name:     GuiTrade_Buy::mouseMoved
Purpose:  Mouse moved event for this widget.
Params:   position of the mouse.
Returns:  none

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

void GuiTrade_Buy::mouseMoved( int x , int y )
{
    // Save the current position of the mouse

    this->lastMouseX = x;
    this->lastMouseY = y;
}

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

Name:     GuiTrade_Buy::mousePressed()
Purpose:  Mouse pressed event for the widget
Params:   none
Returns:  none

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

void GuiTrade_Buy::mousePressed( int x , int y , GLWindow::MouseButton button )
{
    // Save the current position of the mouse

    this->lastMouseX = x;
    this->lastMouseY = y;

    // See first if the left mouse is pressed and the the mouse is over the general area where goods are displayed

    if (
            button == GLWindow::MOUSE_BUTTON_LEFT
            &&
            this->hasFocus
            &&
            lastMouseX >= this->position_x
            &&
            lastMouseY >= this->position_y + 30
            &&
            lastMouseX <  this->position_x + this->size_x
            &&
            lastMouseY <  this->position_y + this->size_y
        )
    {
        // Mouse over the general area of where items are shown: figure out which item it is on

        int item = ( lastMouseY - this->position_y - 30 ) / 12;

        // See if this item number is a valid goods item in the game:

        if ( item < GoodsInventory::NUM_ITEMS )
        {
            // If item is different to the last item then play the mouse over trade item sound

            if ( item != lastItem )
            {
                // Play the mouse over trade item sound

                SoundSystem::playSound( SoundManager::getSndTradeItemOver() );

                // Save the last selected trade item as this

                lastItem = item;
            }

            // Valid game item: get how much money the player has from the game

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

            // Get the goods inventory for the current star system from the game

            GoodsInventory & goods = game->getSystem()->getGoodsInventory();

            // Get the players ship

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

            // Get how much of the selected item there is available

            unsigned quantity = goods.getItemAmount(item);

            // Get how much the item costs to buy:

            double cost = goods.getItemBuyPrice(item);

            //------------------------------------------------------------------
            // See if the item is out of stock and issue an error message if it is:
            //------------------------------------------------------------------

            if ( quantity == 0 )
            {
                // Issue an error message

                GuiScreen::showMessageDialog("Cannot buy item","Item is out of stock");

                // Abort doing anything further

                return;
            }

            //------------------------------------------------------------------
            // See if the player has the money to buy the item. Issue an error
            // message if not:
            //------------------------------------------------------------------

            if ( money < cost )
            {
                // Issue an error message

                GuiScreen::showMessageDialog("Cannot buy item","You do not have sufficient credits");

                // Abort doing anything further

                return;
            }

            //------------------------------------------------------------------
            // See if the player has room for the item in his her/ship
            //------------------------------------------------------------------

            if ( ship->getGoodsInventory()->getTotalAmount() + 1 > ship->getCargoCapacity() )
            {
                // Issue an error message

                GuiScreen::showMessageDialog("Cannot buy item","You do not have any more room on board");

                // Abort doing anything further

                return;
            }

            //------------------------------------------------------------------
            // If we have got to here then the player is allowed to buy the item
            //------------------------------------------------------------------

            // Subtract the cost from the players money

            money -= cost;

            // Set the players new money amount:

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

            // Decrement the amount of this good available in this system

            goods.setItemAmount( item, quantity - 1 );

            // Get the players ship goods inventory:

            GoodsInventory * shipGoods = ship->getGoodsInventory();

            // Increase the amount of this item by 1 in the ships inventory

            shipGoods->setItemAmount( item, shipGoods->getItemAmount(item) + 1 );

            // Play the buy / sell sound:

            SoundSystem::playSound( SoundManager::getSndTradeBuySell() );

        }   // end if a valid item is selected

        else
        {
            // Invalid item selected: set last item to no item

            lastItem = -1;
        }

    }   // end if left mouse pressed and mouse over general goods area

    else
    {
        // Mouse not over an item: set last selected item to no item

        lastItem = -1;
    }
}

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

Name:     GuiTrade_Buy::windowRedrawing()
Purpose:  Redraw event for widget. Redraws the widget.
Params:   none
Returns:  none

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

void GuiTrade_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 market information for the current system the player is in:
    //--------------------------------------------------------------------------

    GoodsInventory & goods = game->getSystem()->getGoodsInventory();

    //--------------------------------------------------------------------------
    // If the mouse cursor is over one of the lines for the goods items being
    // displayed then draw the line highlighted:
    //--------------------------------------------------------------------------

    // See first if the mouse is on one of the lines where goods are being displayed

    if (
            this->hasFocus
            &&
            lastMouseX >= this->position_x
            &&
            lastMouseY >= this->position_y + 30
            &&
            lastMouseX <  this->position_x + this->size_x
            &&
            lastMouseY <  this->position_y + this->size_y
        )
    {
        // Mouse over the general area of where items are shown: figure out which item it is on

        int item = ( lastMouseY - this->position_y - 30 ) / 12;

        // Do not draw the highlight if the item is greater than the number of items in the game

        if ( item < GoodsInventory::NUM_ITEMS )
        {
            // If the item selected is different to the last item then play the mouse over trade item sound

            if ( item != lastItem )
            {
                // Play the mouse over trade item sound

                SoundSystem::playSound( SoundManager::getSndTradeItemOver() );

                // Save the last selected trade item as this

                lastItem = item;
            }

            // Draw the highlight of the line:

            glBegin( GL_QUADS );

                glColor4f(0.2f,0.2f,0.2f,1.0f);

                glVertex2f( float( this->position_x					)	, float( this->position_y + 30 + item * 12		)	);
                glVertex2f( float( this->position_x + this->size_x	)	, float( this->position_y + 30 + item * 12		)	);
                glVertex2f( float( this->position_x + this->size_x	)	, float( this->position_y + 30 + item * 12 + 12	)	);
                glVertex2f( float( this->position_x					)	, float( this->position_y + 30 + item * 12 + 12	)	);

            glEnd();
        }
        else
        {
            // Set the last selected item to no item

            lastItem = -1;
        }
    }
    else
    {
        // Set the last selected item to no item

        lastItem = -1;
    }

    //--------------------------------------------------------------------------
    // Draw the titles for the fields shown in the widget:
    //--------------------------------------------------------------------------

    // Get the main game font first:

    GLFont * font = GLFontManager::getFont_main();

    // Draw the name title:

    font->drawString
    (
        "Name"							,
        float( this->position_x + 8	)	,
        float( this->position_y + 8	)	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Draw the supply title:

    font->drawString
    (
        "Supply"							,
        float( this->position_x + 128	)	,
        float( this->position_y + 8		)	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f	
    );

    // Draw the amount available title:

    font->drawString
    (
        "In stock"							,
        float( this->position_x + 280	)	,
        float( this->position_y + 8		)	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f
    );

    // Draw the price title:

    font->drawString
    (
        "Buy price"							,
        float( this->position_x + 384	)	,
        float( this->position_y + 8		)	,
        8.0f	,
        1.0f	,
        1.0f	,
        1.0f
    );

    //--------------------------------------------------------------------------
    // Draw a rule underneath these titles
    //--------------------------------------------------------------------------

    // Set the position and size of the rule

    rule.setPosition( this->position_x + 8, this->position_y + 20);
    rule.setSize(this->size_x - 16 , 4);

    // Draw the rule

    rule.windowRedrawing();

    //--------------------------------------------------------------------------
    // Draw the name, quantity available and price of each item in stock
    //--------------------------------------------------------------------------

    for ( unsigned i = 0 ; i < GoodsInventory::NUM_ITEMS ; i++ )
    {
        // Draw the name of the item first:

        font->drawString
        (
            goods.getItemName(i)						,
            float( this->position_x + 8				)	,
            float( this->position_y + 32 + i * 12	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f
        );

        // Get the amount of the current item

        unsigned stock = goods.getItemAmount(i);

        // Convert the item quantity to string and draw

        char buffer[32]; sprintf_s( buffer, 32 , "%1u" , stock );

        font->drawString
        (
            buffer										,
            float( this->position_x + 280			)	,
            float( this->position_y + 32 + i * 12	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f
        );

        // Clamp the amount to twice the normal supply for visual purposes

        if ( stock > GoodsInventory::NORMAL_SUPPLY * 2 ) stock = GoodsInventory::NORMAL_SUPPLY * 2;

        // Decide what color to draw the supply/demand bar from the item amount

        float color[3] =
        {
            1.0f - ( float( stock ) / float( GoodsInventory::NORMAL_SUPPLY * 2 ) ),
            0.0f + ( float( stock ) / float( GoodsInventory::NORMAL_SUPPLY * 2 ) ),
            0.0f
        };

        // Draw the supply bar

        glColor4f(color[0],color[1],color[2],1);

        glRecti
        (
            this->position_x + 128,
            this->position_y + 32  + i * 12,
            this->position_x + 128 + int( ( stock / float( GoodsInventory::NORMAL_SUPPLY * 2.0f ) ) * 100.0f ),
            this->position_y + 32  + i * 12 + 8
        );

        // Convert the item buy price to a string and draw

        sprintf_s( buffer, 32 , "Cr %1.2f" , goods.getItemBuyPrice(i) );

        font->drawString
        (
            buffer										,
            float( this->position_x + 384			)	,
            float( this->position_y + 32 + i * 12	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f	
        );

    }   // end for each item in the inventory draw name, amount and price
}
