#include "GameWindow.h"
#include "ScoreDisplay.h"

#include <qlayout.h>
#include <qvbox.h>
#include <qwidget.h>
#include <qmenubar.h>
#include <qpopupmenu.h>
#include <qapplication.h>
#include <qlcdnumber.h>
#include <qlabel.h>
#include <qmessagebox.h>


#include "Board.h"
#include "Player.h"
#include "TileBank.h"

#include <iostream>
using std::cout;

GameWindow::GameWindow(QWidget* parent, const char*name) :QWidget(parent, name)
{

	setMinimumSize(400, 400);
	setMaximumSize(800, 900);
	resize(400,400);

	setCaption("Scrabble v .02" );

	// the grid used to organize all widgets inside
	QGridLayout* grid = new QGridLayout(this, 2, 2, 1);
	grid->setColStretch(0, 10);
	grid->setRowStretch(0, 10);

	//the game menu
	QPopupMenu* GameMenu = new QPopupMenu(this);
	CHECK_PTR( GameMenu );
	GameMenu->insertItem( "&New Game", this, SLOT(newGame()), CTRL+Key_N );
	GameMenu->insertSeparator();
	GameMenu->insertItem( "&Quit", qApp, SLOT(quit()), CTRL+Key_Q );

	//help menu
	QPopupMenu* HelpMenu = new QPopupMenu(this);
	CHECK_PTR( HelpMenu );
	HelpMenu->insertItem( "&Instructions", this, SLOT(helpScreen()), Key_F1 );

	//the bar that actually holds the menus
	menu = new QMenuBar(this);
	CHECK_PTR(menu);
	menu->insertItem( "&Game", GameMenu);
	menu->insertItem( "&Help", HelpMenu);
	grid->setMenuBar( menu );

	//make all the game parts here////////////
	GBoard = new Board(this, "gameboard");
	grid->addWidget( GBoard, 0, 0, Qt::AlignLeft);

	Human = new Player(this, "human");
	grid->addWidget( Human, 1, 0);

	QBoxLayout* rightbox = new QVBoxLayout;
	grid->addLayout( rightbox, 0, 1);

	NextTurn = new QPushButton("&Next Turn", this);
	rightbox->addWidget( NextTurn, Qt::AlignTop);
	NextTurn->setFixedWidth(70);

	humanScore = new ScoreDisplay("Human Player", this, "human score");
	humanScore->setMinimumSize(60,60);
	computerScore = new ScoreDisplay("Computer Player", this, "comp score");
	computerScore->setMinimumSize(60,60);
	rightbox->addWidget( humanScore );
	rightbox->addWidget( computerScore );

	TileBag = new TileBank;

	///////////////////////////////////////////////////////////////////////////

	//*************************************************************************************
	// these are the connects that determine program flow
	//*************************************************************************************
	connect( NextTurn, SIGNAL(clicked()), GBoard, SLOT(newTurn()) );
	connect( GBoard, SIGNAL(boardChanged()), Human, SLOT( updateHand()));
	connect( GBoard, SIGNAL(resetHand()), Human, SLOT(resetHand()));
	connect( Human, SIGNAL(tileClicked(const Tile*)), GBoard, SLOT(setRegister(const Tile*)));
	connect( GBoard, SIGNAL(humanScoreChanged(int)), humanScore, SLOT(display(int)) );
	connect( GBoard, SIGNAL(humanScoreChanged(int)), SLOT(redealPlayer(int)) );
	connect( GBoard, SIGNAL(computerScoreChanged(int)), computerScore, SLOT(display(int)));
	connect( GBoard, SIGNAL(computerScoreChanged(int)), SLOT(redealComputer(int)) );
	connect( GBoard, SIGNAL(gameOver()), SLOT(endGame()) );

	//*************************************************************************************
	
	//the numbers don't mean anything, cuz this is kindof a cheap trick
	//when a score is changed, it emits a single that gives an int
	//at this point we want to redeal, so instead of going through the trouble
	//of making the ScoreChanged(int) and redealPlayer() match arguments as is
	//required by signal/slot
	redealPlayer(666);
	redealComputer(666);

	Human->setFocus();


}

void GameWindow::newGame()
{
	cout << "beginning of new game\n";
	GBoard->eraseBoard();

	TileBag->reset();

	cout << "erase hand...\n";
	Human->eraseHand();
	GBoard->deleteComputerHand();

	cout << "dealing hand...\n";
	redealPlayer(69);
	redealComputer(96);


}


void GameWindow::redealPlayer(int whocares)
{

	connect( TileBag, SIGNAL(returnTile(int)), Human, SLOT( getTile(int)));

	Human->newHand();

	while ( Human->tilesNeeded()>0 && TileBag->TilesLeft()>0 )
		TileBag->dealTile();

	disconnect( TileBag, SIGNAL(returnTile(int)), Human, SLOT(getTile(int)) );

	if ( (Human->tilesNeeded() == 7 || GBoard->CompTilesInHand() == 0) 
		&& TileBag->isEmpty())
		endGame();

}

void GameWindow::redealComputer(int doesntmatter)
{

	connect( TileBag, SIGNAL(returnTile(int)), GBoard, SLOT(getComputerTile(int)) );

	int CompHandSize=5;

	while ( GBoard->CompTilesInHand()<CompHandSize && TileBag->TilesLeft()>0 )
		TileBag->dealTile();

	disconnect( TileBag, SIGNAL(returnTile(int)), GBoard, SLOT(getComputerTile(int)) );

}


void GameWindow::endGame()
{
	qWarning("Game Over!?!?!");

	computerScore->display( computerScore->intValue() - GBoard->computerHandValue() );
	humanScore->display( humanScore->intValue() - Human->handValue() );

	if (humanScore->intValue() > computerScore->intValue())
		QMessageBox::information( this, "Scrabble",
        "Congratulations!!!!\n"
        "You beat the computer!" );



	else if (humanScore->intValue() < computerScore->intValue())
		QMessageBox::information( this, "Scrabble",
        "So Sorry!!!!"
        "You lost to the computer!" );

	else
		QMessageBox::information( this, "Scrabble",
        "What the heck!?"
        "You tied!" );

	newGame();
}


void GameWindow::helpScreen()
{

	QWidget * popup = new QWidget;
	QLabel* message = new QLabel(popup);
	message->resize(700,300);

	QString s="How To Play Scrabble: \n";
	s += "Left-Mouse Click on the tile to play. The selected tile will be grayed out.\n";
	s+=	"Left-Mouse Click on a spot on the board to place the tile there. \n";
	s+="Once all tiles for that turn are on the board, left-mouse click on the next turn button.\n\n";
	
	s+="If the word is valid, the word value is added to the player score, and the computer's turn begins. \n";
	s+="If the word is not valid, the tiles that were played are cleared from the board and the tiles are returned to the hand.\n";
	s+="After the computer takes a turn, the score is computed, new tiles are given to replace used tiles.\n\n";

	s+="Play continues until one of the following occurs: \n";
	s+="\t 1. Both the player and computer pass on consecutive turns. \n";
	s+="\t 2. All tiles have been played.\n";
	s+="If the player has a higher score then the computer, the player wins.\n\n";
	
	s+="Keyboard shortcuts: \n";
	s+="F1 - Access this help screen. \n";
	s+="Alt-N - Next Turn.\n";
	s+="Ctrl-N - Start a new game. \n";
	s+="Crtl-Q - Quit current game and exit. \n";
	s+="Tiles can be switched around within a player's hand by holding down ctrl and clicking on 2 different tiles \n";


	popup->setPalette(QPalette(QColor(250,250,200)));
	message->setText(s);
	popup->setFixedSize(575,300);
	popup->show();
}