/* 
    TowBowlTactics: Strategy game for X11

    Copyright (C) 2001 Pascal Bourut (toweld@planetelibre.org)

    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 should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef PLAYER_H
#define PLAYER_H

#include <SDL/SDL.h>
#ifndef _SDL_H
	#include <SDL.h>
#endif

#include "global.h"
#include "debug.h"
#include "Square.h"
#include "Dice.h"
#include "Path.h"
#include "Shared.h"

#include "skills.h"

/**
 * Classe representant un joueur
 * @doc 
 * @author Toweld
 * @version 0.3
 */

class Player{	
 public:
  /** Constructeur avec plein de parametres
   * @param 1 nom du joueur
   * @param 2 number du joueur
   * @param 3 poste du joueur
   * @param 4 id du poste du joueur
   * @param 5 mouvement du joueur
   * @param 6 force du joueur
   * @param 7 agilite du joueur
   * @param 8 armure du joueur
   * @param 9 cout du joueur
   * @param 10 race du joueur
   * @param 11 image du joueur
   * @param 12 id de l'equipe du joueur
   */
  Player(char*,int,char*,int,int,int,int,int,int,char*,char*,int);
  /** Destructeur par defaut 
   */
  ~Player();
  /** Donner un nom a un joueur
   * @param n nom
   */
  void set_name(char*);
  /** Obtenir le nom d'un joueur
   * @return nom
   */
  char* get_name();
  /** Donner une number a un joueur
   * @param p number
   */
  void set_number(int);
  /** Obtenir la number d'un joueur
   * @return number
   */
  char* get_picture_name();
  SDL_Surface* get_picture();
  
  void set_picture(SDL_Surface*);

  int get_number();
  /** Donner un poste
   * @param t poste
   */
  void set_position(char*);
  void set_race(char*);
  void set_picture_name(char*);

  void set_position_id(int);
  char* get_position();
  int get_position_id();
  /** Donner un cout 
   * @param c cout
   */
  void set_cost(int);
  /** Obtenir le cout d'un joueur
   * @return cout
   */
  int get_cost();
  /** Donner des caracs a un gars
   * @param a mouvement
   * @param b force
   * @param c agilite
   * @param d armure
   */
  void set_carac(int,int,int,int);
  /** Donner le mouvement d'un joueur
   * @param m mouvement
   */
  void set_ma(int);
  /** Obtenir la valeur du  mouvement d'un joueur
   * @return mouvement
   */
  int get_ma();
  /** Donner la force d'un joueur
   * @param s force
   */
  void set_st(int);
  /** Obtenir la valeur de la force d'un joueur
   * @return force
   */
  int get_st();
  /** Donner l'agilite d'un joueur
   * @param a agilite
   */
  void set_ag(int);
  /** Obtenir la valeur de l'agilite d'un joueur
   * @return agilite
   */
  int get_ag();
  /** Donner l'armure d'un joueur
   * @param a armure
   */
  void set_av(int);
  /** Obtenir la valeur de l'armure d'un joueur
   * @return armure
   */
  int get_av();
  /** Donner des xps a un joueur
   * @param x nouvelle somme d'xps
   */
  void set_xps(int);
  /** Obtenir la valeur des xps d'un joueur
   * @return xps
   */
  int get_xps();
  /** Obtenir la race d'un joueur
   * @return race
   */
  char* get_race();
  /** Modifiier le status d'un joueur
   * @param s status
   */
  void set_status_only(int);

  void set_status(int);
  /** Obtenir le status d'un joueur
   * @return status
   */
  int get_status();
  /** Associer un joueur a une equipe
   * @param t team 
   */
  void set_team(int);
  /** Obtenir la team d'un joueur
   * @return team
   */
  int get_team();
  /** Indiquer si la relance d'equipe a deja ete utilisee
   * @param b true si utilisee, false sinon
   */
  void set_team_reroll_used(bool);
  /** La relance d'equipe a t'elle deja ete utilisee
   * @return team_reroll_used
   */
  bool is_team_reroll_used();
  /** Indiquer la presence d'un joueur sur le terrain
   * @param b true si present, false si hors du terrain
   */
  void set_on_playground(bool);
  /** Savoir si un joueur est sur le terrain
   * @return true si present, false sinon
   */
  bool is_on_playground();
  /** Selectionner le joueur
   * @param b si true si selectionne
   */
  void set_selected(bool);
  /** Savoir si un joueur est selectionne
   * @return true si oui, false sinon
   */
  bool is_selected();
  /** Donner le ballon a un joueur
   * @param b si true alors donner ballon, si false perdre ballon
   */
  void set_has_ball(bool);
  /** Savoir si un joueur a la balle
   * @return true si oui, false sinon
   */
  bool has_got_ball();
  /** Signaler qu'un joueura deja jouer durant le tour
   * @param b true le joueur a jouer, false sinon
   */
  void set_has_played(bool);
  /** Savoir si un joueur a deja jouer durant le tour
   * @return true si oui, false sinon
   */
  bool has_played();
  /** Donner des competences a un joueur
   * @param l liste de competences
   */
  void set_skills(std::list<char*>*);
  /** Obtenir la liste des competences d'un joueur
   * @return listes de competences
   */
  std::list<char*>* get_skills(); 
   /** Placer un joueur sur une case
   * @param s case du placement
   */
  void place(Square *);
  /** Placer un joueur 
   * @param x abscisse de la case ou on le met
   * @param y ordonnee de la case ou on le met
   */
  void place(int,int);

  void place_in_reserve(int,int);
  
  void place_in_reserve();
  void set_square(Square *);

  void set_square(int,int);

  void set_reserve_square(Square *);

  void set_reserve_square(int,int);

  Square* get_reserve_square();

  /** Connaitre la case occupee par un joueur
   * @return case
   */
  Square* get_square();
  /** Obtenir la liste des joueurs voisins
   * @return liste de voisins
   */
  std::list<Player*>* get_neighbours();

  bool friend_neighbours_has_got_skill(char*);

  bool neighbours_has_got_skill(char*);

  /** Connaitre le nombre de zone de tackle sous le joueur
   * @return nombre de zone de tacle
   */
  int get_tackle_zone(int,int);

  int get_tackle_zone();
  
  /** Ajouter une competence
   * @param n nouvelle competence
   */
  void add_skill(char*);
   /** Pour deplacer le joueur d'une case et effectue les tests necessaires...
   * @return score a effectuer
   */
  int move(int,int);
  /** Pour effectuer les tester pour ramasser un ballon
   * @return score a atteindre
   */
  int gather();
  /** Pour connaitre le nombre de de a jeter pour bloquer un joueur
   * @param p Player qu'on aggresse
   * @return valeur. |valeur| etant le nombre de des a jeter, de plus, si valeur est negatif c'est a l'adversaire de choisr le de a garder, sinon au lancer.
   */
  int block(Player *);
  /** Histoire de savoir si un joueur a une competence
   * @param c competence dont on teste l'existence
   * @return true, si le joueur a la competence, false sinon
   */
  bool has_got_skill(char*);
  /** Frapper un joueur
   * @param p joueur que l'on frappe
   * @return d6->roll(2) + - bonus
   */
  int hit(Player *); 
  /** Faire effectuer une passe
   * @param d distance de la passe
   * @return score a atteindre 
   */ 
  int throw_ball(int);
  /** Faire les tests pour attrapper un ballon
   * @param b perfectitude de la passe
   * @return score a atteindre
   */ 
  
  int receive_ball(bool);

  /** Faire les tests pour recevoir un ballon, sur une tranmission
   * @return SUCCESS, FAIL, TOOBAD
   */
  int receive_transmission();
  /** Faire les tests pour une tentative d'interception
   * @return score a atteindre
   */
  int try_to_intercept();
  /** Mettre le paquet
   * @param b true si le sol est glissant, false sinon
   * @return score a atteindre
   */
  int overmove(bool);
    ////////////////////////////////////////////////////////////////////////////
  // Ragnar Modif4 : cette version de la fonction remplace l'ancienne
  // décompte des soutiens offensif et défensifs comme pour un block classique
  int aggress(Player *);
  /** Pour savoir si un joueur est affecte par un coup de soleil
   * @return true si vrai, false sinon
   */
  bool is_affected_by_sunstroke(); 
  /** Faire les tests pour essayer d'atterir convenablement
   * @param bool la passe etait-elle parfaite?
   * @return score a atteindre
   */
  int landing(bool);
  /** Faire les tests pour lancer un coequipier
   * @param p Player qui va se faire projeter dans les airs
   * @param d distance du lancer
   * @return SUCCESS, FUMBLE, MISSED, FAIL, TOOBAD
   */
  int throw_team_mate(int);
  
  /** Savoir si un joueur est lancable
   * @return true ou false selon le cas
   */
  bool is_throwable(); 
  /** Savoir si un joueur est assez forte pour pouvoir lancer un coequipier
   * @return true ou false selon le cas
   */
  bool can_throw_team_mate(); 
  /** Poursuivre un joueur, cad dire bouger sans effectuer de test.
   * @param x_diff deplacement en x (-1,0,+1) 
   * @param y_diff deplacement en y (-1,0,+1) 
   */
  void pursue(int,int);

  std::list<Player*>* get_down_neighbours();
 
  int get_down_neighbours_count();

  std::list<Player*>* get_friend_neighbours();
  int get_friend_neighbours_count();
  int over_movement_left();

  void inc_move_count();
  void inc_move_count(int);
  int movement_left();
  void inc_overmove_count();
  int get_overmove_count();
  void reset_overmove_count();
  /** Connaitre le nombre de case de deplacement epuise
   * @return nombre de case de deplacement 
   */
  int get_move_count();
  void set_move_count(int);
  void set_overmove_count(int);
  /** Reinitialise le nombre de case de deplacement
   */
  
  bool get_move_reroll_used(void);
  void set_move_reroll_used(bool);

  void reset_move_count();
  void set_block_done(bool);
  bool is_block_done();

  ////////////////////////
  // Ragnar Modif2
  void set_get_up_done(bool);
  bool is_get_up_done();
  ////////////////////////
  // Ragnar Modif3
  void set_mighty_blow_used(bool);
  bool is_mighty_blow_used();
  void set_dirty_player_used(bool);
  bool is_dirty_player_used();
  void set_pilling_on_used(bool);
  bool is_pilling_on_used();
  ////////////////////////
  // Ragnar Modif4
  void set_frenzy_block_done(bool);
  bool is_frenzy_block_done();
  ////////////////////////
  // Ragnar Modif6 : nouveaux champs dans Player
  void set_bone_head_tested(bool);
  bool is_bone_head_tested();
  void set_really_stupid_tested(bool);
  bool is_really_stupid_tested();
  ////////////////////////

  void set_throw_done(bool);
  bool is_throw_done();
 
  void set_throw_team_mate_done(bool);
  bool is_throw_team_mate_done();
 
  void set_aggress_done(bool);
  bool is_aggress_done();

  void set_blitz_done(bool);
  bool is_blitz_done();

  void set_team_blitz_done(bool);
  bool is_team_blitz_done();

  void set_team_aggress_done(bool);
  bool is_team_aggress_done();

  void set_team_throw_done(bool);
  bool is_team_throw_done();
  
  void set_gather_done(bool);
  bool is_gather_done();

  void set_receive_done(bool);
  bool is_receive_done();

  bool can_transmit();
  bool can_move();
  bool can_overmove();
  bool can_block();
  bool can_catch(Square *);
  bool can_throw();
  bool can_aggress();
  bool can_move_and_blitz();
  bool can_blitz();
  bool can_do_something_more(Square *);
  bool has_done_something();
  void debug();
  void save_state(FILE*, int);
	
 protected:
  // attributs
  char* name; // nom 
  int number; // numero sur la feuille de match
  char* position; // poste (bloqueur, 3/4 etc...)
  int position_id;
  int cost; // valeur en tune
  int ma; // mouvement
  int st; // force
  int ag; // agilite
  int av; // armure
  int xps; // point d'experience
  char* picture_name;
  SDL_Surface* picture;
  int status; // ok, touche, blesse, exclut, gravement blesse ou meme mort
  std::list<char*> *skills; // liste des competences
  char* race; // race
  bool on_playground; // suis-je sur la pelouse
  bool has_ball; // ai-je le ballon
  bool selected; // suis-le joueur selectionne
  bool played; // ai-je deja joue
  Square *square; // la case que j'occupe
  Square *reserve_square; // la case que j'occupe dans la reserve
  int overmove_count; // nombre de case parcourut en plus du mouvement
  bool team_reroll_used; // la relance d'equipe est-elle utilise
  bool move_reroll_used;
  int team;  // id de l'equipe
  int move_count; // nombre de case parcourut dans le deplacement normal
  bool block_done;
  bool aggress_done;
  bool gather_done;
  bool throw_done;
  bool throw_team_mate_done;
  bool blitz_done;
  bool team_blitz_done;
  bool team_aggress_done;
  bool team_throw_done;
  bool receive_done;
  ////////////////////////
  // Ragnar Modif2
  bool get_up_done;
  // Ragnar Modif3
  bool mighty_blow_used;
  bool dirty_player_used;
  bool pilling_on_used;
  ////////////////////////
  // Ragnar Modif4
  bool frenzy_block_done;
  ////////////////////////
  // Ragnar Modif6 : nouveaux champs dans Player
  bool bone_head_tested;
  bool really_stupid_tested;
  ////////////////////////

  Dice *d6;
};

#endif



