/*
Copyright (c) 1998 Richard Lawrence

This program is free software; you can redistribute it and/or modify it under the terms 
of the GNU General Public License as published by the Free Software Foundation; either 
version 2 of the License, or (at your option) any later version. This program is 
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. You should have received a copy of the GNU
General Public License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// CGraphicsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Atari800Win.h"
#include "CGraphicsDlg.h"
#include "winatari.h"
#include "GraphicsDesc.h"
#include "CWarnDlg.h"
#include "resource.h"
#include "ddraw.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


extern "C" {
#include "graphics.h"
#include "registry.h"
extern ULONG	ulScreenMode;
extern int Init_Graphics( void );
extern ULONG	ulDontShowFlags;
extern unsigned long ulModesAvail;
}

static ULONG ulNewScreenMode;
/////////////////////////////////////////////////////////////////////////////
// CGraphicsDlg dialog


CGraphicsDlg::CGraphicsDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGraphicsDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CGraphicsDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CGraphicsDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGraphicsDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CGraphicsDlg, CDialog)
	//{{AFX_MSG_MAP(CGraphicsDlg)
	ON_BN_CLICKED(IDC_MODE_320X200_CLIP, OnMode320x200Clip)
	ON_BN_CLICKED(IDC_MODE_320X240_PARTCLIP, OnMode320x240Partclip)
	ON_BN_CLICKED(IDC_MODE_640x400_CLIP, OnMODE640x400CLIP)
	ON_BN_CLICKED(IDC_MODE_640X480_PARTCLIP, OnMode640x480Partclip)
	ON_BN_CLICKED(IDC_MODE_800X600, OnMode800x600)
	ON_BN_CLICKED(IDC_NODIRECTDRAW, OnNodirectdraw)
	ON_BN_CLICKED(IDC_384X240_WINDOWED, On384x240Windowed)
	ON_BN_CLICKED(IDC_768x480_WINDOWED, On768x480WINDOWED)
	ON_BN_CLICKED(IDC_MODE_1024_768, OnMode1024x768)
	ON_BN_CLICKED(IDC_FORCE_VSYNC, OnForceVsync)
	ON_BN_CLICKED(IDC_MODE_512X384, OnMode512x384)
	ON_BN_CLICKED(IDC_LOCALMEM, OnLocalmem)
	ON_BN_CLICKED(IDC_SHOW_SCANLINES, OnShowScanlines)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGraphicsDlg message handlers

BOOL CGraphicsDlg::SetButtonState( unsigned long ulButton, unsigned long ulModeFlag, unsigned long ulDDrawFlag )
{
	CButton *cbButton = (CButton *)GetDlgItem( ulButton );
	ASSERT( cbButton );

	if( ulModesAvail & ulModeFlag )
		cbButton->EnableWindow( TRUE );
	else
		cbButton->EnableWindow( FALSE );

	if( !(ulNewScreenMode & ulDDrawFlag) || !(ulNewScreenMode & DDRAW_FULL) )
		cbButton->SetCheck( 0 );

	if( (ulNewScreenMode & DDRAW_FULL) && (ulNewScreenMode & ulDDrawFlag) )
		cbButton->SetCheck( 1 );

	return TRUE;
}

void CGraphicsDlg::SetGraphicsDesc( void )
{
	CButton *cbButton = NULL;
	HANDLE	icon = NULL;
	CStatic* iconDisp = (CStatic *)GetDlgItem( IDC_SIZE_ICON );
	char	message[LOADSTRING_STRING_SIZE];

	memset( message, 0, LOADSTRING_STRING_SIZE );
	
	cbButton = (CButton *)GetDlgItem( IDC_NODIRECTDRAW );
	ASSERT( cbButton );
	cbButton->SetCheck( (ulNewScreenMode & DDRAW_NONE) != 0 );

	cbButton = (CButton *)GetDlgItem( IDC_LOCALMEM );
	ASSERT( cbButton );
	cbButton->SetCheck( (ulNewScreenMode & DDRAW_USE_LOCALMEM) != 0 );

	SetButtonState( IDC_MODE_1024_768, MODE_1024_768, DDRAW_1024_768 );
	SetButtonState( IDC_MODE_800X600, MODE_800_600, DDRAW_800_600 );
	SetButtonState( IDC_MODE_640X480_PARTCLIP, MODE_640_480, DDRAW_640_480 );
	SetButtonState( IDC_MODE_640x400_CLIP, MODE_640_400, DDRAW_640_400 );
	SetButtonState( IDC_MODE_512X384, MODE_512_384, DDRAW_512_384 );
	SetButtonState( IDC_MODE_320X240_PARTCLIP, MODE_320_240, DDRAW_320_240 );
	SetButtonState( IDC_MODE_320X200_CLIP, MODE_320_200, DDRAW_320_200 );

	cbButton = (CButton *)GetDlgItem( IDC_FORCE_VSYNC );
	ASSERT( cbButton );

	cbButton->SetCheck( (ulNewScreenMode & DDRAW_DDBLT_WAIT)!=0 );

	cbButton = (CButton *)GetDlgItem( IDC_SHOW_SCANLINES );
	ASSERT( cbButton );
	cbButton->SetCheck( (ulNewScreenMode & SHOW_SCANLINES)!=0 );

	if( !(ulNewScreenMode & DDRAW_FULL) )
	{
		//Windowed modes are always full overscan
		icon = AfxGetApp()->LoadIcon( IDI_FULL_OVERSCAN );

		//Fill in appropriate description
		if( ulNewScreenMode & DDRAW_WIND )
			LoadString( NULL, IDS_MODE_DIRECTDRAW_WINDOWED, message, LOADSTRING_STRING_SIZE );
		else
			LoadString( NULL, IDS_MODE_NODIRECTDRAW_DESC, message, LOADSTRING_STRING_SIZE );

		cbButton = (CButton *)GetDlgItem( IDC_384X240_WINDOWED );
		ASSERT( cbButton );
		cbButton->SetCheck( (ulNewScreenMode & WINDOWED_NORMAL) != 0 );

		cbButton = (CButton *)GetDlgItem( IDC_768x480_WINDOWED );
		ASSERT( cbButton );
		cbButton->SetCheck( (ulNewScreenMode & WINDOWED_STRETCH) != 0 );
	}
	else
	{
		cbButton = (CButton *)GetDlgItem( IDC_384X240_WINDOWED );
		ASSERT( cbButton );
		cbButton->SetCheck( 0 );
	
		cbButton = (CButton *)GetDlgItem( IDC_768x480_WINDOWED );
		ASSERT( cbButton );
		cbButton->SetCheck( 0 );

		icon = AfxGetApp()->LoadIcon( IDI_FULL_OVERSCAN );	//The default full overscan icon

		//Load the appropriate overscan icon indicator, description, and check the right button
		if( ulNewScreenMode & DDRAW_320_200 )
		{
			icon = AfxGetApp()->LoadIcon( IDI_NO_OVERSCAN );
			LoadString( NULL, IDS_MODE_320_200_DESC, message, LOADSTRING_STRING_SIZE );
		}

		if( ulNewScreenMode & DDRAW_320_240 )
		{
			icon = AfxGetApp()->LoadIcon( IDI_VERT_OVERSCAN );
			LoadString( NULL, IDS_MODE_320_240_DESC, message, LOADSTRING_STRING_SIZE );
		}

		if( ulNewScreenMode & DDRAW_512_384 )
		{
			LoadString( NULL, IDS_MODE_512_384_DESC, message, LOADSTRING_STRING_SIZE );
		}

		if( ulNewScreenMode & DDRAW_640_400 )
		{
			icon = AfxGetApp()->LoadIcon( IDI_NO_OVERSCAN );
			LoadString( NULL, IDS_MODE_640_400_DESC, message, LOADSTRING_STRING_SIZE );
		}

		if( ulNewScreenMode & DDRAW_640_480 )
		{
			icon = AfxGetApp()->LoadIcon( IDI_VERT_OVERSCAN );
			LoadString( NULL, IDS_MODE_640_480_DESC, message, LOADSTRING_STRING_SIZE );
		}

		if( ulNewScreenMode & DDRAW_800_600 )
			LoadString( NULL, IDS_MODE_800_600_DESC, message, LOADSTRING_STRING_SIZE );

		if( ulNewScreenMode & DDRAW_1024_768 )
			LoadString( NULL, IDS_MODE_1024_768_DESC, message, LOADSTRING_STRING_SIZE );
	}
	
	SetDlgItemText( IDC_DESCRIPTION, message );	

	if( icon && iconDisp )
		iconDisp->SetIcon( (HICON)icon );
}

BOOL CGraphicsDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	ulNewScreenMode = ulScreenMode;

	SetGraphicsDesc	();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CGraphicsDlg::SetFullMode( unsigned long ulModeMask )
{
	ulNewScreenMode &= ~DDRAW_FULL_RES_MASK;
	ulNewScreenMode |= ulModeMask | DDRAW_FULL;
	SetGraphicsDesc	();
}

void CGraphicsDlg::OnMode320x200Clip() 
{
	CWarnDlg	Warning;

	if( !(ulDontShowFlags & DONT_SHOW_MENU_WARN) )
	{
		char	message[LOADSTRING_STRING_SIZE];
		LoadString( NULL, IDS_WARNING_NO_MENU, message, LOADSTRING_STRING_SIZE );
		Warning.csWarnText = message;
		Warning.iWarnBit = DONT_SHOW_MENU_WARN;
		Warning.DoModal();
	}

	SetFullMode( DDRAW_320_200 );
}


void CGraphicsDlg::OnMode320x240Partclip() 
{
	SetFullMode( DDRAW_320_240 );
}

void CGraphicsDlg::OnMODE640x400CLIP() 
{
	CWarnDlg	Warning;

	if( !(ulDontShowFlags & DONT_SHOW_MENU_WARN) )
	{
		char	message[LOADSTRING_STRING_SIZE];
		LoadString( NULL, IDS_WARNING_NO_MENU, message, LOADSTRING_STRING_SIZE );
		Warning.csWarnText = message;
		Warning.iWarnBit = DONT_SHOW_MENU_WARN;
		Warning.DoModal();
	}

	SetFullMode( DDRAW_640_400 );
}

void CGraphicsDlg::OnMode512x384() 
{
	SetFullMode( DDRAW_512_384 );
}

void CGraphicsDlg::OnMode640x480Partclip() 
{
	SetFullMode( DDRAW_640_480 );
}

void CGraphicsDlg::OnMode800x600() 
{
	SetFullMode( DDRAW_800_600 );
}

void CGraphicsDlg::OnMode1024x768() 
{
	SetFullMode( DDRAW_1024_768 );
}

void CGraphicsDlg::On384x240Windowed() 
{
	ulNewScreenMode &= ~WIND_RES_MASK;
	ulNewScreenMode &= ~DDRAW_FULL;
	ulNewScreenMode |= WINDOWED_NORMAL;	
	SetGraphicsDesc ();
}

void CGraphicsDlg::On768x480WINDOWED() 
{
	int result = IDOK;

	if( !(ulDontShowFlags & DONT_SHOW_GRAPHICS_WARN ) )
	{
		CWarnDlg	Warning;
		char	message[LOADSTRING_STRING_SIZE];

		LoadString( NULL, IDS_WARNING_GRAPHICS_WINDOW, message, LOADSTRING_STRING_SIZE );
		Warning.csWarnText = message;
		Warning.iWarnBit = DONT_SHOW_GRAPHICS_WARN;
		result = Warning.DoModal();
	}

	if( result == IDOK )
	{
		ulNewScreenMode &= ~WIND_RES_MASK;
		ulNewScreenMode &= ~DDRAW_FULL;
		ulNewScreenMode |= WINDOWED_STRETCH;	
	}
	SetGraphicsDesc ();
}

void CGraphicsDlg::OnNodirectdraw() 
{
	CButton *cbButton = (CButton *)GetDlgItem( IDC_NODIRECTDRAW );
	ASSERT( cbButton );

	if( cbButton->GetCheck() )
	{
		ulNewScreenMode &= ~DDRAW_WIND;
		ulNewScreenMode |= DDRAW_NONE;
	}
	else
	{
		ulNewScreenMode &= ~DDRAW_NONE;
		ulNewScreenMode |= DDRAW_WIND;
	}
	SetGraphicsDesc ();
}

void CGraphicsDlg::OnForceVsync() 
{
	CButton *cbButton = (CButton *)GetDlgItem( IDC_FORCE_VSYNC );
	ASSERT( cbButton );

	if( cbButton->GetCheck() )
		ulNewScreenMode |= DDRAW_DDBLT_WAIT;
	else
		ulNewScreenMode &= ~DDRAW_DDBLT_WAIT;
	SetGraphicsDesc();
}

void CGraphicsDlg::OnOK() 
{
	CDialog::OnOK();

	if( ulNewScreenMode != ulScreenMode )
	{
		ULONG	savedmode = ulScreenMode;

		ulScreenMode = ulNewScreenMode;
		if( !Init_Graphics() )
		{
			ulScreenMode = savedmode;
			Init_Graphics();
		}
		WriteRegDWORD( NULL, REG_DDRAW_MODE, ulScreenMode );
	}
}


void CGraphicsDlg::OnLocalmem() 
{
	CButton *cbButton = (CButton *)GetDlgItem( IDC_LOCALMEM );
	ASSERT( cbButton );

	if( cbButton->GetCheck() )
		ulNewScreenMode |= DDRAW_USE_LOCALMEM;
	else
		ulNewScreenMode &= ~DDRAW_USE_LOCALMEM;

	SetGraphicsDesc ();
}

void CGraphicsDlg::OnShowScanlines() 
{
	CButton *cbButton = (CButton *)GetDlgItem( IDC_SHOW_SCANLINES );
	ASSERT( cbButton );

	if( cbButton->GetCheck() )
		ulNewScreenMode |= SHOW_SCANLINES;
	else
		ulNewScreenMode &= ~SHOW_SCANLINES;

	SetGraphicsDesc ();
}
