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

// some enumerate:
// - GameStatus
// - Team
// - GameType
// - Announcement
// - MarriageSelector
// - Rotation
// - Position


#include "constants.h"


////////////////
// GAMESTATUS //
////////////////

namespace GAMESTATUS
{
  int const PARTY = 0x10;
  int const GAME = 0x100;
  enum GameStatus {
    PROGRAMSTART = 0,
    QUIT = 1,
    PARTY_NEW = PARTY,
    PARTY_INIT,
    PARTY_PLAY,
    PARTY_FINISHED,
    GAME_NEW = GAME,
    GAME_INIT,
    GAME_RESERVATION,
    GAME_SHOW_GAMETYPE,
    GAME_REDISTRIBUTE,
    GAME_POVERTY_SHIFT,
    GAME_PLAY,
    GAME_GENSCHER,
    GAME_SHOW_FULL_TRICK,
    GAME_SHOW_LAST_TRICK,
    GAME_FINISHED,
    GAME_CLOSE
  }; // enum GameStatus
} // namespace GAMESTATUS
using GAMESTATUS::GameStatus;

bool in_running_game();

extern GameStatus game_status;

string name(GameStatus const& game_status);
ostream& operator<<(ostream& ostr, GameStatus const& game_status);


//////////
// Team //
//////////

namespace TEAM
{
  enum Team {
    NOTEAM,
    RE,
    CONTRA, 
    UNKNOWN,
    MAYBE_RE,   // Team for AI-Heuristics
    MAYBE_CONTRA // Team for AI-Heuristics
  }; // enum Team
} // namespace TEAM
using TEAM::Team;

/// converts team MAYBE_X to X
Team maybe_to_team(Team const& t);
/// converts team X to MAYBE_X
Team team_to_maybe(Team const& t);
Team opposite(Team const& t);

string name(Team const& team);
ostream& operator<<(ostream& ostr, Team const& t);



//////////////
// GAMETYPE //
//////////////

namespace GAMETYPE {
  enum GameType {
    FIRST,
    NORMAL = FIRST, 
    FIVE_NINES,
    SIX_KINGS,
    FOX_HIGHEST_TRUMP,
    POVERTY,
    GENSCHER,
    MARRIAGE,
    MARRIAGE_SOLO,
    MARRIAGE_SILENT,
    SOLO_MEATLESS,
    SOLO_JACK,
    SOLO_QUEEN,
    SOLO_KING,
    SOLO_QUEEN_JACK,
    SOLO_KING_JACK,
    SOLO_KING_QUEEN,
    SOLO_KOEHLER,
    SOLO_CLUB,
    SOLO_HEART,
    SOLO_SPADE,
    SOLO_DIAMOND,
    LAST = SOLO_DIAMOND
  }; // enum GameType
  unsigned const NUMBER = LAST - FIRST + 1;
  bool is_normal(GameType const& game_type);
  bool is_solo(GameType const& game_type);
  bool is_color_solo(GameType const& game_type);
  bool is_picture_solo(GameType const& game_type);
} // namespace GAMETYPE
using GAMETYPE::GameType;

string name(GameType const& game_type);
ostream& operator<<(ostream& ostr, GameType const& game_type);



//////////////////
// ANNOUNCEMENT //
//////////////////

namespace ANNOUNCEMENT
{
  enum Announcement{
    NOANNOUNCEMENT,
    NO120, // means RE or CONTRA
    NO90,
    NO60,
    NO30,
    NO0,
    REPLY,
    NO120_REPLY,
    NO90_REPLY,
    NO60_REPLY,
    NO30_REPLY,
    NO0_REPLY
  }; // enum Announcement
  unsigned const NUMBER = NO0_REPLY - NOANNOUNCEMENT + 1;

  bool is_real(Announcement const& announcement);
  bool is_reply(Announcement const& announcement);
  Announcement to_reply(Announcement const& announcement);
  Announcement from_reply(Announcement const& announcement);
  Announcement from_name(string const& name);
} // namespace ANNOUNCEMENT
using ANNOUNCEMENT::Announcement;

string name(ANNOUNCEMENT::Announcement const& announcement);
ostream& operator<<(ostream& ostr, Announcement const& announcement);



///////////////////////
// MARRIAGE_SELECTOR //
///////////////////////

namespace MARRIAGE_SELECTOR {
  enum MarriageSelector {
    FIRST,
    TEAM_SET = FIRST,
    FIRST_FOREIGN,
    FIRST_TRUMP,
    FIRST_COLOR,
    FIRST_CLUB,
    FIRST_SPADE,
    FIRST_HEART,
    LAST = FIRST_HEART
  }; // enum MarriageSelector
  unsigned const MARRIAGE_SELECTOR_NUMBER = 1 + 1 + 1 + 3;
} // namespace MARRIAGE_SELECTOR
using MARRIAGE_SELECTOR::MarriageSelector;

string name(MarriageSelector const& marriage_selector);
ostream& operator<<(ostream& ostr, MarriageSelector const& marriage_selector);

enum Rotation {
  UP,
  DOWN,
  LEFT,
  RIGHT
}; // enum ROTATION
unsigned const ROTATION_NUMBER = RIGHT + 1;

enum Position {
  NORTH,
  SOUTH,
  WEST,
  EAST
}; // enum Position


#endif // #ifndef BASISTYPES_HEADER
