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

                                 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 "../PieceType.h"
#include "../Board.h"
#include "../ChessV.h"
#include "../GUI/Brush.h"
#include "../GUI/Pen.h"
#include "BoardWithHangingSquares.h"


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


BoardWithHangingSquares::BoardWithHangingSquares
	( int ranks, 
	  int files ):
		Board(ranks, files)
{
	pHangingSquares = new HangingSquare[MAX_HANGING_SQUARES];
	nHangingSquares = 0;
}

BoardWithHangingSquares::~BoardWithHangingSquares()
{
	delete[] pHangingSquares;
}

void BoardWithHangingSquares::AddHangingSquare
	( int rank, 
	  int file )
{
	int newSquareNumber = nSquares;
	HangingSquare &square = pHangingSquares[nHangingSquares];
	square.rank = rank;
	square.file = file;
	int directionNumber;

	//	add this square, assuming for the moment that it is totally 
	//	isolated; we will attach it later
	for( directionNumber = 0; directionNumber < directionCount; directionNumber++ )
	{
		int *matrix = movementMatrix[directionNumber];
		for( int squareNumber = 0; squareNumber < nSquares; squareNumber++ )
			matrix[squareNumber] = -1;
	}

	//	in order to "attach" this hanging square, we need to step out in 
	//	each direction, and if we hit a square, add the appropriate 
	//	entries to the movement matrix-es.
	for( directionNumber = 0; directionNumber < directionCount; directionNumber++ )
	{
		Direction &direction = directions[directionNumber];
		int oppositeDirectionNumber = direction.GetOppositeDirectionNumber();

		int newFile = file + direction.GetFileDifference();
		int newRank = rank + direction.GetRankDifference();

		//	first, check to see if this "target square" is part of the 
		//	main part of the board
		if( newFile >= 0 && newFile < nFiles &&
			newRank >= 0 && newRank < nRanks )
		{
			int nSquare = newFile * nRanks + newRank;
			movementMatrix[directionNumber][newSquareNumber] = nSquare;
			movementMatrix[oppositeDirectionNumber][nSquare] = newSquareNumber;
		}
		else
		{
			//	ok, if the target square is not on the main board, make sure it's 
			//	not another hanging square; if it is, we need to hook it up 
			bool found = false;
			for( int x = 0; x < nHangingSquares && !found; x++ )
			{
				if( newFile == pHangingSquares[x].file &&
					newRank == pHangingSquares[x].rank )
				{
					int nSquare = nRanks * nFiles + x;
					movementMatrix[directionNumber][newSquareNumber] = nSquare;
					movementMatrix[oppositeDirectionNumber][nSquare] = newSquareNumber;
					found = true;
				}
			}
		}
	}
	nSquares++;
	nHangingSquares++;
}

void BoardWithHangingSquares::DrawBoard( HWND hwnd, HDC hdc, LPPAINTSTRUCT ps )
{
	Board::DrawBoard( hwnd, hdc, ps );

	Brush lightSquareBrush( squareColor1 );
	Brush darkSquareBrush( squareColor2 );
	Brush hilightedSquareBrush( RGB(0, 204, 0) );
	Brush captureSquareBrush( RGB(255, 0, 0) );
	RECT rect;
	int topMargin    = 50;
	int leftMargin   = 20;
	if( theBoard->GetNumberOfFiles() < 8 )
		leftMargin += 54;

	Pen blackPen;
	if( boardDisplayType == BOARD_IS_UNCHECKERED )
	{
		blackPen.CreateSolidPen( RGB(0, 0, 0) );
		::SelectObject( hdc, blackPen );
	}

	int totalHeightOfSquares = theBoard->GetNumberOfRanks() * squareHeight;

	Piece *liftedPiece = theBoard->GetPieceBeingLifted();

	for( int x = 0; x < nHangingSquares; x++ )
	{
		HangingSquare &hangingSquare = pHangingSquares[x];
		int rank = hangingSquare.rank;
		int file = hangingSquare.file;
		::SelectObject( hdc, (rank + file) % 2 == 1 || boardDisplayType == BOARD_IS_UNCHECKERED ? lightSquareBrush : darkSquareBrush );
		rect.left = leftMargin + borderWidth + file * squareWidth;
		rect.top = topMargin + borderWidth + totalHeightOfSquares - ((rank + 1) * squareHeight);
		rect.right = rect.left + squareWidth + 1;
		rect.bottom = rect.top + squareHeight + 1;
		::Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );
	}

/*			//	DRAW PIECE
			Piece *piece = NULL;
			for( int player = 0; player < 2; player++ )
			{
				for( int x = 0; x < nPieces[player]; x++ )
				{
					if( !pieces[player][x]->IsReallyCaptured() &&
						 pieces[player][x]->GetRealSquareNumber() == squareNumber )
						 piece = pieces[player][x];
				}
			}
			if( piece != NULL && piece != liftedPiece )
			{
				HBITMAP hBitmap = piece->GetBitmap();
				if( hBitmap != NULL )
				{
					DrawTransparentBitmap( hdc, hBitmap, (short) rect.left, (short) rect.top, RGB(0, 255, 0), true,
						piece->GetPlayerNumber() == 0 ? RGB(255, 255, 255) : RGB(255, 0, 0), 
						piece->GetPlayerNumber() == 0 ? pieceColor1 : pieceColor2 );
				}
			}

	if( liftedPiece != NULL )
	{
		HBITMAP hBitmap = liftedPiece->GetBitmap();
		DrawTransparentBitmap( hdc, hBitmap, mouseX, mouseY, RGB(0, 255, 0), false,
			liftedPiece->GetPlayerNumber() == 0 ? RGB(255, 255, 255) : RGB(255, 0, 0), 
			liftedPiece->GetPlayerNumber() == 0 ? pieceColor1 : pieceColor2, false, true );
	}*/
}
