/*
 *     This program 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.
 *
 *     This program 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.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef KPOKER_H
#define KPOKER_H

// QT includes
#include <qwidget.h>
#include <qgroupbox.h>
#include <qlist.h>

// KDE includes
#include <klocale.h>
#include <kaccel.h>
#include <krandomsequence.h>

typedef enum _cardtype { // I don't use this anymore. But it helps to understand the numbers :)
	        DECK=0,
	        CA=1,SA=2,HA=3,DA=4,
	        CK=5,SK=6,HK=7,DK=8,
	        CQ=9,SQ=10,HQ=11,DQ=12,
	        CJ=13,SJ=14,HJ=15,DJ=16,
	        CTEN=17,STEN=18,HTEN=19,DTEN=20,
	        CNINE=21,SNINE=22,HNINE=23,DNINE=24,
	        CEIGHT=25,SEIGHT=26,HEIGHT=27,DEIGHT=28,
	        CSEVEN=29,SSEVEN=30,HSEVEN=31,DSEVEN=32,
	        CSIX=33,SSIX=34,HSIX=35,DSIX=36,
	        CFIVE=37,SFIVE=38,HFIVE=39,DFIVE=40,
	        CFOUR=41,SFOUR=42,HFOUR=43,DFOUR=44,
	        CTHREE=45,STHREE=46,HTHREE=47,DTHREE=48,
	        CTWO=49,STWO=50,HTWO=51,DTWO=52
};

// QT classes
class QPushButton;
class QLineEdit;
class QLabel;
class QFrame;  
class QLineEdit;
class QFrame;

// KDE classes
class KAudio;

// own classes
class BetBox;
class CardWidget;
class OptionsDlg;
class NewGameDlg;
class Player;
class PlayerBox;

enum Status {statDraw=0, statBet, statContinueBet, statExchange, statRaise, statContinueRaise, statSee};


class kpok : public QWidget
{
	Q_OBJECT
public:
	kpok(QWidget * parent = 0, const char *name = 0);
	virtual ~kpok();
	
	int getCard(int cardNr);
	int getCash(int playerNr); 
	QString getName (int playerNr); 
	void paintCash();
	void setCard(int num, int value);

	int getPlayers() const			{ return player.count(); }
	Status getStatus() const		{ return status; }
	
	void setStatus(Status newStatus) 	{ status = newStatus; }

	void setBlinking (bool bl)		{ blinking = bl; }
	void setAdjust(bool ad);
	void setSound(bool s);
	
	void updateLHLabel();//tomporary function, only called once

signals:
	void changeLastHand(QString newHand, bool lastHand = true);
	void showClickToHold(bool show);

protected:
	void setSize(int players); // will resize the window depending on the number of players
	void readOptions();
	void drawCards(Player* p, bool skip[], bool done[]);
	void initSomeStuff(); // called only once 
	void newRound();
	void noMoney();
	void paintEvent( QPaintEvent * );	
	void playSound(const char *filename);
	void setBetButtonEnabled(bool enabled);
	void setHand(const QString& newHand, bool lastHand = true);
	void setLastWinner(const QString& lastWinner);
	void startBlinking();
	void stopBlinking();
	void result();
	void winner();
	
	void bet();

	void displayWin(const QString& hand, int cashWon);
	void displayWinner_Computer(Player* winner);
	
	void removePlayerFromRound(Player* removePlayer);
	void switchToOnePlayerRules();

	/**
	  * @return The human player if he is in the game
	 **/
	Player* findHumanPlayer();

	/**
	  * This method first reads the config file then starts @ref setNewGameOptions() if it wasn't forbidden in config
	  * 
	  * After all options and defaults were set the method starts @ref initPoker() with only the number of the players as an argument or with a complete player class, depending on the options the player chose
	  * @return True if successful false if player clicked 'cancel' in the new game dialog
	 **/
	bool readEntriesAndInitPoker();

	/**
	  * This should only be done in the see phase and shows the cards of the computer players
	 **/
	void showComputerCards();

	/**
	  * The main method for starting the game
	  *
	  * It constructs the players if only the number of players are given or uses an existing array
	  * Then all player boxes are being constructed as well as some smaller  things like the pot
	  * @param players the number of the players
	  * @param ownAllPlayers This is used if there is already an array of players existing e.g. from @ref readEntriesAndInitPoker()
	 **/
	void initPoker(int players, Player* ownAllPlayers = 0);

	/**
	  * Gives all players the deck as a card
	 **/
	void drawAllDecks();

	/**
	  * Used when there is a REAL draw, which means two players have exactly the same cards but different suites
	  * 
	  * @param suite The suite to be tested (see cardHelp[])
	  * @return Points for the suite:
	  * 1 for hearts
	  * 2 for spades
	  * 3 for diamonds
	  * 4 for clubs
	 **/
	int getSuitePoints(int suite);

public slots:
	bool initSound();

	/**
	  * Just as the name says: This method/slot saves the current game (to the config file)
	  *
	  * The game can be loaded on startup by activating the button 'read from config'
	 **/
	void saveGame();
	void commandCallback(int id);

protected slots:
	void newGame();
	
	void bTimerEvent();
	void drawCardsEvent();
	void drawClick();
	void frameClick(CardWidget *);
	void waveTimerEvent();

	void betChange(int);
	void adjustBet();
	void out();

	bool setNewGameOptions(bool hideReadingFromConfig = false);

	void startWave();
	void stopWave();

private:
	int allPlayersNr; // used for constructing and deleting only

	PlayerBox** playerBox;        //one box per player
	Player *allPlayers;           //the players
	QList<Player> player;         //players in the round
	QList<Player> removedPlayers; //players not in the round

	OptionsDlg* options;
	NewGameDlg* newGameDlg;
	
	QLabel       *potLabel;
	BetBox       *betBox;

	int pot; 
	int currentMustBet; // the minimum bet amount
	int oldBet_raise;   // used for raising only

	KRandomSequence random;

	QPushButton 	*drawButton;    // the main Button
	QLabel 		*wonLabel;      // the winner
	QLabel 		*clickToHold; 
	QLabel 		*weWillAdjustLabel; //TODO
	bool		adjust;

	QTimer       *blinkTimer; // the winning cards will blink 
	QTimer       *drawTimer;  // delay between drawing of the cards 
	QTimer       *waveTimer;  // for displaying of the win (if winner == human)

	bool          *done; 		 // is the card alreay taken?
	int           blinkStat;         // status of blinking
	int           blinkingBox;       // box of winning player
	int           drawStat;          // status of drawing (which card already was drawn etc.

	bool          sound;
	bool          blinking;
	KAccel        *kacc;
   
	bool          waveActive;
	int           fCount;

	Status status;

	int minBet;
	int maxBet;
	int cashPerRound;
};

#endif
