/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2005  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 "trickweighting.h"
#include "exception.h"

#include "VirtualGamesInterface.h"
#include "ai.h"
#include "info.h"
#include "../../../party/party.h"
#include "../../../game/game.h"
#include "../../../game/gamepoints.h"
#include "../../../misc/setting.h"
#include "../../../ui/ui.h"

namespace FORK_0_5_4 {

/**
 **
 ** -> result
 **
 ** @param      trick   the trick to be examined
 ** @param      team    the team which should make points
 ** @param      card    the card played by the player
 **
 ** @return     the weighting of the trick for the team 'team'
 **
 ** @version    0.4.4
 **
 ** @author     Borg Enders
 **
 ** @todo       perhaps points for getting the fox home
 **
 **/
int
TrickWeighting::modi(VirtualGamesInterface const& vgi, Trick const& trick, Team const team, Card const& card)
{
  DEBUG_CALLING(INFO_W_VIRTUAL_GAMES && INFO_VALUE,
		"WVirtualGames::modi()");

  Game const& game_virt = trick.game();
  Ai const& ai = static_cast<const Ai&>(game_virt.player( vgi.no() ));
  Team const winnerteam = trick.winnerplayer().team();

  int modi = 0;

  if (winnerteam == team)
    modi += trick.points();
  else
    modi -= trick.points();


  // have played a very high card
  if (card.isswine()
      || card.ishyperswine()
      || card.isdolle())
    modi -= 14; // previous values: 23
  if (card.isswine()) // so that a dolle is prefered to a swine
    modi -= 2;

  if ( card.istrump() )
    modi-= 4; 

  // have played a high card
  if (ai.value(Aiconfig::LIMITHIGH).less(card, game_virt))
  {
    modi -= 3;
  }
  
  // forced enemy to play high card
  if ( card != trick.winnercard() && 
       ai.value(Aiconfig::LIMITHIGH).less(trick.winnercard(), game_virt) &&
       ai.team() != winnerteam &&
       !card.isdolle() && !card.isswine())
  {
    modi += 7;
  }

  // create the teams-vector
  vector<Team> teams;
  for (vector<Player*>::const_iterator
       player = game_virt.player_begin();
       player != game_virt.player_end();
       player++) 
  {
    // determine team of player from ai out of virtual game
    Team const t = ai.teamofplayer( **player );
    if ( t != TEAM::UNKNOWN)
    {
      teams.push_back( maybe_to_team( t ) );
    } else
    {
      teams.push_back( opposite(ai.team()) );
    }

  } // for (player)

  if (maybe_to_team(winnerteam) == team)
  {
    Specialpointsvector spv=trick.specialpoints(game_virt.type(),
						teams,
						(game_virt.tricks_remaining_no()
						 == 0));
    modi += (30
	     * Sum_of_Specialpoints(spv,
				    winnerteam,
				    trick.startplayer().game()));

  }
  else
  {
    Specialpointsvector spv=trick.specialpoints(game_virt.type(),
						teams,
						(game_virt.tricks_remaining_no()
						 == 0));
    modi -= (30
	     * Sum_of_Specialpoints(spv,
				    winnerteam,
				    trick.startplayer().game()));
  }

  // bad style to play fox as first card
  if( card.isfox() && trick.card(0) == card)
  {
    modi -= 90; // previous	
  }


  for (unsigned c = 0; c < trick.actcardno(); c++) {
    // test, whether the fox has been brought home

    if (trick.card(c).isfox() 
	&& (trick.player_of_card(c).team() == winnerteam))
    {

      modi += 40 * ((team == trick.player_of_card(c).team())
		    ? +1
		    : -1);                    
    }
  } // for (c < trick.actcardno())


  // don't play two times the same card
  for (unsigned c = 0; c < trick.actcardno(); c++) {
    if(    trick.card(c) == card 
	   && (trick.cardno_of_player(trick.player_of_card(c))
	       < trick.cardno_of_player( ai ) ))
    {
      modi+= card.value() * ((team == trick.player_of_card(c).team())
			     ? -1
			     : 0);   
    }           
  }
  DEBUG_RETURNING(modi,
		  INFO_W_VIRTUAL_GAMES && INFO_VALUE,
		  "WVirtualGames::modi()");

  DEBUG_ASSERTION(false,
		  "WVirtualGames::modi():\n"
		  "  after 'RETURNING'");
  return 0;
} // int WVirtualGames::modi(Trick const& trick, Team const& team, Card const& card)

} // namespace FORK_0_5_4
