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

                                 ChessV

                   COPYRIGHT (C) 2007 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

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


#ifndef FILE__CHESSV_H
#define FILE__CHESSV_H


#include "resource.h"
#include "MovementCapability.h"
#include "PieceType.h"
#include "Piece.h"
#include "Drop.h"
#include "Pickup.h"
#include "Player.h"
#include "Board.h"
#include "Game.h"
#include "MovementList.h"
#include "StructureVector.h"


struct GameInformation
{
	char *name;
	char *baseGameName;
	void (*startGameFunction)();
	Game *(*createGameFunction)( Board &brd, Player &plr0, Player &plr1 );
	int rank_count;
	int file_count;
	int square_count;
	char *year_of_invention;
	char *inventor;
	char *filename;
	char *player0Name;
	char *player1Name;
	WORD dialogResourceID;
};


typedef StructureVector<GameInformation> GameInformationVector;

extern GameInformation adHocGameInformation;

#define FN_ARG_TYPE__INTEGER    1
#define FN_ARG_TYPE__BOOLEAN    2
#define FN_ARG_TYPE__STRING     3

struct FunctionDecl
{
	char *name;
	int nArgs;
	int argType[6];
	void *pFunction;
	int priority;
};

struct FunctionCall
{
	FunctionDecl *pFunctionDecl;
	union
	{
		char *stringArg;
		int integerArg;
		bool booleanArg;
	} args[6];
};

extern int nFunctionCalls;
extern FunctionCall functionCalls[];

void QueueRemovePieceTypeFunctionCall
	( char *pieceName );

void QueueAddPieceTypeFunctionCall
	( char *pieceName );

#define ONE_PLY		 60
#define TWO_PLY		120
#define THREE_PLY	180
#define FOUR_PLY	240

#define INTERNAL_CHESS_VARIANT(variant_name, variant_class_name, rank_count, file_count, square_count, invented, inventor, player0, player1, dialogResID )   \
	{ variant_name, NULL, NULL, Create##variant_class_name, rank_count, file_count, square_count, invented, inventor, NULL, player0, player1, dialogResID  }

#define INTERNAL_CHESS_VARIANT2(variant_name, variant_class_name, rank_count, file_count, square_count, invented, inventor, player0, player1, dialogResID )   \
	{ variant_name, NULL, Start##variant_class_name, Create##variant_class_name, rank_count, file_count, square_count, invented, inventor, NULL, player0, player1, dialogResID  }

#define END_INTERNAL_VARIANT_LIST  \
	{ NULL, NULL, 0, 0, 0, NULL, NULL, NULL, NULL, 0 }

//	board appearance types
#define BOARD_IS_CHECKERED          1
#define BOARD_IS_UNCHECKERED        2
#define BOARD_IS_THREE_COLORED      3

//	helper functions
bool stringCompNoCase( const char *, const char * );

//	static start game functions
void GenericStartGameFunction( GameInformation *game );
void StartCylindricalChessGame();
void StartChessGame();
void StartDiamondChessGame();
void StartSwitchingChessGame();
void StartPolymorphChessGame();
void StartEurasianChessGame();
void StartShatranjKamilGame();
void StartGreatShatranjGame();
void StartCWAKGame();
void StartCWDAGame();
void StartCWUPGame();


//	static create game functions
Game *CreateChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCapablancaGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateLosAlamosGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateAlapoGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateExtinctionChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateBerolinaChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateSpartanChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateDiamondChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateKingletGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateThreeChecksChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCylindricalChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateShatranjKamilGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateGreatShatranjGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateModernShatranjGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateLemurianShatranjGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateShatranjKamil64Game( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCourierChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateGame_12x8( Board &brd, Player &plr0, Player &plr1 );
Game *CreateArchchessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateSwitchingChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreatePolymorphChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateDecimalChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCitadelChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateGrandChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateLionsAndUnicornsGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateJanusChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateAngelsAndDevilsGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCWAKGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCWDAGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateEnepGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateCWUPGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateUltimaGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateGrotesqueChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateGreatShatranjDGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateEurasianChessGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateOdinsRuneGame( Board &brd, Player &plr0, Player &plr1 );
Game *CreateXiangQiGame( Board &brd, Player &plr0, Player &plr1 );

void LoadGame( char *filename = NULL );
void SaveGame();


LRESULT CALLBACK About
	( HWND hDlg, 
	  UINT message, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK PiecePropertiesWndProc
	( HWND hWnd, 
	  UINT message, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK MoveSelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK CompMoveSelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK GameSelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK NewGameSelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK ComputerSettingsDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK BoardOptionsDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK FRC_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK CWDA_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK CWAK_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK CWUP_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Chess_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Chess256_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Generic_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Generic_SelectSubDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Capablanca_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK Shatranj_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK GreatShatranj_SelectDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK SaveNewVariantDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

LRESULT CALLBACK PositionTestingDlgProc
	( HWND hWndDlg, 
	  UINT Msg, 
	  WPARAM wParam, 
	  LPARAM lParam );

void LoadSquareTextureBitmaps( int squares, int texture );
void LoadSquareTextureBitmaps( int squares, char *textureName );
void UnloadSquareTextureBitmaps( int squares );

void CreatePlayers
	( char *player0Name, 
	  char *player1Name, 
	  bool player0ComputerControlled, 
	  bool player1ComputerControlled );

void DrawTransparentBitmap
	( HDC hdc, 
	  HBITMAP hBitmap, 
	  short xStart,
	  short yStart, 
	  COLORREF cTransparentColor,
	  bool centerInSquare,
	  COLORREF colorToReplace, 
	  COLORREF replacementColor,
	  bool doubleSize = false,
	  bool centerOnCursor = false );

int GetSecondsElapsed
	( const SYSTEMTIME *pTime1, 
	  const SYSTEMTIME *pTime2 );

int CallFunctions
	( int GEPriority,			//	functions with priority greater-than-or-equal-to this
	  int LTPriority, 			//	and with priority less-than this
	  Game *pGame,				//	pointer to the Game object
	  Board *pBoard );			//	pointer to the Board object


// *** GLOBALS *** //

extern bool mouseCaptured;
extern int mouseX;
extern int mouseY;
extern int destinationSquare;
extern char gameSelection[];
extern char newVariantName[];
extern GameInformation *selectedVariant;
extern bool whiteComp;
extern bool blackComp;
extern bool rotateBoard;
extern int maxThinkTime;
extern int maxIDepth;
extern bool interactiveComputer;
extern bool useOpeningBook;
extern bool refreshCausedByBookkeeping;
extern MoveInfo **allowableMoves;
extern int *allowableMoveIndexes;
extern int allowableMoveCount;
extern int squareTexture1;
extern int squareTexture2;
extern int squareTexture3;
extern HBITMAP *squareTextureBitmaps[3];
extern COLORREF squareColor1;
extern COLORREF squareColor2;
extern COLORREF squareColor3;
extern COLORREF borderColor;
extern COLORREF pieceColor1;
extern COLORREF pieceColor2;
extern bool gameSpecificBoardDisplay;
extern char *gameSpecificBoardDisplayDescription;
extern char *textures[];
extern char *textureDirectories[];
extern int nTextures;
extern int boardDisplayType;
extern char *pieceSets[];
extern int pieceSetSizes[];
extern int nPieceSets;
extern int selectedPieceSet;
extern COLORREF *colorBeingSelected;
extern int textureBeingSelected;
extern HKEY hVariantKey;
extern HWND hMoveList;
extern HWND hThinkingList;
extern int extraCaptureSquares[];
extern int extraCaptures;
extern GameInformation supportedVariants[];
extern GameInformationVector includedVariants;
extern int nSupportedVariants;
extern int nIncludedVariants;
extern int transpositionTableSize;
extern int evaluationCacheSize;
extern bool loadingGame;
extern bool justLoaded;
extern bool testingPosition;
extern bool saveNewVariant;
extern int testingDepth;
extern int testingMaxMoves;
extern int spinner;
extern FILE *traceFile;
extern bool singular;
extern int singularMargin;
extern int maxThinkTime;
extern int minIDepth;
extern int maxIDepth;


#endif
