/*
 =======================================================================================
  Name        : DispMode.c
  Author      : vincent lhullier            Date :04/09/98
  Description : Manage the different display mode available
 =======================================================================================
 */
 
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <windows.h>
#include <stdio.h>
#include "Init_Gli.h"
#include "GLI_util.h"
#include "DllInter.h"
#include "DispMode.h"
#include "Tex.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 
/*
 =======================================================================================
    Extern (globals and function prototypes) 
 =======================================================================================
 */
 
extern HINSTANCE    fn_hGetApplicationInstance(void);
extern HWND         fn_hGetApplicationWindow(void);
/* Defined in project main2_0 */
extern void         fn_vChangeDeviceResolution(void);
/* Defined in Gliglou\Gld */
extern BOOL GLD_fn_bChangeDeviceDisplayMode( GLD_tdhDevice hDev );
/* Defined if GAM\Basic.c */
extern void GAM_fn_vActualizeAllGameViewportSize(void);

/*
 =======================================================================================
    Globals
 =======================================================================================
 */
/*
 * to store display mode 
 */
GLI_tdstDisplayMode  GLI_gs_a_stDisplayMode[ GLI_C_lMaxDisplayMode ];
long                 GLI_gs_lNumberOfDisplayModes = 0; 
long                 GLI_gs_lCurrentDisplayMode; 
long                 GLI_gs_lRequestedDisplayMode = -1;
 
/*
 * Brightness value
 */
float                GLI_g_xBrightness = 0.5f;
 
/*
 =======================================================================================
    Access function
 =======================================================================================
 */
 
/*
 * for display mode
 */
long GLI_fn_lIsFullScreenMode( void )
{
    return (GLI_gs_a_stDisplayMode[GLI_gs_lCurrentDisplayMode].lFullScreen); 
}
 
long GLI_fn_lDisplayModeWidth( void )
{
    /*if (GLI_fn_lIsFullScreenMode() )*/
        return GLI_gs_a_stDisplayMode[GLI_gs_lCurrentDisplayMode].lWidth; 
 
    /*
     * windowed
     */
    /*return 640;*/
}
 
long GLI_fn_lDisplayModeHeight( void )
{
    /*if (GLI_fn_lIsFullScreenMode() )*/
        return GLI_gs_a_stDisplayMode[GLI_gs_lCurrentDisplayMode].lHeight; 
 
    /*
     * windowed
     */
    /*return 480;*/
 
}
 
long GLI_fn_lDisplayModeBPP( void )
{
    return GLI_gs_a_stDisplayMode[GLI_gs_lCurrentDisplayMode].lBpp; 
}
 
long GLI_fn_lGetDisplayMode( void )
{
    return GLI_gs_lCurrentDisplayMode;
}
 
/*
 =======================================================================================
    function for list of display modes
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Add a display mode in list (no check if already exist are done)
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lAddDisplayMode( long _lFullScreen, long _lWidth, long _lHeight, long _lBpp )
{
    GLI_gs_a_stDisplayMode[ GLI_gs_lNumberOfDisplayModes ].lFullScreen  = _lFullScreen;
    GLI_gs_a_stDisplayMode[ GLI_gs_lNumberOfDisplayModes ].lWidth       = _lWidth;
    GLI_gs_a_stDisplayMode[ GLI_gs_lNumberOfDisplayModes ].lHeight      = _lHeight;
    GLI_gs_a_stDisplayMode[ GLI_gs_lNumberOfDisplayModes ].lBpp         = _lBpp;
    GLI_gs_lNumberOfDisplayModes++;
    return TRUE;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : return number of display modes
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lGetNumberOfDisplayModes( void )
{
	return GLI_gs_lNumberOfDisplayModes;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : return index of current dsplay mode
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lGetCurrentDisplayMode( void )
{
	return GLI_gs_lCurrentDisplayMode;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : return current display mode width and height
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lGetDisplayModeParameters( long _lDisplayMode, long *_p_lWidth, long *_p_lHeight )
{
	if ( (_lDisplayMode < 0) || (_lDisplayMode >= GLI_gs_lNumberOfDisplayModes) )
		return  0;
 
	*_p_lWidth = GLI_gs_a_stDisplayMode[ _lDisplayMode ].lWidth;
	*_p_lHeight= GLI_gs_a_stDisplayMode[ _lDisplayMode ].lHeight;
	return 1;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : return a string with display description (640x480 for example)
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lGetDisplayModeDescription( long _lDisplayMode, char *_szDesc )
{
	long lWidth, lHeight;
 
	if ( !GLI_fn_lGetDisplayModeParameters( _lDisplayMode, &lWidth, &lHeight ) )
		return 0;
 
	sprintf( _szDesc, "%dx%d", lWidth, lHeight );
	return 1;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : to do a request to change display mode
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_lRequestNewDisplayMode( long _lDisplayMode )
{
    /* check is there is not already a request */
    if (GLI_gs_lRequestedDisplayMode != -1)
        return;
 
    /* check if mode requested is not equal to current */
    if (_lDisplayMode == GLI_gs_lCurrentDisplayMode)
        return;
 
    /* make the request */
    GLI_gs_lRequestedDisplayMode = _lDisplayMode;
    fn_vChangeDeviceResolution();
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : change really display mode (have to be called by win app
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lChangeDisplayMode( void )
{
    long lOldDisplayMode;
 
 
    if (GLI_gs_lRequestedDisplayMode == -1)
        return 0;
 
    lOldDisplayMode = GLI_gs_lCurrentDisplayMode;
    GLI_gs_lCurrentDisplayMode = GLI_gs_lRequestedDisplayMode;
 
    GLI_vCloseGli();
    GLI_xInitGli();
    GLI_vComputeTextures();
 
    GLD_fn_bChangeDeviceDisplayMode( 0 );
	GAM_fn_vActualizeAllGameViewportSize();
    GLI_gs_lRequestedDisplayMode = -1;
    return 1;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Readapt display (called by win app when window is windowed and is moved 
                    or resized )
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vReadaptDisplay( void )
{
    if ( !GLI_DRV_vReadaptDisplay )
        return ;
 
    GLI_DRV_vReadaptDisplay();
    GLD_bAdjustDeviceToWindow( 0 );
}
 
/*
 =======================================================================================
    choose / select
 =======================================================================================
 */
 
 
/*
 ----------------------------------------------------------------------------------------
  Description   : select display mode by index
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lSelectDisplayModeByIndex( long _lIndex )
{
    if ( (_lIndex < 0) || (_lIndex >= GLI_gs_lNumberOfDisplayModes) )
        return -1;
 
    GLI_gs_lCurrentDisplayMode = _lIndex;
    return GLI_gs_lCurrentDisplayMode;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : select display mode by dimension
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lSelectDisplayModeByDimension( long _lWidth, long _lHeight, long _lBpp )
{
    long lIndex;
 
    for (lIndex = 0; lIndex < GLI_gs_lNumberOfDisplayModes; lIndex++)
    {
        if (
                (_lWidth == GLI_gs_a_stDisplayMode[ lIndex ].lWidth) &&
                (_lHeight == GLI_gs_a_stDisplayMode[ lIndex ].lHeight) &&
                (_lBpp == GLI_gs_a_stDisplayMode[ lIndex ].lBpp) 
           )
        {
             GLI_gs_lCurrentDisplayMode = lIndex;
             return lIndex;
        }
    }
    return -1;
}
 
/*
 ----------------------------------------------------------------------------------------
  Description   : choose display mode 
 ----------------------------------------------------------------------------------------
 */
long GLI_fn_lChooseDisplayMode( void )
{
    GLI_gs_lCurrentDisplayMode = -1;
 
    /* no resolution available */
    if (GLI_gs_lNumberOfDisplayModes == 0)
    {
        Erm_fn_iMessageBox( "No available resolution", "FatalError", MB_OK | MB_ICONSTOP );
        return FALSE;
    }

    /* try default resolution */
    GLI_gs_lCurrentDisplayMode = GLI_fn_lSelectDisplayModeByDimension( GLI_gst_DllInfo.l_InitWidth, GLI_gst_DllInfo.l_InitHeight, GLI_gst_DllInfo.l_InitBpp );
 
    /* try 640x480 resolution */
    if (GLI_gs_lCurrentDisplayMode == -1)
	{
		HDC hDC = GetDC(NULL);
		long lBPP = GetDeviceCaps(hDC, PLANES) * GetDeviceCaps(hDC, BITSPIXEL);
		ReleaseDC(NULL, hDC);
        GLI_gs_lCurrentDisplayMode = GLI_fn_lSelectDisplayModeByDimension( 640, 480, lBPP );
	}
 
    /* first resolution */
    if (GLI_gs_lCurrentDisplayMode == -1)
        GLI_gs_lCurrentDisplayMode = 0;

    return TRUE;
}
 
/*
 =======================================================================================
    Main functions
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : Ask driver to enumerate available display modes
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vLoadDisplayMode( void )
{
    GLI_gs_lNumberOfDisplayModes = 0; 
#if 0
	GLI_gs_lNumberOfDisplayModes = 1;
	GLI_gs_a_stDisplayMode[0].lWidth = 640;
	GLI_gs_a_stDisplayMode[0].lHeight = 480;

	HDC hDC = GetDC(NULL);
	GLI_gs_a_stDisplayMode[0].lBpp = GetDeviceCaps(hDC, PLANES) * GetDeviceCaps(hDC, BITSPIXEL);
	ReleaseDC(NULL, hDC);

	GLI_gs_a_stDisplayMode[0].lFullScreen = 0;
#else
    GLI_DRV_fnl_EnumModes( GLI_gst_DllInfo.sz_DriverName, GLI_gst_DllInfo.sz_DeviceName );
#endif
}
 
/*
 =======================================================================================
    Brightness
 =======================================================================================
 */
 
/*
 ----------------------------------------------------------------------------------------
  Description   : change brightness value (_lValue is from 0 to 100)
 ----------------------------------------------------------------------------------------
 */
void GLI_fn_vSetBrightness( long _lValue )
{
    if (_lValue < 0)
        _lValue = 0;
    else if (_lValue >= 100)
        _lValue = 100;
    
    GLI_g_xBrightness = ((float) _lValue) / 100.0f;
}

long GLI_fn_lGetBrightness()
{
    return (long)(GLI_g_xBrightness * 100.0f);
}
