/**********************************************************************
 *
 *   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_UI_HEADER
#define CLASS_UI_HEADER

#include "../basistypes.h"

#include "../misc/translator.h"

class Party;
class Game;
class Player;
class Trick;
class Hand;
namespace OS_NS {
  class BugReportReplay;
}

namespace UI_TYPE {
  enum UIType {
    DUMMY,
    WRAP,
#ifdef USE_UI_TEXT
    TEXT,
#endif
#ifdef USE_UI_AATEXT
    AATEXT,
#endif
#ifdef USE_UI_GTKMM
    GTKMM_DOKO
#endif
  }; // enum UIType
} // namespace UI_TYPE

/**
 **
 ** @brief	the base ui (user interface) class
 **
 ** @author	Diether Knof
 **
 **/
class UI {
  friend UI* new_UI(UI_TYPE::UIType const type);

  public:
  UI(UI_TYPE::UIType const type);

  virtual ~UI();

  // initialize the ui
  virtual void init(int& argc, char**& argv) { }

  // updates the UI
  virtual void update() { }
  // sleeps 'sleep_usec' thousands of seconds
  // (< 0 for infinity)
  virtual void sleep(unsigned const sleep_usec) { }
  // updates the language
  virtual void language_update() { }

  // the parts of a party
  virtual Party& party();
  virtual void party_open(Party& party); // to be called from childs
  virtual void party_get_settings() { }
  virtual void party_start() { }
  virtual void party_start_round(unsigned const round) { }
  virtual void party_finish() { }
  virtual void party_close(); // to be called from childs

  // the parts of a game
  virtual Game& game();
  virtual void game_open(Game& game); // to be called from childs
  virtual void game_cards_distributed() { }
  virtual void game_redistribute() { }
  virtual Reservation reservation_get(Player const& player) = 0;
  virtual void game_start() { }
  virtual void game_finish() { }
  virtual void game_close(); // to be called from childs

  // the parts of a trick
  virtual void trick_open(Trick const& trick); // to be called from childs
  virtual void trick_full() { }
  virtual void trick_move_in_pile() { }
  virtual void trick_close(); // to be called from childs
  // get a card
  virtual HandCard card_get(Player const& player) = 0;
  virtual void card_played(HandCard const& card) { }
  virtual void announcement_made(Announcement const& announcement,
				 Player const& player) { }
  virtual void swines_announced(Player const& player) { }
  virtual void hyperswines_announced(Player const& player) { }
  // ai actions
  virtual void ai_test_card(Card const& card, unsigned const playerno) { }
  virtual void ai_card_weighting(int const weighting) { }
  virtual void virtual_card_played(HandCard const& card) { }
  virtual void virtual_trick_full() { }

  // 'player' has a poverty and shifts
  virtual void poverty_shifting(Player const& player) { }
  // 'player' shifts 'cardno' cards
  virtual void poverty_shift(Player const& player, unsigned const cardno) { }
  // ask 'player' whether to accept the poverty
  virtual void poverty_ask(Player const& player, unsigned const cardno) { }
  // the player 'player' has denied the poverty trumps
  virtual void poverty_take_denied(Player const& player) { }
  // all players have denied to take the cards
  virtual void poverty_take_denied_by_all() { }
  // the player 'player' has accepted the poverty trumps
  // and has returned 'cardno' cards with 'trumpno' trumps
  virtual void poverty_take_accepted(Player const& player,
				     unsigned const cardno,
				     unsigned const trumpno) { }
  // 'player' shifts cards
  virtual HandCards poverty_shift(Player& player) = 0;
  // returns whether 'player' accepts the poverty
  virtual bool poverty_take_accept(Player& player,
				   unsigned const cardno) = 0;
  // the player changes the cards of the poverty
  virtual HandCards poverty_cards_change(Player& player,
					 HandCards const&
					 cards) = 0;
  // the poverty player 'player' gets 'cards'
  virtual void poverty_cards_get_back(Player& player,
				      HandCards const& cards) { }

  // the marriage partner has found a bride
  virtual void marriage(Player const& bridegroom, Player const& bride) { }
  // return a partner for a genscher
  virtual Player const* genscher_partner() = 0;
  // a player has announced a genscher
  virtual void genscher(Player const& genscher, Player const& partner) { }

  // redrawing
  virtual void redraw_all() { }
  virtual void gametype_update() { }
  virtual void player_update(Player const& player) { }
  virtual void name_update(Player const& player) { }
  virtual void hand_update(Player const& player) { }
  virtual void teaminfo_update(Player const& player) { }

  virtual void bug_report_replay_open(OS_NS::BugReportReplay const&
				      bug_report_replay);
  virtual void bug_report_replay_close();

  // change of the rules
  virtual void rule_update(int const type, void const* const old_value) { }
  // changes of the settings
  virtual void setting_update(int const type, void const* const old_value) { }
  // load the help page
  virtual void help_load(string const& page) { }

  // 'player' has chatted 'message'
  virtual void chat(string const& player, string const& message) { }

  // for status messages
  Translator::Translation status_message() const;
  void add_status_message(Translator::Translation const& status_message);
  void remove_status_message(Translator::Translation const& status_message);
  virtual void status_message_changed(Translator::Translation const&
				      status_message) { }

  // whether the ui is busy
  virtual void set_busy();
  virtual void set_not_busy();

  // for progress
  double progress() const;
  void set_max_progress(double const progress_max);
  void add_progress(double const progress);
  void finish_progress();
  virtual void progress_changed(double const progress) { }
  virtual void progress_finished() { }

  // information for the user
  virtual void information(Translator::Translation const& message) { }
  // an error has occured
  virtual void error(string const& message) { }


  protected:
  PRIV_VAR_R(UI_TYPE::UIType, type);

  private:
  PRIV_VAR_P_R(Party, party);
  PRIV_VAR_P_R(Game, game);
  PRIV_VAR_CP_R(Trick, trick);

  PRIV_VAR_CP_R(OS_NS::BugReportReplay, bug_report_replay);

  vector<Translator::Translation> status_message_;
  PRIV_VAR_R(bool, busy);
  PRIV_VAR(double, progress);
  PRIV_VAR(double, progress_max);

  private: // unused
  UI();
  UI(UI const&);
  UI& operator=(UI const&);

}; // class UI

UI* new_UI(UI_TYPE::UIType const type);

extern UI* ui;

#endif // #ifndef CLASS_UI_HEADER
