#include "Player.h"
#include "Tile.h"
#include <vector>
#include <qlayout.h>
#include "qevent.h"
#include <iostream>
#include <cassert>

using std::cout;
using std::cin;

using std::vector;



Player::Player(QWidget* parent, const char* name) : QWidget(parent, name)
{
	//grid used to orgranize tiles
	grid = new QGridLayout(this, 1, 7, 4);

	DisabledTile=-1, SwapTiles=false;
		//set intial values

	//intialize emptypositions, all positions are empty
	for (int i=6; i>=0; i--)
		EmptyPositions.push_back(i);

	//set InHandsize
	InHand.resize(MAX_HUMHAND);

	//set minimumsize of player's hand displayed on screen
	setMinimumSize(210, 60);

}

Player::~Player()
{
	for (int i=0 ; i<InHand.size() ; i++)
		delete InHand[i];
	
	InHand.clear();
}

void Player::getTile(int i)
{
	if (EmptyPositions.empty())
		return;			// need free space!

	qWarning("Adding Tile");

	//make a new tile from int i, and add it to the grid at the proper spot
	Tile* NewTile = new Tile(i, this);
	grid->addWidget( NewTile, 0, EmptyPositions.back() );
	NewTile->setFixedSize(45, 45);
	NewTile->show();
	/////////////////////////////////////////////////////////////////////////

	connect( NewTile, SIGNAL(clicked()), SLOT(tileClickEvent()) );
		//connect the new tile to the player's clickEvent handler

	//add the tile to the hand in right spot
	InHand.insert(EmptyPositions.back(), NewTile);
	EmptyPositions.pop_back();
}


//***************************************************************************
//	activated when board is changed, -1 signals to player to move on to next
//	tile, as the current one was put on the board
//********************************************************************************/
void Player::updateHand()
{
	DisabledTile=-1;
}

//********************************************************************************/
//	handles all logic when clicking on a tile in the players hand
//	it finds the tile clicked and disabled it, reenabling the old disabled tile
//	unless disabledtile=-1, then sets this new tile to disabled tile
//********************************************************************************/
void Player::tileClickEvent()
{

	//find the tile that was clicked
	int pos = InHand.findRef( (Tile*)sender() ); //who sent the clicked signal?
	Tile* pTile = InHand[pos];
	pTile->setEnabled( false );
		//disable it


	if (SwapTiles)	//if holding ctrl, then swap tile with the disabled tile
	{
		SwapTileAt(pos);
		return;
	}

	//send tileClicked signal so board knows which tile to play
	emit tileClicked(pTile);
	
	cout << "clicked tile at position: " << pos
		 << "\nHand size: " << InHand.size() << "\n";

	//setting DisabledTile=-1 in updateHand() makes this part skip, thus
	//the tile that was placed on the board stays disabled
	if (DisabledTile!=-1)
		InHand[DisabledTile]->setEnabled( true );

	//the tile just clicked is now the DisabledTile
	DisabledTile=pos;

}

//********************************************************************************/
//	resets hand to the state it was in at beginning of turn, i.e. all disabled tiles
// are reenabled
//********************************************************************************/
void Player::resetHand()
{
	DisabledTile=-1;

	if (InHand.isEmpty())
		return;

	for (int i=0 ; i<InHand.size() ; i++)
	{
		if (InHand[i] != 0)
			InHand[i]->setEnabled(true);
	}

}

//********************************************************************************/
//	deletes old tiles to make room for new dealt tiles
//********************************************************************************/
void Player::newHand()
{
	//if this is not -1, that means updateHand wasn't called and the board wasn't
	//clicked after clicking on a player tile, therefore isn't on board, and
	//shouldn't be deleted
	if (DisabledTile!=-1)	
		InHand[DisabledTile]->setEnabled(true);

	for (int i=0 ; i<7 ; i++)
	{
		if (InHand[i]!=0)
		if (!InHand[i]->isEnabled())
		{	delete InHand[i];
			InHand.insert(i,0);
			EmptyPositions.push_back(i);
		}

	}

}

//********************************************************************************/
//	returns number of empty tiles, eg tiles needed for a full hand
//********************************************************************************/
int Player::tilesNeeded()
{
	cout << "empty tiles: " <<// InHand.contains(0) << "\n";
		EmptyPositions.size();
	//return InHand.contains(0);
	return EmptyPositions.size();
}


//********************************************************************************/
//	erases entire hand, for use in newGame()
//********************************************************************************/
void Player::eraseHand()
{

	DisabledTile=-1;

	for (int i=6; i>=0; i--)
	{
		EmptyPositions.push_back(i);
		delete InHand[i];
		InHand.insert(i,0);
	}

}

//********************************************************************************/
//	simply set swaptiles=true when ctrl key is held down, so tileClickEvent knows when to
//	start swapping tiles
//********************************************************************************/
void Player::keyPressEvent(QKeyEvent* Event)
{
	if (Event->key() != Key_Control )
	{
		Event->ignore();
		return;
	}
	cout << "key is pressed!\n\n";

	SwapTiles=true;

}

//********************************************************************************/
//	sets it back to false when ctrl key is released
//********************************************************************************/
void Player::keyReleaseEvent(QKeyEvent* Event)
{
	if (Event->key() != Key_Control)
	{
		Event->ignore();
		return;
	}

	
	SwapTiles=false;
}


//********************************************************************************/
// private function used to swap tile at pos with tile at disabledTile
//********************************************************************************/
void Player::SwapTileAt(int pos)
{

	//if there is no previously disabledTile, then can't swap
	if (DisabledTile == -1)
	{
		DisabledTile=pos;
		return;
	}

	cout << "Swapping tile at " << pos << " with tile at " << DisabledTile;

	// temp tile pointers, used in swap
	Tile* temp1 = new Tile(InHand[pos]->letterID(), this);
	Tile* temp2 = new Tile(InHand[DisabledTile]->letterID(), this);

	//delete old tiles at those positions and insert the temp copies
	delete InHand[pos];
	grid->addWidget( temp2, 0, pos );
	temp2->setEnabled(true);
	temp2->show();
	delete InHand[DisabledTile];
	grid->addWidget( temp1, 0, DisabledTile );
	temp1->show();
	///////////////////////////////////////////////////////////////////

	//connect the new tiles to player's tileClickEvent
	connect(temp1, SIGNAL(clicked()), SLOT(tileClickEvent()) );
	connect(temp2, SIGNAL(clicked()), SLOT(tileClickEvent()) );

	//put the tiles in the players hand in correct spot
	InHand.insert(DisabledTile, temp1);
	InHand.insert(pos, temp2);

	DisabledTile=-1;
		//no more disabledtile at the moment

	emit tileClicked(0);
		//make sure that objects outside think nothing was clicked
}

//********************************************************************************/
//	returns total value of tiles in hand
//********************************************************************************/
int Player::handValue() const
{
	int handValue=0;
	for (int i=InHand.size()-1; i>=0; i--)
		if (InHand[i]!=0)
			handValue+=InHand[i]->value();

	return handValue;
}