/*
 =======================================================================================
  Name        : GLI_Menu.c
  Author      : vincent lhullier            Date :10/03/99
  Description : function to display gli menu
 =======================================================================================
 =======================================================================================
        !!!! Warning : In retail version this file is empty !!!!
 =======================================================================================
 =======================================================================================
 */

#if !defined(RETAIL) && !defined(PRESS_DEMO)


 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <string.h>
#include <malloc.h>

#include "GLI.h"
#include "DllInter.h"
#include "DispMode.h"
#include "GLIText.h"
#include "mater_st.h"

#include "Tex.h"
#include "Texture.h" 
#include "TexArray.h"

#include "FIL.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
    Macro definition 
 =======================================================================================
 */
#ifdef EXGEOM_APPLI

#define M_bKeyJustPressed(code) ( KBD_fnb_IsKeyJustPressed( code ) )
#define M_bKeyPressed(code) ( KBD_fnb_IsKeyPressed( code ) )
#define C_GliMenu_Activate  VK_DELETE
#define C_GliMenu_Next      VK_END
#define C_GliMenu_Prev      VK_HOME
#define C_GliMenu_Select    VK_NEXT
#define C_GliMenu_Zoom      VK_PRIOR
#define C_GliMenu_Goto      VK_INSERT

#else

#include "ipt.h"
#include "gam/structur/input_s.h"
#define M_bKeyPressed( code ) ( IPT_fn_bIsValidated ( code ) == IPT_C_TRUE )
#define M_bKeyJustPressed( code ) ( IPT_fn_bIsJustValidated( code ) == IPT_C_TRUE )

#define C_GliMenu_Activate  (g_st_3DOS_EntryActions.hGliMenu_Activate)
#define C_GliMenu_Next      (g_st_3DOS_EntryActions.hGliMenu_Next)
#define C_GliMenu_Prev      (g_st_3DOS_EntryActions.hGliMenu_Prev)
#define C_GliMenu_Select    (g_st_3DOS_EntryActions.hGliMenu_Select)
#define C_GliMenu_Zoom      (g_st_3DOS_EntryActions.hGliMenu_Zoom)
#define C_GliMenu_Goto      (g_st_3DOS_EntryActions.hGliMenu_Goto)

#endif

/*
 =======================================================================================
    Structures
 =======================================================================================
 */
typedef struct GLI_tdst_Menu_
{
    char    cDisplay;
    char    a_szString[1024][50];
    long    alValue[ 1024 ]; 
    long    lNumberOfString;
    long    lMaxString;
    long    lFirstStringIndex;
    long    lCurrent;
    long    lWidth;
    long    lHeight;
    void    (* pfnv_Validate)(void);
    void    (* pfnv_DisplayAdditionalString)(void);
    void    (* pfnv_DisplayAdditional)(void);

    void   *p_cBackBuffer;
    long    lPitch;
} GLI_tdst_Menu;

/*
 =======================================================================================
    Globals
 =======================================================================================
 */
static GLI_tdst_Menu    GLI_gsst_Menu;
static char             GLI_gsasz_MenuString[ 32 ][ 50 ];
static char             GLI_gc_MenuInit = 0;

unsigned long GLIMENU_aul_Palette[ 7 ] = { 0x00000000, 0x00FFFFFF, 0x00D7AF4B, 0x005F3B0F, 0x00472B0B, 0x00C38B2F, 0x002F0F07};
unsigned short GLIMENU_auw_Palette[ 7 ] = { 0x0000, 0xFFFF, 0xD569, 0x59C1, 0x4141, 0xC445, 0x2860};
unsigned char GLIMENU_aauc_Letter[ 26 ][ 40 ] = 
{
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0},
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0},
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0},
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}
};
unsigned char GLIMENU_aauc_Digit[ 10 ][ 40 ] = 
{
    { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
    { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
    { 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
    { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0},
    { 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}
};
unsigned char GLIMENU_aauc_Cursor[ 9 ][ 10 ] = 
{
    { 2, 3, 4, 3, 5, 0, 0, 0, 0, 0},
    { 2, 3, 4, 3, 5, 5, 0, 0, 0, 0},
    { 2, 3, 4, 4, 3, 3, 5, 0, 0, 0},
    { 2, 3, 4, 4, 4, 4, 3, 5, 5, 0},
    { 2, 3, 4, 4, 4, 4, 4, 3, 3, 5},
    { 2, 3, 4, 4, 4, 4, 4, 3, 3, 5},
    { 2, 3, 4, 4, 4, 4, 3, 5, 5, 0},
    { 2, 3, 4, 4, 3, 3, 5, 0, 0, 0},
    { 2, 3, 4, 3, 5, 5, 0, 0, 0, 0}
};

extern ACP_tdxHandleOfMaterial gs_hDefaultMaterial;
extern void GLI_vDraw2DSprite( GLD_tdstViewportAttributes *p_stVpt ,MTH_tdxReal  xXMin,MTH_tdxReal  xXMax,MTH_tdxReal  xYMin,MTH_tdxReal  xYMax,ACP_tdxHandleOfMaterial hMaterial);

GLI_tdstTexture  *GLIMENU_gap_stTexturesCurrentlyDisplayed[ C_lMaxNumberOfTexture ];
int               g_iTexturesCurrentlyDisplayedCounter = 0;
float             fSizeFactorForTextureDisplay = 1.0f;

/*
 =======================================================================================
    Functions
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : display a string
 ----------------------------------------------------------------------------------------
 */
static void GLI_fnv_Menu_DisplayString( char *_sz_String, long _lX, long _lY )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lX2, lY2;
    unsigned short  *p_uwStart, *p_uwCurrent;
    char            *pc_Char;
    unsigned char   *puc_Copy;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

    pc_Char     = _sz_String;
    p_uwStart   = (unsigned short *) GLI_gsst_Menu.p_cBackBuffer + _lY * GLI_gsst_Menu.lPitch + _lX;

    while( *pc_Char != 0 )
    {
        p_uwCurrent = p_uwStart;
        if ( (tolower( *pc_Char ) >= 'a') && (tolower( *pc_Char ) <= 'z') )
            puc_Copy = GLIMENU_aauc_Letter[ tolower( *pc_Char ) - 'a' ];
        else if ( (*pc_Char >= '0') && (*pc_Char <= '9') )
            puc_Copy = GLIMENU_aauc_Digit[*pc_Char - '0' ];
        else
        {
            p_uwStart += 6;
            pc_Char++;
            continue;
        }
        pc_Char++;

        for (lY2 = 0; lY2 < 8; lY2 ++ )
        {
            for (lX2 = 0; lX2 < 5; lX2++)
            {
                *p_uwCurrent++ = GLIMENU_auw_Palette[ *puc_Copy++ ];
            }
            p_uwCurrent += GLI_gsst_Menu.lPitch - 5;
        }
        p_uwStart += 6;
    }
}

/*
 ----------------------------------------------------------------------------------------
  Description   : compute size needed to display menu
 ----------------------------------------------------------------------------------------
 */
static void GLI_fnv_Menu_ComputeSize( void )
{
    long i;
    long lWidth;

    GLI_gsst_Menu.lWidth = 0;
    for (i = 0; i < GLI_gsst_Menu.lNumberOfString; i++ )
    {
        lWidth = strlen( GLI_gsst_Menu.a_szString[i] );
        if (lWidth > GLI_gsst_Menu.lWidth)
            GLI_gsst_Menu.lWidth = lWidth;
    }
    GLI_gsst_Menu.lWidth = GLI_gsst_Menu.lWidth * 6 + 15;

    GLI_gsst_Menu.lHeight           = GLI_gsst_Menu.lMaxString * 9 + 10;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : resolution menu
 ----------------------------------------------------------------------------------------
 */
static void GLI_fnv_Menu_ResolutionValidate( void )
{
    GLI_gsst_Menu.cDisplay = 0;
    GLI_fn_lRequestNewDisplayMode( GLI_gsst_Menu.lCurrent );
}

static void GLI_fnv_Menu_Resolution( void )
{
    long lMode;

    for ( lMode = 0; lMode < GLI_gs_lNumberOfDisplayModes && lMode < 1024; lMode++ )
    {
        GLI_fn_lGetDisplayModeDescription( lMode, GLI_gsst_Menu.a_szString[lMode] );
    }

    GLI_gsst_Menu.lNumberOfString   = lMode;
    GLI_gsst_Menu.lMaxString        = (lMode < 5) ? GLI_gs_lNumberOfDisplayModes : 5;
    GLI_gsst_Menu.lCurrent          = GLI_gs_lCurrentDisplayMode;
    
    GLI_fnv_Menu_ComputeSize();

    GLI_gsst_Menu.lFirstStringIndex = GLI_gsst_Menu.lCurrent;
    if (GLI_gsst_Menu.lFirstStringIndex + GLI_gsst_Menu.lMaxString > GLI_gsst_Menu.lNumberOfString )
        GLI_gsst_Menu.lFirstStringIndex = GLI_gsst_Menu.lNumberOfString - GLI_gsst_Menu.lMaxString;

    GLI_gsst_Menu.pfnv_Validate = GLI_fnv_Menu_ResolutionValidate;
    GLI_gsst_Menu.pfnv_DisplayAdditionalString = NULL;
    GLI_gsst_Menu.pfnv_DisplayAdditional = NULL;
}

/* 
 ----------------------------------------------------------------------------------------
  Function for changing texture sample display size
 ----------------------------------------------------------------------------------------
*/
void fn_vCheckForTextureDisplaySize()
{
	/* Key 'PageUp' to change texture size for displayed sample */
    if( M_bKeyJustPressed( C_GliMenu_Zoom ) )
    {
        if( fSizeFactorForTextureDisplay > 3.9f )
            fSizeFactorForTextureDisplay = 0.5f;
        else
            fSizeFactorForTextureDisplay *= 2.0f;
    }
}


/*
 ----------------------------------------------------------------------------------------
  Description   : init display text menu
 ----------------------------------------------------------------------------------------
 */
static void GLI_fnv_Menu_TextureValidate( void )
{
    GLI_gsst_Menu.cDisplay = 0;
}

static void GLI_fnv_Menu_TextureAdditionalString( void )
{
    long            lX, lY;
    long            lTexture;
    GLI_tdstTexture *p_stTexture;
    char            szText[100];

    fn_vCheckForTextureDisplaySize();

    lTexture = GLI_gsst_Menu.alValue[ GLI_gsst_Menu.lCurrent ];
    p_stTexture = gs_aDEFTableOfTextureAlreadyRead[ lTexture ];

    sprintf( 
        szText, 
        "in memory %dx%d   original %dx%d   sample %dx%d", 
        p_stTexture->lWidth, p_stTexture->lHeight, 
        p_stTexture->lRealWidth, p_stTexture->lRealHeight, 
        (unsigned long)(p_stTexture->lWidth*fSizeFactorForTextureDisplay), 
        (unsigned long)(p_stTexture->lHeight*fSizeFactorForTextureDisplay) );

    lX = 20 + GLI_gsst_Menu.lWidth; 
    lY = 10;
    GLI_fnv_Menu_DisplayString( szText, lX, lY );
}

static void GLI_fnv_Menu_TextureAdditional( void )
{
    long            lX, lY;
    long            lTexture;
    GLI_tdstTexture *p_stTexture;

    lTexture = GLI_gsst_Menu.alValue[ GLI_gsst_Menu.lCurrent ];
    p_stTexture = gs_aDEFTableOfTextureAlreadyRead[ lTexture ];


    lX = 20 + GLI_gsst_Menu.lWidth; 
    lY = 20;
    
    gs_hDefaultMaterial->stAmbient.xR = gs_hDefaultMaterial->stAmbient.xG = gs_hDefaultMaterial->stAmbient.xB = 1.0f;
    gs_hDefaultMaterial->p_stTexture = p_stTexture;
    GLI_vDraw2DSprite( NULL, (float) lX + p_stTexture->lWidth*fSizeFactorForTextureDisplay, (float) lX, (float) lY, (float) lY + p_stTexture->lHeight*fSizeFactorForTextureDisplay,gs_hDefaultMaterial);
    gs_hDefaultMaterial->p_stTexture = NULL;

}


static void GLI_fnv_Menu_Texture( void )
{
    long lTextureCounter;
    long lIndex;
    char *p_cTextureName;

    for (lIndex = 0, lTextureCounter = 0 ; lTextureCounter < GLI_C_lNBMaxOfTextures ; lTextureCounter ++ )
    {
        if ( (gs_aDEFTableOfTextureMemoryChannels[lTextureCounter] != GLI_TEXIsUnallocated) && (gs_aDEFTableOfTextureAlreadyRead[lTextureCounter] != NULL))
        {
            p_cTextureName = 1 + strrchr( gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]->a255_cFileName, '\\' );
            if( p_cTextureName == 1+(char*)NULL )
                p_cTextureName = gs_aDEFTableOfTextureAlreadyRead [lTextureCounter]->a255_cFileName;
 
            sprintf( GLI_gsst_Menu.a_szString[ lIndex ], " %i  %s", lTextureCounter, p_cTextureName );
            GLI_gsst_Menu.alValue[ lIndex ] = lTextureCounter;
            lIndex++;
        }
    }
    
    GLI_gsst_Menu.lNumberOfString   = lIndex;
    GLI_gsst_Menu.lMaxString        = 20;
    GLI_gsst_Menu.lCurrent          = 0;
    GLI_gsst_Menu.lFirstStringIndex = 0;
    
    GLI_fnv_Menu_ComputeSize();

    GLI_gsst_Menu.pfnv_Validate = GLI_fnv_Menu_TextureValidate;
    GLI_gsst_Menu.pfnv_DisplayAdditionalString = GLI_fnv_Menu_TextureAdditionalString;
    GLI_gsst_Menu.pfnv_DisplayAdditional = GLI_fnv_Menu_TextureAdditional;
}


/* * * * * * *  Menu for currently displayed textures  * * * * * * */
static void GLI_fnv_Menu_DisplayedTextureAdditionalString( void )
{
    long            lX, lY;
    GLI_tdstTexture *p_stTexture;
    char            szText[100];

    p_stTexture = (GLI_tdstTexture *)GLI_gsst_Menu.alValue[ GLI_gsst_Menu.lCurrent ];

    fn_vCheckForTextureDisplaySize();

    sprintf( 
        szText, 
        "in memory %dx%d   original %dx%d   sample %dx%d", 
        p_stTexture->lWidth, p_stTexture->lHeight, 
        p_stTexture->lRealWidth, p_stTexture->lRealHeight, 
        (unsigned long)(p_stTexture->lWidth*fSizeFactorForTextureDisplay), 
        (unsigned long)(p_stTexture->lHeight*fSizeFactorForTextureDisplay) );

    lX = 20 + GLI_gsst_Menu.lWidth; 
    lY = 10;
    GLI_fnv_Menu_DisplayString( szText, lX, lY );
}

static void GLI_fnv_Menu_DisplayedTextureAdditional( void )
{
    long            lX, lY;
    GLI_tdstTexture *p_stTexture;

    p_stTexture = (GLI_tdstTexture *)GLI_gsst_Menu.alValue[ GLI_gsst_Menu.lCurrent ];


    lX = 20 + GLI_gsst_Menu.lWidth; 
    lY = 20;
    
    gs_hDefaultMaterial->stAmbient.xR = gs_hDefaultMaterial->stAmbient.xG = gs_hDefaultMaterial->stAmbient.xB = 1.0f;
    gs_hDefaultMaterial->p_stTexture = p_stTexture;
    GLI_vDraw2DSprite( NULL, (float) lX + p_stTexture->lWidth*fSizeFactorForTextureDisplay, (float) lX, (float) lY, (float) lY + p_stTexture->lHeight*fSizeFactorForTextureDisplay,gs_hDefaultMaterial);
    gs_hDefaultMaterial->p_stTexture = NULL;

}

static void GLI_fnv_Menu_DisplayedTexture( void )
{
    long lTextureCounter;
    long lIndex;
    char *p_cTextureName;
 
    for (lIndex = 0, lTextureCounter = 0 ; lTextureCounter < g_iTexturesCurrentlyDisplayedCounter ; lTextureCounter ++ )
    {
        if ( GLIMENU_gap_stTexturesCurrentlyDisplayed[lTextureCounter] != NULL )
        {
            p_cTextureName = 1+strrchr( GLIMENU_gap_stTexturesCurrentlyDisplayed [lTextureCounter]->a255_cFileName, '\\' );
            if( p_cTextureName == 1+(char *)NULL )
                p_cTextureName = GLIMENU_gap_stTexturesCurrentlyDisplayed [lTextureCounter]->a255_cFileName;
            sprintf( GLI_gsst_Menu.a_szString[ lIndex ], " %i  %s", lTextureCounter, p_cTextureName );
            GLI_gsst_Menu.alValue[ lIndex ] = (long)GLIMENU_gap_stTexturesCurrentlyDisplayed[lTextureCounter];
            lIndex++;
        }
    }
    
    GLI_gsst_Menu.lNumberOfString   = lIndex;
    GLI_gsst_Menu.lMaxString        = 20;
    GLI_gsst_Menu.lCurrent          = 0;
    GLI_gsst_Menu.lFirstStringIndex = 0;
    
    GLI_fnv_Menu_ComputeSize();

    GLI_gsst_Menu.pfnv_Validate = GLI_fnv_Menu_TextureValidate;
    GLI_gsst_Menu.pfnv_DisplayAdditionalString = GLI_fnv_Menu_DisplayedTextureAdditionalString;
    GLI_gsst_Menu.pfnv_DisplayAdditional = GLI_fnv_Menu_DisplayedTextureAdditional;
}

void GLI_fn_vAddDisplayedVisualMaterial( ACP_tdxHandleOfMaterial _hVisualMaterial )
{
    GLIMENU_gap_stTexturesCurrentlyDisplayed[g_iTexturesCurrentlyDisplayedCounter] = _hVisualMaterial -> p_stTexture;
	if ( g_iTexturesCurrentlyDisplayedCounter < C_lMaxNumberOfTexture - 1 )
		g_iTexturesCurrentlyDisplayedCounter ++ ;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : init start menu
 ----------------------------------------------------------------------------------------
 */
static void GLI_fnv_Menu_StartValidate( void )
{
    switch( GLI_gsst_Menu.lCurrent )
    {
        case 0: GLI_fnv_Menu_Resolution(); break;
        case 1: GLI_fnv_Menu_Texture(); break;
        case 2: GLI_fnv_Menu_DisplayedTexture(); break;
    }
}

static void GLI_fnv_Menu_Start( void )
{
    strcpy( GLI_gsst_Menu.a_szString[0], "resolution" );
    strcpy( GLI_gsst_Menu.a_szString[1], "textures" );
    strcpy( GLI_gsst_Menu.a_szString[2], "displayed textures" );

    GLI_gsst_Menu.lNumberOfString   = 3;
    GLI_gsst_Menu.lMaxString        = 3;
    GLI_gsst_Menu.lCurrent          = 0;
    GLI_gsst_Menu.lFirstStringIndex = 0;
    
    GLI_fnv_Menu_ComputeSize();

    GLI_gsst_Menu.pfnv_Validate = GLI_fnv_Menu_StartValidate;
    GLI_gsst_Menu.pfnv_DisplayAdditionalString = NULL;
    GLI_gsst_Menu.pfnv_DisplayAdditional = NULL;

}

/*
 ----------------------------------------------------------------------------------------
  Description   : Main function -> lock device, display police in virtual screen and
                            unlock buffer
 ----------------------------------------------------------------------------------------
 */
void GLI_fnv_DisplayMenuWindow(long _lX, long _lY )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lX, lY, lX2, lY2;
    unsigned short  *p_uwStart, *p_uwEnd;
    long            lString;
    unsigned char   *puc_Copy;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    
    if ( !GLI_DRV_bLockDevice( &GLI_gsst_Menu.p_cBackBuffer, &GLI_gsst_Menu.lPitch ) )
        return;

    GLI_gsst_Menu.lPitch >>= 1;
    p_uwEnd = p_uwStart = (unsigned short *) GLI_gsst_Menu.p_cBackBuffer;
    p_uwStart += _lY * GLI_gsst_Menu.lPitch + _lX;

    *p_uwStart++ = 0;
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = 0;

    lX = GLI_gsst_Menu.lWidth - 5;
    while (lX)
    {
        *p_uwStart++ = 0;
        lX--;
    }
    p_uwStart += GLI_gsst_Menu.lPitch - GLI_gsst_Menu.lWidth;

    p_uwEnd += (_lY + GLI_gsst_Menu.lHeight - 2) * GLI_gsst_Menu.lPitch + ( _lX + GLI_gsst_Menu.lWidth - 1);

    while ( p_uwStart < p_uwEnd )
    {
        for ( lX2 = 0; lX2 < 5; lX2 ++)
            *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[ 0 ][ lX2 ] ];
        
        lX = GLI_gsst_Menu.lWidth - 5;
        while (lX)
        {
            *p_uwStart++ = 0;
            lX--;
        }
        p_uwStart += GLI_gsst_Menu.lPitch - GLI_gsst_Menu.lWidth;
    }

    *p_uwStart++ = 0;
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = GLIMENU_auw_Palette[ GLIMENU_aauc_Cursor[0][0] ];
    *p_uwStart++ = 0;

    lX = GLI_gsst_Menu.lWidth - 5;
    while (lX)
    {
        *p_uwStart++ = 0;
        lX--;
    }

    lX = _lX + 10;
    lY = _lY + 5;
    for ( lString = GLI_gsst_Menu.lFirstStringIndex; lString < GLI_gsst_Menu.lFirstStringIndex + GLI_gsst_Menu.lMaxString; lString++ )
    {
        if (lString >= GLI_gsst_Menu.lNumberOfString )
            break;

        if ( lString == GLI_gsst_Menu.lCurrent )
        {
            puc_Copy  = GLIMENU_aauc_Cursor[ 1 ];
            p_uwStart = (unsigned short *) GLI_gsst_Menu.p_cBackBuffer + lY * GLI_gsst_Menu.lPitch + _lX;
            for ( lY2 = 0; lY2 < 8; lY2 ++)
            {
                for ( lX2 = 0; lX2 < 10; lX2++)
                {
                    *p_uwStart++ = GLIMENU_auw_Palette[ *puc_Copy++ ];
                }
                p_uwStart += GLI_gsst_Menu.lPitch - 10;
            }
        }
        
        GLI_fnv_Menu_DisplayString( GLI_gsst_Menu.a_szString[ lString ], lX, lY );

        lY += 9;
    }

    if (GLI_gsst_Menu.pfnv_DisplayAdditionalString)
        GLI_gsst_Menu.pfnv_DisplayAdditionalString();

    GLI_DRV_bUnlockDevice();

    if (GLI_gsst_Menu.pfnv_DisplayAdditional)
        GLI_gsst_Menu.pfnv_DisplayAdditional();

    GLI_xSendListToViewport(NULL);
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Manage with GLI_Menu
 ----------------------------------------------------------------------------------------
 */
void GLI_fnv_ManageMenu( void )
{
    static long lMaxCountInit = 7;
    static long lCount;
    static long lCountInit;

    if ( !GLI_gc_MenuInit )
    {
        memset( &GLI_gsst_Menu, 0, sizeof( GLI_tdst_Menu ) );
        GLI_gc_MenuInit = 1;
    }

    if ( M_bKeyJustPressed( C_GliMenu_Activate ) )
    {
        if ( !GLI_gsst_Menu.cDisplay )
            GLI_fnv_Menu_Start();

        GLI_gsst_Menu.cDisplay = ~GLI_gsst_Menu.cDisplay;
    }

    if ( !GLI_gsst_Menu.cDisplay )
    {
        g_iTexturesCurrentlyDisplayedCounter = 0;
        return;
    }

    if (M_bKeyPressed( C_GliMenu_Next ) )
    {
        if (M_bKeyJustPressed( C_GliMenu_Next ) )
        {
            lCountInit = lMaxCountInit;
            lCount = 0;
        }
        else
        {
            lCount--;
        }
    
        if (lCount == 0)
        {
            if (GLI_gsst_Menu.lCurrent + 1 < GLI_gsst_Menu.lNumberOfString )
            {
                GLI_gsst_Menu.lCurrent += 1;

                if (GLI_gsst_Menu.lCurrent - GLI_gsst_Menu.lFirstStringIndex >= GLI_gsst_Menu.lMaxString )
                {
                    GLI_gsst_Menu.lFirstStringIndex++;
                }
            }
            if (lCountInit > 1)
                lCountInit--;
            lCount = lCountInit;
        }
    }
    else if (M_bKeyPressed( C_GliMenu_Prev ) )
    {
        if (M_bKeyJustPressed( C_GliMenu_Prev ) )
        {
            lCountInit = lMaxCountInit;
            lCount = 0;
        }
        else
        {
            lCount--;
        }
        
        if (lCount == 0)
        {
            if (GLI_gsst_Menu.lCurrent > 0)
            {
                GLI_gsst_Menu.lCurrent -= 1;
                if (GLI_gsst_Menu.lCurrent < GLI_gsst_Menu.lFirstStringIndex)
                    GLI_gsst_Menu.lFirstStringIndex--;
            }
            if (lCountInit > 1 )
                lCountInit--;
            lCount = lCountInit;
        }
    }
    else if( M_bKeyJustPressed( C_GliMenu_Goto ) )
    {
        if( GLI_gsst_Menu.lCurrent > 0 )
        {
            GLI_gsst_Menu.lCurrent = 0;
            GLI_gsst_Menu.lFirstStringIndex = 0;
        }
        else
        {
            GLI_gsst_Menu.lCurrent = GLI_gsst_Menu.lNumberOfString - 1;
            GLI_gsst_Menu.lFirstStringIndex = GLI_gsst_Menu.lNumberOfString - GLI_gsst_Menu.lMaxString;
            if( GLI_gsst_Menu.lFirstStringIndex < 0 )
                GLI_gsst_Menu.lFirstStringIndex = 0;
        }
    }
    
    if (M_bKeyJustPressed( C_GliMenu_Select ) )
    {
        if (GLI_gsst_Menu.pfnv_Validate)
            GLI_gsst_Menu.pfnv_Validate();
    }

    GLI_fnv_DisplayMenuWindow( 10, 10 );

    g_iTexturesCurrentlyDisplayedCounter = 0;
}


#endif /* RETAIL && PRESS_DEMO */
