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

#include "GuiTrade_Sell.h"

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

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

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

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

    this->game = game;

    // Set the last selected trade item to -1 or no item

    lastItem = -1;
}

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

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

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

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

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

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

Name:     GuiTrade_Sell::mousePressed
Purpose:  Mouse pressed event for this widget.
Params:   position of the mouse.
Returns:  none

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

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

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

    //--------------------------------------------------------------------------
    // Get the player's ship and its goods inventory
    //--------------------------------------------------------------------------

    // Get the players ship first

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

    // If the player's ship no longer exists then abort

    if ( ship == 0 ) return;

    // Otherwise get the stock inventory of the ship

    GoodsInventory * shipGoods = ship->getGoodsInventory();

    //--------------------------------------------------------------------------
    // Find out how many goods the player has on board and what they are:
    //--------------------------------------------------------------------------

    // Store the item numebr of all the goods the player has in this array:

    int itemNums[ GoodsInventory::NUM_ITEMS ];

    // The the number of different items the player has here

    int numItems = 0;

    // Figure out how many different types of items the player has and save them to the item number array

    for ( unsigned i = 0 ; i < GoodsInventory::NUM_ITEMS ; i++ )
    {
        // See if the player has any of this good:

        if ( shipGoods->getItemAmount(i) > 0 )
        {
            // Player has some of this good: save the item number of this good to the array

            itemNums[numItems] = i;

            // Increment the number of different items the player has

            numItems++;
        }
    }

    //--------------------------------------------------------------------------
    // Find out which good the mouse is over: but only do if this is a left click
    //--------------------------------------------------------------------------

    // See first if the mouse is in the general area where the goods information is 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 the player has clicked on a valid item

        if ( item < numItems )
        {
            //------------------------------------------------------------------
            // Player has clicked on a valid item:
            //------------------------------------------------------------------

            // 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;
            }

            // Get the goods inventory for the system the player is in

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

            // Increase the amount of funds available to the player by the market sale price of this good

            game->getPlayer()->setCredits( game->getPlayer()->getCredits() + systemGoods.getItemSellPrice( itemNums[item] ) );

            // Increase the amount of this good that the system market has by one

            systemGoods.setItemAmount( itemNums[item] , systemGoods.getItemAmount( itemNums[item] ) + 1 );

            // Decrease the amount of this good that the player has by one

            shipGoods->setItemAmount( itemNums[item] , shipGoods->getItemAmount( itemNums[item] ) - 1 );

            // Play the buy / sell sound:

            SoundSystem::playSound( SoundManager::getSndTradeBuySell() );
        }
        else
        {
            // No item selected:

            lastItem = -1;
        }
    }
    else
    {
        // No trade item selected: set last item to no item

        lastItem = -1;
    }

}

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

Name:     GuiTrade_Sell::mousePressed()
Purpose:  Redraw event for widget. Redraws the widget.
Params:   none
Returns:  none

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

void GuiTrade_Sell::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 player's ship and its goods inventory
    //--------------------------------------------------------------------------

    // Get the players ship first

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

    // If the player's ship no longer exists then abort

    if ( ship == 0 ) return;

    // Otherwise get the stock inventory of the ship

    GoodsInventory * shipGoods = ship->getGoodsInventory();

    //--------------------------------------------------------------------------
    // 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 amount available title:

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

    // Draw the demand title:

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

    // Draw the price title:

    font->drawString
    (
        "Sell 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();

    //--------------------------------------------------------------------------
    // Find out how many goods the player has on board and what they are:
    //--------------------------------------------------------------------------

    // Store the item numebr of all the goods the player has in this array:

    int itemNums[ GoodsInventory::NUM_ITEMS ];

    // The the number of different items the player has here

    int numItems = 0;

    // Figure out how many different types of items the player has and save them to the item number array

    for ( unsigned i = 0 ; i < GoodsInventory::NUM_ITEMS ; i++ )
    {
        // See if the player has any of this good:

        if ( shipGoods->getItemAmount(i) > 0 )
        {
            // Player has some of this good: save the item number of this good to the array

            itemNums[numItems] = i;

            // Increment the number of different items the player has

            numItems++;
        }
    }

    //--------------------------------------------------------------------------
    // 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 < numItems )
        {
            // 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
        {
            // Not over a valid item: set last item as none

            lastItem = -1;
        }
    }
    else
    {
        // Mouse not over any item: set last item as none

        lastItem = -1;
    }

    //--------------------------------------------------------------------------
    // Draw a list of names, amounts and prices that each item will fetch for all
    // the goods in the player's inventory:
    //--------------------------------------------------------------------------

    // Start drawing goods at this y value and increase for each line

    int offsetY = 32;

    // Get the goods inventory for the current system the player is in:

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

    // Start drawing the names, amounts and market prices of all the goods the player has

    for ( int i = 0 ; i < numItems ; i++ )
    {
        // Draw the name of this good:

        font->drawString
        (
            shipGoods->getItemName(itemNums[i])		,
            float( this->position_x + 8			)	,
            float( this->position_y + offsetY	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f
        );

        // Get the amount of the current item in the ship

        unsigned stock = shipGoods->getItemAmount(itemNums[i]);

        // Get the amount of the current item in the stock market

        unsigned marketStock = marketGoods.getItemAmount(itemNums[i]);

        // 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 demand bar from the amount of this item in the market

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

        // Draw the demand bar to indicate demand for this item

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

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

        // Save and convert how much of this item the player has on board to a string buffer

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

        // Print how much of this particular type of good the player has

        font->drawString
        (
            buffer									,
            float( this->position_x + 280		)	,
            float( this->position_y + offsetY	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f	
        );

        // Save and convert the market sale price of this particular good into a string buffer

        sprintf_s( buffer , 32 , "Cr %1.2f" , marketGoods.getItemSellPrice(itemNums[i]) );

        // Print the market price of this good onto the screen

        font->drawString
        (
            buffer									,
            float( this->position_x + 384		)	,
            float( this->position_y + offsetY	)	,
            8.0f	,
            1.0f	,
            1.0f	,
            1.0f
        );

        // Move onto the next line for drawing the next item

        offsetY += 12;

    }   // end for each type of item the player has on board, draw info
}
