/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2004  by Diether Knof and Borg Enders
 *
 *   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 can find this license in the file 'gpl.txt'.
 *
 *   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., 59 Temple Place, Suite 330, Boston, 
 *   MA  02111-1307  USA
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 **********************************************************************/

#ifndef CLASS_CARD_HEADER
#define CLASS_CARD_HEADER

#include "../basistypes.h"

class Game;

/// Class for a card
class Card {
  public:

    static Card const CLUB_QUEEN;
    static Card const CHARLIE;
    static Card const DOLLE;


    static unsigned const NUMBER_OF_COLORS;
    static unsigned const NUMBER_OF_TCOLORS;
    static unsigned const NUMBER_OF_VALUES;

    enum Value {
      NINE = 0,
      JACK = 2,
      QUEEN = 3,
      KING = 4,
      TEN = 10,
      ACE = 11,
      NOCARDVALUE = 100 // for simpler error-tracking
    }; // enum Value

    enum TColor {
      DIAMOND = 0,
      HEART,
      SPADE,
      CLUB,
      TRUMP,
      NOCARDCOLOR = 100 // for simpler error-tracking
    }; // enum TColor
    typedef TColor Color;

    // converts the string in a value
    static Value value(string const& value);
    // converts the string in a color
    static Color color(string const& color);

    // Converts an Integer into a Value
    static Value InttoValue(int const i);

    // Covert an Integer into a Color
    static Color InttoColor(int const i);

    // for sorting the hands
    static int relative_position(Card const& a, Card const& b);

  public:

    Card();
    Card(Card const& c);
    Card(Color const c, Value const v);
    Card(string const& name);

    ~Card();

    Card& operator=(Card const& card);
    istream& read(istream& istr);

    operator bool() const;

    Color color() const;
    TColor tcolor() const;

    Value value() const;

    unsigned points() const;

    bool istrump() const;
    bool istrump(GameType const gametype) const;

    bool istrumpace() const;
    bool istrumpnine() const;
    bool istrumpking() const;

    bool isfox() const;
    bool isdolle() const;
    bool isswine() const;
    bool ishyperswine() const;


    // returns whether the card is less than 'card'
    bool less(Card const& b, Game const& game) const;

  private:
    Color color_p; // Color of the card
    Value value_p; // Value of the card

  private: // not to be used
    Card(unsigned const color_u, unsigned const value_u);
    Card(int const color, int const value);
    bool operator<(Card const& b) const;
    bool operator>(Card const& b) const;
    bool operator<=(Card const& b) const;
    bool operator>=(Card const& b) const;
}; // class Card

// comparison between two cards
// it can be, that !(a < b || a > b || a == b),
// f.e. a = clubs nine, b = spade nine

bool operator==(Card const& a, Card const& b);
bool operator!=(Card const& a, Card const& b);

// the name of the value
string name(Card::Value const& value);
// the name of the tcolor
string name(Card::TColor const& tcolor);
// the name of the card
string name(Card const& card);


// output of the value in the stream
ostream& operator<<(ostream& ostr, Card::Value const& value);
// read the value out of the stream
istream& operator>>(istream& istr, Card::Value& value);
// output of the tcolor in the stream
ostream& operator<<(ostream& ostr, Card::TColor const& tcolor);
// read the color out of the stream
istream& operator>>(istream& istr, Card::Color& color);
// output of the card in the stream
ostream& operator<<(ostream& ostr, Card const& card);
// read the card out of the stream
istream& operator>>(istream& istr, Card& card);

#endif // #ifndef CLASS_CARD_HEADER
