/**********************************************************************
 *
 *   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
 *
 *********************************************************************/

#include "constants.h"
#include "card.h"

unsigned const Card::NUMBER_OF_VALUES = 6;


/**
 **
 ** -> result
 **
 ** @param	i	int value to be transformed into a CardValue
 **
 ** @return	ACE		: for input 0  or 1
 **		TEN		: for input 2  or 3
 **		KING		: for input 4  or 5
 **		QUEEN		: for input 6  or 7
 **		JACK		: for input 8  or 9
 **		NINE		: for input 10 or 11
 **		NOCARDVALUE	: otherwise
 **
 ** @version	0.5.4
 **
 ** @author	Borg Enders
 **
 **/
Card::Value
Card::InttoValue(int const i)
{
  DEBUG_CALLING(INFO_CARD && INFO_VALUE, "Card::InttoValue()");

  switch(i) {
  case 0:
  case 1:
    DEBUG_RETURNING(ACE,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  case 2:
  case 3:
    DEBUG_RETURNING(TEN,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  case 4:
  case 5:
    DEBUG_RETURNING(KING,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  case 6: 
  case 7:
    DEBUG_RETURNING(QUEEN,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  case 8: 
  case 9:
    DEBUG_RETURNING(JACK,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  case 10:
  case 11:
    DEBUG_RETURNING(NINE,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
    break;

  default: 
    DEBUG_ASSERTION(false,
		    "Card::InttoValue(): illegal Value" << i);
    break;
  }

  DEBUG_RETURNING(NOCARDVALUE,INFO_CARD && INFO_VALUE, "Card::InttoValue()");
} // Card::Value Card::InttoValue();

/**
 **
 ** -> result
 **
 ** @param	value	CardValue to be transformed in an int
 **
 ** @return	 0  : for input ACE
 **		 2  : for input TEN
 **		 4  : for input KING
 **		 6  : for input QUEEN
 **		 8  : for input JACK
 **		10  : for input NINE
 **		-1  : otherwise
 **
 ** @version	0.5.4
 **
 ** @author	Borg Enders
 **
 **/
int
Card::ValuetoInt(Value const& value)
{
  DEBUG_CALLING(INFO_CARD && INFO_VALUE, "Card::ValuetoInt(value)");

  switch(value) {
  case ACE:
    DEBUG_RETURNING(0,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case TEN:
    DEBUG_RETURNING(2,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case KING:
    DEBUG_RETURNING(4,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case QUEEN:
    DEBUG_RETURNING(6,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case JACK:
    DEBUG_RETURNING(8,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case NINE:
    DEBUG_RETURNING(10,
		    INFO_CARD && INFO_VALUE,
		    "Card::ValuetoInt(value)");
    break;

  case NOCARDVALUE:
    DEBUG_ASSERTION(false,
		    "Card::ValuetoInt(value): illegal value");

    break;
  } // switch(value)

  DEBUG_RETURNING(-1,
		  INFO_CARD && INFO_VALUE,
		  "Card::ValuetoInt(value)");
} // int Card::ValuetoInt(Value const& value);

/**
 **
 ** -> result
 **
 ** @param	value_name	name of the value
 **
 ** @return	value 'name'
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 **/
Card::Value
Card::value(string const& value_name)
{
  DEBUG_CALLING(INFO_CARD && INFO_BASISTYPES && INFO_NAME,
		"Card::Value value(value_name)");

  Card::Value value = Card::NOCARDVALUE;
  if (value_name == ::name(Card::NINE))
    value = Card::NINE;
  else if (value_name == ::name(Card::JACK))
    value = Card::JACK;
  else if (value_name == ::name(Card::QUEEN))
    value = Card::QUEEN;
  else if (value_name == ::name(Card::KING))
    value = Card::KING;
  else if (value_name == ::name(Card::TEN))
    value = Card::TEN;
  else if (value_name == ::name(Card::ACE))
    value = Card::ACE;
  else
    DEBUG_ASSERTION(false,
		    "Card::value(value_name):\n"
		    "  value '" << value_name << "' unknown");

  DEBUG_RETURNING(value,
		  INFO_CARD && INFO_BASISTYPES && INFO_NAME,
		  "Card::Value value(value_name)");
} // static Card::Value Card::value(string const& value_name)

/**
 **
 ** -> result
 **
 ** @param	value	card value
 **
 ** @return	name of the value
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 **/
string
name(Card::Value const& value)
{
  DEBUG_CALLING(INFO_CARD && INFO_BASISTYPES && INFO_NAME,
		"string name(Card::Value const& value)");

  string name;

  switch(value) {
  case Card::NINE:
    name = "nine";
    break;
  case Card::JACK:
    name = "jack";
    break;
  case Card::QUEEN:
    name = "queen";
    break;
  case Card::KING:
    name = "king";
    break;
  case Card::TEN:
    name = "ten";
    break;
  case Card::ACE:
    name = "ace";
    break;
  case Card::NOCARDVALUE:
    name = "no card value";
    break;
  } // switch(value)

  DEBUG_RETURNING(name,
		  INFO_CARD && INFO_BASISTYPES && INFO_NAME,
		  "string name(Card::Value const& value)");
} // string name(Card::Value const& value)

/**
 **
 ** writes the card value in the output stream
 **
 ** @param	ostr	output stream
 ** @param	value	card value
 **
 ** @return	output stream
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 **/
ostream&
operator<<(ostream& ostr, Card::Value const& value)
{
  DEBUG_CALLING(INFO_CARD && INFO_BASISTYPES && INFO_IO,
		"ostream& operator<<(ostr, value)");

  ostr << name(value);

  DEBUG_RETURNING(ostr,
		  INFO_CARD && INFO_BASISTYPES && INFO_IO,
		  "ostream& operator<<(ostr, value)");
} // ostream& operator<<(ostream& ostr, Card::Value const& value);

/**
 **
 ** read the card value out of the stream
 **
 ** @param	istr	input stream
 ** @param	value	card value
 **
 ** @return	output stream
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 **/
istream&
operator>>(istream& istr, Card::Value& value)
{
  DEBUG_CALLING(INFO_CARD && INFO_BASISTYPES && INFO_IO,
		"ostream& operator<<(ostr, value)");

  string value_name;
  istr >> value_name;

  value = Card::value(value_name);
  
  DEBUG_RETURNING(istr,
		  INFO_CARD && INFO_BASISTYPES && INFO_IO,
		  "ostream& operator<<(ostr, value)");
} // istream& operator>>(istream& istr, Card::Value& value);
