/**********************************************************************
 *
 *   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_PLAYERSDB_HEADER
#define CLASS_PLAYERSDB_HEADER

#include "../game/specialpoint.h"
#include "../game/gamepoints.h"
#include "player.h"

/// [T]otal[L]ost[W]on count
class TLWcount
{
  public:
    TLWcount(): total_(0), lost_(0), won_(0){};

    void hasLost() { total_++; lost_++; };
    void hasWon()  { total_++; lost_++; };

    unsigned int total() { return total_; };
    unsigned int lost() { return lost_; };
    unsigned int won() { return won_; };	

  private:
    unsigned int total_;
    unsigned int lost_;
    unsigned int won_;	
}; // class TLWcount

class Ranking
{
  public:
    Ranking( double const d = 0 ) : value_( d ) {};

    void add( Ranking const r )
    {
      this->value_ = ( 0.9 * this->value_ + r.value_ ) / 1.9;
    }

    double value() const { return value_; };

    Ranking& operator=( Ranking const r )
    {
      this->value_ = r.value_;
      return *this;
    }

    Ranking& operator+=( Ranking const& b )
    {
      this->add( b );
      return *this;
    };
  private:
    double value_;
}; // class Ranking



class PlayersDb
{
  public:
    PlayersDb();
    PlayersDb( PlayersDb& p );

    virtual ~PlayersDb() {}

    virtual void evaluate( const Player& p, const GamePoints& g );

    /// number of each played game  lost and won
    TLWcount games( GAMETYPE::GameType i )
    {
      DEBUG_ASSERT( i >= 0 && (unsigned int)i < games_.size() );
      return games_[i];
    }	

    /// number of special points made or given away
    TLWcount specialpoints( SPECIALPOINT::Specialpoint i )
    {
      DEBUG_ASSERT( i >= 0 && (unsigned int)i < specialpoints_.size() );
      return specialpoints_[i];
    }	

    /// average points made with each game
    double averageGamePoints() { return averageGamePoints_; };

    /// average point made with trikcs in each game
    double averageGameTrickPoints() { return averageGameTrickPoints_; };

    Ranking rank;
  private:
    std::vector<TLWcount> games_; // a map would be better

    std::vector<TLWcount> specialpoints_; // a map would be better

    double averageGamePoints_;
    double averageGameTrickPoints_;
    long long totalGames_;
}; // class PlayersDb

#endif // #ifndef CLASS_PLAYERSDB_HEADER
