/**********************************************************************
 *
 *   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 "game.h"

#include "../party/rule.h"
#include "../player/player.h"
#include "../card/trick.h"
#include "../ui/ui.h"

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	which trick selects the team
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 */
MarriageSelector const&
Game::marriage_selector() const
{
  DEBUG_CALLING(INFO_GAME && INFO_VALUE,
		"Game::marriage_selector()");

  DEBUG_RETURNING(this->marriage_selector_p,
		  INFO_GAME && INFO_VALUE,
		  "Game::marriage_selector()");
} // MarriageSelector const& Game::marriage_selector() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	in which trick the marriage has been determined
 **
 ** @version	0.4.4
 **
 ** @author	Diether Knof
 **
 */
unsigned
Game::marriage_determination_trickno() const
{
  DEBUG_CALLING(INFO_GAME && INFO_VALUE,
		"Game::marriage_determination_trickno()");

  DEBUG_RETURNING(this->marriage_determination_trickno_p,
		  INFO_GAME && INFO_VALUE,
		  "Game::marriage_determination_trickno()");
} // unsigned Game::marriage_determination_trickno() const

/**
 **
 ** test, if the marriage is solved
 **
 ** @param	-
 **
 ** @return	
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 */
void
Game::determine_marriage()
{
  DEBUG_CALLING(INFO_GAME && INFO_GAMEPLAY,
		"Game::determine_marriage()");

  if ((this->type() == GAMETYPE::MARRIAGE)
      && (this->marriage_selector() != MARRIAGE_SELECTOR::TEAM_SET)) {

    // whether the player has to play alone
    // note that 'trick_current_no()' begins at '0'
    // but 'MARRIAGE_DETERMINATION' at '1'
    bool alone = (this->trick_current_no()
		  >= this->rule()(Rule::MARRIAGE_DETERMINATION));

    if (this->trick_current().winnerplayer() != this->soloplayer()) {

      if ((this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_FOREIGN)
	  || ( (this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_TRUMP)
	       && (this->trick_current().startcard().istrump()) )
	  || ( (this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_COLOR)
	       && (!this->trick_current().startcard().istrump()) )
	  || ( (this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_CLUB)
	       && (this->trick_current().startcard().tcolor() == Card::CLUB) )
	  || ( (this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_SPADE)
	       && (this->trick_current().startcard().tcolor() == Card::SPADE) )
	  || ( (this->marriage_selector() == MARRIAGE_SELECTOR::FIRST_HEART)
	       && (this->trick_current().startcard().tcolor() == Card::HEART) )
	 ) {

	// set the teams
	for (vector<Player*>::const_iterator player = this->player_begin();
	     player != this->player_end();
	     player++) {
	  this->teaminfo_p[(*player)->no()]
	    = (((**player == this->soloplayer())
		|| (**player == this->trick_current().winnerplayer()))
	       ? TEAM::RE
	       : TEAM::CONTRA);
	}
	this->marriage_selector_p = MARRIAGE_SELECTOR::TEAM_SET;
	this->marriage_determination_trickno_p = this->trick_current_no();
	// update the teaminfo of the players
	for (vector<Player*>::iterator player = this->player_p.begin();
	     player != this->player_p.end();
	     player++)
	  (*player)->teaminfo_update();

	if (!this->isvirtual())
	  ::ui->marriage(this->soloplayer(),
			 this->trick_current().winnerplayer());

	alone = false;
      } // if selected trick is caught
    } // if ((winnerplayer != soloplayer)


    if ((this->marriage_selector() != MARRIAGE_SELECTOR::TEAM_SET)
	&& !alone) {
      // test, whether there is a remaining card of the color
      bool has_card = false; // whether a player has a card of the color
      for (vector<Player*>::const_iterator player = this->player_begin();
	   player != this->player_end();
	   player++) {
	switch(this->marriage_selector()) {
	case MARRIAGE_SELECTOR::TEAM_SET:
	case MARRIAGE_SELECTOR::FIRST_FOREIGN:
	  has_card = true;
	  break;
	case MARRIAGE_SELECTOR::FIRST_TRUMP:
	  if ((*player)->hand().existstcolor(Card::TRUMP))
	    has_card = true;
	  break;
	case MARRIAGE_SELECTOR::FIRST_COLOR:
	  if ((*player)->hand().existstcolor(Card::CLUB)
	      || (*player)->hand().existstcolor(Card::SPADE)
	      || (*player)->hand().existstcolor(Card::HEART))
	    has_card = true;
	  break;
	case MARRIAGE_SELECTOR::FIRST_CLUB:
	  if ((*player)->hand().existstcolor(Card::CLUB))
	    has_card = true;
	  break;
	case MARRIAGE_SELECTOR::FIRST_SPADE:
	  if ((*player)->hand().existstcolor(Card::SPADE))
	    has_card = true;
	  break;
	case MARRIAGE_SELECTOR::FIRST_HEART:
	  if ((*player)->hand().existstcolor(Card::HEART))
	    has_card = true;
	  break;
	} // switch (this->marriage_selector())
      } // for (p < this->playerno())

      if (!has_card)
	alone = true;
    } // if (!alone)

    if (alone) {
      this->marriage_determination_trickno_p = this->trick_current_no();
      this->type_set(GAMETYPE::MARRIAGE_SOLO);
      for (vector<Player*>::const_iterator player = this->player_begin();
	   player != this->player_end();
	   player++)
	this->teaminfo_p[(*player)->no()]
	  = ((**player == this->soloplayer())
	     ? TEAM::RE
	     : TEAM::CONTRA);
      this->marriage_selector_p = MARRIAGE_SELECTOR::TEAM_SET;
      // update the teaminfo of the players
      for (vector<Player*>::iterator player = this->player_p.begin();
	   player != this->player_p.end();
	   player++)
	(*player)->teaminfo_update();

      if (!this->isvirtual())
	::ui->marriage(this->soloplayer(), this->soloplayer());
    } // if (this->acttrick() >= this->rule()(Rule::MARRIAGE_DETERMINATION))

    // it can be, that the team of the swines owner or the first fox catcher
    // has changed
    if (this->rule()(Rule::SWINE_ONLY_SECOND)
	&& this->swines_owner()
	&& this->first_fox_catcher()
	&& (this->marriage_selector() == MARRIAGE_SELECTOR::TEAM_SET)){
      this->swines_owner_p->hand_sort();
      if (!this->isvirtual())
	::ui->redraw_all();
    } // if (first fox of swines in trick)
  } // if (type() == GAMETYPE::MARRIAGE)

  DEBUG_RETURNING(VOID,
		  INFO_GAME && INFO_GAMEPLAY,
		  "Game::determine_marriage()");
} // void Game::determine_marriage()
