/*
	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:   GuiButton
// Purpose:      A panel is a bit like a gui screen in that it can contain other
//               widgets, but has no purpose other than stylistic. It does propogate
//               events down to contained widgets however, much like the GuiScreen
//               does with its contained widgets.
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

#include "GuiPanel.h"

//------------------------------------------------------------------------------
// Constant initialisation
//------------------------------------------------------------------------------

// These constants control the shading of the panel

const float GuiPanel::INTENSITY_NORMAL_1 = 0.6f;    // normal fill brightness for the panel: first shade
const float GuiPanel::INTENSITY_NORMAL_2 = 0.8f;    // normal fill brightness for the panel: second shade
const float GuiPanel::INTENSITY_SHINE_1  = 1.0f;    // fill brightness around the shiny parts of the widget: first shade
const float GuiPanel::INTENSITY_SHINE_2  = 0.8f;    // fill brightness around the shiny parts of the widget: second shade
const float GuiPanel::INTENSITY_SHADE_1  = 0.3f;    // fill brightness around the shady parts of the widget: first shade
const float GuiPanel::INTENSITY_SHADE_2  = 0.5f;    // fill brightness around the shady parts of the widget: second shade

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

Name:     GuiPanel::GuiPanel()
Purpose:  Default constructor for the panel. Initialises panel settings.
Params:   none
Returns:  n/a

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

GuiPanel::GuiPanel()
{
    // initialise the panel settings to their defaults

    setSize(400,200);

    // Set panel to raised

    setRaised(true);

    // Initialise the widget list to null initially

    for ( unsigned i = 0 ; i < MAX_WIDGETS ; i ++ ) widgets[i] = 0;
}

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

Name:     GuiPanel::~GuiPanel()
Purpose:  Panel destructor: deletes all attached widgets
Params:   n/a
Returns:  n/a

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

GuiPanel::~GuiPanel()
{
    // Delete all widgets from the panel

    for ( unsigned i = 0 ; i < MAX_WIDGETS ; i ++ )
    {
        // If this slot in the array is valid then delete the widget

        if ( widgets[i] ) delete widgets[i];
    }
}

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

Name:     GuiPanel::addWidget()
Purpose:  Attempts to add a widget to the panel. deletes the given widget on
          failure since it is the panel's repsonsibility to manage widget memory.
Params:   widget to add
Returns:  none

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

void GuiPanel::addWidget( GuiWidget * widget )
{
    // Search in the widget array for a free slot

    int freeSlotIndex = -1;

    for ( unsigned i = 0 ; i <  MAX_WIDGETS ; i ++ )
    {
        if ( widgets[i] == 0 )
        {
            // found a free slot: abort search

            freeSlotIndex = i;
        }
    }

    // Set the free slot to point to the widget if successful. delete the widget otherwise.

    if ( freeSlotIndex >= 0 )
    {
    
        // Success: Add in the widget

		widget->setParent(this);
        widgets[freeSlotIndex] = widget;
    }
    else
    {
        // Failure: delete the widget

        delete widget;
    }
}

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

Name:     GuiPanel::removeWidget()
Purpose:  Attempts to remove the given widget from the panel.
Params:   widget to remove
Returns:  none

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

void GuiPanel::removeWidget( GuiWidget * widget )
{
    // Search for the given widget in the array of widgets
    // Will continue searching even if found just in case there is duplicates
    // of the same widget in the array.

    for ( unsigned i = 0 ; i <  MAX_WIDGETS ; i ++ )
    {
        if ( widgets[i] == widget )
        {
            // found the widget: delete it

            delete widget;

            // Set this slot in the array to free

            widgets[i] = 0;
        }
    }
}

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

Name:     GuiPanel::mouseMoved()
Purpose:  Send mouse move event to current widget the mouse is over.
Params:   mouse position.
Returns:  none

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

void GuiPanel::mouseMoved( int x , int y )
{
    // Translate the coordinates first into panel local coordinates.
    // Objects contained within the panel have locations describe in terms of
    // is coordinate system and not the screen coordinate system.

    x -= int(this->getPositionX());
    y -= int(this->getPositionY());

    // Go through every widget in the panel

    for ( unsigned i = 0; i < MAX_WIDGETS ; i++ )
    {
        // Get current widget

        GuiWidget * widget = widgets[i];

        // If valid then check for lost/gained focus

        if ( widget && widget->isEnabled() )
        {
            // See if the mouse is over the widget

            if (
                    x >= widget->getPositionX() && x < widget->getPositionX() + widget->getSizeX()
                    &&
                    y >= widget->getPositionY() && y < widget->getPositionY() + widget->getSizeY()
                )
            {
                // Mouse is over widget: see if it is already in focus

                if ( ! widget->getFocus() )
                {
                    // Not focused. Set focused and call gainedFocus event.

                    widget->setFocus(true);
                    widget->gainedFocus(x,y);
                }

                // Call also the mouse moved event on the widget

                widget->mouseMoved(x,y);
            }
            else
            {
                // Mouse is not over widget: see if it was in focus

                if ( widget->getFocus() )
                {
                    // Focused. Set not focused and call lostFocus event.

                    widget->setFocus(false);
                    widget->lostFocus();
                }

            }
        }

    }
}

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

Name:     GuiPanel::mousePressed()
Purpose:  Send mouse pressed event to current widget the mouse is over.
Params:   mouse position. mouse button pressed
Returns:  none

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

void GuiPanel::mousePressed( int x , int y , GLWindow::MouseButton button )
{
    // Translate the coordinates first into panel local coordinates.
    // Objects contained within the panel have locations describe in terms of
    // is coordinate system and not the screen coordinate system.

    x -= int(this->getPositionX());
    y -= int(this->getPositionY());

    // Go through every widget in the panel

    for ( unsigned i = 0; i < MAX_WIDGETS ; i++ )
    {
        // Get current widget

        GuiWidget * widget = widgets[i];

        // If valid then check to see if cursor is over widget

        if ( widget && widget->isEnabled() )
        {
            // See if the mouse is over the widget

            if (
                    x >= widget->getPositionX() && x < widget->getPositionX() + widget->getSizeX()
                    &&
                    y >= widget->getPositionY() && y < widget->getPositionY() + widget->getSizeY()
                )
            {
                // Mouse is over widget: send the mouse pressed event to the widget

                widget->mousePressed(x,y,button);

                // Abort any further event dispatching

                break;
            }
        }
    }
}

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

Name:     GuiPanel::mouseReleased()
Purpose:  Send mouse released event to current widget the mouse is over.
Params:   mouse position. mouse button released
Returns:  none

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

void GuiPanel::mouseReleased( int x , int y , GLWindow::MouseButton button )
{
    // Translate the coordinates first into panel local coordinates.
    // Objects contained within the panel have locations describe in terms of
    // is coordinate system and not the screen coordinate system.

    x -= int(this->getPositionX());
    y -= int(this->getPositionY());

    // Go through every widget in the panel

    for ( unsigned i = 0; i < MAX_WIDGETS ; i++ )
    {
        // Get current widget

        GuiWidget * widget = widgets[i];

        // If valid then check to see if cursor is over widget

        if ( widget && widget->isEnabled() )
        {
            // See if the mouse is over the widget

            if (
                    x >= widget->getPositionX() && x < widget->getPositionX() + widget->getSizeX()
                    &&
                    y >= widget->getPositionY() && y < widget->getPositionY() + widget->getSizeY()
                )
            {
                // Mouse is over widget: send the mouse released event to the widget

                widget->mouseReleased(x,y,button);

                // Abort any further event dispatching

                break;
            }
        }
    }
}

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

Name:     GuiPanel::lostFocus()
Purpose:  Lost focus event for the GUI panel. puts any items that are in focus
          out of focus.
Params:   none
Returns:  none

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

void GuiPanel::lostFocus()
{
    // Go through every widget in the panel

    for ( unsigned i = 0; i < MAX_WIDGETS ; i++ )
    {
        // Get current widget

        GuiWidget * widget = widgets[i];

        // If valid then check to see if cursor is over widget

        if ( widget )
        {
            // If the widget has focus then cause it loose focus

            if ( widget->getFocus() )
            {
                widget->setFocus(false);
                widget->lostFocus();
            }
        }
    }
}

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

Name:     GuiPanel::setRaised()
Purpose:  Sets whether the panel is to be raised or sunken.
Params:   If panel is raised or not (sunken)
Returns:  none

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

void GuiPanel::setRaised( bool raised )
{
    this->raised = raised;
}

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

Name:     GuiPanel::getRaised()
Purpose:  Tells whether the panel is raised
Params:   none
Returns:  whether the panel is raised (true) or sunken (false)

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

bool GuiPanel::getRaised()
{
    return this->raised;
}

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

Name:     GuiPanel::windowRedrawing()
Purpose:  Draws the panel.
Params:   none
Returns:  none

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

void GuiPanel::windowRedrawing()
{
    //--------------------------------------------------------------------------
    // Don't draw if not visible
    //--------------------------------------------------------------------------

    if ( this->visible == false ) return;

    //--------------------------------------------------------------------------
    // Make sure blending and texturing is disabled:
    //--------------------------------------------------------------------------

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    //--------------------------------------------------------------------------
    // Draw the panel itself: do differently depending if it is raised or sunken
    //--------------------------------------------------------------------------

    if ( ! raised )
    {
        //----------------------------------------------------------------------
        // Panel is sunken
        //----------------------------------------------------------------------

        // Draw the main filled part of the panel

        glBegin(GL_QUADS);

        glColor4f
        (
            getColorR() * INTENSITY_NORMAL_2,
            getColorG() * INTENSITY_NORMAL_2,
            getColorB() * INTENSITY_NORMAL_2,
            1.0f
        );

        glVertex2f
        (
            float( getPositionX()	),
            float( getPositionY()	)
        );

        glVertex2f
        (
            float( getPositionX() + getSizeX()	),
            float( getPositionY()				)
        );

        glColor4f
        (
            getColorR() * INTENSITY_NORMAL_1,
            getColorG() * INTENSITY_NORMAL_1,
            getColorB() * INTENSITY_NORMAL_1,
            1.0f
        );

        glVertex2f
        (
            float( getPositionX() + getSizeX()	),
            float( getPositionY() + getSizeY()	)
        );

        glVertex2f
        (
            float( getPositionX()				),
            float( getPositionY() + getSizeY()	)
        );

        glEnd();


        // draw the shaded outline of the panel: left and top sides


        glColor4f       // set color for the first two lines
        (
            getColorR() * INTENSITY_SHADE_1,
            getColorG() * INTENSITY_SHADE_1,
            getColorB() * INTENSITY_SHADE_1,
            1.0f
        );

        glRecti
        (
            getPositionX(),
            getPositionY(),
            getPositionX() + getSizeX(),
            getPositionY() + 1
        );

        glRecti
        (
            getPositionX(),
            getPositionY(),
            getPositionX() + 1,
            getPositionY() + getSizeY()
        );

        glColor4f       // set color for the second two lines
        (
            getColorR() * INTENSITY_SHADE_2,
            getColorG() * INTENSITY_SHADE_2,
            getColorB() * INTENSITY_SHADE_2,
            1.0f
        );


        glRecti
        (
            getPositionX() + 1,
            getPositionY() + 1,
            getPositionX() + getSizeX() - 1,
            getPositionY() + 2
        );

        glRecti
        (
            getPositionX() + 1,
            getPositionY() + 1,
            getPositionX() + 2,
            getPositionY() + getSizeY() - 1
        );

        // Draw the shiny part of the panel: right and bottom lines

        glColor4f       // set color for the first two lines
        (
            getColorR() * INTENSITY_SHINE_1,
            getColorG() * INTENSITY_SHINE_1,
            getColorB() * INTENSITY_SHINE_1,
            1.0f
        );

        glRecti
        (
            getPositionX() + getSizeX() - 1,
            getPositionY(),
            getPositionX() + getSizeX(),
            getPositionY() + getSizeY()
        );

        glRecti
        (
            getPositionX(),
            getPositionY() + getSizeY() - 1,
            getPositionX() + getSizeX(),
            getPositionY() + getSizeY()
        );

        glColor4f       // set color for the second two lines
        (
            getColorR() * INTENSITY_SHINE_2,
            getColorG() * INTENSITY_SHINE_2,
            getColorB() * INTENSITY_SHINE_2,
            1.0f
        );

        glRecti
        (
            getPositionX() + getSizeX() - 2,
            getPositionY() + 1,
            getPositionX() + getSizeX() - 1,
            getPositionY() + getSizeY() - 1
        );

        glRecti
        (
            getPositionX() + 1,
            getPositionY() + getSizeY() - 2,
            getPositionX() + getSizeX() - 1,
            getPositionY() + getSizeY() - 1
        );

    }
    else
    {
        //----------------------------------------------------------------------
        // Panel is raised
        //----------------------------------------------------------------------

        // Draw the main filled part of the panel

        glBegin(GL_QUADS);

        glColor4f
        (
            getColorR() * INTENSITY_NORMAL_1,
            getColorG() * INTENSITY_NORMAL_1,
            getColorB() * INTENSITY_NORMAL_1,
            1.0f
        );

        glVertex2f
        (
            float( getPositionX()	),
            float( getPositionY()	)
        );

        glVertex2f
        (
            float( getPositionX() + getSizeX()	),
            float( getPositionY()				)
        );

        glColor4f
        (
            getColorR() * INTENSITY_NORMAL_2,
            getColorG() * INTENSITY_NORMAL_2,
            getColorB() * INTENSITY_NORMAL_2,
            1.0f
        );

        glVertex2f
        (
            float( getPositionX() + getSizeX()	),
            float( getPositionY() + getSizeY()	)
        );

        glVertex2f
        (
            float( getPositionX()				),
            float( getPositionY() + getSizeY()	)
        );

        glEnd();


        // draw the shiny outline of the panel: left and top sides


        glColor4f       // set color for the first two lines
        (
            getColorR() * INTENSITY_SHINE_1,
            getColorG() * INTENSITY_SHINE_1,
            getColorB() * INTENSITY_SHINE_1,
            1.0f
        );

        glRecti
        (
            getPositionX(),
            getPositionY(),
            getPositionX() + getSizeX(),
            getPositionY() + 1
        );

        glRecti
        (
            getPositionX(),
            getPositionY(),
            getPositionX() + 1,
            getPositionY() + getSizeY()
        );

        glColor4f       // set color for the second two lines
        (
            getColorR() * INTENSITY_SHINE_2,
            getColorG() * INTENSITY_SHINE_2,
            getColorB() * INTENSITY_SHINE_2,
            1.0f
        );


        glRecti
        (
            getPositionX() + 1,
            getPositionY() + 1,
            getPositionX() + getSizeX() - 1,
            getPositionY() + 2
        );

        glRecti
        (
            getPositionX() + 1,
            getPositionY() + 1,
            getPositionX() + 2,
            getPositionY() + getSizeY() - 1
        );

        // Draw the shaded part of the panel: right and bottom lines

        glColor4f       // set color for the first two lines
        (
            getColorR() * INTENSITY_SHADE_1,
            getColorG() * INTENSITY_SHADE_1,
            getColorB() * INTENSITY_SHADE_1,
            1.0f
        );

        glRecti
        (
            getPositionX() + getSizeX() - 1,
            getPositionY(),
            getPositionX() + getSizeX(),
            getPositionY() + getSizeY()
        );

        glRecti
        (
            getPositionX(),
            getPositionY() + getSizeY() - 1,
            getPositionX() + getSizeX(),
            getPositionY() + getSizeY()
        );

        glColor4f       // set color for the second two lines
        (
            getColorR() * INTENSITY_SHADE_2,
            getColorG() * INTENSITY_SHADE_2,
            getColorB() * INTENSITY_SHADE_2,
            1.0f
        );

        glRecti
        (
            getPositionX() + getSizeX() - 2,
            getPositionY() + 1,
            getPositionX() + getSizeX() - 1,
            getPositionY() + getSizeY() - 1
        );

        glRecti
        (
            getPositionX() + 1,
            getPositionY() + getSizeY() - 2,
            getPositionX() + getSizeX() - 1,
            getPositionY() + getSizeY() - 1
        );
    }

    //--------------------------------------------------------------------------
    // Draw all contained objects within the panel
    //--------------------------------------------------------------------------

    // First do a translation by panel position. Objects within the panel are
    // described in terms of its local coordinate system.

    glTranslatef( float(getPositionX()) , float(getPositionY()) , 0 );

    //--------------------------------------------------------------------------
    // Now draw any existing widgets:
    //--------------------------------------------------------------------------

    for ( int i = MAX_WIDGETS - 1 ; i >= 0 ; i-- )
    {
        // Draw the current widget if it is valid:

        if ( widgets[i] )
        {
            //------------------------------------------------------------------
            // Enable the four additional OpenGL clipping planes
            //------------------------------------------------------------------

            glEnable(GL_CLIP_PLANE0);
            glEnable(GL_CLIP_PLANE1);
            glEnable(GL_CLIP_PLANE2);
            glEnable(GL_CLIP_PLANE3);

            //------------------------------------------------------------------
            // Set the clipping plane equations such that the widgets are clipped
            // to the panel dimensions
            //------------------------------------------------------------------

            double planeT[] = {  0 ,  1 , 0 , -2             };   // top clipping plane equation
            double planeB[] = {  0 , -1 , 0 , getSizeY() - 2 };   // bottom clipping plane equation
            double planeL[] = {  1 ,  0 , 0 , -2             };   // left clipping plane equation
            double planeR[] = { -1 ,  0 , 0 , getSizeX() - 2 };   // right clipping plane equation

            glClipPlane( GL_CLIP_PLANE0 , planeT );
            glClipPlane( GL_CLIP_PLANE1 , planeB );
            glClipPlane( GL_CLIP_PLANE2 , planeL );
            glClipPlane( GL_CLIP_PLANE3 , planeR );

            //------------------------------------------------------------------
            // Draw the widget
            //------------------------------------------------------------------

            widgets[i]->windowRedrawing();
        }
    }

    //--------------------------------------------------------------------------
    // Put the transformation matrix for the twoD display back to normal: undo
    // the previous translation.
    //--------------------------------------------------------------------------

    glTranslatef( float(-getPositionX()) , float(-getPositionY()) , 0 );

    //--------------------------------------------------------------------------
    // Diable the four additional OpenGL clipping planes
    //--------------------------------------------------------------------------

    glDisable(GL_CLIP_PLANE0);
    glDisable(GL_CLIP_PLANE1);
    glDisable(GL_CLIP_PLANE2);
    glDisable(GL_CLIP_PLANE3);
}
