/* **************************************************************************************
   File: Cards.h
   By Mauro Mindoli January 2003
***************************************************************************************** */

#ifndef _CARDS_H_
#define _CARDS_H_

#include <iostream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <time.h>

namespace game
{
   enum {GAME_LOST = 0, GAME_OK, GAME_WON};
   enum {ME, PC};
   enum {COPPE, DENARI, SPADE, BASTONI, END};
}

class CGameCard
{

public:
   CGameCard(int fam, int val) : mVal(val), mFam(fam) {}
   void SetFamVal(int fam, int val) {mFam = fam; mVal = val;}
   void GetFamVal (int &fam, int &val) const {fam = mFam; val = mVal;}
   int GetIdCard();
   virtual ~CGameCard() {}
   CGameCard();

protected:
   int mVal;
   int mFam;

private :

};

class CGameCardNapoletano : public CGameCard
{

public:
   CGameCardNapoletano() : CGameCard(1, game::BASTONI) {}
   CGameCardNapoletano(int fam, int val) : CGameCard(fam, val) {} 
   bool isJolly () 
   { 
      if ((mVal == 10) && (mFam == game::DENARI)) 
         return true; 
      else return false;  
   }
   ~CGameCardNapoletano() {}

};

typedef std::vector<CGameCard *> VecPCards;

class CDeck
{

public:
   CDeck(int numCards, int numFams); 
   void ShuffleDeck();
   int GetNumCards() const {return mNumCards;}
   bool GiveMeACard (const CGameCard* &card);
   virtual ~CDeck() {}
   VecPCards shuffledDeck;

protected : 
   int mNumCards;
   int mNumFams;
   int mCurPos;
   VecPCards mDeck;

private :
   CDeck();

};

class CDeckNapoletano: public CDeck
{

public:
   CDeckNapoletano();
   ~CDeckNapoletano();
   void Reshuffle(VecPCards &outCards);

private:
   enum {NCARDS = 40, NFAMS = 4}; 

};

class CPlayer
{

public:
   CPlayer(std::string name);
   virtual ~CPlayer() {}
   inline double GetPoints() const {return mPoints;}
   inline void SetPoints(double points) {mPoints = points;}
   virtual int AddCard(CGameCard *pCard) = 0;
   virtual void AddHand(CGameCard *pCard) = 0;
   virtual void ResetHand() = 0;

protected:
   std::string mName;
   double mPoints;

private:

};

class CPlayerNapoletano : public CPlayer
{

public:
   CPlayerNapoletano(std::string name) : 
      CPlayer(name), mEstimatedCard(5), mJollyValue(0.0) {}
   ~CPlayerNapoletano() {}
   int AddCard(CGameCard *pCard);
   void AddHand(CGameCard *pCard);
   void ResetHand();
   double GetEstimatedPoints() const; 
   VecPCards mHand;   

private:
   double mEstimatedCard;
   double mJollyValue;
};


class GameNapoletano
{

public:
   int Play(int who);
   void ResetPoints();
   void Init();
   int Try(CPlayer *pp);
   void GiveTheCard(CGameCard &card) const {card = *pCard;} 
   void GetPoints(double &myPoints, double &pcPoints) const
      {myPoints = pMe->GetPoints(); pcPoints = pPc->GetPoints();}
   GameNapoletano();
   ~GameNapoletano() {delete pMe; delete pPc;}

private:
   int gameResult;
   CGameCardNapoletano *pCard;
   CDeckNapoletano dn;
   CPlayerNapoletano *pMe;
   CPlayerNapoletano *pPc;
   void Reshuffle();
   VecPCards mOutCards;

};

#endif
