
/***************************************************************************

                                 ChessV

                   COPYRIGHT (C) 2005 BY GREGORY STRONG

This file is part of ChessV.  ChessV 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.

ChessV 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; the file 'COPYING' contains the License text, but if for
some reason you need a copy, please write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

****************************************************************************/


#include "StdAfx.h"
#include "ChessV.h"
#include "Resource.h"


// *** DEBUG MEMORY ALLOCATION *** //
#ifdef _DEBUG
#define new SAFE_NEW
#endif


LRESULT CALLBACK colorPickerDlgProc
	( HWND hdlg, 
	  UINT message, 
	  WPARAM wParam, 
	  LPARAM lparam );

static COLORREF newSquareColor1;
static COLORREF newSquareColor2;
static COLORREF newSquareColor3;
static COLORREF newBorderColor;
static COLORREF newPieceColor1;
static COLORREF newPieceColor2;

COLORREF *colorBeingSelected;
int textureBeingSelected;

LRESULT CALLBACK BoardOptionsDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam )
{
	HDC hdc;
	RECT rc;
	HBRUSH hbrush;
	HBITMAP hbitmap;
	DRAWITEMSTRUCT *pdis;

	static int nPieceTypes = 0;
	static PieceType **pieceTypes = NULL;
	int pieceSetIndex = 0;
	int selectedIndex = 0;

	switch( Msg )
	{
	  case WM_INITDIALOG:
		::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_ADDSTRING, 0, (LPARAM) "Checkered" );
		::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_ADDSTRING, 0, (LPARAM) "Uncheckered" );
		::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_ADDSTRING, 0, (LPARAM) "3-Color Knightrider" );
		if( boardDisplayType == BOARD_IS_CHECKERED )
			::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0 );
		else if( boardDisplayType == BOARD_IS_UNCHECKERED )
			::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_SETCURSEL, (WPARAM) 1, (LPARAM) 0 );
		else if( boardDisplayType == BOARD_IS_THREE_COLORED )
			::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_SETCURSEL, (WPARAM) 2, (LPARAM) 0 );
		if( gameSpecificBoardDisplayDescription == NULL )
			::ShowWindow( ::GetDlgItem( hWndDlg, IDC_CUSTOM_DISPLAY_CHECK ), SW_HIDE );
		else
		{
			::SetWindowText( ::GetDlgItem( hWndDlg, IDC_CUSTOM_DISPLAY_CHECK ), gameSpecificBoardDisplayDescription );
			::SendDlgItemMessage( hWndDlg, IDC_CUSTOM_DISPLAY_CHECK, BM_SETCHECK, gameSpecificBoardDisplay, 0 );
		}
		newSquareColor1 = squareColor1;
		newSquareColor2 = squareColor2;
		newSquareColor3 = squareColor3;
		newBorderColor = borderColor;
		newPieceColor1 = pieceColor1;
		newPieceColor2 = pieceColor2;

		pieceTypes = theGame->GetPieceTypesRequired( nPieceTypes );
		for( int x = 0; x < nPieceSets; x++ )
		{
			bool supported = true;
			for( int y = 0; y < nPieceTypes; y++ )
				if( !pieceTypes[y]->DoesSupportPieceSet( x ) )
					supported = false;
			if( supported )
			{
				::SendDlgItemMessage( hWndDlg, IDC_PIECE_SET_LIST, LB_ADDSTRING, pieceSetIndex, (LPARAM) pieceSets[x] );
				::SendDlgItemMessage( hWndDlg, IDC_PIECE_SET_LIST, LB_SETITEMDATA, pieceSetIndex, (LPARAM) x );
				if( x == selectedPieceSet )
					::SendDlgItemMessage( hWndDlg, IDC_PIECE_SET_LIST, LB_SETCURSEL, pieceSetIndex, (LPARAM) 0 );
				pieceSetIndex++;
			}
		}

		return TRUE;

	  case WM_DRAWITEM:
		hbitmap = NULL;
		pdis = (DRAWITEMSTRUCT *) lParam;
		hdc = pdis->hDC;
		rc = pdis->rcItem;

		//	NULL object?
		if( pdis->itemData == -1 ) 
			return 0;

		if( pdis->CtlID == IDC_LIGHT_COLOR_STATIC )
		{
			if( squareTextureBitmaps[0] != NULL )
				hbitmap = squareTextureBitmaps[0][0];
			else
				hbrush = ::CreateSolidBrush( newSquareColor1 );
		}
		else if( pdis->CtlID == IDC_DARK_COLOR_STATIC )
		{
			if( squareTextureBitmaps[1] != NULL )
				hbitmap = squareTextureBitmaps[1][0];
			else
				hbrush = ::CreateSolidBrush( newSquareColor2 );
		}
		else if( pdis->CtlID == IDC_THIRD_COLOR_STATIC )
		{
			if( squareTextureBitmaps[2] != NULL )
				hbitmap = squareTextureBitmaps[2][0];
			else
				hbrush = ::CreateSolidBrush( newSquareColor3 );
		}
		else if( pdis->CtlID == IDC_BORDER_COLOR_STATIC )
			hbrush = ::CreateSolidBrush( newBorderColor );
		else if( pdis->CtlID == IDC_PIECE_COLOR1_STATIC )
			hbrush = ::CreateSolidBrush( newPieceColor1 );
		else if( pdis->CtlID == IDC_PIECE_COLOR2_STATIC )
			hbrush = ::CreateSolidBrush( newPieceColor2 );
		rc = pdis->rcItem;
		if( hbitmap == NULL )
		{
			::FillRect( hdc, &rc, hbrush );
			::DeleteObject( hbrush );
		}
		else
		{
			HDC hMemDC = ::CreateCompatibleDC( pdis->hDC ); 
			::SelectObject( hMemDC, hbitmap );
			::BitBlt( pdis->hDC, 0, 0, pdis->rcItem.right, pdis->rcItem.bottom, hMemDC, 0, 0, SRCCOPY );
			::DeleteDC( hMemDC );
		}
		break;

	  case WM_COMMAND:
		switch( wParam )
		{
		  case IDOK:
			//	update global UI variables
			squareColor1 = newSquareColor1;
			squareColor2 = newSquareColor2;
			squareColor3 = newSquareColor3;
			pieceColor1 = newPieceColor1;
			pieceColor2 = newPieceColor2;
			borderColor = newBorderColor;
			boardDisplayType = (int) ::SendDlgItemMessage( hWndDlg, IDC_BOARD_TYPE_COMBO, CB_GETCURSEL, 0, (LPARAM) 0 ) + 1;
			selectedIndex = (int) ::SendDlgItemMessage( hWndDlg, IDC_PIECE_SET_LIST, LB_GETCURSEL, 0, (LPARAM) 0 );
			selectedPieceSet = (int) ::SendDlgItemMessage( hWndDlg, IDC_PIECE_SET_LIST, LB_GETITEMDATA, selectedIndex, (LPARAM) 0 );

			if( gameSpecificBoardDisplayDescription != NULL )
			{
				gameSpecificBoardDisplay = ::SendDlgItemMessage( hWndDlg, IDC_CUSTOM_DISPLAY_CHECK, BM_GETCHECK, 0, (LPARAM) 0 ) == BST_CHECKED;
			}

			//	update registry information
			if( squareTexture1 == -1 )
			{
				::RegSetValueEx( hVariantKey, "SquareColor1", 0, REG_DWORD, (BYTE *) &squareColor1, sizeof(DWORD) );
				::RegDeleteValue( hVariantKey, "SquareTexture1" );
			}
			else
				::RegSetValueEx( hVariantKey, "SquareTexture1", 0, REG_SZ, (BYTE *) textures[squareTexture1], (DWORD) strlen(textures[squareTexture1]) + 1 );
			if( squareTexture2 == -1 )
			{
				::RegSetValueEx( hVariantKey, "SquareColor2", 0, REG_DWORD, (BYTE *) &squareColor2, sizeof(DWORD) );
				::RegDeleteValue( hVariantKey, "SquareTexture2" );
			}
			else
				::RegSetValueEx( hVariantKey, "SquareTexture2", 0, REG_SZ, (BYTE *) textures[squareTexture2], (DWORD) strlen(textures[squareTexture2]) + 1 );
			if( squareTexture3 == -1 )
			{
				::RegSetValueEx( hVariantKey, "SquareColor3", 0, REG_DWORD, (BYTE *) &squareColor3, sizeof(DWORD) );
				::RegDeleteValue( hVariantKey, "SquareTexture3" );
			}
			else
				::RegSetValueEx( hVariantKey, "SquareTexture3", 0, REG_SZ, (BYTE *) textures[squareTexture3], (DWORD) strlen(textures[squareTexture3]) + 1 );
			::RegSetValueEx( hVariantKey, "PieceColor1", 0, REG_DWORD, (BYTE *) &pieceColor1, sizeof(DWORD) );
			::RegSetValueEx( hVariantKey, "PieceColor2", 0, REG_DWORD, (BYTE *) &pieceColor2, sizeof(DWORD) );
			::RegSetValueEx( hVariantKey, "BorderColor", 0, REG_DWORD, (BYTE *) &borderColor, sizeof(DWORD) );
			::RegSetValueEx( hVariantKey, "PieceSet", 0, REG_DWORD, (BYTE *) &selectedPieceSet, sizeof(DWORD) );
			::RegSetValueEx( hVariantKey, "BoardDisplayType", 0, REG_DWORD, (BYTE *) &boardDisplayType, sizeof(DWORD) );
			if( gameSpecificBoardDisplayDescription != NULL )
			{
				if( gameSpecificBoardDisplay )
					::RegSetValueEx( hVariantKey, "GameSpecificBoardDisplay", 0, REG_SZ, (BYTE *) "On", (DWORD) 3 );
				else
					::RegSetValueEx( hVariantKey, "GameSpecificBoardDisplay", 0, REG_SZ, (BYTE *) "Off", (DWORD) 4 );
			}

			theBoard->SetSquareWidth( pieceSetSizes[selectedPieceSet] );
			theBoard->SetSquareHeight( pieceSetSizes[selectedPieceSet] );
			for( int x = 0; x < nPieceTypes; x++ )
				pieceTypes[x]->LoadPieceSet( selectedPieceSet );
			::InvalidateRect( theWindow, NULL, true );
			::EndDialog( hWndDlg, IDOK );
			return TRUE;

		  case IDCANCEL:
			::EndDialog( hWndDlg, IDCANCEL );
			return TRUE;

		  case IDC_LIGHT_SQUARE_COLOR_BUTTON:
			colorBeingSelected = &newSquareColor1;
			if( ::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc ) == IDOK )
				if( textureBeingSelected >= 0 )
					LoadSquareTextureBitmaps( 0, textureBeingSelected );
				else
				{
					UnloadSquareTextureBitmaps( 0 );
					squareTexture1 = -1;
				}
			break;

		  case IDC_DARK_SQUARE_COLOR_BUTTON:
			colorBeingSelected = &newSquareColor2;
			if( ::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc ) == IDOK )
				if( textureBeingSelected >= 0 )
					LoadSquareTextureBitmaps( 1, textureBeingSelected );
				else
				{
					UnloadSquareTextureBitmaps( 1 );
					squareTexture2 = -1;
				}
			break;

		  case IDC_THIRD_SQUARE_COLOR_BUTTON:
			colorBeingSelected = &newSquareColor3;
			if( ::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc ) == IDOK )
				if( textureBeingSelected >= 0 )
					LoadSquareTextureBitmaps( 2, textureBeingSelected );
				else
				{
					UnloadSquareTextureBitmaps( 2 );
					squareTexture3 = -1;
				}
			break;

		  case IDC_BORDER_COLOR_BUTTON:
			colorBeingSelected = &newBorderColor;
			::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc );
			break;

		  case IDC_PIECE_COLOR1_BUTTON:
			colorBeingSelected = &newPieceColor1;
			::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc );
			break;

		  case IDC_PIECE_COLOR2_BUTTON:
			colorBeingSelected = &newPieceColor2;
			::DialogBox( theInstance, (LPCTSTR) IDD_COLOR_SELECT_DIALOG, hWndDlg, (DLGPROC) colorPickerDlgProc );
			break;
		}
		break;
	}

	return FALSE;
}
