/* 
    TowBowlTactics: Adaptation of the tabletop game Blood Bowl

    Copyright (C) 2001-2003 Pascal Bourut (toweld@rocketmail.com)

    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.
*/

#include "Main.h"

#ifndef NOSOUND
#include "sounds.h"
#endif

#ifndef NOVIDEO
#include "movies.h"
#endif

#ifndef NONET
#include "Network.h"
#include "NetClient.h"
#include "NetServer.h"
#endif

#include "Screen.h"
#include "Translator.h"

State *game_state;
SDL_Event event;
SDL_Surface *screen, *actions[3];
graphical_object *panel, *pg, *actions_menu, *pass_arrow, *reserve_nav[2][2];
panel_info_object *panel_info = NULL;
SDL_Surface *pg_empty,*reserve_empty,*reserve,*status,*circle, *player_img[2], *colored_dots, *colored_squares, *colored_crosses, *ball_img, *public_img, *pass_arrow_end, *pass_arrow_body,*push, *fonts[PANEL_FONTS], *panel_empty, *turn_pawn,*turn_indicator,*wheels,*url, *intercept_img,*rain,*copyright,*pawn_img,*sharp_img,*player_num_img,*blink_turn_indicator,*starplayer_img,*bigguys_img;
SDL_Surface *pg_zoomed, *console_font;
SDL_Rect throw_in_ball_s,throw_in_ball_d,old_throw_in_ball_d,pass_arrow_rect;
SDL_Rect kick_off_ball_s, kick_off_ball_d,old_kick_off_ball_d;
SDL_Surface *throw_in_ball;
SDL_Surface *kick_off_ball;
SDL_Surface *team_mate_img;
SDL_Surface* pass_ball_img;
SDL_Rect pass_s,pass_d,old_pass_d;
SDL_Rect team_mate_img_d;
SDL_Rect team_mate_img_s;
SDL_Rect old_team_mate_img_d;
SDL_Rect pg_cliprect,panel_cliprect,screen_cliprect,path_rect;
SDL_Rect victims_rect[6];

bool blinking = false;
char results[7] = {'>','<','<','<','<','<','>'};
bool update_console;
bool update_indicator;
bool focus_on_game;
int slide_playground;
//bool over_url;

int event_x_mouse,event_y_mouse;

Console *console;
Screen *screens;
DialogBox *dialog_box;
ProgressBar *progress_bar;

Dice *d2;
Dice *d3;
Dice *d4;
Dice *d6;
Dice *d8;
Dice *d66;
Dice *dblock;
Dice *d10;
Dice *d12;
Dice *d16;

#ifndef NOSOUND
SoundPlayer* sp;
#endif

#ifndef NOVIDEO
MoviePlayer* mp;
#endif

#ifndef NONET
Network* net;
#endif

SDL_Surface* load_image(char *datafile, int transparent){

  if(progress_bar) progress_bar->draw_next_step(datafile); 
  
  SDL_Surface *image;
  image = IMG_Load(datafile);
  if ( image == NULL ) {
    fprintf(stderr, "Couldn't load image %s: %s\n",datafile, IMG_GetError());
    return NULL;
  }
   
  if ( transparent ) {
    /* Assuming 8-bit BMP image */
    SDL_SetColorKey(image, (SDL_SRCCOLORKEY|SDL_RLEACCEL),*(Uint8 *)image->pixels);
  }
  
  SDL_Surface *r =  SDL_DisplayFormat(image);
  SDL_FreeSurface(image);

  return r;
}

int load_image_into(char *datafile, int transparent, graphical_object *obj){
  obj->image = load_image(datafile,transparent);
 
  return 0;
}

int set_object_position(graphical_object *obj, int x,int y){ 
  obj->x = x;
  obj->y = y;
  return 0;
}

int init(){
  const SDL_VideoInfo *vi;
  
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); 
    exit(1); 
  }
  atexit(SDL_Quit);

  vi = SDL_GetVideoInfo();
  if ( vi && vi->wm_available ) {
  	SDL_WM_SetCaption(CAPTION,CAPTION);
	SDL_WM_SetIcon(SDL_LoadBMP("./tbt.ico"), NULL);
  }

  Config::load();
		
  if ( !(screen = SDL_SetVideoMode(Config::get_screen_w(),Config::get_screen_h(), vi->vfmt->BitsPerPixel,SDL_SWSURFACE|SDL_DOUBLEBUF)) ){
	  fprintf(stderr, "Couldn't set %d %d: %s\n",Config::get_screen_w(), Config::get_screen_h(), SDL_GetError());
    exit(1);
  }
    
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);

  screens = new Screen(screen);
  
#ifndef NOVIDEO
	if(Config::is_video_enabled()){
		mp = new MoviePlayer();
	}
#endif

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp = new SoundPlayer();
		sp->set_volume(40);
		sp->set_enabled(true);
		screens->set_sound_player(sp);
	}

#ifndef NOVIDEO
	if(Config::is_video_enabled()){
		mp->set_sound_player(sp);	
	}
#endif

#endif

#ifndef NONET
	net = NULL;
#endif

	return 0;
}

int init_game(team_summary_t* home,team_summary_t* visitor){
	DEBUG ( printf("-> init_game()\n"); );

    game_state = new State();

	d2 = new Dice(D2);
	d3 = new Dice(D3);
	d4 = new Dice(D4);
	d6 = new Dice(D6);
	d8 = new Dice(D8);
	d66 = new Dice(D66);
	dblock = new Dice(DBLOCK);
	d10 = new Dice(D10);
	d12 = new Dice(D12);
	d16 = new Dice(D16);

	panel = (graphical_object*)malloc(sizeof(graphical_object));
	pg = (graphical_object*)malloc(sizeof(graphical_object));
	actions_menu = (graphical_object*)malloc(sizeof(graphical_object));
	panel_info = (panel_info_object*)malloc(sizeof(panel_info_object));
	panel_info->visible = false;

	reserve_nav[HOME][0] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[VISITOR][0] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[HOME][1] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[VISITOR][1] = (graphical_object*)malloc(sizeof(graphical_object));

	DEBUG ( printf("-> init_game: raz du playground\n"); );

	int i,j;
	for(i=0;i<PLAYGROUND_WIDTH;i++){
		for(j=0;j<PLAYGROUND_HEIGHT;j++){
			Shared::set_playground(i,j,NULL);
		}
	}

	DEBUG ( printf("-> init_game: fin raz du playground\n"); );
	DEBUG ( printf("-> init_game: raz des reserves\n"); );

	for(i=0;i<RESERVE_PAGE_W*RESERVE_PAGE_COUNT;i++){
		for(j=0;j<RESERVE_PAGE_H;j++){
			Shared::set_reserve_box(HOME,j,i,NULL);
			Shared::set_reserve_box(VISITOR,j,i,NULL);
		}
	}
  
	DEBUG ( printf("-> init_game: fin raz des reserves\n"); );

	DEBUG ( printf("-> init_game: dialog_box initialisation\n"); );
	dialog_box = new DialogBox(screen, Config::get_language()==0?"Fr":"En");

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		dialog_box->set_sound_player(sp);
	}
#endif

	DEBUG ( printf("-> init_game: fin dialog_box initialisation\n"); );

	DEBUG ( printf("-> init_game: console initialisation\n"); );
	console = new Console(screen,CONSOLE_X,CONSOLE_Y,CONSOLE_WIDTH,CONSOLE_HEIGHT,NONE);
	console->set_focus(false);
	console->set_visible(false);
	DEBUG ( printf("-> init_game: fin console initialisation\n"); );

	
	
	DEBUG ( printf("-> init_game: load_team HOME\n"); );
	game_state->team[HOME] = xml_load_team(home->filename,HOME);
	DEBUG ( printf("-> init_game: fin load_team HOME\n"); );
	
	DEBUG ( printf("-> init_game: load_team VISITOR\n"); );
	game_state->team[VISITOR] = xml_load_team(visitor->filename,VISITOR); 
	DEBUG ( printf("-> init_game: fin load_team VISITOR\n"); );

	DEBUG ( printf("LE MATCH DU JOUR EST %s vs %s\n",home->filename,visitor->filename); );

	DEBUG ( printf("-> init_game: open_vs_screen\n"); );
	screens->open_vs(home,visitor);
	DEBUG ( printf("-> init_game: fin open_vs_screen\n"); );
	
	DEBUG ( printf("-> init_game: load_game_data\n"); );

	load_game_data(-1);

	DEBUG ( printf("-> init_game: fin load_game_data\n"); );

	DEBUG ( printf("-> init_game: init ballon\n"); );
	game_state->ball = new Ball();
	game_state->ball->set_visible(false);
	game_state->ball->place(-1,-1);
  
	DEBUG ( printf("-> init_game: init public\n"); );
	game_state->audience = new Public;
  
	DEBUG ( printf("-> init_game: init selection\n"); );
	
	pg_zoomed = NULL;

	slide_playground = NONE;
	focus_on_game = true;
 
	DEBUG ( printf("-> init_game: contextual_info\n"); );
	game_state->contextual_info->font = DT_InitFont(console_font, TRANS_FONT);
	game_state->contextual_info->visible = true;
	set_contextual_info(Config::get_screen_w(),Config::get_screen_h(),"");
	DEBUG ( printf("-> init_game: fin contextual_info\n"); );
  
	DEBUG ( printf("-> init_game: prepare_for_next_kick_off\n"); );
	prepare_for_next_kick_off();
	DEBUG ( printf("-> init_game: fin prepare_for_next_kick_off\n"); );

	DEBUG ( printf("<- init_game\n"); );

	return 0;
}

int init_game_from_save(State *loaded_state){
	
	game_state = loaded_state;

	d2 = new Dice(D2);
	d3 = new Dice(D3);
	d4 = new Dice(D4);
	d6 = new Dice(D6);
	d8 = new Dice(D8);
	d66 = new Dice(D66);
	dblock = new Dice(DBLOCK);
	d10 = new Dice(D10);
	d12 = new Dice(D12);
	d16 = new Dice(D16);

	panel = (graphical_object*)malloc(sizeof(graphical_object));
	pg = (graphical_object*)malloc(sizeof(graphical_object));
	actions_menu = (graphical_object*)malloc(sizeof(graphical_object));
	panel_info = (panel_info_object*)malloc(sizeof(panel_info_object));
	panel_info->visible = false;

	reserve_nav[HOME][0] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[VISITOR][0] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[HOME][1] = (graphical_object*)malloc(sizeof(graphical_object));
	reserve_nav[VISITOR][1] = (graphical_object*)malloc(sizeof(graphical_object));

	dialog_box = new DialogBox(screen, Config::get_language()==0?"Fr":"En");

	console = new Console(screen,CONSOLE_X,CONSOLE_Y,CONSOLE_WIDTH,CONSOLE_HEIGHT,NONE);
	console->set_focus(false);
	console->set_visible(false);

	team_summary_t * home = (team_summary_t*)malloc(sizeof(team_summary_t));
	memset(home,0,sizeof(team_summary_t));
	home->name = (char*) malloc( CHAR_64 );
	strcpy(home->name, game_state->team[HOME]->get_name());
	home->emblem = (char*) malloc( CHAR_64 );
	strcpy(home->emblem, game_state->team[HOME]->get_emblem());
		
	team_summary_t * visitor = (team_summary_t*)malloc(sizeof(team_summary_t));
	memset(visitor,0,sizeof(team_summary_t));
    visitor->name = (char*) malloc( CHAR_64 );
	strcpy(visitor->name, game_state->team[VISITOR]->get_name());
	visitor->emblem = (char*) malloc( CHAR_64 );
	strcpy(visitor->emblem, game_state->team[VISITOR]->get_emblem());

	screens->open_vs(home,visitor);

	free(home->name);
	free(home->emblem);
	free(home);
	
	free(visitor->name);
	free(visitor->emblem);
	free(visitor);

	load_game_data(game_state->weather);

	pg_zoomed = NULL;

	slide_playground = NONE;
	focus_on_game = true;

	game_state->contextual_info->font = DT_InitFont(console_font, TRANS_FONT);
	set_contextual_info(Config::get_screen_w(),Config::get_screen_h(),"");
	game_state->contextual_info->visible = true;
	game_state->turn_begining_time = SDL_GetTicks() - (TURN_DURATION - game_state->remaining_time)*1000;
	
	draw_all(true);
	return 0;
}

int load_game_data(int w){  
  progress_bar = new ProgressBar(screen);
  progress_bar->set_data_count(TOTAL_DATA + 4 + game_state->team[HOME]->get_players()->size() + game_state->team[VISITOR]->get_players()->size());

  if(w!=-1){
	switch(game_state->weather){
		case DOGDAYS: w = 2;break;
		case SUNNY: w = 3;break;
		case GOOD: w = 7;break;
		case SHOWER: w = 11;break;
		case BLIZZARD: w = 12;break;
		default: w = 7; break;
	}
  }
  else {
	w = d6->roll(2);
  }

  set_weather(w);

  sharp_img = load_image(ADD_IMG_PATH("panel/sharp.png"),TRANSPARENT);
  pawn_img = load_image(ADD_IMG_PATH("general/pawn.png"),TRANSPARENT);
  player_num_img = load_image(ADD_IMG_PATH("general/player_num.png"),TRANSPARENT);
  SDL_SetAlpha(pawn_img, ALPHA_FLAGS, 220);
  ball_img = load_image(ADD_IMG_PATH("general/ball.png"),TRANSPARENT);
  load_image_into(ADD_IMG_PATH("panel/panel.jpg"),NO_TRANSPARENT,panel);
  panel_empty = SDL_ConvertSurface(panel->image, panel->image->format, panel->image->flags);
  public_img = load_image(ADD_IMG_PATH("general/public.jpg"),NO_TRANSPARENT);
  pass_arrow_body = load_image(ADD_IMG_PATH("general/pass_arrow_body.jpg"),NO_TRANSPARENT);
  pass_arrow_end = load_image(ADD_IMG_PATH("general/pass_arrow_end.png"),TRANSPARENT);
  push = load_image(ADD_IMG_PATH("general/push.png"),TRANSPARENT);
  actions[ITEM_OFF] = load_image(ADD_IMG_PATH("general/actions_off.jpg"),NO_TRANSPARENT);
  actions[ITEM_ON] = load_image(ADD_IMG_PATH("general/actions_on.jpg"),NO_TRANSPARENT);
  actions[ITEM_UP] = load_image(ADD_IMG_PATH("general/actions_up.jpg"),NO_TRANSPARENT);
  circle = load_image(ADD_IMG_PATH("general/circle.png"),TRANSPARENT);
  status = load_image(ADD_IMG_PATH("general/status.png"),TRANSPARENT);
  colored_squares = load_image(ADD_IMG_PATH("general/rgbbw.png"),NO_TRANSPARENT);
  colored_dots = load_image(ADD_IMG_PATH("general/dots_rgbbw.png"),NO_TRANSPARENT);
  colored_crosses = load_image(ADD_IMG_PATH("general/crosses_rgbbw.png"),NO_TRANSPARENT);
  fonts[PANEL_CARAC_FONT] = load_image(ADD_IMG_PATH("panel/digits_score.png"),TRANSPARENT);
  fonts[PANEL_UPPER_FONT] = load_image(ADD_IMG_PATH("panel/upper_chars.png"),TRANSPARENT);
  fonts[PANEL_LOWER_FONT] = load_image(ADD_IMG_PATH("panel/lower_chars.png"),TRANSPARENT);
  fonts[PANEL_TIME_FONT] = load_image(ADD_IMG_PATH("panel/digits_time.png"),TRANSPARENT);
  fonts[PANEL_REROLL_FONT] = load_image(ADD_IMG_PATH("panel/digits_reroll.png"),TRANSPARENT);
  fonts[PANEL_SKILLS_FONT] = load_image(ADD_IMG_PATH("panel/skills_chars.png"),TRANSPARENT);
  turn_pawn = load_image(ADD_IMG_PATH("panel/turn.png"),TRANSPARENT);
  turn_indicator = load_image(ADD_IMG_PATH("panel/turn_in.jpg"),NO_TRANSPARENT);
  blink_turn_indicator = load_image(ADD_IMG_PATH("panel/turn_in.jpg"),NO_TRANSPARENT);
  wheels = load_image(ADD_IMG_PATH("panel/wheels.png"),TRANSPARENT);
  url = load_image(ADD_IMG_PATH("panel/url.jpg"),NO_TRANSPARENT);
  copyright = load_image(ADD_IMG_PATH("panel/copyright.png"),TRANSPARENT);
  intercept_img = load_image(ADD_IMG_PATH("general/intercept.png"),TRANSPARENT);
  load_image_into(ADD_IMG_PATH("general/reserve_navigator_down.png"),TRANSPARENT,reserve_nav[HOME][0]);
  load_image_into(ADD_IMG_PATH("general/reserve_navigator_up.png"),TRANSPARENT,reserve_nav[HOME][1]);
  load_image_into(ADD_IMG_PATH("general/reserve_navigator_down.png"),TRANSPARENT,reserve_nav[VISITOR][0]);
  load_image_into(ADD_IMG_PATH("general/reserve_navigator_up.png"),TRANSPARENT,reserve_nav[VISITOR][1]);

  progress_bar->draw_next_step("dialog box data..."); 
  dialog_box->load_images();

  console_font = IMG_Load(ADD_IMG_PATH("general/console_font.png"));

  SDL_Surface *tmp = SDL_AllocSurface(SDL_HWSURFACE,
										ACTIONS_MENU_WIDTH, ACTIONS_MENU_HEIGHT,
										screen->format->BitsPerPixel,
										screen->format->Rmask,
										screen->format->Gmask,
										screen->format->Bmask,
										screen->format->Amask);

	actions_menu->image  =  SDL_DisplayFormat(tmp);
	SDL_FreeSurface(tmp);

  actions_menu->visible = false; 

  SDL_SetAlpha(actions_menu->image, ALPHA_FLAGS, 225);
  SDL_SetAlpha(circle, ALPHA_FLAGS, 175);
  SDL_SetAlpha(colored_squares, ALPHA_FLAGS, ALPHA_SQUARES); 
  SDL_SetAlpha(colored_dots, ALPHA_FLAGS, ALPHA_DOTS); 
  SDL_SetAlpha(colored_crosses, ALPHA_FLAGS, ALPHA_CROSSES); 
  SDL_SetAlpha(push, ALPHA_FLAGS, ALPHA_PUSH);
  SDL_SetAlpha(intercept_img, ALPHA_FLAGS, ALPHA_INTERCEPT);
  game_state->reserve_nav_alpha[HOME][0] = ALPHA_RESERVE_NAV;
  game_state->reserve_nav_alpha[VISITOR][0] = ALPHA_RESERVE_NAV;
  game_state->reserve_nav_alpha[HOME][1] = ALPHA_RESERVE_NAV;
  game_state->reserve_nav_alpha[VISITOR][1] = ALPHA_RESERVE_NAV;
  SDL_SetAlpha(reserve_nav[HOME][0]->image, ALPHA_FLAGS, ALPHA_RESERVE_NAV);
  SDL_SetAlpha(reserve_nav[VISITOR][0]->image, ALPHA_FLAGS, ALPHA_RESERVE_NAV);
  SDL_SetAlpha(reserve_nav[HOME][1]->image, ALPHA_FLAGS, ALPHA_RESERVE_NAV);
  SDL_SetAlpha(reserve_nav[VISITOR][1]->image, ALPHA_FLAGS, ALPHA_RESERVE_NAV);

  SDL_SetAlpha(player_num_img, ALPHA_FLAGS, 200);
  SDL_SetAlpha(blink_turn_indicator, ALPHA_FLAGS, 125);

  set_object_position(panel,PANEL_X, PANEL_Y);
 
  set_object_position(pg,-pg->image->w+FRAME_LIMIT,Config::get_screen_h()/2-SQUARE_TO_PIXEL(PLAYGROUND_HEIGHT/2)-SQUARE_SIZE/2);
  
  // je loade la barre d'image pour les pions des deux equipes
  char str[256];
  sprintf(str,"%s/figs/%s.png",IMG_PATH,game_state->team[HOME]->get_race());
  player_img[HOME] = load_image(str,TRANSPARENT);
  sprintf(str,"%s/figs/%s.png",IMG_PATH,game_state->team[VISITOR]->get_race());
  player_img[VISITOR] = load_image(str,TRANSPARENT);

  starplayer_img = load_image(ADD_IMG_PATH("figs/starplayers/starplayers.png"),TRANSPARENT);
  bigguys_img = load_image(ADD_IMG_PATH("figs/bigguys/bigguys.png"),TRANSPARENT);

  // je loade les images individuelles de chaque gars
  std::map<int,Player*> ::iterator it;
  map<int,Player*> *players;
  int i;
  SDL_Surface* s_tmp;

  for ( i=HOME ; i<=VISITOR ; i++ ) {
	  players = game_state->team[i]->get_players();
	  for(it=players->begin();it!=players->end();it++){
		sprintf(str,"%s/figs/%s",IMG_PATH,((*it).second)->get_picture_name());
		s_tmp = load_image(str,NO_TRANSPARENT);
		((*it).second)->set_picture(s_tmp);
	}
  }


  SDL_SetEventFilter(filter_events);

  delete progress_bar;
  progress_bar = NULL;

  return 0;
}

int free_minimum_data(){
	DEBUG ( printf("-> free_minimum_data()\n"); );

	screens->free_images(ALL_SCREENS);
#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		delete sp;
	}
#endif

#ifndef NOVIDEO
	if(Config::is_video_enabled()){
		delete mp;
	}
#endif

  delete screens;

  SDL_FreeSurface(screen);
  DEBUG ( printf("<- free_minimum_data()\n"); );
  return 0;
}

int free_game_data(){

	reset_vars();

	SDL_SetEventFilter(NULL);
	SDL_FreeSurface(console_font);
	SDL_FreeSurface(panel->image);
	SDL_FreeSurface(sharp_img);
	SDL_FreeSurface(pg->image);
	SDL_FreeSurface(pg_empty);
	SDL_FreeSurface(reserve);
	SDL_FreeSurface(reserve_empty);
	SDL_FreeSurface(pawn_img);
	SDL_FreeSurface(player_num_img);
	SDL_FreeSurface(starplayer_img);
	SDL_FreeSurface(bigguys_img);
	free(pg);

	SDL_FreeSurface(actions_menu->image);
	SDL_FreeSurface(actions[ITEM_OFF]);
	SDL_FreeSurface(actions[ITEM_ON]);
	SDL_FreeSurface(actions[ITEM_UP]);
	SDL_FreeSurface(player_img[HOME]);
	SDL_FreeSurface(player_img[VISITOR]);
	if(rain) SDL_FreeSurface(rain);
	SDL_FreeSurface(circle);
	SDL_FreeSurface(status);
	SDL_FreeSurface(reserve_nav[HOME][0]->image);
	SDL_FreeSurface(reserve_nav[VISITOR][0]->image);
	SDL_FreeSurface(reserve_nav[HOME][1]->image);
	SDL_FreeSurface(reserve_nav[VISITOR][1]->image);

	free(reserve_nav[HOME][0]);
	free(reserve_nav[VISITOR][0]);
	free(reserve_nav[HOME][1]);
	free(reserve_nav[VISITOR][1]);

	SDL_FreeSurface(colored_dots);
	SDL_FreeSurface(colored_squares);
	SDL_FreeSurface(colored_crosses);
	SDL_FreeSurface(ball_img);
	SDL_FreeSurface(public_img);
	SDL_FreeSurface(pass_arrow_end);
	SDL_FreeSurface(pass_arrow_body);
	SDL_FreeSurface(push);
	for(int i=0;i<PANEL_FONTS;i++){
		SDL_FreeSurface(fonts[i]);
	}
	SDL_FreeSurface(panel_empty);
	SDL_FreeSurface(turn_indicator);
	SDL_FreeSurface(blink_turn_indicator);
	SDL_FreeSurface(turn_pawn);
	SDL_FreeSurface(wheels);
	SDL_FreeSurface(url);
	SDL_FreeSurface(copyright);
	SDL_FreeSurface(intercept_img);
  
	free(panel);
	free(actions_menu);
	free(pass_arrow);
	pass_arrow = NULL;
	free(panel_info);
	
	delete dialog_box;
	delete console;
	delete d2;
	delete d3;
	delete d4;
	delete d6;
	delete d8;
	delete d66;
	delete dblock;
	delete d10;
	delete d12;
	delete d16;
	delete game_state;
	game_state = NULL;

	return 0;
}

int filter_events(const SDL_Event *event){

  if(event->type == SDL_MOUSEMOTION){
	event_x_mouse = event->motion.x;
	event_y_mouse = event->motion.y;
  }

  if(dialog_box->is_visible() || screens->is_visible()) return 1;  // 0 -> effacer event, 1 -> continue
  // tout d'abord les events que je gere tout le temps sauf durant les boites de dialogue 

  if(game_state->grab_mouse_mode && (event->type == SDL_MOUSEMOTION) && (event->motion.x > (FRAME_LIMIT-FRAME_LINE))){
    SDL_WarpMouse(FRAME_LIMIT-FRAME_LINE-1,event->motion.y);
  }

  if(event->type == SDL_QUIT){   
	quit_game_box();
  }
  else if(event->type == SDL_ACTIVEEVENT){
    if ( event->active.state & SDL_APPACTIVE ) {
      if ( event->active.gain ) {
	DEBUG( printf("Application activate\n"); );
      } else {
	DEBUG( printf("Application iconifie\n"); );
	if(game_state->current_mode==MODE_PLAYING) toggle_pause(true);
      }
    }
    if ( event->active.state & SDL_APPMOUSEFOCUS ) {
      if ( event->active.gain ) {
	DEBUG( printf("Application gagne le focus\n"); );
	focus_on_game = true;
      } else {
	DEBUG( printf("Application perd le focus\n"); );
	focus_on_game = false;
      }
    }   
  }
  else if(event->type == SDL_KEYUP){
    if(event->key.keysym.sym==SDLK_SPACE)
      toggle_grab_mouse_mode(false);
    if(event->key.keysym.sym==SDLK_LCTRL){
      if(actions_menu->visible && game_state->selected_player){
		if(game_state->selected_player->can_block()){
			game_state->actions_menu_items[ACTIONS_BLOCK_INDEX] = ACTIONS_BLOCK;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);  
			set_actions_menu(ACTIONS_BLOCK,game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX],ACTIONS_BLOCK_INDEX);
		}
		else if(game_state->selected_player->can_overmove() && game_state->actions_menu_items[ACTIONS_MOVE_INDEX] == ACTIONS_MOVE_AND_BLITZ ){
			game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_MOVE_PLUS;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);  
			set_actions_menu(ACTIONS_MOVE_PLUS,game_state->actions_menu_items_state[ACTIONS_MOVE_INDEX],ACTIONS_MOVE_INDEX);
		}

		if(game_state->selected_player->can_throw() ){
			game_state->actions_menu_items[ACTIONS_THROW_INDEX] = ACTIONS_THROW;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);
			set_actions_menu(ACTIONS_THROW,game_state->actions_menu_items_state[ACTIONS_THROW_INDEX],ACTIONS_THROW_INDEX);
			game_state->actions_menu_throw_team_mate = false;
		}

		if(game_state->selected_player->can_aggress() ){
			game_state->actions_menu_items[ACTIONS_AGGRESS_INDEX] = ACTIONS_AGGRESS;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);
			set_actions_menu(ACTIONS_AGGRESS,game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX],ACTIONS_AGGRESS_INDEX);
			game_state->actions_menu_leap = false;
		}
      }
    }  
  }
  else if(event->type == SDL_KEYDOWN){
    switch(event->key.keysym.sym){
    case SDLK_ESCAPE: 
	  quit_game_box();  
      break;
	  case 96: // touche ² 
	  case SDLK_F1:
		console->toggle_visibility();
		draw_all(true);
		return 0;
		break;
	  case SDLK_F2:
		if(-1!=save_game("quicksave"))
			console->print("Quick save ok !");
		else 
			console->print("Quick save failed !");

		if( !console->get_visible() ){
			console->set_visible(true);
			draw_all(true);
			SDL_Delay(750);
			console->set_visible(false);
		}
		
		draw_all(true);
		return 0;
		break;
	  case SDLK_RCTRL:
	  case SDLK_LCTRL:
      if(actions_menu->visible && game_state->selected_player ){
		if( !(game_state->team[game_state->selected_player->get_team()]->is_blitz_done()) && game_state->selected_player->can_blitz() ){
			game_state->actions_menu_items[ACTIONS_BLOCK_INDEX] = ACTIONS_BLITZ;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);
			set_actions_menu(ACTIONS_BLITZ,game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX],ACTIONS_BLOCK_INDEX);
		}
		else if(game_state->selected_player->can_overmove() && game_state->actions_menu_items[ACTIONS_MOVE_INDEX] == ACTIONS_MOVE_PLUS && !(game_state->team[game_state->selected_player->get_team()]->is_blitz_done()) && game_state->selected_player->can_move_and_blitz() ){
			game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_MOVE_AND_BLITZ;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);  
			set_actions_menu(ACTIONS_BLITZ,game_state->actions_menu_items_state[ACTIONS_MOVE_INDEX],ACTIONS_MOVE_INDEX);
		}
      
		if( !(game_state->team[game_state->selected_player->get_team()]->is_throw_team_mate_done()) && 
			  game_state->selected_player->can_throw_team_mate() && 
			  game_state->selected_player->friend_neighbours_has_got_skill(RIGHT_STUFF) && 
			  game_state->selected_player->get_status() == OK){
			game_state->actions_menu_items[ACTIONS_THROW_INDEX] = ACTIONS_CHOOSE_TEAM_MATE;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);
			set_actions_menu(ACTIONS_CHOOSE_TEAM_MATE,(game_state->actions_menu_items_state[ACTIONS_THROW_INDEX]==ITEM_UP)?ITEM_UP:ITEM_ON,ACTIONS_THROW_INDEX);
			game_state->actions_menu_throw_team_mate = true;
		}

		if(   game_state->selected_player->movement_left()>=2 && 
			  game_state->selected_player->has_got_skill(LEAP) &&
			  game_state->selected_player->get_status() == OK){
			game_state->actions_menu_items[ACTIONS_AGGRESS_INDEX] = ACTIONS_LEAP;
			SDL_Rect tmp;
			tmp.x = actions_menu->x;
			tmp.y = actions_menu->y;
			tmp.w = actions_menu->image->w;
			tmp.h = actions_menu->image->h;
			pg_cliprect = rect_union(pg_cliprect,tmp);
			set_actions_menu(ACTIONS_LEAP,(game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX]==ITEM_UP)?ITEM_UP:ITEM_ON,ACTIONS_AGGRESS_INDEX);
			game_state->actions_menu_leap = true;
		}
	  }
      break;
    case SDLK_SPACE:
      if(!console->get_focus()) {
		toggle_grab_mouse_mode(true);
		return 0;
	  }
      break;
    case SDLK_f: 
		if(!console->get_focus()) {
			SDL_WM_ToggleFullScreen(screen);
			return 0;
		}
      break;
	case SDLK_p:
		if(!console->get_focus()) {
			toggle_pause(!game_state->pause);
			return 0;
	    }
		else if(game_state->pause){
			toggle_pause(false);
		}
      break;

#ifndef NOSOUND
	case SDLK_F3:
		if(Config::is_sound_enabled())
			sp->dec_volume();
		break;
	case SDLK_F4:
		if(Config::is_sound_enabled())
			sp->inc_volume();
		break;
#endif

	case SDLK_F5:
	  if(game_state->current_mode==MODE_TEAM_PLACEMENT){
		change_formation(game_state->team_in_placement, 0);
		return 0;
	  }
	  break;
	case SDLK_F6:
	  if(game_state->current_mode==MODE_TEAM_PLACEMENT){
		change_formation(game_state->team_in_placement, 1);
		return 0;
	  }
	  break;
	case SDLK_F7:
	  if(game_state->current_mode==MODE_TEAM_PLACEMENT){
		change_formation(game_state->team_in_placement, 2);
		return 0;
	  }
	  break;
	case SDLK_F8:
	  if(game_state->current_mode==MODE_TEAM_PLACEMENT){
		change_formation(game_state->team_in_placement, 3);
		return 0;
	  }
	  break;

	DEBUG ( 
	case SDLK_HOME: // debut de tour
	  if(game_state->current_mode==MODE_PLAYING){
		
		  if( game_state->active_team!=HOME ){
			if(game_state->active_team==NONE && (game_state->old_active_team==NONE||game_state->team[HOME]->has_free_turn()) && ((game_state->kick_off_team==VISITOR&&(!game_state->team[VISITOR]->has_free_turn())) || (game_state->kick_off_team==HOME && game_state->team[HOME]->has_free_turn()) )) start_turn(HOME);
			if(game_state->old_active_team==VISITOR) start_turn(HOME);
	      }
	      if( game_state->active_team!=VISITOR ){
			if(game_state->active_team==NONE && (game_state->old_active_team==NONE||game_state->team[VISITOR]->has_free_turn()) && ((game_state->kick_off_team==HOME&&(!game_state->team[HOME]->has_free_turn())) || (game_state->kick_off_team==VISITOR && game_state->team[VISITOR]->has_free_turn()) )) start_turn(VISITOR);
			if(game_state->old_active_team==HOME) start_turn(VISITOR);
	      }
	      
		return 0;
	  }	
	  break;
	
	case SDLK_END: // fin de tour
	  if(game_state->current_mode==MODE_PLAYING){
		if(game_state->active_team==HOME) stop_turn();
		else if(game_state->active_team==VISITOR) stop_turn();	      	
		return 0;
	  }	
	  break;
  
	);

    default:
	  break;
    }
  }  

  if( game_state->pause ) return 0;

  // et maintenant les events gere uniquement pour jouer cad quand il n'y a pas la game_state->pause
  if ( event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT ) {
		if(console->get_visible()){
			if( (!console->get_focus()) && (FILTER_CLIC_INTO_RECT(CONSOLE_X,console->get_y(),CONSOLE_WIDTH,console->get_height())) ){
				console->set_focus(true);
				update_console = true;
				return 0;
			} 
			else if( console->get_focus() ) {
				if (!FILTER_CLIC_INTO_RECT(CONSOLE_X,console->get_y(),CONSOLE_WIDTH,console->get_height()) ){
					console->set_focus(false);
					update_console = true;
				}
			return 0;
			}
		}
	}

  if ( event->type == SDL_MOUSEMOTION  ) {

    SDL_Rect d,s;
    s.x = 0;
    s.y = 0;
    s.w = PANEL_URL_WIDTH;
    s.h = PANEL_URL_HEIGHT;
    d.x = PANEL_URL_X;
    d.y = PANEL_URL_Y;
    d.w = s.w;
    d.h = s.h;

    if(game_state->freeze_interaction) return 1;

    int x_pg = pg->x;
    int y_pg = pg->y;

    if(game_state->grab_mouse_mode && (event->motion.x < SIDE_SIZE) && (x_pg!=0) ) {
      slide_playground = W;
    }
    else if(game_state->grab_mouse_mode && (event->motion.x <= FRAME_LIMIT-FRAME_LINE) && (event->motion.x > FRAME_LIMIT-FRAME_LINE-SIDE_SIZE)&& (x_pg != -pg->image->w+FRAME_LIMIT) ) {
      slide_playground = E;
    }
    else if(game_state->grab_mouse_mode &&  (event->motion.y < SIDE_SIZE) && (y_pg!=0) && (event->motion.x <= FRAME_LIMIT-FRAME_LINE) ) {
      slide_playground = N;
    }
    else if(game_state->grab_mouse_mode && (event->motion.y <= Config::get_screen_h()) && (event->motion.y > Config::get_screen_h()-SIDE_SIZE) && (y_pg != -pg->image->h+Config::get_screen_h()) && (event->motion.x <= FRAME_LIMIT-FRAME_LINE) ) {
      slide_playground = S;
    }
    else slide_playground = NONE;
   
    int x_mouse = event->motion.x - pg->x;
    int y_mouse = event->motion.y - pg->y;
    int x_square = (x_mouse-MARGIN_SIZE)/SQUARE_SIZE;
    int y_square = (y_mouse-MARGIN_SIZE)/SQUARE_SIZE;
   
    for(int i=HOME; i<=VISITOR; i++){
      for(int j=0;j<=1;j++){
	
	if( REL_MOUSE_OVER_RECT(reserve_nav[i][j]->x,
				reserve_nav[i][j]->y,
				reserve_nav[i][j]->image->w,
				reserve_nav[i][j]->image->h) ){
	  game_state->reserve_nav_alpha[i][j] = ALPHA_RESERVE_NAV*2;
	  SDL_SetAlpha(reserve_nav[i][j]->image, ALPHA_FLAGS,game_state->reserve_nav_alpha[i][j]);
	  pg_cliprect.x = reserve_nav[i][j]->x;
	  pg_cliprect.y = reserve_nav[i][j]->y;
	  pg_cliprect.w = reserve_nav[i][j]->image->w;
	  pg_cliprect.h = reserve_nav[i][j]->image->h;
	}
	else if(game_state->reserve_nav_alpha[i][j] != ALPHA_RESERVE_NAV) {
	   game_state->reserve_nav_alpha[i][j] = ALPHA_RESERVE_NAV;
	  SDL_SetAlpha(reserve_nav[i][j]->image, ALPHA_FLAGS,game_state->reserve_nav_alpha[i][j] );
	  pg_cliprect.x = reserve_nav[i][j]->x;
	  pg_cliprect.y = reserve_nav[i][j]->y;
	  pg_cliprect.w = reserve_nav[i][j]->image->w;
	  pg_cliprect.h = reserve_nav[i][j]->image->h;
	}
      }
    }
   
	if(OVER_PLAYGROUND(x_mouse,y_mouse) && Shared::get_playground(x_square,y_square)){
		fill_panel_player_info(Shared::get_playground(x_square,y_square));
	}
	else if(game_state->selected_player && game_state->selected_player->is_selected()){
		fill_panel_player_info(game_state->selected_player);
	}
	else if(game_state->current_mode==MODE_TEAM_PLACEMENT && game_state->player_to_place){
		fill_panel_player_info(game_state->player_to_place);
	}
	else {
		erase_panel_player_info();
	}

    switch(game_state->current_mode){
    case MODE_NONE:      
      break;
    case MODE_SURPRISE:
      if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) &&
	  game_state->selected_player &&
	  game_state->selected_player->get_square() && 
	  !Shared::get_playground(x_square,y_square) && 
	  abs(x_square - game_state->selected_player->get_square()->get_x()) <= 1 &&
	  abs(y_square - game_state->selected_player->get_square()->get_y()) <= 1){
	SDL_Rect tmp;
	if(game_state->target){
	  tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  tmp.w = SQUARE_SIZE;
	  tmp.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
	else {
	  tmp.x = -1;
	}
	
	if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);  

	game_state->target = new Square(x_square,y_square);
	
	tmp.x = SQUARE_TO_PIXEL(x_square);
	tmp.y = SQUARE_TO_PIXEL(y_square);
	tmp.w = SQUARE_SIZE;
	tmp.h = SQUARE_SIZE;
	
	if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);  
      }
      else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	if(game_state->target){
	  pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
      }
      break;
    case MODE_CHOOSE_BALL_OWNER:
      if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	SDL_Rect tmp;
	if(game_state->target){
	  tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  tmp.w = SQUARE_SIZE;
	  tmp.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
	else {
	  tmp.x = -1;
	}
	
	if ( Shared::get_playground(x_square,y_square) && Shared::get_playground(x_square,y_square)->get_status()==OK && Shared::get_playground(x_square,y_square)->get_team()!=game_state->kick_off_team ){
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);
	}
	else {
	  if(tmp.x != -1) pg_cliprect = tmp;
	}
      }
      else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	if(game_state->target){
	  pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
      }
      break;
    case MODE_BALL_PLACEMENT:
      if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	SDL_Rect tmp;
	if(game_state->target){
	  tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  tmp.w = SQUARE_SIZE;
	  tmp.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
	else {
	  tmp.x = -1;
	}
	
	if ( (game_state->kick_off_team==VISITOR && y_square>=0 && y_square<PLAYGROUND_HEIGHT/2) || ( game_state->kick_off_team==HOME && y_square>=PLAYGROUND_HEIGHT/2 && y_square<PLAYGROUND_HEIGHT ) ){
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);
	}
	else {
	  if(tmp.x != -1) pg_cliprect = tmp;
	}
      }
      else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	if(game_state->target){
	  pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	  pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  delete game_state->target;
	  game_state->target = NULL;
	}
      }
      break;
    case MODE_TEAM_PLACEMENT:
      if( event->motion.x < (FRAME_LIMIT-FRAME_LINE) && game_state->player_to_place ){
	pg_cliprect.x = game_state->player_to_place_x - (SQUARE_SIZE*3/2);
	pg_cliprect.y = game_state->player_to_place_y - (SQUARE_SIZE*3/2);
	pg_cliprect.w = SQUARE_SIZE*4;
	pg_cliprect.h = SQUARE_SIZE*4;
	game_state->player_to_place_x = x_mouse - SQUARE_SIZE/2;
	game_state->player_to_place_y = y_mouse - SQUARE_SIZE/2;
	
	SDL_Rect tmp;
	tmp.x = game_state->player_to_place_x - (SQUARE_SIZE*3/2);
	tmp.y = game_state->player_to_place_y - (SQUARE_SIZE*3/2);
	tmp.w = SQUARE_SIZE*4;
	tmp.h = SQUARE_SIZE*4;
	pg_cliprect = rect_union(pg_cliprect,tmp);
      }
      
      if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) && (!Shared::get_playground(x_square,y_square)) && game_state->player_to_place && !OVER_DOCK(x_mouse,y_mouse) 
	  ){
	delete game_state->location_square;
	game_state->location_square = NULL;
	if (is_good_location(game_state->player_to_place, x_square, y_square)){
	  game_state->location_square = new Square(x_square,y_square);
	}
      }
      else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
		delete game_state->location_square;
		game_state->location_square = NULL;
      }
      break;
    case MODE_PLAYING:

      // -->
      switch(game_state->current_action){
	  case ACTIONS_LEAP:
		if( OVER_PLAYGROUND(x_mouse,y_mouse) && 
		(x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&
		(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) && 
		!Shared::get_playground(x_square,y_square) && 
		abs(x_square - game_state->selection->get_x()) <= 2 &&
	    abs(y_square - game_state->selection->get_y()) <= 2 && 
		abs(x_square - game_state->selection->get_x()) != 1 &&
	    abs(y_square - game_state->selection->get_y()) != 1 ){
	  SDL_Rect tmp;
	  
	  if(game_state->target){
	    tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    tmp.x = -1;
	  }	  
	  
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);

	  set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());

	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  if(game_state->target){
	    pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    pg_cliprect.w = SQUARE_SIZE;
	    pg_cliprect.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
   	    
		unset_contextual_info();

	  }
	}
	

	  break;
      case ACTIONS_CHOOSE_TRANSMIT_SQUARE:
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	  game_state->transmit_square = NULL;
	  SDL_Rect tmp;

	  for(int i=0;i<game_state->transmit_square_count;i++){
	    int x_s = game_state->transmit_squares[i]->get_x();
	    int y_s = game_state->transmit_squares[i]->get_y();
	    tmp.x = SQUARE_TO_PIXEL(x_s);
	    tmp.y = SQUARE_TO_PIXEL(y_s);
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect, tmp);
	    if( x_square == x_s &&
		y_square == y_s  ){
	      game_state->transmit_square = game_state->transmit_squares[i];
	    }
	  }

	  if(game_state->transmit_square) {
			set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());
	  }
	  else unset_contextual_info();

	}
	break;
      case ACTIONS_CHOOSE_INTERCEPTION_SQUARE:
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	  game_state->interception_square = NULL;
	  SDL_Rect tmp;
	 
 	  for(int i=0;i<game_state->interception_square_count;i++){
	    int x_s = game_state->interception_squares[i]->get_x();
	    int y_s = game_state->interception_squares[i]->get_y();
	    tmp.x = SQUARE_TO_PIXEL(x_s);
	    tmp.y = SQUARE_TO_PIXEL(y_s);
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect, tmp);
	    if( x_square == x_s &&
		y_square == y_s  ){
	      game_state->interception_square = game_state->interception_squares[i];
	    }
	  }

	if(game_state->interception_square) {
			set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());
	  }
	  else unset_contextual_info();


	}
	break;
      case ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE:
      case ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE:
		if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
		  
		  DEBUG( printf("ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE game_state->x_push=%d game_state->y_push=%d game_state->target->get_x()=%d game_state->target->get_y()=%d\n",
				game_state->x_indirect_push,game_state->y_indirect_push,game_state->target->get_x(),game_state->target->get_y()); );
		  
		  game_state->indirect_push_square = NULL;
		  SDL_Rect tmp;
		  
		  for(int i=0;i<game_state->indirect_push_square_count;i++){
			tmp.x = SQUARE_TO_PIXEL(game_state->indirect_push_squares[i]->get_x());
			tmp.y = SQUARE_TO_PIXEL(game_state->indirect_push_squares[i]->get_y());
			tmp.w = SQUARE_SIZE;
			tmp.h = SQUARE_SIZE;
			pg_cliprect = rect_union(pg_cliprect, tmp);
			if( x_square == game_state->indirect_push_squares[i]->get_x() &&
			y_square == game_state->indirect_push_squares[i]->get_y() ){
			  game_state->indirect_push_square = game_state->indirect_push_squares[i];
			}
		  }	  
		}
	break;

	case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE:
	case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE:
		if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
		  
		  DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE game_state->x_push=%d game_state->y_push=%d game_state->target->get_x()=%d game_state->target->get_y()=%d\n",
				game_state->x_double_indirect_push,game_state->y_double_indirect_push,game_state->target->get_x(),game_state->target->get_y()); );
		  
		  game_state->double_indirect_push_square = NULL;
		  SDL_Rect tmp;
		  
		  for(int i=0;i<game_state->double_indirect_push_square_count;i++){
			tmp.x = SQUARE_TO_PIXEL(game_state->double_indirect_push_squares[i]->get_x());
			tmp.y = SQUARE_TO_PIXEL(game_state->double_indirect_push_squares[i]->get_y());
			tmp.w = SQUARE_SIZE;
			tmp.h = SQUARE_SIZE;
			pg_cliprect = rect_union(pg_cliprect, tmp);
			if( x_square == game_state->double_indirect_push_squares[i]->get_x() &&
			y_square == game_state->double_indirect_push_squares[i]->get_y() ){
			  game_state->double_indirect_push_square = game_state->double_indirect_push_squares[i];
			}
		  }	  
		}
	break;

      case ACTIONS_CHOOSE_PUSH_SQUARE:
      case ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE:
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	  
	  DEBUG( printf("ACTIONS_CHOOSE_PUSH_SQUARE game_state->x_push=%d game_state->y_push=%d game_state->target->get_x()=%d game_state->target->get_y()=%d\n",
			game_state->x_push,game_state->y_push,game_state->target->get_x(),game_state->target->get_y()); );

	  game_state->push_square = NULL;
	  SDL_Rect tmp;
	  for(int i=0;i<game_state->push_square_count;i++){
	    tmp.x = SQUARE_TO_PIXEL(game_state->push_squares[i]->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->push_squares[i]->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect, tmp);
	    if( x_square == game_state->push_squares[i]->get_x() &&
		y_square == game_state->push_squares[i]->get_y() ){
	      game_state->push_square = game_state->push_squares[i];
	    }
	  }
	}
	break;
      case ACTIONS_MOVE:

	if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	  DEBUG(printf("filter event -> move\n"); );
 
	  pg_cliprect = rect_union(pg_cliprect,path_rect);
	  delete game_state->path;
	  game_state->path = NULL;
	  game_state->path = make_path_to(x_square,y_square,NO_LIMIT);

	  if(!game_state->path) {
	  	  unset_contextual_info();
	  }
	  else {
	    SDL_Rect tmp;
		tmp.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
		tmp.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect,tmp);
	    tmp.x = SQUARE_TO_PIXEL(x_square);
	    tmp.y = SQUARE_TO_PIXEL(y_square);
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect,tmp);
	    path_rect = pg_cliprect; 
		int sf = get_success_floor();
		if(sf!=99)
			set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+%s",((sf>100)?(sf-100):(sf)),((sf>100)?(",.."):("")) );
		else unset_contextual_info();
	  }
	}
	else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  pg_cliprect = path_rect;
	  delete game_state->path;
	  game_state->path = NULL;
	  unset_contextual_info();
	}
	
	break;
      case ACTIONS_MOVE_PLUS:
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) ){
	  DEBUG(printf("filter event -> move move\n"); );
	  
	  pg_cliprect = rect_union(pg_cliprect,path_rect);
	  delete game_state->path;
	  game_state->path = NULL;
	  
	  game_state->path = make_path_to(x_square,y_square,1);
	  if(!game_state->path) {
		  unset_contextual_info();
	  }
	  else {
	    SDL_Rect tmp;
	    tmp.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect,tmp);
	    tmp.x = SQUARE_TO_PIXEL(x_square);
	    tmp.y = SQUARE_TO_PIXEL(y_square);
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect,tmp);
	    path_rect = pg_cliprect; 
	    set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());
	  }
	}
	else if ((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  pg_cliprect = path_rect;
	  delete game_state->path;
	  game_state->path = NULL;
	  unset_contextual_info();
	}
	
	break;
      case ACTIONS_BLOCK:
	DEBUG(printf("filter event -> block\n"); );
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && 
	    (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&
	    (event->motion.x < (FRAME_LIMIT-FRAME_LINE))&&
	    Shared::get_playground(x_square,y_square) && 
	    Shared::get_playground(x_square,y_square)->get_team() != Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->get_team() &&
	    Shared::get_playground(x_square,y_square)->get_status()==OK && 
	    abs(x_square - game_state->selection->get_x()) <= 1 &&
	    abs(y_square - game_state->selection->get_y()) <= 1 ){

	  SDL_Rect tmp;
	  if(game_state->target){
	    tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    tmp.x = -1;
	  }	  
	  
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp); 
		
	  ////////////////////////////////////////
	  // Ragnar Modif3 : dauntless
	  if (game_state->selected_player->has_got_skill(DAUNTLESS) && (game_state->selected_player->get_st() < Shared::get_playground(x_square,y_square)->get_st())){
		  int fa = game_state->selected_player->get_st();
		  int fd = Shared::get_playground(x_square,y_square)->get_st();
		  int dices_if_not_dauntless = game_state->selected_player->block(Shared::get_playground(x_square,y_square)); 
		  game_state->selected_player->set_st(fd);
		  int dices_if_dauntless = game_state->selected_player->block(Shared::get_playground(x_square,y_square));
		  game_state->selected_player->set_st(fa);
		  if (dices_if_dauntless != dices_if_not_dauntless)
			  set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i|%id",dices_if_not_dauntless,dices_if_dauntless);
		  else set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%id",dices_if_not_dauntless);
	  }
	  else set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%id",game_state->selected_player->block(Shared::get_playground(x_square,y_square)));
	  ////////////////////////////////////////
	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  if(game_state->target){
	    pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    pg_cliprect.w = SQUARE_SIZE;
	    pg_cliprect.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
		unset_contextual_info();
	  }
	}
	
	break;
      case ACTIONS_THROW:
	DEBUG(printf("filter event -> throw square\n"); );
	
	if(game_state->select_throw_target && 
	   OVER_PLAYGROUND(x_mouse,y_mouse) && 
	   ((x_square!=game_state->old_x_square) || (y_square!=game_state->old_y_square)) &&
	   (event->motion.x < (FRAME_LIMIT-FRAME_LINE))){
	  SDL_Rect t_tmp;

	  if(game_state->interception_square_count>0){
	    for(int i=0;i<game_state->interception_square_count;i++){
	      int x_s = game_state->interception_squares[i]->get_x();
	      int y_s = game_state->interception_squares[i]->get_y();
	      t_tmp.x = SQUARE_TO_PIXEL(x_s);
	      t_tmp.y = SQUARE_TO_PIXEL(y_s);
	      t_tmp.w = SQUARE_SIZE;
	      t_tmp.h = SQUARE_SIZE;
	      pg_cliprect = rect_union(pg_cliprect, t_tmp);
	    }
		game_state->interception_square = NULL;

	    game_state->interception_square_count = 0;
	  }

	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    t_tmp.x = -1;
	  }	  

	  pg_cliprect = rect_union(pass_arrow_rect,pg_cliprect);
	  if(t_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, t_tmp); 

	  game_state->target = new Square(x_square,y_square);
	  

	  ////////////////////////////////////////////////////
	  // Ragnar Modif4 : pas de portée bombe pour les minus (sauf si compétence "strong arm")
	  if ( Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->has_got_skill(STUNTY) 
		  && !Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->has_got_skill(STRONG_ARM)) {

		  if(pass_arrow) {
			free(pass_arrow);
			pass_arrow = NULL;
		  }

		  pass_arrow = make_pass_arrow(game_state->selection, game_state->target,LONG_PASS_INDEX);
	  }
	  ////////////////////////////////////////////////////
	  // Ragnar Modif5 : Dump off uniquement en portée éclair
	  else if(game_state->is_a_dump_off || game_state->is_a_blitz_dump_off){
		if(pass_arrow) {
			free(pass_arrow);
			pass_arrow = NULL;
		}
		pass_arrow = make_pass_arrow(game_state->selection, game_state->target,FLASH_PASS_INDEX);
	  }
	  ////////////////////////////////////////////////////
	  else{
		if(pass_arrow) {
			free(pass_arrow);
			pass_arrow = NULL;
		}
		pass_arrow = make_pass_arrow(game_state->selection, game_state->target,BOMB_PASS_INDEX);
	  }
	  /////////////////////////////////////////////////////

	  if(pass_arrow && pass_arrow->image){
	    t_tmp.x = pass_arrow->x;
	    t_tmp.y = pass_arrow->y;
	    t_tmp.w = pass_arrow->image->w;
	    t_tmp.h = pass_arrow->image->h;
	    pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	    set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());
	  } 
	  else unset_contextual_info();
	
	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	  }
	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  SDL_Rect t_tmp,p_tmp;
	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    t_tmp.x = -1;
	  }	  
	  
	  if(pass_arrow && pass_arrow->image){
	    p_tmp.x = pass_arrow->x;
	    p_tmp.y = pass_arrow->y;
	    p_tmp.w = pass_arrow->image->w;
	    p_tmp.h = pass_arrow->image->h;
	    free(pass_arrow);
		pass_arrow = NULL;
	  }
	  else {
	    p_tmp.x = -1;
	  }	
	  
	  if(t_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	  if(p_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, p_tmp); 
	  if( p_tmp.x == -1 && t_tmp.x == -1){
	     pg_cliprect.x = 0;
	     pg_cliprect.y = 0;
	     pg_cliprect.w = 0;
	     pg_cliprect.h = 0;
	  }
	  game_state->interception_square = NULL;
	  game_state->interception_square_count = 0;
	  delete game_state->target;
	  game_state->target = NULL;
	  free(pass_arrow);
	  pass_arrow = NULL;
	  unset_contextual_info();
	}
	break;
case ACTIONS_CHOOSE_TEAM_MATE:
	///////////-------------------------------------------/////////
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && 
		(x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&
		(event->motion.x < (FRAME_LIMIT-FRAME_LINE)) && 
		Shared::get_playground(x_square,y_square) && 
		Shared::get_playground(x_square,y_square)->get_square() && 
		Shared::get_playground(x_square,y_square)->get_status() == OK && 
		Shared::get_playground(x_square,y_square)->is_throwable() && 
		Shared::get_playground(x_square,y_square)->get_team() == Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->get_team() && 
	    abs(x_square - game_state->selection->get_x()) <= 1 &&
	    abs(y_square - game_state->selection->get_y()) <= 1){
	  SDL_Rect tmp;
	  
	  if(game_state->target){
	    tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    tmp.x = -1;
	  }	  
	  
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp);

	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  if(game_state->target){
	    pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    pg_cliprect.w = SQUARE_SIZE;
	    pg_cliprect.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	}
	//////////---------------------------------------------//////////
	break;
case ACTIONS_THROW_TEAM_MATE:
	/////////--------------------------------------------/////////


	// DEBUG(printf("filter event -> throw team mate\n"); );
	
	if(game_state->select_throw_target && 
	   OVER_PLAYGROUND(x_mouse,y_mouse) && 
	   ((x_square!=game_state->old_x_square) || (y_square!=game_state->old_y_square)) &&
		!Shared::get_playground(x_square,y_square) &&
	   (event->motion.x < (FRAME_LIMIT-FRAME_LINE))){
	  SDL_Rect t_tmp;
	  
	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    t_tmp.x = -1;
	  }	  

	  pg_cliprect = rect_union(pass_arrow_rect,pg_cliprect);
	  if(t_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, t_tmp); 

	  game_state->target = new Square(x_square,y_square);

	  if(pass_arrow) {
		free(pass_arrow);
		pass_arrow = NULL;
	  }

	  pass_arrow = make_pass_arrow(game_state->selection, game_state->target, LONG_PASS_INDEX);
	  
	  if(pass_arrow && pass_arrow->image){
	    t_tmp.x = pass_arrow->x;
	    t_tmp.y = pass_arrow->y;
	    t_tmp.w = pass_arrow->image->w;
	    t_tmp.h = pass_arrow->image->h;
	    pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	    
		set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i+",get_success_floor());
	  }
	  else unset_contextual_info();
	 
	
	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	  }
	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  SDL_Rect t_tmp,p_tmp;
	  if(game_state->target){
	    t_tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    t_tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    t_tmp.w = SQUARE_SIZE;
	    t_tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    t_tmp.x = -1;
	  }	  
	  
	  if(pass_arrow && pass_arrow->image){
	    p_tmp.x = pass_arrow->x;
	    p_tmp.y = pass_arrow->y;
	    p_tmp.w = pass_arrow->image->w;
	    p_tmp.h = pass_arrow->image->h;
	    free(pass_arrow);
		pass_arrow = NULL;
	  }
	  else {
	    p_tmp.x = -1;
	  }	
	  
	  if(t_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, t_tmp); 
	  if(p_tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, p_tmp); 
	  if( p_tmp.x == -1 && t_tmp.x == -1){
	     pg_cliprect.x = 0;
	     pg_cliprect.y = 0;
	     pg_cliprect.w = 0;
	     pg_cliprect.h = 0;
	  }
	  delete game_state->target;
	  game_state->target = NULL;
	  free(pass_arrow);
	  pass_arrow = NULL;
	  unset_contextual_info();
	}

	////////-------------------------------------------//////////
	
	break;

      case ACTIONS_AGGRESS:
	DEBUG(printf("filter event -> aggress\n"); );
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && 
	    (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&
	    (event->motion.x < (FRAME_LIMIT-FRAME_LINE))&&
	    Shared::get_playground(x_square,y_square) && 
	    Shared::get_playground(x_square,y_square)->get_team() != Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->get_team() &&
	    Shared::get_playground(x_square,y_square)->get_status()>OK && 
	    abs(x_square - game_state->selection->get_x()) <= 1 &&
	    abs(y_square - game_state->selection->get_y()) <= 1){
	 
	  SDL_Rect tmp;
	  if(game_state->target){
	    tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    tmp.x = -1;
	  }	  
	  
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;

	  ////////////////////////////////////////////////////////////////////
	  //Ragnar Modif6 : affichage de la difficulté de l'agression dans la petite bulle
	  // bonus +2 pour les vicieux, +1 pour les autres
	  // RM7 +1+2=+3 pour les vicieux, +1 pour les autres

	  if (game_state->selected_player->has_got_skill(DIRTY_PLAYER)) 
		  set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square), "%i+", get_success_floor()-/*2 RM7*/3/**/);
	  else set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square), "%i+", get_success_floor()-1);
	  /////////////////////////////////////////////////////////////////////

	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp); 
	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  if(game_state->target){
	    pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    pg_cliprect.w = SQUARE_SIZE;
	    pg_cliprect.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
		unset_contextual_info();
	  }
	}
	break;
      case ACTIONS_BLITZ:
	DEBUG(printf("filter event -> blitz\n"); );
	
	if( OVER_PLAYGROUND(x_mouse,y_mouse) && 
	    (x_square!=game_state->old_x_square || y_square!=game_state->old_y_square)&&
	    (event->motion.x < (FRAME_LIMIT-FRAME_LINE))&&
	    Shared::get_playground(x_square,y_square) && 
	    Shared::get_playground(x_square,y_square)->get_team() != Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y())->get_team() &&
	    Shared::get_playground(x_square,y_square)->get_status()==OK && 
	    abs(x_square - game_state->selection->get_x()) <= 1 &&
	    abs(y_square - game_state->selection->get_y()) <= 1 ){
	  SDL_Rect tmp;
	  if(game_state->target){
	    tmp.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    tmp.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    tmp.w = SQUARE_SIZE;
	    tmp.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  }
	  else {
	    tmp.x = -1;
	  }	  
	  
	  game_state->target = new Square(x_square,y_square);
	  pg_cliprect.x = SQUARE_TO_PIXEL(x_square);
	  pg_cliprect.y = SQUARE_TO_PIXEL(y_square);
	  pg_cliprect.w = SQUARE_SIZE;
	  pg_cliprect.h = SQUARE_SIZE;
	  if(tmp.x != -1) pg_cliprect = rect_union(pg_cliprect, tmp); 
	
	  ////////////////////////////////////////
	  // Ragnar Modif3 : dauntless
	  if (game_state->selected_player->has_got_skill(DAUNTLESS) && (game_state->selected_player->get_st() < Shared::get_playground(x_square,y_square)->get_st())){
		  int fa = game_state->selected_player->get_st();
		  int fd = Shared::get_playground(x_square,y_square)->get_st();
		  int dices_if_not_dauntless = game_state->selected_player->block(Shared::get_playground(x_square,y_square)); 
		  game_state->selected_player->set_st(fd);
		  int dices_if_dauntless = game_state->selected_player->block(Shared::get_playground(x_square,y_square));
		  game_state->selected_player->set_st(fa);
		  if (dices_if_dauntless != dices_if_not_dauntless)
			  set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%i|%id",dices_if_not_dauntless,dices_if_dauntless);
		  else set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%id",dices_if_not_dauntless);
	  }
	  else set_contextual_info(SQUARE_TO_PIXEL(x_square),SQUARE_TO_PIXEL(y_square),"%id",game_state->selected_player->block(Shared::get_playground(x_square,y_square)));
	  ////////////////////////////////////////
	}
	else if((game_state->old_x_square != x_square) || (game_state->old_y_square != y_square)){
	  if(game_state->target){
	    pg_cliprect.x = SQUARE_TO_PIXEL(game_state->target->get_x());
	    pg_cliprect.y = SQUARE_TO_PIXEL(game_state->target->get_y());
	    pg_cliprect.w = SQUARE_SIZE;
	    pg_cliprect.h = SQUARE_SIZE;
	    delete game_state->target;
		game_state->target = NULL;
	  unset_contextual_info();
	  }
	}
	
	break;
      case ACTIONS_NONE:
	
	// si menu visible alors je gere le deplacement sur le menu  
	if( actions_menu->visible ){
	  for(int i=ACTIONS_MOVE_INDEX;i<ACTIONS_NB;i++)
	    if( game_state->actions_menu_items_state[i] == ITEM_UP ) 
	      rollover_actions_item(ITEM_ON, i);
	  
	  int x_m = event->motion.x - pg->x;
	  int y_m = event->motion.y - pg->y;
	  
	  if( x_m > actions_menu->x && 
	      x_m < (actions_menu->x+actions_menu->image->w) &&
	      y_m > actions_menu->y && 
	      y_m < (actions_menu->y+actions_menu->image->h) ){
	    int item = (y_m - actions_menu->y)/ACTIONS_MENU_ITEM_HEIGHT;
		if(game_state->actions_menu_throw_team_mate && item==ACTIONS_THROW_INDEX){
			rollover_actions_item(ITEM_UP, item);
		}
		else if(game_state->actions_menu_leap && item==ACTIONS_AGGRESS_INDEX){
			rollover_actions_item(ITEM_UP, item);
		}
		else {
			if( game_state->actions_menu_items_state[item] == ITEM_ON ) 
				rollover_actions_item(ITEM_UP, item);
		}
	  } 
	 
	  pg_cliprect.x = actions_menu->x;
	  pg_cliprect.y = actions_menu->y;
	  pg_cliprect.w = actions_menu->image->w;
	  pg_cliprect.h = actions_menu->image->h;
	}
	break;
      }
      // fin du case MODE_PLAYING
      break;
    }

    if(event->type == SDL_MOUSEMOTION &&  
       event->motion.x < (FRAME_LIMIT-FRAME_LINE) &&
       game_state->current_mode == MODE_TEAM_PLACEMENT && 
       (event->motion.state&SDL_BUTTON(SDL_BUTTON_LEFT)) &&
	   game_state->drag_dock ){
      game_state->x_dock = -pg->x + event->motion.x - DOCK_W/2; 
      game_state->y_dock = -pg->y + event->motion.y - DOCK_H/2;
      
	  if ( game_state->x_dock < (-pg->x) ) game_state->x_dock = -pg->x;
      else if ( game_state->x_dock > (-pg->x + FRAME_LIMIT - FRAME_LINE - DOCK_W) ) game_state->x_dock = -pg->x + FRAME_LIMIT - FRAME_LINE - DOCK_W;
      if ( game_state->y_dock < (-pg->y) ) game_state->y_dock = -pg->y;
      else if ( game_state->y_dock > (-pg->y + Config::get_screen_h() - DOCK_H) ) game_state->y_dock = -pg->y + Config::get_screen_h() - DOCK_H;
  
      pg_cliprect.x = -pg->x;
      pg_cliprect.y = -pg->y;
      pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
      pg_cliprect.h = Config::get_screen_h();
    }

    // deplacement de la map avec bouton du mileu
    if ( event->type == SDL_MOUSEMOTION && 
		 event->motion.x < (FRAME_LIMIT-FRAME_LINE) &&
		 (event->motion.state&SDL_BUTTON(SDL_BUTTON_MIDDLE)) &&
		 game_state->drag_playground &&
		 !actions_menu->visible ){
      DEBUG(printf("deplacement de la souris (%d,%d)\n",event->motion.xrel, event->motion.yrel); );
      int x = pg->x+event->motion.xrel;
      int y = pg->y+event->motion.yrel;
      if ( x > 0 ) x = 0;
      else if ( x < (-pg->image->w+FRAME_LIMIT) ) x = -pg->image->w+FRAME_LIMIT;
      if ( y > 0 ) y = 0;
      else if ( y < (-pg->image->h+Config::get_screen_h()) ) y = -pg->image->h+Config::get_screen_h();
      
      set_object_position(pg,x,y); 
      
      pg_cliprect.x = -pg->x;
      pg_cliprect.y = -pg->y;
      pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
      pg_cliprect.h = Config::get_screen_h();
      
      return 0;
    }
    
    game_state->old_x_square = x_square;
    game_state->old_y_square = y_square;
    
  }

  return 1;
}



bool is_good_location(Player *pl, int x_s, int y_s){

  switch(pl->get_team()){
  case HOME:
    if(x_s<0 || x_s>PLAYGROUND_WIDTH) return false; 
    if(y_s<=0 || y_s>=PLAYGROUND_HEIGHT/2) return false;
    break;
  case VISITOR:
    if(x_s<0 || x_s>PLAYGROUND_WIDTH) return false; 
    if(y_s<PLAYGROUND_HEIGHT/2 || y_s>=(PLAYGROUND_HEIGHT-1)) return false;
    break;
  }
  
  if( game_state->team[pl->get_team()]->on_playground_player_count() >= MAX_PLAYER_ON_PLAYGROUND ) return false;
 
  return true;
}

void change_formation(int team_id, int formation_id){
	if (team_id!=HOME && team_id!=VISITOR) return;
	
	if (formation_id==game_state->old_formation_id) formation_id = 4;
	game_state->team[team_id]->adopt_formation(formation_id);
	draw_all(true);
	game_state->old_formation_id = formation_id;
}

bool is_good_formation(int id){
 
  std::map<int,Player*> ::iterator it;
  map<int,Player*> *players = game_state->team[id]->get_players();
  
  int center_line_count[2] = {0,0};
  game_state->corridor_count[id][0] = 0;
  game_state->corridor_count[id][1] = 0;

  for(it=players->begin();it!=players->end();it++){
    if(((*it).second)->get_square()) {
      int x_s = ((*it).second)->get_square()->get_x();
      int y_s = ((*it).second)->get_square()->get_y();
      if( x_s < (CORRIDOR_WIDTH) ){ 
			game_state->corridor_count[id][0]++;
      }
      
	  if( x_s > (PLAYGROUND_WIDTH-CORRIDOR_WIDTH-1) ) {
		  game_state->corridor_count[id][1]++;
      }
      
      if( ( id==HOME && x_s>=CORRIDOR_WIDTH && x_s<=(PLAYGROUND_WIDTH-CORRIDOR_WIDTH-1) && y_s == (PLAYGROUND_HEIGHT/2-1) ) || 
	  ( id==VISITOR && x_s>=CORRIDOR_WIDTH && x_s<=(PLAYGROUND_WIDTH-CORRIDOR_WIDTH-1) && y_s == (PLAYGROUND_HEIGHT/2) ) ) 

	  center_line_count[id]++;
    }
  }

	if( game_state->corridor_count[id][0] > (MAX_PLAYER_IN_CORRIDOR)){ 

		DEBUG( printf("Trop de mec sur le couloir gauche (%i/%i max)\n",game_state->corridor_count[id][0],MAX_PLAYER_IN_CORRIDOR); );
		draw_all(true);
		dialog_box->open_info(screen,ICONS_AFRAID, MSG_TOO_MUCH_PLAYER_ON_LEFT_CORRIDOR,false,game_state->team[id]->get_name());
		draw_all(true);
		return false;
    }

    if( game_state->corridor_count[id][1] > (MAX_PLAYER_IN_CORRIDOR)) {

		DEBUG( printf("Trop de mec sur le couloir droit (%i/%i max)\n",game_state->corridor_count[id][1],MAX_PLAYER_IN_CORRIDOR); );
		draw_all(true);
		dialog_box->open_info(screen,ICONS_AFRAID, MSG_TOO_MUCH_PLAYER_ON_RIGHT_CORRIDOR,false,game_state->team[id]->get_name());
		draw_all(true);
		return false;
    }

  if(center_line_count[id] < MIN_PLAYER_ON_CENTER_LINE ){
    DEBUG( printf("Pas assez de gars contre la ligne centrale %i (au moins %i)\n",center_line_count[id],MIN_PLAYER_ON_CENTER_LINE); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_NOT_ENOUGH_PLAYER_ON_CENTER_LINE,false,game_state->team[id]->get_name());
    draw_all(true);
    return false;
  }

  if(game_state->team[id]->on_playground_player_count() > MAX_PLAYER_ON_PLAYGROUND ){
    DEBUG( printf("Trop de gars sur le terrain (%d max)\n",MAX_PLAYER_ON_PLAYGROUND); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_TOO_MUCH_PLAYER_ON_PLAYGROUND,false,game_state->team[id]->get_name());
    draw_all(true);
    return false;
  } 

  game_state->team[id]->set_placed(true);

  return true;
}

int draw_object_into(graphical_object *obj, SDL_Surface *where,int frame, int x, int y){
  if(x>Config::get_screen_w() || y>Config::get_screen_h()) return 0;
  
  SDL_Rect d,s;

  switch(frame){
  case NO_FRAME:
    s.x = 0;
    s.y = 0;
    s.w = MIN(obj->image->w,Config::get_screen_w());
    s.h = MIN(obj->image->h,Config::get_screen_h());
    d.x = x;
    d.y = y;
    d.w = obj->image->w;
    d.h = obj->image->h;
    break;
  case LEFT_FRAME:
    s.x = -x;
    s.y = -y;
    s.w = MIN(obj->image->w,FRAME_LIMIT-FRAME_LINE);
    s.h = MIN(obj->image->h,Config::get_screen_h());
    d.x = 0;
    d.y = 0;
    d.w = FRAME_LIMIT-FRAME_LINE;
    d.h = Config::get_screen_h();
    break;
  case RIGHT_FRAME:
    s.x = 0;
    s.y = 0;
    s.w = MIN(obj->image->w,Config::get_screen_w()-FRAME_LIMIT);
    s.h = MIN(obj->image->h,Config::get_screen_h());
    d.x = x+FRAME_LIMIT;
    d.y = y;
    d.w = Config::get_screen_w()-FRAME_LIMIT;
    d.h = Config::get_screen_h();
    break;
  }

  BlitSurface(obj->image,&s, where, &d);

  return 0;
}

void start_turn(int which_team){
  DEBUG ( printf("-> start_turn(%i)\n",which_team); ); 
  unset_contextual_info();

  if(check_for_end_of_half()) return;
  game_state->team[HOME]->prepare_for_next_turn();
  game_state->team[VISITOR]->prepare_for_next_turn();
  game_state->active_team = which_team;
  reset_vars();
  game_state->current_action = ACTIONS_NONE;
  if(game_state->team[which_team]->has_free_turn()) {
    game_state->team[which_team]->set_has_free_turn(false);
  }
  else {
    game_state->team[game_state->active_team]->inc_turn();
  }
  
  game_state->turn_begining_time = SDL_GetTicks(); 

  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();
  
  panel_cliprect.x = PANEL_URL_X;
  panel_cliprect.y = PANEL_PLAYER_INFO_Y;
  panel_cliprect.w = PANEL_W; 
  panel_cliprect.h = Config::get_screen_h()-PANEL_PLAYER_INFO_Y;

  DEBUG ( printf("<- start_turn(%i)\n",which_team); ); 
}

void reset_vars(){
	if(game_state->target){
		delete game_state->target;
		game_state->target = NULL;
	}
	if(game_state->path){
		delete game_state->path;
		game_state->path = NULL;
	}
	game_state->x_menu_clic = 0;
	game_state->y_menu_clic = 0;
	game_state->x_player_clic = 0;
	game_state->y_player_clic = 0;
	game_state->select_throw_target = false;
	game_state->selected_player = NULL;
	if(game_state->old_selected_player){
		delete game_state->old_selected_player;
		game_state->old_selected_player = NULL;
	}
	free(pass_arrow);
	pass_arrow = NULL;
	game_state->throw_in_anim = false;
	game_state->autocenter_anim = false;
	game_state->pass_anim = false;
	game_state->target_anim = false;
	game_state->perfect_pass = false;
	game_state->interception_square = NULL;
	game_state->interception_square_count = 0;
	game_state->interception_attempt = false;
	game_state->transmit_square = NULL;
	game_state->transmit_square_count = 0;
	game_state->x_push = 0;
	game_state->y_push = 0;
	game_state->push_square = NULL;
	game_state->push_square_count = 0;
	game_state->direct_push = true;
	game_state->x_indirect_push = 0;
	game_state->y_indirect_push = 0;
	game_state->indirect_push_square = NULL;
	game_state->indirect_push_square_count = 0;
	game_state->direct_indirect_push = true;
  
	game_state->x_double_indirect_push = 0;
	game_state->y_double_indirect_push = 0;
	game_state->double_indirect_push_square = NULL;
	game_state->double_indirect_push_square_count = 0;
	game_state->direct_double_indirect_push = true;
  
	game_state->old_ball_owner_team = NONE;
	slide_playground = NONE;
	focus_on_game = true;
	game_state->x_push = 0;
	game_state->y_push = 0;
	game_state->old_x_square = -1;
	game_state->old_y_square = -1;
	game_state->x_dock=DOCK_X,game_state->y_dock=DOCK_Y;
	game_state->drag_dock = false;
	game_state->drag_playground = false;
	game_state->player_is_moving = false;
	game_state->ball->set_has_bounced(false);
	//////////////////////////////////////////////
	// Ragnar Modif : re-initialisation des nouvelles variables 
	game_state->freeze_time = false;
	game_state->is_a_dump_off = false;
	game_state->is_a_blitz_dump_off = false;
	game_state->selection_save = NULL;
	game_state->player_save = NULL;
	//////////////////////////////////////////////
	// Ragnar Modif3 : écrasement
	game_state->is_a_skull_and_star = false;
	//////////////////////////////////////////////
}

void stop_turn(){
  DEBUG( printf("-> stop turn()\n"); );

  unset_contextual_info();

  select_none();
  game_state->current_action = ACTIONS_NONE;
  reset_vars();
  game_state->turn_begining_time = 0;
  
  if(game_state->team[game_state->active_team]->has_free_turn()) {
    game_state->team[game_state->active_team]->set_has_free_turn(false);
  }
 
  game_state->old_active_team = game_state->active_team;
  game_state->active_team = NONE;
  check_for_end_of_half();
  
  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();

  panel_cliprect.x = PANEL_URL_X;
  panel_cliprect.y = PANEL_PLAYER_INFO_Y;
  panel_cliprect.w = PANEL_W; 
  panel_cliprect.h = Config::get_screen_h()-PANEL_PLAYER_INFO_Y;

  DEBUG( printf("<- stop turn()\n"); );
}

bool check_for_end_of_half(){

  if(game_state->team[HOME]->get_turn()>=TURN_PER_HALF && game_state->team[VISITOR]->get_turn()>=TURN_PER_HALF){
    game_state->turn_begining_time = 0;
    game_state->old_active_team = game_state->active_team;
	game_state->selected_player = NULL;
    game_state->active_team = NONE;
    game_state->current_action = ACTIONS_NONE;
    
    game_state->team[HOME]->set_referee_intimidated(false);
    game_state->team[VISITOR]->set_referee_intimidated(false);
    
    game_state->team[HOME]->set_has_free_turn(false);
    game_state->team[VISITOR]->set_has_free_turn(false);
    
    switch(game_state->half){
    case FIRST_HALF:
      half_time();
      break;
    case SECOND_HALF:
      full_time();
      break;
    case EXTRA_TIME:

	   //////////////////////////////////
	  // Ragnar Modif4 : penalty
	  
	 draw_all(true);
	 switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_QUESTION_PENALTY,"")){
		case YES: 
			game_state->need_a_winner = true;
			draw_all(true);
			break;
		case NO:
			game_state->need_a_winner = false;
			draw_all(true);
			break;
	}

	  if (game_state->need_a_winner){
		  draw_all(true);
		  dialog_box->open_info(screen,ICONS_REFEREE,MSG_PENALTY,false,"");
		  draw_all(true);
		  int visitor_score = 0;  
		  int home_score = 0;
		  while (home_score==visitor_score){
			home_score = d6->roll() + game_state->team[HOME]->get_reroll();
			visitor_score = d6->roll() + game_state->team[VISITOR]->get_reroll();
		  }
		  if(game_state->dices_roll) console->print("Penalties : ");
		  if(game_state->dices_roll) console->print("Home : %i + %i",home_score-game_state->team[HOME]->get_reroll(),game_state->team[HOME]->get_reroll());
		  if(game_state->dices_roll) console->print("Visitor : %i + %i",visitor_score-game_state->team[VISITOR]->get_reroll(),game_state->team[VISITOR]->get_reroll());
		  
		  draw_all(true);
		  dialog_box->open_info_s(screen,ICONS_SMILEY,MSG_WINNER_X,false,game_state->team[((home_score > visitor_score)?(HOME):(VISITOR))]->get_name(),game_state->team[((home_score > visitor_score)?(HOME):(VISITOR))]->get_name());
		  draw_all(true);
		  quit_game();
	  }
	  else {
		  draw_all(true);
		  dialog_box->open_info(screen,ICONS_SMILEY,MSG_DRAW,false,"");
		  draw_all(true);
		  quit_game();
	  }
	  //////////////////////////////////
    
      break;
    }
    return true;
  }
  return false;
}

void start_placement(int which_team){
  game_state->team_in_placement = which_team;
  game_state->old_formation_id = -1;
  switch_mode(MODE_TEAM_PLACEMENT);

  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();
  
  panel_cliprect.x = PANEL_URL_X;
  panel_cliprect.y = PANEL_PLAYER_INFO_Y;
  panel_cliprect.w = PANEL_W; 
  panel_cliprect.h = Config::get_screen_h()-PANEL_PLAYER_INFO_Y;
}

void stop_placement(){
	if (((game_state->team_in_placement != game_state->kick_off_team) || (game_state->kick_off_result==KICKOFF_DEFENSE) ) && game_state->team[HOME]->is_placed() && game_state->team[VISITOR]->is_placed() ) {
		delete game_state->target;
		game_state->target = NULL;
   
		if(game_state->kick_off_result!=KICKOFF_DEFENSE) {
			switch_mode(MODE_BALL_PLACEMENT);
		}
		else {
			game_state->current_mode = MODE_BALL_PLACEMENT;
			kick_off(game_state->target);
		}
	}
  
	if(game_state->kick_off_result!=KICKOFF_DEFENSE && game_state->kick_off_result!=KICKOFF_SURPRISE ){
		game_state->team_in_placement = NONE;
	}
  
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();
  
	panel_cliprect.x = PANEL_URL_X;
	panel_cliprect.y = PANEL_PLAYER_INFO_Y;
	panel_cliprect.w = PANEL_W; 
	panel_cliprect.h = Config::get_screen_h()-PANEL_PLAYER_INFO_Y;
  		
}

void handle_kick_off_event(void){
	game_state->kick_off_result = d6->roll(2);
	int home_roll;
	int visitor_roll;
	int dice_roll;
	Player* p;
	Player* victims[6];
	int i;
  

//////////////////////////////////////////////////////

  if(game_state->dices_roll) console->print("Kick off result roll : %i", game_state->kick_off_result);

//////////////////////////////////////////////////////

  switch(game_state->kick_off_result){
  
  ////////////////////////////////////////////////////
  case 0:
	switch_mode(MODE_BALL_PLACEMENT); 
	break;
  ////////////////////////////////////////////////////
  
  case KICKOFF_RIOT: // emeute
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_RIOT,false,"");
    dice_roll = d6->roll();

	if(game_state->dices_roll) console->print("Kick off riot roll : %i", dice_roll);
    
	DEBUG( printf("KICKOFF_RIOT during %d turn\n",dice_roll); );
    game_state->team[HOME]->set_turn(game_state->team[HOME]->get_turn()+dice_roll);
    game_state->team[VISITOR]->set_turn(game_state->team[VISITOR]->get_turn()+dice_roll);
    draw_all(true);
    DEBUG( printf("KICKOFF_RIOT home->turn = %d visitor->turn = %d\n",game_state->team[HOME]->get_turn(),game_state->team[VISITOR]->get_turn()); );
    if(check_for_end_of_half()) return;
	kick_off(game_state->target);
    break;
  case KICKOFF_REFEREE: // a mort l'arbitre     
    home_roll = d6->roll(2) + game_state->team[HOME]->get_fan_factor(); 
    visitor_roll = d6->roll(2) + game_state->team[VISITOR]->get_fan_factor();

    if(game_state->dices_roll) console->print("Kick off referee roll : %i vs %i", home_roll, visitor_roll);

    DEBUG( printf("KICKOFF_REFEREE %d vs %d\n",home_roll,visitor_roll); );
   
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,(home_roll==visitor_roll)?MSG_KICKOFF_REFEREE:MSG_KICKOFF_REFEREE_X,false,game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name());
    draw_all(true);

    if(home_roll>=visitor_roll) game_state->team[HOME]->set_referee_intimidated(true);
    if(home_roll<=visitor_roll) game_state->team[VISITOR]->set_referee_intimidated(true);
   
	kick_off(game_state->target);
    break;
  case KICKOFF_DEFENSE: // defense parfaite
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_DEFENSE,false,game_state->team[game_state->kick_off_team]->get_name());
    draw_all(true);
    DEBUG( printf("KICKOFF_DEFENSE\n"); );
    start_placement(game_state->kick_off_team);
    break;
  case KICKOFF_SUPPORTERS: // supporters
    do{
      home_roll = d6->roll() + game_state->team[HOME]->get_fan_factor() + game_state->team[HOME]->get_cheer_leaders();
      visitor_roll = d6->roll() + game_state->team[VISITOR]->get_fan_factor() + game_state->team[VISITOR]->get_cheer_leaders();
      DEBUG( printf("KICKOFF_SUPPORTERS %d vs %d\n",home_roll,visitor_roll); );
    } while(home_roll==visitor_roll);

    if(game_state->dices_roll) console->print("Kick off supporters roll : %i vs %i", home_roll, visitor_roll);
    
    draw_all(true);
    dialog_box->open_info_s(screen,ICONS_KICKOFF,MSG_KICKOFF_SUPPORTERS_X,false,game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name(),game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name());
    
    if(home_roll>visitor_roll) game_state->team[HOME]->inc_reroll();
    else game_state->team[VISITOR]->inc_reroll();
    
    draw_all(true);

	kick_off(game_state->target);
    break;
  case KICKOFF_CANNONBALL: // boulet de canon
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_CANNONBALL,false,game_state->team[game_state->kick_off_team]->get_name());
    draw_all(true);
    DEBUG( printf("KICKOFF_CANNONBALL\n"); );
	kick_off(game_state->target);
    break;
  case KICKOFF_WEATHER: // meteo
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_WEATHER,false,"");
    draw_all(true);
    DEBUG( printf("KICKOFF_WEATHER\n"); );
    change_weather();
	DEBUG( printf("KICKOFF_WEATHER 1\n"); );
	kick_off(game_state->target);
	DEBUG( printf("KICKOFF_WEATHER 2\n"); );
    break;
  case KICKOFF_SURPRISE: // surprise
    DEBUG( printf("KICKOFF_SURPRISE\n"); ); 
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_SURPRISE,false,game_state->team[1-game_state->kick_off_team]->get_name());
    draw_all(true);
    
    switch_mode(MODE_SURPRISE);
    break;
  case KICKOFF_TRAINING: // entrainement
    do{
      home_roll = d6->roll() + game_state->team[HOME]->get_assistant(); 
      visitor_roll = d6->roll() + game_state->team[VISITOR]->get_assistant();
      DEBUG( printf("KICKOFF_TRAINING %d vs %d\n",home_roll,visitor_roll); );
    }while(home_roll==visitor_roll);
    
    if(game_state->dices_roll) console->print("Kick off training roll : %i vs %i", home_roll, visitor_roll);

    draw_all(true);
    dialog_box->open_info_s(screen,ICONS_KICKOFF,MSG_KICKOFF_TRAINING_X,false,game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name(),game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name()); 
    if(home_roll>visitor_roll) game_state->team[HOME]->inc_reroll();
    else game_state->team[VISITOR]->inc_reroll();
   
    draw_all(true);
    
	kick_off(game_state->target);
    break;
  case KICKOFF_BLITZ: // blitz
    DEBUG( printf("KICKOFF_BLITZ\n"); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_KICKOFF,MSG_KICKOFF_BLITZ,false,game_state->team[game_state->kick_off_team]->get_name());
    draw_all(true);
    game_state->team[game_state->kick_off_team]->set_has_free_turn(true);
	kick_off(game_state->target);
    break;
  case KICKOFF_ROCK: // rocher
    do{
      home_roll = d6->roll(2) + game_state->team[HOME]->get_fan_factor(); 
      visitor_roll = d6->roll(2) + game_state->team[VISITOR]->get_fan_factor();
      DEBUG( printf("KICKOFF_ROCK %d vs %d\n",home_roll,visitor_roll); );
    }while(home_roll==visitor_roll);

    if(game_state->dices_roll) console->print("Kick off rock roll : %i vs %i", home_roll, visitor_roll);
 
    if(game_state->team[(home_roll>visitor_roll)?VISITOR:HOME]->on_playground_player_count()>0) { 
      dice_roll = d6->roll(2);
      p = (game_state->team[(home_roll>visitor_roll)?VISITOR:HOME]->get_random_player());
      game_state->max_victims = 1;
      victims_rect[0].x = SQUARE_TO_PIXEL(p->get_square()->get_x());
      victims_rect[0].y = SQUARE_TO_PIXEL(p->get_square()->get_y());
      victims_rect[0].w = SQUARE_SIZE;
      victims_rect[0].h = SQUARE_SIZE; 

      draw_all(true);
      dialog_box->open_info_i(screen,ICONS_KICKOFF,MSG_KICKOFF_ROCK_X,false,game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name(), p->get_number());
	  draw_all(true);

      /////////////////////////////////////////////////
	  // Ragnar Modif3 : stunty
	  if (p->has_got_skill(STUNTY)) {
		  dice_roll++;
		  if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
	  }
	  /////////////////////////////////////////////////

      injure_player(p,dice_roll,false);
    }

    game_state->max_victims = 0;
    
	kick_off(game_state->target);
    break;
  case KICKOFF_INVASION: // invasion du terrain
    do{
      home_roll = d6->roll(2) + game_state->team[HOME]->get_fan_factor(); 
      visitor_roll = d6->roll(2) + game_state->team[VISITOR]->get_fan_factor();
      DEBUG( printf("KICKOFF_INVASION %d vs %d\n",home_roll,visitor_roll); );
    }while(home_roll==visitor_roll);
 
    if(game_state->dices_roll) console->print("Kick off invasion roll : %i vs %i", home_roll, visitor_roll);
    
    DEBUG( printf("player on playground = %d\n",game_state->team[(home_roll>visitor_roll)?VISITOR:HOME]->on_playground_player_count()); );
    
    dice_roll = d6->roll();

    game_state->max_victims = MIN(dice_roll,game_state->team[(home_roll>visitor_roll)?VISITOR:HOME]->on_playground_player_count());
    
    DEBUG( printf("max victims = %d\n", game_state->max_victims); );

    i=0;
    do{
      p = (game_state->team[(home_roll>visitor_roll)?VISITOR:HOME]->get_random_player());
      bool find = false;
      for(int j=0;j<=i;j++){
	if(p==victims[j]) {
	  find = true;
	  break;
	}
      }
      if(!find){
	victims[i] = p;
	victims_rect[i].x = SQUARE_TO_PIXEL(p->get_square()->get_x());
	victims_rect[i].y = SQUARE_TO_PIXEL(p->get_square()->get_y());
	victims_rect[i].w = SQUARE_SIZE;
	victims_rect[i].h = SQUARE_SIZE;
	i++;
      }
    }while(i<game_state->max_victims);

    draw_all(true);
    dialog_box->open_info_i(screen,ICONS_KICKOFF,MSG_KICKOFF_INVASION_X,false,game_state->team[((home_roll>visitor_roll)?(HOME):(VISITOR))]->get_name(), game_state->max_victims);
    draw_all(true);

    for(int i=0;i<game_state->max_victims;i++){
      dice_roll = d6->roll(2);
	  /////////////////////////////////////////////////
	  // Ragnar Modif3 : stunty
	  if (victims[i]->has_got_skill(STUNTY)) dice_roll++;
	  /////////////////////////////////////////////////
      injure_player(victims[i],dice_roll,false);
      victims_rect[i].x = -SQUARE_SIZE;
      victims_rect[i].y = -SQUARE_SIZE;
      victims_rect[i].w = 0;
      victims_rect[i].h = 0;
    }
    game_state->max_victims = 0;

	kick_off(game_state->target);
    break;
  }
}

void wait_for_next_frame(void){
  static Uint32 next_tick = 0;
  Uint32 this_tick;
  
  /* Wait for the next game_state->frame */
  this_tick = SDL_GetTicks(); 
  if ( this_tick < next_tick ) {
    SDL_Delay(next_tick-this_tick);
  }
 
  next_tick = this_tick + (1000/FPS);
}

void set_weather(int i){

	int weather_roll = i;
	switch(weather_roll){
		case 2:
		game_state->weather = DOGDAYS;
		break;
	case 3: 
		game_state->weather = SUNNY;
		break;
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
	case 10:
		game_state->weather = GOOD;
		break;
	case 11:
		game_state->weather = SHOWER;
		break;
	case 12:
		game_state->weather = BLIZZARD;
		break;
	}

    char img[256];
	
    sprintf(img,"%s/general/playground_%d.jpg",IMG_PATH,game_state->weather);
    load_image_into(img,NO_TRANSPARENT,pg);
    pg_empty = SDL_ConvertSurface(pg->image, pg->image->format, pg->image->flags);
	sprintf(img,"%s/general/reserve_%d.jpg",IMG_PATH,game_state->weather);
    reserve = load_image(img,NO_TRANSPARENT); 
    reserve_empty = SDL_ConvertSurface(reserve, reserve->format, reserve->flags);
	if(game_state->weather==SHOWER && !rain){ 
      rain = load_image(ADD_IMG_PATH("general/rain.png"), TRANSPARENT);
      SDL_SetAlpha(rain, ALPHA_FLAGS, ALPHA_RAIN);
    }
    
    if(game_state->weather!=SHOWER){
      if(rain) {SDL_FreeSurface(rain);rain=NULL;}
    }

}

void change_weather(void){

DEBUG ( printf("-> change_weather\n"); );

try{
	int weather_roll = d6->roll(2);

	int old_weather = game_state->weather;

	switch(weather_roll){
	case 2:
		game_state->weather = DOGDAYS;
		break;
	case 3: 
		game_state->weather = SUNNY;
		break;
	case 4:
	case 5:
	case 6:
	case 7:
	case 8:
	case 9:
	case 10:
		game_state->weather = GOOD;
		break;
	case 11:
		game_state->weather = SHOWER;
		break;
	case 12:
		game_state->weather = BLIZZARD;
		break;
	}

	DEBUG ( printf("change_weather weather=%d\n",game_state->weather); );

	if(old_weather!=game_state->weather){
	//SOUND - TALID	

		DEBUG ( printf("change_weather, le temps change\n"); );

#ifndef NOSOUND
		if(game_state->weather==SHOWER){
			if(Config::is_sound_enabled()){
				sp->stop_sound();
				sp->loop_sound(SND_SHOWER, BGM_CHANNEL);
			}
		}

		if(game_state->weather==BLIZZARD){
			if(Config::is_sound_enabled()){
				sp->stop_sound();
				sp->loop_sound(SND_BLIZZARD, BGM_CHANNEL);
			}
		}
  
		if(game_state->weather!=SHOWER && game_state->weather!=BLIZZARD){
			if(Config::is_sound_enabled()){	
				sp->stop_sound();
				sp->loop_sound(SND_CROWD, BGM_CHANNEL);
			}
		}
#endif
		DEBUG ( printf("change_weather, le temps change apres son\n"); );

		char img[256];
		DEBUG ( printf("change_weather, le temps change +\n"); );
		sprintf(img,"%s/general/playground_%d.jpg",IMG_PATH,game_state->weather);
		DEBUG ( printf("change_weather, le temps change ++\n"); );
		load_image_into(img,NO_TRANSPARENT,pg);
		DEBUG ( printf("change_weather, le temps change +++\n"); );
		pg_empty = SDL_ConvertSurface(pg->image, pg->image->format, pg->image->flags);
		DEBUG ( printf("change_weather, le temps change ++++\n"); );
		sprintf(img,"%s/general/reserve_%d.jpg",IMG_PATH,game_state->weather);
		DEBUG ( printf("change_weather, le temps change +++++\n"); );
		reserve = load_image(img,NO_TRANSPARENT); 
		DEBUG ( printf("change_weather, le temps change ++++++\n"); );
		reserve_empty = SDL_ConvertSurface(reserve, reserve->format, reserve->flags);
		DEBUG ( printf("change_weather, le temps change +++++++\n"); );

		if(game_state->weather==SHOWER && !rain){ 
			rain = load_image(ADD_IMG_PATH("general/rain.png"), TRANSPARENT);
			SDL_SetAlpha(rain, ALPHA_FLAGS, ALPHA_RAIN);
		}
		DEBUG ( printf("change_weather, le temps change ++++++++\n"); );
		if(game_state->weather!=SHOWER){
			if(rain) {SDL_FreeSurface(rain);rain=NULL;}
		}
		DEBUG ( printf("change_weather, le temps change +++++++++\n"); );
	}
  
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();

	DEBUG ( printf("<- change_weather\n"); );

}catch(char *str){
	fprintf(stderr,"Change_weather: %s\n",str);
}

}

int set_actions_menu(int action,int state, int number){
  SDL_Rect s,d;
  s.x = 0;
  s.y = action*ACTIONS_MENU_ITEM_HEIGHT;
  s.w = ACTIONS_MENU_WIDTH;
  s.h = ACTIONS_MENU_ITEM_HEIGHT;
  d.x = 0;
  d.y = number*ACTIONS_MENU_ITEM_HEIGHT;
  d.w = s.w;
  d.h = s.h;
  BlitSurface(actions[state],&s, actions_menu->image, &d);
  return 0;
}

int rollover_actions_item(int state, int number){
  game_state->actions_menu_items_state[number] = state;
  set_actions_menu(game_state->actions_menu_items[number],state, number);
  return 0;
}

Path* make_path_to(int x_dest,int y_dest,int max_length){
	Path *pa=new Path;
  int x = game_state->selection->get_x();
  int y = game_state->selection->get_y();

  Player *p = Shared::get_playground(x,y);
  float x_diff = x_dest - x;
  float y_diff = y_dest - y;
  int square_nb;

  if(fabs(x_diff)>fabs(y_diff))
    square_nb = (int)fabs(x_diff);
  else
    square_nb = (int)fabs(y_diff);
 
  DEBUG(printf("de (%i,%i) a (%i,%i) %i %i %i\n",x,y,x_dest,y_dest,
		      square_nb,
		      p->get_ma(),
		      p->get_move_count()); );

  if(max_length==NO_LIMIT){
    if ( square_nb==0 || square_nb> ( p->get_ma() - p->get_move_count()))  {
      DEBUG(printf(" ce chemin est pas bon car trop long (NO_LIMIT)\n"); );
	  delete pa;
      return NULL;
    }
  }
  else {
    if( square_nb==0 || square_nb>max_length){
      DEBUG(printf(" ce chemin est pas bon car trop long (LIMIT=%d)\n", max_length); );
	  delete pa;
      return NULL;
    } 
  }

  x_diff=x_diff/square_nb;
  y_diff=y_diff/square_nb;

  DEBUG(printf("x_diff %i y_diff %i\n",(int)x_diff,(int)y_diff); );

  int x_bis=(x_diff>0)?1:(x_diff==0)?0:-1;
  int y_bis=(y_diff>0)?1:(y_diff==0)?0:-1;

  DEBUG(printf("x_bis %i y_bis %i\n",x_bis,y_bis); );

  float x_cpt=0;
  float y_cpt=0;

	
  for(int i=0;i<(square_nb-1);i++){
    x_cpt+=x_diff;
    y_cpt+=y_diff;

    DEBUG(printf("x_cpt %i y_cpt %i\n",(int)x_cpt,(int)y_cpt); );

    if (fabs(x_cpt)>=1){
      x+=x_bis;
      x_cpt-=x_bis;
    }
    if (fabs(y_cpt)>=1){
      y+=y_bis;
      y_cpt-=y_bis;
    }

    if (Shared::get_playground(x,y)) {
      delete pa;
      return NULL;
    }

    pa->squares->push_back(new Square(x,y));

    DEBUG(printf("etape %i:case[%i][%i]\n",i,x,y); );

    if(max_length!=NO_LIMIT && i>=max_length) break;
  }
  
  if (Shared::get_playground(x_dest,y_dest)) {
    delete pa;
    return NULL;
  }
  
  pa->squares->push_back(new Square(x_dest,y_dest));
  pa->set_dist_done(0);
  pa->set_ok(true);

  return pa;
}

int build_actions_menu(int x_pixel,int y_pixel,int x_square,int y_square){  
  Player *p = Shared::get_playground(x_square,y_square);
  game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_MOVE;
  game_state->actions_menu_items[ACTIONS_BLOCK_INDEX] = ACTIONS_BLOCK;
  game_state->actions_menu_items[ACTIONS_GATHER_INDEX] = ACTIONS_GATHER;
  game_state->actions_menu_items[ACTIONS_THROW_INDEX] = ACTIONS_THROW;
  game_state->actions_menu_items[ACTIONS_AGGRESS_INDEX] = ACTIONS_AGGRESS;
  game_state->actions_menu_items[ACTIONS_TRANSMIT_INDEX] = ACTIONS_TRANSMIT;
  
  game_state->actions_menu_items_state[ACTIONS_MOVE_INDEX] = ITEM_ON;
  game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_ON;
  game_state->actions_menu_items_state[ACTIONS_GATHER_INDEX] = ITEM_ON;
  game_state->actions_menu_items_state[ACTIONS_THROW_INDEX] = ITEM_ON;
  game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX] = ITEM_ON;
  game_state->actions_menu_items_state[ACTIONS_TRANSMIT_INDEX] = ITEM_ON;
  
  if(!p->can_transmit() || game_state->team[p->get_team()]->is_transmit_done()) 
    game_state->actions_menu_items_state[ACTIONS_TRANSMIT_INDEX] = ITEM_OFF;
  
  if(!p->has_played()) {
    if(p->get_status()!=OK){
      if(p->get_status()==GROUND) game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_GET_UP;
      if(p->get_status()==DOWN) game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_ROLL_OVER;
      game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_OFF;
      game_state->actions_menu_items_state[ACTIONS_GATHER_INDEX] = ITEM_OFF;
      game_state->actions_menu_items_state[ACTIONS_THROW_INDEX] = ITEM_OFF;
      game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX] = ITEM_OFF;
      game_state->actions_menu_items_state[ACTIONS_TRANSMIT_INDEX] = ITEM_OFF;
    }
    else {
      
      if(!p->can_move()) game_state->actions_menu_items[ACTIONS_MOVE_INDEX] = ACTIONS_MOVE_PLUS;
      if(!p->can_overmove()) game_state->actions_menu_items_state[ACTIONS_MOVE_INDEX] = ITEM_OFF;
      
      if((!p->can_catch(game_state->ball->get_square())) || (!game_state->ball->is_visible())) game_state->actions_menu_items_state[ACTIONS_GATHER_INDEX] = ITEM_OFF;
      if(!p->can_throw() || game_state->team[p->get_team()]->is_throw_done() ) game_state->actions_menu_items_state[ACTIONS_THROW_INDEX] = ITEM_OFF;
      if(!p->can_aggress() || game_state->team[p->get_team()]->is_aggress_done() ) game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX] = ITEM_OFF;
      
      if(p->get_move_count()==0){
	if(!p->can_block()) {
	  game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_OFF;
	}
      }
      else {
	if(p->can_blitz() && !game_state->team[p->get_team()]->is_blitz_done() ){
	  game_state->actions_menu_items[ACTIONS_BLOCK_INDEX] = ACTIONS_BLITZ;
	  game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_ON;
	}
	else {
	  game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_OFF;
	}
      }
    }
  }
  else{ // p->has_played()
    game_state->actions_menu_items_state[ACTIONS_MOVE_INDEX] = ITEM_OFF;
    game_state->actions_menu_items_state[ACTIONS_BLOCK_INDEX] = ITEM_OFF;
    game_state->actions_menu_items_state[ACTIONS_GATHER_INDEX] = ITEM_OFF;
    game_state->actions_menu_items_state[ACTIONS_THROW_INDEX] = ITEM_OFF;
    game_state->actions_menu_items_state[ACTIONS_AGGRESS_INDEX] = ITEM_OFF;
  }
  
  for(int i=ACTIONS_MOVE_INDEX;i<ACTIONS_NB;i++)
    set_actions_menu(game_state->actions_menu_items[i], game_state->actions_menu_items_state[i], i);
  
  if(y_pixel+ACTIONS_MENU_HEIGHT > (Config::get_screen_h()-pg->y) ) y_pixel = (Config::get_screen_h()-pg->y) - ACTIONS_MENU_HEIGHT;
  if(x_pixel+actions_menu->image->w+pg->x > (FRAME_LIMIT-pg->x) ) x_pixel = (FRAME_LIMIT-pg->x) - actions_menu->image->w - pg->x;
  set_object_position(actions_menu,x_pixel,y_pixel);
  return 0;
}
 
#define TX(x,y) (((cosa)*(x)) - ((sina)*(y)))
#define TY(x,y) (((sina)*(x)) + ((cosa)*(y)))

graphical_object* make_pass_arrow(Square *start, Square *end, int max){ 

  // DEBUG(printf("-> make pass arrow\n"); );

  int x_start = SQUARE_TO_PIXEL(start->get_x()) + SQUARE_SIZE/2;
  int y_start = SQUARE_TO_PIXEL(start->get_y()) + SQUARE_SIZE/2;

  int x_end = SQUARE_TO_PIXEL(end->get_x()) + SQUARE_SIZE/2;
  int y_end = SQUARE_TO_PIXEL(end->get_y()) + SQUARE_SIZE/2;

  int delta_x = x_start - x_end;
  int delta_y = y_start - y_end;
  
  if(delta_x==0 && delta_y == 0) return NULL;

  int arrow_height = (int)(hypot((double)delta_x, (double)delta_y) - pass_arrow_end->h);
  
  int pass_length = arrow_height + pass_arrow_end->h;
  if( pass_length > ((game_state->weather==BLIZZARD)?NORMAL_PASS_SIZE:BOMB_PASS_SIZE) ) return NULL;

  int index = BOMB_PASS_INDEX;
  SDL_Rect e,b;
  
  if( pass_length<=FLASH_PASS_SIZE) index = FLASH_PASS_INDEX;
  else if( pass_length<=NORMAL_PASS_SIZE) index = NORMAL_PASS_INDEX;
  else if( pass_length<=LONG_PASS_SIZE) index = LONG_PASS_INDEX;

  if(index > max) return NULL;

  double angle;
  
  if(delta_y==0) {
    if(delta_x>0){ 
      angle=M_PI/2; 
    }
    else {
      angle=-M_PI/2;
    }
  }   
  else {
    angle = atan((double)delta_x/(double)delta_y);
  }
  
  if(delta_y < 0) angle+=M_PI;
  
  double cosa = cos(angle);
  double sina = sin(angle);
  double dw = PASS_ARROW_END_WIDTH/2;
  double dh = (pass_arrow_end->h+arrow_height)/2;

  e.x = index;
  e.y = 0;
  e.w = PASS_ARROW_END_WIDTH;
  e.h = pass_arrow_end->h;
  b.x = 0;
  b.y = pass_arrow_body->h-arrow_height;
  b.w = pass_arrow_body->w;
  b.h = arrow_height;

  SDL_Surface* the_pass_arrow = stack_up_surface(pass_arrow_end,&e,pass_arrow_body,&b);

  graphical_object *arrow;
  arrow = (graphical_object*)malloc(sizeof(graphical_object)); 
  arrow->image = roto_zoom_surface(the_pass_arrow, angle*180/M_PI, 1/*zoom*/,0);
  arrow->x = (int)(x_end - fabs(TY(dh,0) - MAX(TY(dh,dw),(MAX(TY(dh,-dw),(MAX(TY(-dh,-dw),TY(-dh,dw))))))));
  arrow->y = (int)(y_end - fabs(TX(dh,0) - MAX(TX(dh,dw),(MAX(TX(dh,-dw),(MAX(TX(-dh,-dw),TX(-dh,dw))))))));
  
  update_interception_squares(arrow);

  SDL_FreeSurface(the_pass_arrow);

//  DEBUG( printf("<- make pass arrow\n"); );

  return arrow;
}


/*
 * Return the pixel value at (x, y)
 * NOTE: The surface must be locked before calling this!
 */
Uint32 getpixel(SDL_Surface *surface, int x, int y){
  int bpp = surface->format->BytesPerPixel;
  /* Here p is the address to the pixel we want to retrieve */
  Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
  
  switch(bpp) {
  case 1:
    return *p;
  case 2:
    return *(Uint16 *)p;
  case 3:
    if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
      return p[0] << 16 | p[1] << 8 | p[2];
    else
      return p[0] | p[1] << 8 | p[2] << 16;
  case 4:
    return *(Uint32 *)p;
  default:
    return 0;       /* shouldn't happen, but avoids warnings */
  }
}

void update_pass_arrow_matrix(SDL_Surface *surf){
  int w = surf->w;
  int h = surf->h;
  int step = SQUARE_SIZE/PASS_ARROW_PRECISION;
  int i,j,x=0,y=0;

  memset(game_state->pass_arrow_matrix, 0, (sizeof(bool)*PASS_ARROW_MATRIX_MAX_SIZE)*(sizeof(bool)*PASS_ARROW_MATRIX_MAX_SIZE));

  game_state->pass_arrow_matrix_w = w/step;
  game_state->pass_arrow_matrix_h = h/step;
  
  if ( SDL_MUSTLOCK(surf) ) {
    if ( SDL_LockSurface(surf) < 0 ) {
      fprintf(stderr, "Can't lock surface: %s\n", SDL_GetError());
      return;
    }
  }
  
  for(i=step/2;i<(w-step);i+=step){
    for(j=step/2;j<(h-step);j+=step){
      game_state->pass_arrow_matrix[x][y] = (getpixel(surf,i,j)==0)?false:true;
      y++;
    }
    y=0;
    x++;
  }
  
  if ( SDL_MUSTLOCK(surf) ) {
    SDL_UnlockSurface(surf);
  }
}


void update_interception_squares(graphical_object *obj){
  update_pass_arrow_matrix(obj->image);
  
  game_state->interception_square_count = 0;
  game_state->interception_square = NULL;

  if(game_state->active_team==NONE) {
    DEBUG( printf("pas d'active game_state->team\n"); );
    return;
  }

  map<int,Player*> *players = game_state->team[1-game_state->active_team]->get_players();
    
  std::map<int,Player*> ::iterator it;
  Player *p;
  int p_x,p_y,x,y,x_test,y_test;
  bool goto_next_player;
  int pixel;
  
  for(it=players->begin();it!=players->end();it++){
    
    p = (*it).second;
    
    if(!p->get_square()) continue;
    
    p_x = SQUARE_TO_PIXEL(p->get_square()->get_x());
    p_y = SQUARE_TO_PIXEL(p->get_square()->get_y());
    
    if( p->get_status()==OK && !(p->get_square()->get_x()==game_state->target->get_x() && p->get_square()->get_y()==game_state->target->get_y()) && ((p_x+SQUARE_SIZE)>obj->x) && ((p_y+SQUARE_SIZE)>obj->y) && (p_x<(obj->x+obj->image->w)) && (p_y<(obj->y+obj->image->h))) {
      goto_next_player = false;
      pixel = 0;
      for(x=p_x;x<(p_x+SQUARE_SIZE)&& !goto_next_player;x++){
	for(y=p_y;y<(p_y+SQUARE_SIZE) && !goto_next_player;y++){
	  if ((x-obj->x)>0) x_test = x - obj->x;
	  else x_test = -1; 
	  
	  if ((y-obj->y)>0) y_test = y - obj->y;
	  else y_test = -1;
	  
	  if(x_test!=-1 && y_test!=-1) {
	    x_test = x_test/(SQUARE_SIZE/PASS_ARROW_PRECISION);
	    y_test = y_test/(SQUARE_SIZE/PASS_ARROW_PRECISION);
	    
	    if(game_state->pass_arrow_matrix[x_test][y_test]){
	      pixel++;
	      if(pixel>INTERCEPT_PIXEL_NEEDED){
		game_state->interception_squares[game_state->interception_square_count] = p->get_square(); 
		game_state->interception_square_count++;
		goto_next_player = true;
	      }
	    }
	  }
	}
      }
    }
  }
  
}

void draw_interception_squares(){
  SDL_Rect s,r;
  for(int i=0;i<game_state->interception_square_count;i++){   
    s.x = INTERCEPT_OFF;
    s.y = 0;
    s.w = SQUARE_SIZE;
    s.h = SQUARE_SIZE;
    r.x = SQUARE_TO_PIXEL(game_state->interception_squares[i]->get_x());
    r.y = SQUARE_TO_PIXEL(game_state->interception_squares[i]->get_y());
    r.w = s.w;
    r.h = s.h;
    BlitSurface(intercept_img,&s,pg->image,&r);
  }
}

void throw_in(){

  game_state->ball->set_visible(false);
  game_state->freeze_interaction = true;

  int ball_anim_x_start=0, ball_anim_y_start=0, ball_anim_x_end, ball_anim_y_end;
  double ball_anim_x_step;
  double ball_anim_y_step;
  double ball_anim_x; 
  double ball_anim_y; 
  int ball_anim_x_dir,ball_anim_y_dir;
  double ball_anim_angle;
  int x_ball = game_state->ball->get_square()->get_x();
  int y_ball = game_state->ball->get_square()->get_y();
  
  ball_anim_x_dir = 0;
  ball_anim_y_dir = 0;
  ball_anim_angle = 0;

  if(x_ball<0){
    ball_anim_x_start = SQUARE_TO_PIXEL(0);
    ball_anim_y_start = SQUARE_TO_PIXEL(y_ball);
	x_ball = 0;
    ball_anim_x_dir = 1;
  }
  else if( x_ball>=PLAYGROUND_WIDTH){
    x_ball = PLAYGROUND_WIDTH-1;
	ball_anim_x_start = SQUARE_TO_PIXEL((PLAYGROUND_WIDTH-1));
    ball_anim_y_start = SQUARE_TO_PIXEL(y_ball);
    ball_anim_x_dir = -1;
  }
  else if(y_ball<0){
    ball_anim_x_start = SQUARE_TO_PIXEL(x_ball);
    ball_anim_y_start = SQUARE_TO_PIXEL(0);
	y_ball = 0;
    ball_anim_y_dir = 1;
  }
  else if( y_ball>=PLAYGROUND_HEIGHT){
    ball_anim_x_start = SQUARE_TO_PIXEL(x_ball);
	y_ball = PLAYGROUND_HEIGHT-1;
	ball_anim_y_start = SQUARE_TO_PIXEL((PLAYGROUND_HEIGHT-1));
    ball_anim_y_dir = -1;
  }

  int direction = game_state->audience->throwin_direction();
  int distance = game_state->audience->throwin_distance();
 
  switch(direction){
  case LEFT: //0
    if(ball_anim_x_dir!=0) {
      ball_anim_y_dir = -1;
      if(ball_anim_x_dir==1) ball_anim_angle = M_PI/2;
    }
    else if(ball_anim_y_dir!=0) {
      ball_anim_x_dir = -1;
      if(ball_anim_y_dir==1) ball_anim_angle = M_PI/2;
    }
    break;
  case RIGHT: //2
    if(ball_anim_x_dir!=0) {
      ball_anim_y_dir = 1; 
      if(ball_anim_x_dir==-1) ball_anim_angle = M_PI/2;
    }
    else if(ball_anim_y_dir!=0) {
      ball_anim_x_dir = 1; 
      if(ball_anim_y_dir==-1) ball_anim_angle = M_PI/2;
    }
    break;
  case SIDE: //1
    if(ball_anim_x_dir!=0) {
      ball_anim_y_dir = 0;
      ball_anim_angle = M_PI/4;
    }
    else if(ball_anim_y_dir!=0) {
      ball_anim_x_dir = 0;
      ball_anim_angle = -M_PI/4;
    }
    break;
  }
 
	SDL_Surface *ball_ball = SDL_CreateRGBSurface(SDL_SWSURFACE, ball_img->w, ball_img->h, 32, ball_img->format->Rmask, ball_img->format->Gmask, ball_img->format->Bmask, 0xff000000);
	BlitSurface(ball_img,NULL,ball_ball,NULL);
	
  throw_in_ball = roto_zoom_surface(ball_ball, ball_anim_angle*180/M_PI, 1/*zoom*/,0);
  throw_in_ball_s.x = 0;
  throw_in_ball_s.y = 0;
  throw_in_ball_s.w = throw_in_ball->w;
  throw_in_ball_s.h = throw_in_ball->h;

  ball_anim_x_end = ball_anim_x_start + (ball_anim_x_dir * distance * SQUARE_SIZE);
  ball_anim_y_end = ball_anim_y_start + (ball_anim_y_dir * distance * SQUARE_SIZE);
  
  int x_diff = ball_anim_x_end - ball_anim_x_start;
  int y_diff = ball_anim_y_end - ball_anim_y_start;
  double dist = hypot(x_diff,y_diff);
  double dist_done = 0;
  
  ball_anim_x = ball_anim_x_start; 
  ball_anim_y = ball_anim_y_start; 

  ball_anim_x_step = x_diff/(dist/PASS_STEP);
  ball_anim_y_step = y_diff/(dist/PASS_STEP);

  double ball_anim_zoom = 1;
  game_state->throw_in_anim = true;
    
  for(double i = 0; i<(dist-PASS_STEP); i+=PASS_STEP){
    ball_anim_x += ball_anim_x_step;
    ball_anim_y += ball_anim_y_step;

	dist_done = hypot(ball_anim_x - ball_anim_x_start , ball_anim_y - ball_anim_y_start);	

	ball_anim_zoom = 1 + sin( (dist_done*M_PI)/dist );

	throw_in_ball = roto_zoom_surface(ball_ball, ball_anim_angle*180/M_PI, ball_anim_zoom,0);
	throw_in_ball_s.x = 0;
	throw_in_ball_s.y = 0;
	throw_in_ball_s.w = throw_in_ball->w;
	throw_in_ball_s.h = throw_in_ball->h;

    old_throw_in_ball_d = throw_in_ball_d;
    throw_in_ball_d.x = (Sint16)ball_anim_x - (throw_in_ball->w - SQUARE_SIZE)/2;
    throw_in_ball_d.y = (Sint16)ball_anim_y - (throw_in_ball->h - SQUARE_SIZE)/2;
    throw_in_ball_d.w = throw_in_ball_s.w;
    throw_in_ball_d.h = throw_in_ball_s.h;
    
    draw_all(false);
  }
  game_state->ball->set_visible(true);
  game_state->ball->place(x_ball+ball_anim_x_dir*distance,y_ball+ball_anim_y_dir*distance);
  game_state->freeze_interaction = false;
  game_state->throw_in_anim = false;
  SDL_FreeSurface(ball_ball);

  verify_ball_placement();
}

void verify_ball_placement(){
	int x_ball = game_state->ball->get_square()->get_x();
	int y_ball = game_state->ball->get_square()->get_y();

	DEBUG(printf("-> verify game_state->ball placement avec game_state->ball (%d,%d)\n",x_ball,y_ball); );

	if(x_ball<0 || x_ball>=PLAYGROUND_WIDTH || y_ball<0 || y_ball >= PLAYGROUND_HEIGHT){
		// public throw in
#ifndef NOSOUND
		if(Config::is_sound_enabled()){
			sp->play_sound(SND_WHISTLE,FX0_CHANNEL);
		}
#endif
		draw_all(true);
		dialog_box->open_info(screen,ICONS_REFEREE,MSG_THROW_IN,false,"");
		draw_all(true);

//SOUND - TALID    
#ifndef NOSOUND
		if(Config::is_sound_enabled()){
			sp->play_sound(SND_THROW, FX0_CHANNEL);
		}
#endif
	
		throw_in();
	}
	else if (Shared::get_playground(x_ball,y_ball)){ 
		if (Shared::get_playground(x_ball,y_ball)->get_status() == OK ){
			// le gars peut tenter de recuperer le ballon
			if( !Shared::get_playground(x_ball,y_ball)->has_got_ball() ){ 
				bool tmp = game_state->autocenter_mode; // enfin d'afficer le ballon durant le recentrage
				game_state->autocenter_mode = false;
				select_square(x_ball,y_ball);
				game_state->autocenter_mode = tmp;
	
				draw_all(true);
				if( game_state->current_action == ACTIONS_MOVE || game_state->current_action == ACTIONS_MOVE_PLUS /*	RM6*/|| game_state->current_action == ACTIONS_LEAP/*RM6*/) {
					// ICI, on est dans la cas d'un mouvement volontaire et donc le gars est obligé de 
					// tenter de ramasser la balle...
					switch_action(ACTIONS_GATHER);
				}
				else {
					switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_RECEIVE_QUESTION, game_state->team[Shared::get_playground(x_ball,y_ball)->get_team()]->get_name() ) ){
						case YES: 
							draw_all(true);
							if( game_state->ball->has_bounced() ) {
								switch_action(ACTIONS_RECEIVE);
							}
							else if (game_state->perfect_pass){
								switch_action(ACTIONS_RECEIVE);
							}  
							else{
								switch_action(ACTIONS_GATHER);
							} 
							break;
						case NO:
							game_state->ball->bounce();
							select_square(x_ball,y_ball);
							draw_all(true);
							game_state->ball->set_has_bounced(true);
							verify_ball_placement();
							break;
					}
				}
				autocenter(x_ball,y_ball);
			}
		}
		else {
			game_state->ball->bounce();
			select_square(x_ball,y_ball);
			draw_all(true);
			verify_ball_placement();
		}
	}
	else {
		// le ballon a atterit sur du vide... => 1 rebond

//SOUND - TALID    
#ifndef NOSOUND
		if(Config::is_sound_enabled()){
			sp->play_sound(SND_DROP, FX0_CHANNEL);
		}
#endif

		game_state->ball->set_visible(true);
		select_square(x_ball,y_ball);
		draw_all(true);
    
		if(!game_state->ball->has_bounced()){
			game_state->ball->set_has_bounced(true);
			SDL_Rect b_tmp;
			b_tmp.x = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_x());
			b_tmp.y = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_y());
			b_tmp.w = SQUARE_SIZE;
			b_tmp.h = SQUARE_SIZE;
			game_state->ball->bounce();
			select_square(x_ball,y_ball);
			pg_cliprect.x = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_x());
			pg_cliprect.y = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_y());
			pg_cliprect.w = SQUARE_SIZE;
			pg_cliprect.h = SQUARE_SIZE;
			pg_cliprect = rect_union(pg_cliprect,b_tmp);
			draw_all(false);
			verify_ball_placement();
		}
		else {
			///////////////////////////////////////////////////
			// Ragnar Modif : pas de turnover pour passe ou réception manquée lors d'un dump-off
			//if(game_state->old_ball_owner_team == game_state->active_team){
			if(!game_state->is_a_dump_off && !game_state->is_a_blitz_dump_off && game_state->old_ball_owner_team == game_state->active_team){
				turnover(game_state->active_team,1);
			}
		}
		game_state->ball->set_has_bounced(false);
	}
	DEBUG(printf("<- verify game_state->ball placement\n"); ); 
}

void turnover(int t,int j){
	DEBUG ( printf("-> turnover %d current_action=%d\n",j,game_state->current_action); );
	draw_all(true);
	dialog_box->open_info(screen,ICONS_STOP,MSG_TURNOVER,false,game_state->team[t]->get_name());
	stop_turn();
	draw_all(true);
	DEBUG ( printf("<- turnover %d current_action=%d\n",j,game_state->current_action); );
}

void half_time(){

//SOUND - TALID
  #ifndef NOSOUND
  if(Config::is_sound_enabled()){
	sp->play_sound(SND_ENDWHISTLE,FX0_CHANNEL);
	}
  #endif

  draw_all(true);
  dialog_box->open_info(screen,ICONS_REFEREE,MSG_HALF_TIME,false,"");
  draw_all(true);
  
  game_state->half = SECOND_HALF;

  prepare_for_next_kick_off();
 
  game_state->kick_off_team = 1 - game_state->first_half_kick_off_team;

  for(int i=HOME;i<=VISITOR;i++){
    game_state->team[i]->set_turn(0);
    game_state->team[i]->reset_reroll();
    game_state->corridor_count[i][0] = 0;
    game_state->corridor_count[i][1] = 0;
  }
  
  switch_mode(MODE_NONE);
}

void full_time(){
  if(game_state->team[HOME]->get_score() != game_state->team[VISITOR]->get_score() ) {

//SOUND - TALID
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_ENDWHISTLE,FX0_CHANNEL);
	}
	#endif
		
	draw_all(true);
    dialog_box->open_info(screen,ICONS_REFEREE,MSG_FULL_TIME,false,"");

	//SOUND - TALID
	#ifndef NOSOUND
	int test = ((game_state->team[HOME]->get_score() > game_state->team[VISITOR]->get_score())?(HOME):(VISITOR));
	if (test==VISITOR){
		if(Config::is_sound_enabled()){
			sp->play_sound(SND_VISITOR, FX0_CHANNEL);
		}
	}
	if (test==HOME){
		if(Config::is_sound_enabled()){
			sp->play_sound(SND_HOME, FX0_CHANNEL);
		}
	}
	#endif
	
	draw_all(true);
    dialog_box->open_info_s(screen,ICONS_SMILEY,MSG_WINNER_X,false,game_state->team[((game_state->team[HOME]->get_score() > game_state->team[VISITOR]->get_score())?(HOME):(VISITOR))]->get_name(),game_state->team[((game_state->team[HOME]->get_score() > game_state->team[VISITOR]->get_score())?(HOME):(VISITOR))]->get_name());
    draw_all(true);
    quit_game(); // fin de la partie
  }
  else {
    extra_time();
  }
}

void extra_time(){
#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_WHISTLE,FX0_CHANNEL);
	}
#endif
  draw_all(true);
  dialog_box->open_info(screen,ICONS_REFEREE,MSG_EXTRA_TIME,false,"");
  draw_all(true);
  
  game_state->half = EXTRA_TIME;
  prepare_for_next_kick_off();
    
  for(int i=HOME;i<=VISITOR;i++){
    game_state->team[i]->set_turn(0);
	
	/////////////////////////////////////
	// Ragnar Modif4 : prolongations, on joue avec les relances qui restent
	//game_state->team[i]->reset_reroll();
	/////////////////////////////////////
    game_state->corridor_count[i][0] = 0;
    game_state->corridor_count[i][1] = 0;
  }
  
  toss();
}

bool touchdown(){

  int team_id = NONE;
  
  for(int i=0;i<PLAYGROUND_WIDTH;i++){
    if(Shared::get_playground(i,0) && Shared::get_playground(i,0)->get_square() && Shared::get_playground(i,0)->get_status()==OK && Shared::get_playground(i,0)->has_got_ball() && Shared::get_playground(i,0)->get_team()==VISITOR) {
      team_id = VISITOR;
      Shared::get_playground(i,0)->set_has_ball(false);
      break;
    }
    
    if(Shared::get_playground(i,PLAYGROUND_HEIGHT-1) && Shared::get_playground(i,PLAYGROUND_HEIGHT-1)->get_square() && Shared::get_playground(i,PLAYGROUND_HEIGHT-1)->get_status()==OK  && Shared::get_playground(i,PLAYGROUND_HEIGHT-1)->has_got_ball() && Shared::get_playground(i,PLAYGROUND_HEIGHT-1)->get_team()==HOME) {
      team_id = HOME;
      Shared::get_playground(i,PLAYGROUND_HEIGHT-1)->set_has_ball(false);
      break;
    }
  }
  if(team_id==NONE) return false;

#ifndef NOSOUND
	if(Config::is_sound_enabled()){	
		sp->play_sound(SND_WHISTLE,FX0_CHANNEL);
	}
#endif
  draw_all(true);
  dialog_box->open_info(screen,ICONS_REFEREE,MSG_TOUCHDOWN,false,game_state->team[team_id]->get_name());
  
  game_state->team[team_id]->inc_score();
  
	// TOUCHDOWN MARQUE DURANT LE TOUR ADVERSE
	if(game_state->active_team==(1-team_id)) {
		game_state->team[team_id]->inc_turn();
		game_state->active_team = team_id;
	}
	
  stop_turn();

  draw_all(true);
  
  if( game_state->half==EXTRA_TIME) { // mort subite
    draw_all(true);
	dialog_box->open_info_s(screen,ICONS_SMILEY,MSG_WINNER_X,false,game_state->team[((game_state->team[HOME]->get_score() > game_state->team[VISITOR]->get_score())?(HOME):(VISITOR))]->get_name(),game_state->team[((game_state->team[HOME]->get_score() > game_state->team[VISITOR]->get_score())?(HOME):(VISITOR))]->get_name());
    draw_all(true);
    ///////////////////////////////
	// Ragnar Modif4 : mort subite
    //exit(0); // fin de la partie /*fait planter*/
	quit_game();
	///////////////////////////////
    return true;
  }
 
  // check for sunstroke <=> weather=DOGDAYS
  if(game_state->weather==DOGDAYS){
    std::map<int,Player*> ::iterator it;
    map<int,Player*> *players;
  
    for(int j=HOME;j<=VISITOR;j++){
      players = game_state->team[j]->get_players();
      for(it=players->begin();it!=players->end();it++){
	if( ((*it).second) && (((*it).second)->get_square()) && (((*it).second)->is_affected_by_sunstroke()) ){
	  ((*it).second)->place_in_reserve();
	  draw_all(true);
	  dialog_box->open_info_i(screen, ICONS_KO,MSG_X_AFFECTED_BY_SUNSTROKE,false,game_state->team[j]->get_name(),((*it).second)->get_number());
	  draw_all(true);
	}
      }
    }
  }

  prepare_for_next_kick_off();
  
  // l'equipe qui frappe est celle qui vient de marquer sauf si on recommence une mi-temps ( cad les turns == 0 )
 
  if(game_state->team[HOME]->get_turn()!=0 || game_state->team[VISITOR]->get_turn()!=0){
	game_state->kick_off_team = team_id;
  }
  
  switch_mode(MODE_NONE);
  return true;
}

void prepare_for_next_kick_off(){
	// degage le ballon
	game_state->ball->set_visible(false);
	game_state->ball->place(-1,-1);
	select_none();
	game_state->kick_off_result = NONE;

	game_state->old_formation_id = -1;

	std::map<int,Player*> ::iterator it;
	map<int,Player*> *players;

	int nb_player_ok[2] = {0,0};
	int j,roll;
	for(j=HOME;j<=VISITOR;j++){
		// reset le nombre de mec dans le corridor
		game_state->corridor_count[j][0] = 0;
		game_state->corridor_count[j][1] = 0;
		game_state->team[j]->set_placed(false);
		game_state->team[j]->set_has_free_turn(false);
		// mettre les joueurs du terrain en reserve
		DEBUG( printf("->transfer_players_to_reserve()\n" ); );
		game_state->team[j]->transfer_players_to_reserve();
		DEBUG( printf("<-transfer_players_to_reserve()\n" ); );
		// voir si les joueurs ko peuvent revenir
		players = game_state->team[j]->get_players();
		for(it=players->begin();it!=players->end();it++){
			if( ((*it).second) && ((*it).second)->has_got_ball()) ((*it).second)->set_has_ball(false); 
			switch(((*it).second)->get_status()){
				case KO:
					DEBUG( printf("->case KO:\n" ); );
					roll = d6->roll(); 
					
					if(game_state->dices_roll) console->print("Ko recovery roll : %i (%c%i)",roll, (roll>=KO_RECOVERY)?'>':'<',  KO_RECOVERY);

					if(roll >= KO_RECOVERY){
						DEBUG( printf("->roll >= KO_RECOVERY\n" ); );
						DEBUG( printf("le joueur num. %i revient en jeu apres ko!\n",((*it).second)->get_number() ); );
						DEBUG( printf("->place_in_reserve()\n" ); );
						((*it).second)->place_in_reserve();
						DEBUG( printf("<-place_in_reserve()\n" ); );
						draw_all(true);
						dialog_box->open_info_i(screen, ICONS_RESERVE,MSG_X_KO_RECOVERY_OK,false,game_state->team[j]->get_name(),((*it).second)->get_number());
						draw_all(true); 
						DEBUG( printf("<-roll >= KO_RECOVERY\n" ); );
					} 
					else {
						DEBUG( printf("->roll < KO_RECOVERY\n" ); );
						DEBUG( printf("le joueur num. %i n'a toujours pas recupere de son ko!\n",((*it).second)->get_number() ); );
				  
						draw_all(true);
						dialog_box->open_info_i(screen, ICONS_KO,MSG_X_KO_RECOVERY_FAILED,false,game_state->team[j]->get_name(),((*it).second)->get_number());
						draw_all(true);
						DEBUG( printf("<-roll < KO_RECOVERY\n" ); );
					}
					DEBUG( printf("<-case KO:\n" ); );
				break;
				case GROUND:
				case DOWN: 
					((*it).second)->set_status(OK);
				break;
			}
    
			if( ((*it).second)->get_status()==OK || 
				((*it).second)->get_status()==RESERVE ) 
				nb_player_ok[j]++;
		}
	}

	if( (nb_player_ok[HOME]<3) && (nb_player_ok[VISITOR]<3) ){	
		// c'est une vrai boucherie, on arrete le match
		draw_all(true);
		dialog_box->open_info(screen,ICONS_SMILEY,MSG_DRAW,false,"");
		draw_all(true);
		quit_game();
	}
	else if (nb_player_ok[HOME] < 3) {
		// defaite de HOME par forfait
		draw_all(true);
		dialog_box->open_info_s(screen,ICONS_SMILEY,MSG_WINNER_X,false,game_state->team[VISITOR]->get_name(),game_state->team[VISITOR]->get_name());
		draw_all(true);
		quit_game();
	}
	else if (nb_player_ok[VISITOR] < 3) {
		// defaite de VISITOR par forfait
		draw_all(true);
		dialog_box->open_info_s(screen,ICONS_SMILEY,MSG_WINNER_X,false,game_state->team[HOME]->get_name(),game_state->team[HOME]->get_name());
		draw_all(true);
		quit_game();
	}

}

// fonction servant a faire en sorte qu'on ne puisse pas jouer un peu avec un gars puis un autre et enfin fin l'action avec le joueur precedent
void check_for_multi_play(){

  if( game_state->old_selected_player && 
	  Shared::get_playground(game_state->old_selected_player->get_x(),game_state->old_selected_player->get_y()) && 
	  Shared::get_playground(game_state->old_selected_player->get_x(),game_state->old_selected_player->get_y())->has_done_something() && 
	  game_state->selected_player && 
	  ( game_state->selected_player->get_square()->get_x() != game_state->old_selected_player->get_x() || game_state->selected_player->get_square()->get_y() != game_state->old_selected_player->get_y())
	  ) {
    Shared::get_playground(game_state->old_selected_player->get_x(),game_state->old_selected_player->get_y())->set_has_played(true);
    pg_cliprect.x = -pg->x;
    pg_cliprect.y = -pg->y;
    pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
    pg_cliprect.h = Config::get_screen_h();
  } 
}

/*
bool everybody_has_played(int team_id){
  map<int,Player*> ::iterator it;
  map<int,Player*> *players = game_state->team[team_id]->get_players();
  bool r = true;
  
  for(it=players->begin();it!=players->end();it++){
    if (((*it).second)->get_square()){
      r = ((*it).second)->has_played() && r;
    }
  }
  return r;
}
*/

void switch_mode(int mode){
  game_state->current_mode = mode;
  
  erase_panel_player_info();
  toggle_grab_mouse_mode(false);

  switch(game_state->current_mode){
  case MODE_SURPRISE:
	game_state->x_dock = DOCK_X;
	game_state->y_dock = DOCK_Y;
	game_state->team_in_placement = 1 - game_state->kick_off_team;
	draw_all(true);
    break;
  case MODE_NONE:
	game_state->x_dock = DOCK_X;
	game_state->y_dock = DOCK_Y;
	game_state->team_in_placement = NONE;
    draw_all(true);	
    dialog_box->open_info_s(screen, ICONS_INFO, MSG_X_PLACEMENT_FIRST, false,game_state->team[game_state->kick_off_team]->get_name(),game_state->team[game_state->kick_off_team]->get_name());
    draw_all(true);
    if(game_state->autocenter_mode) autocenter(PLAYGROUND_WIDTH-1,PLAYGROUND_HEIGHT/2 );
    draw_all(true);
	break;
  case MODE_PLAYING:
	game_state->x_dock = DOCK_X;
	game_state->y_dock = DOCK_Y;
    game_state->current_action = ACTIONS_NONE;
    draw_all(true);
    dialog_box->open_info_s(screen, ICONS_INFO,MSG_READY_FOR_PLAYING_X_FIRST,false, game_state->team[(((game_state->kick_off_team==HOME && game_state->team[HOME]->has_free_turn())||(game_state->kick_off_team==VISITOR&&(!game_state->team[VISITOR]->has_free_turn())))?HOME:VISITOR)]->get_name(), game_state->team[(((game_state->kick_off_team==HOME && game_state->team[HOME]->has_free_turn())||(game_state->kick_off_team==VISITOR&&(!game_state->team[VISITOR]->has_free_turn())))?HOME:VISITOR)]->get_name());    
	draw_all(true);
	if(game_state->autocenter_mode) autocenter(PLAYGROUND_WIDTH/2,PLAYGROUND_HEIGHT/2 );
	draw_all(true);
    break;
  case MODE_BALL_PLACEMENT:
	game_state->x_dock = DOCK_X;
	game_state->y_dock = DOCK_Y;
    game_state->team_in_placement = NONE;
	draw_all(true);
    dialog_box->open_info_s(screen, ICONS_INFO, MSG_X_PLACE_BALL,false,game_state->team[game_state->kick_off_team]->get_name(),game_state->team[game_state->kick_off_team]->get_name()); 
	draw_all(true);
	if(game_state->autocenter_mode) autocenter(PLAYGROUND_WIDTH/2,(game_state->kick_off_team==HOME)?(3*PLAYGROUND_HEIGHT/4):(PLAYGROUND_HEIGHT/4) );
	draw_all(true);
    break;
  case MODE_CHOOSE_BALL_OWNER:
	game_state->x_dock = DOCK_X;
	game_state->y_dock = DOCK_Y;
    draw_all(true);
    dialog_box->open_info(screen, ICONS_INFO, MSG_X_CHOOSE_BALL_OWNER,false,game_state->team[game_state->kick_off_team]->get_name()); 
    draw_all(true);
    break;
  }


}

void switch_action(int action){
  DEBUG( printf("joueur a la case (%d,%d) : ", (game_state->selection)?game_state->selection->get_x():-1, (game_state->selection)?game_state->selection->get_y():-1); );
  game_state->current_action = action;
  
  // pour generer un motion event et donc passer dans filter event et etre sur de choisir une game_state->target meme en sortie du menu action
  game_state->old_x_square = -1;
  game_state->old_y_square = -1;
  SDL_WarpMouse(event_x_mouse,event_y_mouse);
  
  Player *p = Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y());
  int goal = 0;
  bool pursue = false;
  int roll = 0;
  int result = 0;
  bool reroll_done = false; 
  int x_target = (game_state->target)?game_state->target->get_x():0;
  int y_target = (game_state->target)?game_state->target->get_y():0;
  Player* player_out = NULL;
  bool ball_out = false;
  switch(game_state->current_action){
  case ACTIONS_LEAP:
	DEBUG( printf("leap\n") );
	break;
  case ACTIONS_LANDING:
	DEBUG( printf("landing\n"); );
	
	pg_cliprect.x = SQUARE_TO_PIXEL(x_target)-SQUARE_SIZE;
	pg_cliprect.y = SQUARE_TO_PIXEL(y_target)-SQUARE_SIZE;
	pg_cliprect.w = SQUARE_SIZE*3;
	pg_cliprect.h = SQUARE_SIZE*3;

	draw_all(false);

	if(x_target < 0 || x_target >= PLAYGROUND_WIDTH || y_target < 0 || y_target >= PLAYGROUND_HEIGHT ){	

		game_state->team_mate->place(NULL);

		if(game_state->team_mate->has_got_ball()) {
			game_state->ball->place(x_target,y_target);
			ball_out = true;
		}

		roll = game_state->audience->aggress_player();
		/////////////////////////////////////////////////
		// Ragnar Modif3 : stunty
		if (game_state->team_mate->has_got_skill(STUNTY)) {
			roll++;
			if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
		}
		/////////////////////////////////////////////////
		injure_player(game_state->team_mate, roll, true);
		
		if(ball_out) {
			game_state->old_ball_owner_team = game_state->team_mate->get_team();
			verify_ball_placement();
		}
		if(x_target < 0) x_target = 0;
		else if(x_target >= PLAYGROUND_WIDTH) x_target = PLAYGROUND_WIDTH-1;
		if(y_target < 0) y_target = 0;
		else if(y_target>= PLAYGROUND_HEIGHT) y_target = PLAYGROUND_HEIGHT-1;
		select_square(x_target,y_target);
	}
	else if( Shared::get_playground(x_target,y_target) && 
			 !(x_target == game_state->team_mate->get_square()->get_x() && 
			 y_target == game_state->team_mate->get_square()->get_y())
			 ) {

		// ATTENTION : POSSIBILITE DE BUGGER ICI SI LE GARS SUR QUI ON TOMBE ET ENTOURE D'AUTRES GARS
		
		Player *under = Shared::get_playground(x_target,y_target);
		Square *go_to = NULL; 
		do{
			go_to = random_move_target(x_target,y_target);
		} while ( go_to->get_x() < 0 || go_to->get_x() >= PLAYGROUND_WIDTH || go_to->get_y() < 0 || go_to->get_y() >= PLAYGROUND_HEIGHT || Shared::get_playground(go_to->get_x(),go_to->get_y()));
		
		under->place(go_to);
		delete go_to;

		game_state->team_mate->place(x_target,y_target);
	
		if(game_state->team_mate->has_got_ball()) {
			game_state->ball->place(x_target,y_target);
		}

		// jet d'armure pour le mec en dessus 
		tackle_player(under,NULL,0,0,true);

		// jet d'armure pour le mec volant
		select_square(x_target,y_target);
		tackle_player(game_state->team_mate,NULL,0,0,true);
	}		
	else {
		game_state->team_mate->place(x_target,y_target);	

		if(game_state->team_mate->has_got_ball()) {
			game_state->ball->place(x_target,y_target);
		}

		goal = game_state->team_mate->landing(game_state->perfect_pass);
		delete game_state->target;
		game_state->target = NULL;

		reroll_done = game_state->team[game_state->team_mate->get_team()]->is_reroll_used();
	landing_begining:
		roll = d6->roll();
		if (roll!=6 && (roll==1 || roll<goal)) 
			result = (reroll_done)?TOOBAD:FAIL;
		else result = SUCCESS;
	
		if(game_state->dices_roll) console->print("Landing roll : %i  (%c%i)", roll, results[result], goal);
	
		switch(result){
			case SUCCESS:
				DEBUG( printf("succes land!\n"); );
				select_square(x_target,y_target);

				// Ragnar Modif6 : dispersion de la balle
				// si le mec volant atterrit sur la balle, il peut tenter de la ramasser
				if(game_state->team_mate->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					game_state->team_mate->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					verify_ball_placement();
				}
				/////////////////////////////////////////
				
				break;
			case FAIL:

				draw_all(true);
				switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_LANDING_REROLL_QUESTION, game_state->team[game_state->team_mate->get_team()]->get_name())){
					case YES: 
						game_state->team[game_state->team_mate->get_team()]->set_reroll_used(true);
						reroll_done = true;
						draw_all(true);
						goto landing_begining;
						break;
					case NO:
						draw_all(true);
						break;
				}

			case TOOBAD: 
				DEBUG( printf("toobad! (tu l'as dans le cul)\n"); );
				select_square(x_target,y_target);
				tackle_player(game_state->team_mate,NULL,0,0,true);
				break;
		}
	}

	game_state->throw_team_mate_fumble = false;
	game_state->team_mate = NULL;
	delete game_state->target;
	game_state->target = NULL;
	game_state->current_action = ACTIONS_NONE;
	draw_all(true);

	break;
  case ACTIONS_MOVE_AND_BLITZ:	
	DEBUG( printf("move and blitz\n"); );
    
    goal = p->overmove((game_state->weather==BLIZZARD)?true:false);
    
  actions_move_and_blitz_begining:
    roll = d6->roll();

    if (roll!=6 && (roll==1 || roll<goal)) 
		result = (reroll_done)?TOOBAD:FAIL;
    else result = SUCCESS;

	if(game_state->dices_roll) console->print("Move extra square roll : %i  (%c%i)", roll, results[result], goal);
		
    DEBUG( printf("resultat de mettre le paquet pour blitzer: %d - ", result); );
    
    switch(result){
    case SUCCESS:
      DEBUG( printf("succes move+!\n"); );
      game_state->current_action = ACTIONS_BLITZ;
      break;
    case FAIL:

    if( p->has_got_skill(SURE_FEET) ){
		draw_all(true);
	    dialog_box->open_info(screen,ICONS_INFO,MSG_MOVE_PLUS_FREE_REROLL,false,game_state->team[p->get_team()]->get_name());
		reroll_done = true;
		draw_all(true);
		goto actions_move_and_blitz_begining;
	}
    ////////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[p->get_team()]->can_reroll()) goto actions_move_and_blitz_case_toobad;
    else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) goto actions_move_and_blitz_case_toobad;
    ////////////////////////////////////////////

	draw_all(true);
	switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_MOVE_PLUS_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
		case YES: 
		game_state->team[p->get_team()]->set_reroll_used(true);
		reroll_done = true;
		draw_all(true);
		goto actions_move_and_blitz_begining;
		break;
		case NO:
		draw_all(true);
		break;
	}

    case TOOBAD: 
	actions_move_and_blitz_case_toobad:
      DEBUG( printf("toobad! (tu l'as dans le cul)\n"); );
      tackle_player(p,NULL,0,0,false);
      game_state->current_action = ACTIONS_NONE;
      break;
    }
        
    break;
  case ACTIONS_CHOOSE_TEAM_MATE:
	DEBUG( printf("choose team mate\n"); );	
		break;
  case ACTIONS_TRANSMIT:
    DEBUG( printf("transmit\n"); );
    update_transmit_squares(p);
    game_state->current_action = ACTIONS_CHOOSE_TRANSMIT_SQUARE;
    break;
  case ACTIONS_CHOOSE_INTERCEPTION_SQUARE:
    DEBUG( printf("choose game_state->interception_square\n"); );
    break;
  case ACTIONS_THROW_TEAM_MATE:
	DEBUG(printf("-> throw team mate\n"); );
	draw_all(false);
    game_state->select_throw_target  = true;
	break;
  case ACTIONS_THROW:
    DEBUG(printf("throw\n"); );
    game_state->select_throw_target  = true;
    break;

  case ACTIONS_GATHER:
    DEBUG(printf("catch\n"); );
    p->set_gather_done(true);
    
    check_for_multi_play();
    
    goal = (p->gather()) + ((game_state->weather==SHOWER)?1:0);
    
  actions_gather_begining:
    roll = d6->roll();

    if (roll!=6 && (roll==1 || roll<goal)) {
      result = (reroll_done)?TOOBAD:FAIL;
    }
    else result = SUCCESS;
    
	if(game_state->dices_roll) console->print("Gather roll : %i  (%c%i)", roll, results[result], goal);
	
    DEBUG(printf("\t resultat du catch : goal=%d   roll=%d   result=%d => ", goal, roll, result); );
    
    switch(result){
    case SUCCESS:

	//SOUND - TALID
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_PICKUP, FX0_CHANNEL);
	}
	#endif

	DEBUG(printf("Cool, tu as le ballon\n"); );
    game_state->ball->set_visible(false);
    p->set_has_ball(true);
    if(game_state->active_team!=p->get_team()) {
		turnover(game_state->active_team,2);
    }
    break;
    case FAIL:
      DEBUG(printf("Dommage, mais tu as une relance\n"); );
      
      if(p->has_got_skill(SURE_HANDS)){
		// open_info
		draw_all(true);
		dialog_box->open_info(screen,ICONS_INFO,MSG_GATHER_FREE_REROLL,false,game_state->team[p->get_team()]->get_name());
		reroll_done = true;
		draw_all(true);
		goto actions_gather_begining;
      }
      ////////////////////////////////////////////
	  // Ragnar Modif5 : big guy
	  //else if(!game_state->team[p->get_team()]->can_reroll()) goto actions_gather_case_toobad;
		else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) goto actions_gather_case_toobad;
      ////////////////////////////////////////////

      draw_all(true);
      switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_GATHER_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
      case YES: 
	game_state->team[p->get_team()]->set_reroll_used(true);
	reroll_done = true;
	draw_all(true);
	goto actions_gather_begining;
	break;
      case NO:
	draw_all(true);
	break;
      }
    case TOOBAD:
    actions_gather_case_toobad:
      DEBUG(printf("Tu l'as dans le cul : "); );
      game_state->ball->bounce();
      game_state->ball->set_has_bounced(true);
      verify_ball_placement();
      
      p->set_has_played(true);
      if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),3);
      }
      
      break;      
    }
    game_state->current_action = ACTIONS_NONE;
    break;
  
  case ACTIONS_RECEIVE:
    DEBUG(printf("receive\n"); );
    
    check_for_multi_play();
    
    goal = (p->receive_ball(game_state->perfect_pass)) + ((game_state->weather==SHOWER)?1:0);
	p->set_receive_done(true);
  actions_receive_begining:
    roll = d6->roll();
    
    if (roll!=6 && (roll==1 || roll<goal)) {
      result = (reroll_done)?TOOBAD:FAIL;
    }
    else result = SUCCESS;
    
	if(game_state->dices_roll) console->print("Receive roll : %i  (%c%i)", roll, results[result], goal);

    DEBUG(printf("\t resultat du receive : goal=%d   roll=%d   result=%d => ", goal, roll, result); );
    
    switch(result){
    case SUCCESS:
      DEBUG(printf("Cool, tu as le ballon\n"); );
      game_state->ball->set_visible(false);

//SOUND - TALID    
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_PICKUP, FX0_CHANNEL);
	}
   #endif

      p->set_has_ball(true);
      ///////////////////////////////////////////////////////
	  // Ragnar Modif : dump off
	  if(!game_state->is_a_dump_off && !game_state->is_a_blitz_dump_off && game_state->active_team!=p->get_team()) {
		turnover(p->get_team(),4);
      }
      break;
    case FAIL:
      DEBUG(printf("Dommage, mais tu as une relance\n"); );
      
      if(p->has_got_skill(CATCH)){
		draw_all(true);
		dialog_box->open_info(screen,ICONS_INFO,MSG_RECEIVE_FREE_REROLL,false,game_state->team[p->get_team()]->get_name());
		reroll_done = true;
		draw_all(true);
		goto actions_receive_begining;
      }

	///////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[p->get_team()]->can_reroll()) goto actions_receive_case_toobad;
	
	// en cas de dump off, l'équipe temporairement "active" (celle qui fait le dump off) n'a pas de relance
	else if(game_state->is_a_blitz_dump_off || game_state->is_a_dump_off){
		if(game_state->active_team==p->get_team()) goto actions_receive_case_toobad;
	}
	// pas de relance pendant le tour adverse
	else if(!game_state->is_a_blitz_dump_off && !game_state->is_a_dump_off && game_state->active_team!=p->get_team()) goto actions_receive_case_toobad;
    // pas de relance si on en a plus ou qu'on est un big guy
	else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) goto actions_receive_case_toobad;
	////////////////////////////////////////////

      draw_all(true);
      switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_RECEIVE_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
      case YES:
		game_state->team[p->get_team()]->set_reroll_used(true);
		reroll_done = true;
		draw_all(true);
		goto actions_receive_begining;
		break;
      case NO:
		draw_all(true);
		break;
      }

    case TOOBAD:
    actions_receive_case_toobad:
      DEBUG(printf("Tu l'as dans le cul : "); );
      game_state->ball->bounce();
      game_state->ball->set_has_bounced(true);
      verify_ball_placement();

		////////////////////////////////////////////////////
		// Ragnar Modif5 : la réception loupée d'un dump off ne supprime pas d'action
		if (!game_state->is_a_blitz_dump_off && !game_state->is_a_dump_off)
			p->set_has_played(true);
		////////////////////////////////////////////////////
	  
	  ////////////////////////////////////////////////////
	  // Ragnar Modif : dump off
	  if(!game_state->is_a_dump_off && !game_state->is_a_blitz_dump_off && p->get_team()==game_state->active_team && game_state->current_mode!=MODE_BALL_PLACEMENT) {
		turnover(p->get_team(),5);
      }
      
      break;      
    }
    game_state->current_action = ACTIONS_NONE;
    break;
  case ACTIONS_ROLL_OVER:
    DEBUG(printf("roll over\n"); );

    check_for_multi_play();

    p->set_status(GROUND);
    p->set_has_played(true);
    game_state->current_action = ACTIONS_NONE;
    break;
  case ACTIONS_GET_UP:
    DEBUG(printf("get up\n"); );
    
    check_for_multi_play();

	////////////////////////////////////////////////
	//Ragnar Modif6 : Take Root
	if (p->has_got_skill(TAKE_ROOT)){
		int get_up_roll = d6->roll();
		if (get_up_roll>=4){
			if(game_state->dices_roll) console->print("Take Root : roll = %i >4, player managed to get up",get_up_roll);
			p->set_status(OK);
		}
		else{
			if(game_state->dices_roll) console->print("Take Root : roll = %i <4, player failed to get up",get_up_roll);
			draw_all(true);
			dialog_box->open_info_i(screen,ICONS_AFRAID,MSG_GET_UP_TAKE_ROOT,false,game_state->team[p->get_team()]->get_name(),p->get_number());
			draw_all(true);
		}
		p->set_has_played(true);
	}
	else {
		p->set_status(OK);
		p->set_get_up_done(true);
		if( !p->has_got_skill(JUMP_UP) ) p->set_move_count(GET_UP_COST);
		game_state->current_action = ACTIONS_NONE;
	}
	////////////////////////////////////////////////

    break;
  case ACTIONS_INTERCEPTION_ATTEMPT:
    DEBUG( printf("intercept pass\n"); );
    game_state->current_action = ACTIONS_THROW;
    break;
  case ACTIONS_INDIRECT_PUSH_PLAYER_OUT:
	player_out = Shared::get_playground(game_state->push_square->get_x(),game_state->push_square->get_y());
	
	player_out->place(NULL);
	
	if(player_out->has_got_ball()) {
		game_state->ball->place(game_state->indirect_push_square);
		ball_out = true;	
	}
	
	game_state->indirect_push_square = NULL;
	
	roll = game_state->audience->aggress_player();
	
	/////////////////////////////////////////////////
	// Ragnar Modif3 : stunty
	if (player_out->has_got_skill(STUNTY)) {
		roll++;
		if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
	}
	/////////////////////////////////////////////////
	
	injure_player(player_out, roll, true);
   
    if(ball_out) {
		game_state->old_ball_owner_team = player_out->get_team();
		verify_ball_placement();
	}

	break;

	case ACTIONS_DOUBLE_INDIRECT_PUSH_PLAYER_OUT:
	player_out = Shared::get_playground(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y());
	
	player_out->place(NULL);
	
	if(player_out->has_got_ball()) {
		game_state->ball->place(game_state->double_indirect_push_square);
		ball_out = true;	
	}
	
	game_state->double_indirect_push_square = NULL;
	
	roll = game_state->audience->aggress_player();
	
	/////////////////////////////////////////////////
	// Ragnar Modif3 : stunty
	if (player_out->has_got_skill(STUNTY)) {
		roll++;
		if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
	}
	/////////////////////////////////////////////////
	
	injure_player(player_out, roll, true);
   
    if(ball_out) {
		game_state->old_ball_owner_team = player_out->get_team();
		verify_ball_placement();
	}

	break;
  
  case ACTIONS_PUSH_PLAYER_OUT:
	DEBUG(printf("push player out\n"); );
		
	player_out = Shared::get_playground(x_target,y_target);
	
	player_out->place(NULL);
	
	if(player_out->has_got_ball()) {
		game_state->ball->place(game_state->push_square);
		ball_out = true;
	}
	game_state->push_square = NULL;
	
	// poursuite 
    draw_all(true);
	delete game_state->target;
	game_state->target = NULL;

    //////////////////////////////////////////////////
	// Ragnar Modif4 : frenetique poursuit toujours
	if (p->has_got_skill(FRENZY)) {
		p->place(x_target,y_target);
        if(p->has_got_ball()) game_state->ball->place(x_target,y_target);

		// Ragnar Modif6 : dispersion de la balle
		// si le frénétique passe sur la balle en poursuivant
		else {
			if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				game_state->ball->bounce();
				game_state->ball->set_has_bounced(true);
				verify_ball_placement();
			}
		}
		/////////////////////////////////////////

		
		draw_all(true);
	}
	else {
		switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_PURSUE,game_state->team[p->get_team()]->get_name())){
		case YES:
		  p->place(x_target,y_target);
		  if(p->has_got_ball()) game_state->ball->place(x_target,y_target);

		  // Ragnar Modif6 : dispersion de la balle
		  // si passe sur la balle en poursuivant peut tenter de la ramasser
		  else {
		  	  if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				  p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				  verify_ball_placement();
			  }
		  }
		  /////////////////////////////////////////

		  draw_all(true);
		  break;
		case NO:
		  draw_all(true);
		  break;
		}
	}
	/////////////////////////////////////////////////
	
	roll = game_state->audience->aggress_player();
	/////////////////////////////////////////////////
	// Ragnar Modif3 : stunty
	if (player_out->has_got_skill(STUNTY)) {
		roll++;
		if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
	}
	/////////////////////////////////////////////////
	injure_player(player_out, roll, true);
    game_state->current_action = ACTIONS_NONE;

	if(ball_out) {
		game_state->old_ball_owner_team = player_out->get_team();
		verify_ball_placement();
	}
	break;
  case ACTIONS_PUSH_PLAYER:
    DEBUG(printf("push player\n"); );
    
	player_out = Shared::get_playground(x_target,y_target);
    
	player_out->place(game_state->push_square->get_x(),game_state->push_square->get_y());
     
    check_for_multi_play();
    
    if ( player_out->has_got_ball() ){
		game_state->ball->place(game_state->push_square);
		////////////////////////////////////////
		// Ragnar Modif3 : dextérité annule arracher le ballon
		if( p->has_got_skill(STRIP_BALL) && !player_out->has_got_skill(SURE_HANDS)) {
		////////////////////////////////////////
			player_out->set_has_ball(false);
			game_state->old_ball_owner_team = player_out->get_team();
			game_state->ball->bounce();
			/////////////////////////////////////////
			// Ragnar Modif3 : le ballon doit rebondir
			//game_state->ball->set_has_bounced(true);
			/////////////////////////////////////////
			verify_ball_placement();
		}
	}
    
	// Ragnar Modif6 : dispersion de la balle
	// si le joueur est repoussé sur la balle
	else {
		if(player_out->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
			player_out->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
			game_state->ball->bounce();
			game_state->ball->set_has_bounced(true);
			verify_ball_placement();
		}
	}
	/////////////////////////////////////////

	game_state->push_square = NULL;

	draw_all(true);
	delete game_state->target;
	game_state->target = NULL;

    // poursuite 
    if( !p->has_got_skill(FRENZY) ){
		draw_all(true);
		switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_PURSUE,game_state->team[p->get_team()]->get_name())){
		case YES: 
			p->place(x_target,y_target);
			if(p->has_got_ball()) game_state->ball->place(x_target,y_target);

			// Ragnar Modif6 : dispersion de la balle
			// si le joueur passe sur la balle, il peut tenter de la ramasser
			else {
				if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					verify_ball_placement();
				}
			}
			/////////////////////////////////////////

			draw_all(true);
			break;
		case NO:
			draw_all(true);
			break;
		}
		game_state->current_action = ACTIONS_NONE;
    }
	else { /* has_got_skill(FRENZY) = frenesie*/
		p->place(x_target,y_target);
		if( p->has_got_ball() ) game_state->ball->place(x_target,y_target);
		
		// Ragnar Modif6 : dispersion de la balle
		// si le frénétique passe sur la balle il la disperse
		else {
			if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				game_state->ball->bounce();
				game_state->ball->set_has_bounced(true);
				verify_ball_placement();
			}
		}
		/////////////////////////////////////////

		////////////////////////////////////////////
		// Ragnar Modif4 : pour s'arrêter là s'il y a but
		if(touchdown()) {
			game_state->current_action = ACTIONS_NONE;
			draw_all(true);
			break;
		}
		////////////////////////////////////////////

		////////////////////////////////////////////
		// Ragnar Modif4 : un seul block supplémentaire
		if( p->movement_left()>0 && !p->is_frenzy_block_done()){
			p->set_frenzy_block_done(true);
			////////////////////////////////////////////
			p->inc_move_count(); 
			select_square(x_target,y_target);
			block_player(p,player_out);	
		}
		else {
			game_state->current_action = ACTIONS_NONE;
			draw_all(true);
		}
	}
    		
    break;
  case ACTIONS_PUSH_AND_HIT_PLAYER:
    DEBUG(printf("push and hit player\n"); );
    
    check_for_multi_play();

	///////////////////////////////////////////////////////////
	// Ragnar Modif5 : doit choisir de poursuivre avant le résultat de la blessure
	if(!p->is_pilling_on_used() && !p->has_got_skill(FRENZY)){
		draw_all(true);
		switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_PURSUE, game_state->team[p->get_team()]->get_name())){
			case YES: 
			  pursue=true;
			  draw_all(true);
			  break;
			case NO:
			  pursue=false;
			  break;
		}
	}
	///////////////////////////////////////////////////////////

    tackle_player(Shared::get_playground(x_target,y_target),
		  p,
		  game_state->push_square->get_x() - x_target,
		  game_state->push_square->get_y() - y_target,
		  true);
   
	game_state->push_square = NULL;

    // poursuite 
    draw_all(true);
    delete game_state->target;
	game_state->target = NULL;

	/////////////////////////////////////////////////////////////
	// Ragnar Modif3 : pilling on -> poursuit obligatoirement
	// se retouve au sol et perd la balle s'il la tenait
	if (p->is_pilling_on_used()){
		p->place(x_target,y_target);
		p->set_status(GROUND);
		if(p->has_got_ball()){
			game_state->ball->place(x_target,y_target);
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->bounce();
			game_state->ball->set_has_bounced(true);
			verify_ball_placement();
		}

		// Ragnar Modif6 : dispersion de la balle
		// si le joueur tombe sur la balle
		else {
			if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				game_state->ball->bounce();
				game_state->ball->set_has_bounced(true);
				verify_ball_placement();
			}
		}
		/////////////////////////////////////////

		/////////////////////////////////////////////
		// Ragnar Modif4 : son action se termine là !
		p->set_has_played(true);
		/////////////////////////////////////////////
		draw_all(true);
	}

	////////////////////////////////////////////////////////////
	// Ragnar Modif4 : frénétique poursuit toujours
	else if (p->has_got_skill(FRENZY) /*Ragnar Modif5*/ || pursue /*Ragnar Modif5*/){
		p->place(x_target,y_target);
		if(p->has_got_ball()) game_state->ball->place(x_target,y_target);
		// Ragnar Modif6 : dispersion de la balle
		// le joueur passe sur la balle. S'il est frénétique, il la disperse, sinon il peut tenter de la ramasser
		else {
			if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				if (p->has_got_skill(FRENZY)){
					game_state->ball->bounce();
					game_state->ball->set_has_bounced(true);
				}
				verify_ball_placement();
			}
		}
		/////////////////////////////////////////

		draw_all(true);
	}
	////////////////////////////////////////////////////////////

	/*
	else {
		switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_PURSUE, game_state->team[p->get_team()]->get_name())){
		case YES: 
		  p->place(x_target,y_target);
		  if(p->has_got_ball()) game_state->ball->place(x_target,y_target);
		  draw_all(true);
		  break;
		case NO:
		  draw_all(true);
		  break;
		}
	}
	*/
	/////////////////////////////////////////////////////////////
  
    game_state->current_action = ACTIONS_NONE;
    break;
	  case ACTIONS_INDIRECT_PUSH:
		game_state->x_indirect_push = game_state->push_square->get_x() - game_state->target->get_x();
		game_state->y_indirect_push = game_state->push_square->get_y() - game_state->target->get_y();
		game_state->direct_indirect_push = true;
		update_indirect_push_squares(game_state->direct_indirect_push);
		if(game_state->indirect_push_square_count==0) {
      
		  bool push_in_touch = check_if_can_indirect_push_in_touch();
		  if( !push_in_touch ) {
			game_state->direct_indirect_push = false;
			update_indirect_push_squares(game_state->direct_indirect_push);
		  }
		  if(push_in_touch || game_state->indirect_push_square_count==0){
		// pas de case libre, ni de case occupe donc c'est direct en touche
		

	//-------------------------  en touche  -----------------------//
		
			if(game_state->indirect_push_square) game_state->indirect_push_square->set_xy(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
			else game_state->indirect_push_square = new Square(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
			
			switch_action(ACTIONS_INDIRECT_PUSH_PLAYER_OUT);
			
			game_state->indirect_push_square = NULL;
			game_state->indirect_push_square_count = 0;
			switch_action(ACTIONS_PUSH_PLAYER);
	//-------------------------------------------------------------//

		  }
		  else {
			// il n'y a pas de case vide alors je vais faire chier tlm autour
			game_state->current_action = ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE;
		  }
		}
		else {
		  // ok, il y a une case vide alors je peux pousser
		  DEBUG ( printf("ok, il y a une case vide alors je peux pousser ! ACTIONS_INDIRECT_PUSH\n"); );
		  game_state->current_action = ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE;
		}
    
    break;
  case ACTIONS_INDIRECT_PUSH_AND_HIT:
		game_state->x_indirect_push = game_state->push_square->get_x() - game_state->target->get_x();
		game_state->y_indirect_push = game_state->push_square->get_y() - game_state->target->get_y();
		game_state->direct_indirect_push = true;
		update_indirect_push_squares(game_state->direct_indirect_push);
		if(game_state->indirect_push_square_count==0) {
      
		  bool push_in_touch = check_if_can_indirect_push_in_touch();
		  if( !push_in_touch ) {
			game_state->direct_indirect_push = false;
			update_indirect_push_squares(game_state->direct_indirect_push);
		  }
		  if(push_in_touch || game_state->indirect_push_square_count==0){
		// pas de case libre, ni de case occupe donc c'est direct en touche

		
	//------------------------  en touche  ------------------------//
			if(game_state->indirect_push_square) game_state->indirect_push_square->set_xy(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
			else game_state->indirect_push_square = new Square(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
			
			switch_action(ACTIONS_INDIRECT_PUSH_PLAYER_OUT);

			game_state->indirect_push_square = NULL;
			game_state->indirect_push_square_count = 0;
			switch_action(ACTIONS_PUSH_AND_HIT_PLAYER);
	//-------------------------------------------------------------//

		  
		  }
		  else {
			// il n'y a pas de case vide alors je vais faire chier tlm autour
			  game_state->current_action = ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE;
		  }
		}
		else {
		  // ok, il y a une case vide alors je peux pousser
		  game_state->current_action = ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE;
		}
    
    
    break;

  	  case ACTIONS_DOUBLE_INDIRECT_PUSH:
		game_state->x_double_indirect_push = game_state->indirect_push_square->get_x() - game_state->push_square->get_x();
		game_state->y_double_indirect_push = game_state->indirect_push_square->get_y() - game_state->push_square->get_y();
		game_state->direct_double_indirect_push = true;
		DEBUG( printf("ACTIONS_DOUBLE_INDIRECT_PUSH update_double_indirect_push_squares(game_state->direct_double_indirect_push)\n"); );
		update_double_indirect_push_squares(game_state->direct_double_indirect_push);
		DEBUG( printf("ACTIONS_DOUBLE_INDIRECT_PUSH game_state->indirect_push_square_count=%d\n",game_state->indirect_push_square_count); );
		if(game_state->double_indirect_push_square_count==0) {
      

		  DEBUG( printf("ACTIONS_DOUBLE_INDIRECT_PUSH push_in_touch\n"); );
		  bool push_in_touch = check_if_can_double_indirect_push_in_touch();
		  DEBUG( printf("ACTIONS_DOUBLE_INDIRECT_PUSH push_in_touch=%d\n",push_in_touch); );
		  if( !push_in_touch ) {
			game_state->direct_double_indirect_push = false;
			update_double_indirect_push_squares(game_state->direct_double_indirect_push);
		  }
		  if(push_in_touch || game_state->double_indirect_push_square_count==0){
		// pas de case libre, ni de case occupe donc c'est direct en touche
			DEBUG( printf("ACTIONS_DOUBLE_INDIRECT_PUSH pas de case libre, ni de case occupe donc c'est direct en touche\n"); );

	//-------------------------  en touche  -----------------------//
		
			if(game_state->double_indirect_push_square) game_state->double_indirect_push_square->set_xy(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
			else game_state->double_indirect_push_square = new Square(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
			
			switch_action(ACTIONS_DOUBLE_INDIRECT_PUSH_PLAYER_OUT);
			
			game_state->double_indirect_push_square = NULL;
			game_state->double_indirect_push_square_count = 0;
			switch_action(ACTIONS_INDIRECT_PUSH); //  OU ACTIONS_PUSH_PLAYER PAS SUR
	//-------------------------------------------------------------//

		  }
		  else {
			// il n'y a pas de case vide alors je vais faire chier tlm autour
			;;
		  }
		}
		else {
		  // ok, il y a une case vide alors je peux pousser
		  game_state->current_action = ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE;
		}
    
    break;
  case ACTIONS_DOUBLE_INDIRECT_PUSH_AND_HIT:
		game_state->x_double_indirect_push = game_state->indirect_push_square->get_x() - game_state->push_square->get_x();
		game_state->y_double_indirect_push = game_state->indirect_push_square->get_y() - game_state->push_square->get_y();
		game_state->direct_double_indirect_push = true;
		update_double_indirect_push_squares(game_state->direct_double_indirect_push);
		if(game_state->double_indirect_push_square_count==0) {
      
		  bool push_in_touch = check_if_can_double_indirect_push_in_touch();
		  if( !push_in_touch ) {
			game_state->direct_double_indirect_push = false;
			update_double_indirect_push_squares(game_state->direct_double_indirect_push);
		  }
		  if(push_in_touch || game_state->double_indirect_push_square_count==0){
		// pas de case libre, ni de case occupe donc c'est direct en touche

		
	//------------------------  en touche  ------------------------//
			if(game_state->double_indirect_push_square) game_state->double_indirect_push_square->set_xy(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
			else game_state->double_indirect_push_square = new Square(game_state->double_indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
			
			switch_action(ACTIONS_DOUBLE_INDIRECT_PUSH_PLAYER_OUT);

			game_state->double_indirect_push_square = NULL;
			game_state->double_indirect_push_square_count = 0;
			switch_action(ACTIONS_INDIRECT_PUSH_AND_HIT); // PAS SUR
			// ou switch_action(ACTIONS_PUSH_AND_HIT_PLAYER);
	//-------------------------------------------------------------//

		  
		  }
		  else {
			// il n'y a pas de case vide alors je vais faire chier tlm autour
			  ;;
		  }
		}
		else {
		  // ok, il y a une case vide alors je peux pousser
			game_state->current_action = ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE;
		}
		break;
  
  default:
    break;
  }

  if(touchdown()) return;

}

void update_transmit_squares(Player *pl){
	std::list<Player*>* neighbour = pl->get_friend_neighbours();
	std::list<Player*>::iterator it;
  game_state->transmit_square_count = 0;
  for(it=neighbour->begin();it!=neighbour->end();it++){
    if( (*it) && (*it) != pl ){ 
      game_state->transmit_squares[game_state->transmit_square_count] = (*it)->get_square();
      game_state->transmit_square_count++;
    }
  }
  delete neighbour;
}

void show_actions_menu(bool visible,int x_pixel,int y_pixel,int x_square,int y_square){
  actions_menu->visible = visible;
  if(visible){
    DEBUG(printf("je fais apparaitre le menu\n"); );
    game_state->x_menu_clic = x_pixel;
    game_state->y_menu_clic = y_pixel;
    build_actions_menu(x_pixel,y_pixel,x_square,y_square);
  }
  else{
    DEBUG(printf("je fais disparaitre le menu\n"); );
    game_state->x_menu_clic = 0;
    game_state->y_menu_clic = 0;
    game_state->actions_menu_transparency=0;
    if(x_pixel>actions_menu->x && 
       x_pixel<(actions_menu->x+actions_menu->image->w) &&
       y_pixel>actions_menu->y && 
	 y_pixel<(actions_menu->y+actions_menu->image->h)){
      int item = (y_pixel-actions_menu->y)/ACTIONS_MENU_ITEM_HEIGHT;
      if(game_state->actions_menu_items_state[item] != ITEM_OFF){
	// je choisi quelquechose dans le menu
		draw_all(true);
		switch_action(game_state->actions_menu_items[item]);
      }
    } 

	for(int i=ACTIONS_MOVE_INDEX;i<ACTIONS_NB;i++) 
		game_state->actions_menu_items_state[i] = ITEM_OFF;
	game_state->actions_menu_throw_team_mate = false;
	game_state->actions_menu_leap = false;
  }

  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();

}

/**
* Retourner  i*100/6 avec une borne inf de 1*100/6 et une borne sup de 5*100/6 car 1 est toujours un echec et 6 toujours une reussite.
*/
int to_rate(int i){
	if( i==99 ) return 99;
	else if( i<=1 ) return (100/6);
	else if( i>=5 ) return (500/6);
	else return (i*100/6);
}

int get_rate_of_success(void){
	switch(game_state->current_action){
	case ACTIONS_AGGRESS: // avec une _grosse_ approximation qui ne fairait pas plaisir aux statisticiens...
		return (13-get_success_floor())*100/12;
	default:
		return to_rate(7-get_success_floor());
		break;
	}
}

static int first_x = -1;
static int first_y = -1;

// retourne 0 si pas de jet a faire, 1 si un jet a faire, 2+ si plus d'un jet a faire...
int linked_dodge_rolls(void){
	std::list<Square*>* squares = game_state->path->get_path_squares();
	std::list<Square*>::iterator it;
	int c=-1;
	int cs[10];
	int r=0;

	int old_x = game_state->selected_player->get_square()->get_x();
	int old_y = game_state->selected_player->get_square()->get_y();
	
	for(it=squares->begin();it!=squares->end();it++){
		if (*it) {
			c++;
			cs[c] = 0;
			int x_s = (*it)->get_x();
			int y_s = (*it)->get_y();
			if( game_state->selected_player->get_tackle_zone(old_x,old_y)>0 ) 
				cs[c]++;
			//////////////////////////////////////////
			old_x = x_s;
			old_y = y_s;
			if(cs[c]>0) r++;
			if(r==1) {
				first_x = x_s;
				first_y = y_s;
			}
		}
	}

	return r;
}

int get_success_floor(void){
	double d_tmp=0;
	int i_tmp=0;
	int x_s = 0;
	int y_s = 0;
	
	if(game_state->current_action==ACTIONS_MOVE && game_state->path ) {
		std::list<Square*>* squares = game_state->path->get_path_squares();
		std::list<Square*>::iterator it;
		for(it=squares->begin();it!=squares->end();it++){	
			x_s = (*it)->get_x();
			y_s = (*it)->get_y();
		}
	}

	switch(game_state->current_action){
	case ACTIONS_MOVE:
		i_tmp = linked_dodge_rolls();
				
		if ( i_tmp == 1 )
			return game_state->selected_player->move(x_s,y_s);
		else if ( i_tmp > 1 )
			return game_state->selected_player->move(first_x,first_y)+100;
		else
			return 99;
		break;
	case ACTIONS_MOVE_PLUS:
		return (game_state->weather==BLIZZARD)?(3):(2);
		break;
	case ACTIONS_THROW:
		d_tmp = hypot(game_state->target->get_x() - game_state->selected_player->get_square()->get_x(),game_state->target->get_y() - game_state->selected_player->get_square()->get_y())*SQUARE_SIZE;
 
		i_tmp = BOMB_PASS;
  
		if(d_tmp<=FLASH_PASS_SIZE) i_tmp = FLASH_PASS;
		else if(d_tmp<=NORMAL_PASS_SIZE) i_tmp = NORMAL_PASS;
		else if(d_tmp<=LONG_PASS_SIZE) i_tmp = LONG_PASS;
		else i_tmp = BOMB_PASS;
  
		/////////////////////////////////////////////////////////
		  // Ragnar Modif4 : pour l'affichage de la difficulté
		  // compétence costaud
		  if (game_state->selected_player->has_got_skill(STRONG_ARM)
			  && !game_state->selected_player->has_got_skill(STUNTY)){
			if (i_tmp == FLASH_PASS) i_tmp = FLASH_PASS;
			else if (i_tmp == NORMAL_PASS) i_tmp = FLASH_PASS;
			else if (i_tmp == LONG_PASS) i_tmp = NORMAL_PASS;
			else if (i_tmp == BOMB_PASS) i_tmp = LONG_PASS;
		  }
	
		  // compétence minus
		  if (game_state->selected_player->has_got_skill(STUNTY)
			  && !game_state->selected_player->has_got_skill(STRONG_ARM)){
			if (i_tmp == FLASH_PASS) i_tmp = NORMAL_PASS;
			else if (i_tmp == NORMAL_PASS) i_tmp = LONG_PASS;
			else if (i_tmp == LONG_PASS) i_tmp = BOMB_PASS;
		  }
		/////////////////////////////////////////////////////////

		return (game_state->selected_player->throw_ball(i_tmp) + ((game_state->weather==SUNNY)?1:0));
		break;
	case ACTIONS_AGGRESS:
		return (game_state->selected_player->aggress(Shared::get_playground(game_state->target->get_x(), game_state->target->get_y()) )+1);
		break;
	case ACTIONS_CHOOSE_TRANSMIT_SQUARE:
		return (Shared::get_playground(game_state->transmit_square->get_x(),game_state->transmit_square->get_y())->receive_transmission()) + ((game_state->weather==SHOWER)?1:0);
		break;
	case ACTIONS_CHOOSE_INTERCEPTION_SQUARE:
		return (Shared::get_playground(game_state->interception_square->get_x(),game_state->interception_square->get_y())->try_to_intercept()) + ((game_state->weather==SHOWER)?1:0);
		break;
	case ACTIONS_LEAP:
		return (7-game_state->selected_player->get_ag());
		break;
	case ACTIONS_THROW_TEAM_MATE:
		d_tmp = hypot(game_state->target->get_x() - game_state->selected_player->get_square()->get_x(),game_state->target->get_y() - game_state->selected_player->get_square()->get_y())*SQUARE_SIZE;

		i_tmp = BOMB_PASS;
  
		if(d_tmp<=FLASH_PASS_SIZE) i_tmp = NORMAL_PASS;
		else if(d_tmp<=NORMAL_PASS_SIZE) i_tmp = LONG_PASS;
		else i_tmp = BOMB_PASS;
  
		return (game_state->selected_player->throw_team_mate(i_tmp)) + ((game_state->weather==SUNNY)?1:0);
		break;
	default:
		return 0;
		break;
	}
}

void unset_contextual_info(void){
	set_contextual_info(Config::get_screen_w(),0,"");
}

void set_contextual_info(int x,int y,char* s, ...){
	va_list marker;
	char temp[255];

	va_start(marker, s);
	vsprintf(temp, s, marker);
	va_end(marker);

	sprintf(game_state->contextual_info->msg,"%s",temp);
	game_state->contextual_info->x = x;
	game_state->contextual_info->y = y;
}

void draw_contextual_info(bool all){
	SDL_Rect r;
	r.x = game_state->contextual_info->x + SQUARE_SIZE - strlen(game_state->contextual_info->msg)*DT_FontWidth(game_state->contextual_info->font) - DT_FontWidth(game_state->contextual_info->font);
	r.y = game_state->contextual_info->y;
	r.w = strlen(game_state->contextual_info->msg) * DT_FontWidth(game_state->contextual_info->font) + DT_FontWidth(game_state->contextual_info->font);
	r.h = DT_FontHeight(game_state->contextual_info->font);
	
	if(all || rect_into_rect(r,pg_cliprect)){
		SDL_FillRect(pg->image,&r,SDL_MapRGB(screen->format,100,100,100));
		DT_DrawText(game_state->contextual_info->msg,pg->image,game_state->contextual_info->font,r.x + DT_FontWidth(game_state->contextual_info->font)/2,r.y);
	}
}

void draw_path(Path *pa,bool all){
	std::list<Square*>* squares = pa->get_path_squares();
	std::list<Square*>::iterator it;
  SDL_Rect s,r;
  unsigned int i=0;

      
  s.x = BLACK_INDEX;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;

  for(it=squares->begin();it!=squares->end();it++){
    if (*it) {
      i++;
	  if(i > pa->get_dist_done()){
		r.x = SQUARE_TO_PIXEL((*it)->get_x());
		r.y = SQUARE_TO_PIXEL((*it)->get_y());
		r.w = SQUARE_SIZE;
		r.h = SQUARE_SIZE;
		if(all || rect_into_rect(r,pg_cliprect)){
			if(i==squares->size()) draw_cross((*it),BLACK_INDEX);
			else BlitSurface(colored_dots,&s,pg->image, &r);
		}
	  }
    }
  }

	if(game_state->selected_player && game_state->selected_player->get_square() ){ 
		s.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
		s.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		r.w = SQUARE_SIZE;
		r.h = SQUARE_SIZE; 
		path_rect = rect_union(s,r);
    }
}

void draw_target(int x,int y,int color_index){
  SDL_Rect s,r;
  s.x = color_index;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  r.x = SQUARE_TO_PIXEL(x);
  r.y = SQUARE_TO_PIXEL(y);
  r.w = s.w;
  r.h = s.h;
  BlitSurface(colored_dots,&s,pg->image, &r);
}

void erase_panel(SDL_Rect *r){
  BlitSurface(panel_empty,r,panel->image,r);
}

void erase_panel_player_info(){
	panel_cliprect.x = PANEL_PLAYER_INFO_X;
	panel_cliprect.y = PANEL_PLAYER_INFO_Y;
	panel_cliprect.w = PANEL_PLAYER_INFO_WIDTH;
	panel_cliprect.h = PANEL_PLAYER_INFO_HEIGHT;
	panel_info->visible = false;
}

void handle_time(void){
  static int old_remaining_time;
  static Uint32 old_t;
  
  Uint32 now = SDL_GetTicks();

  ////////////////////////////////////////////////
  // Ragnar Modif : freeze_time, suspendre le chrono quand 
  // le tour de l'équipe active est interrompu par l'adversaire
  // pour utiliser une compétence (ex: dump-off)
  static bool time_freezed;
  if(game_state->freeze_time){
	time_freezed = true;
	game_state->pause = true;
  }
  ////////////////////////////////////////////////

  if(game_state->current_mode==MODE_PLAYING){
	game_state->update_time = false;

	if(!game_state->pause){
		////////////////////////////////////////////////
		if (time_freezed){
			game_state->turn_begining_time = now - (TURN_DURATION - old_remaining_time)*1000;
			time_freezed = false;
		}
		////////////////////////////////////////////////
		game_state->remaining_time = (game_state->active_team==NONE)?(unsigned int)-1:TURN_DURATION - (SDL_GetTicks() - game_state->turn_begining_time)/1000;
				
		if ((old_remaining_time-game_state->remaining_time)!=0){
			game_state->update_time = true;
			old_remaining_time = game_state->remaining_time;

#ifndef NOSOUND
		if(Config::is_sound_enabled()){
			if((game_state->remaining_time == 60 || 
				game_state->remaining_time == 120 || 
				game_state->remaining_time == 180 || 
				game_state->remaining_time < 5) && game_state->active_team!=NONE )
				sp->play_sound(SND_COUNTDOWN, FX0_CHANNEL);
		}
#endif

		}
    
		if ( game_state->remaining_time < 0 ) {
			game_state->remaining_time = 0;
			if(game_state->active_team!=NONE) {
#ifndef NOSOUND
				if(Config::is_sound_enabled()){
					sp->play_sound(SND_ALARM, FX0_CHANNEL);
				}
#endif
				draw_all(true);
				dialog_box->open_info(screen,ICONS_REFEREE, MSG_TIME_OUT,false, game_state->team[game_state->active_team]->get_name());
				stop_turn();
				draw_all(true);
			}
		}
	}

	if(game_state->active_team!=NONE){
		SDL_Rect r_tmp;
		r_tmp.x = PANEL_WHEELS_X;
		r_tmp.y = PANEL_WHEELS_Y;
		r_tmp.w = PANEL_WHEELS_WIDTH;
		r_tmp.h = PANEL_WHEELS_HEIGHT;
		panel_cliprect = rect_union(panel_cliprect,r_tmp);
	}

	if(game_state->update_time) {
		SDL_Rect r_tmp;
		r_tmp.x = PANEL_MINUTES_X;
		r_tmp.y = PANEL_MINUTES_Y;
		r_tmp.w = PANEL_SECONDS_X+PANEL_SECONDS_WIDTH-PANEL_MINUTES_X+1;
		r_tmp.h = PANEL_MINUTES_HEIGHT;
		panel_cliprect = rect_union(panel_cliprect,r_tmp);
	}
  }

  if(console->get_focus()){  
	if((now-old_t) > CON_BLINK_RATE ){
		update_console = true;
		old_t = now;
	}
  }

  if ( (now-old_t) > CON_BLINK_RATE ){
	update_indicator = true;
	old_t = now;
  }
  
  ////////////////////////////////////////////////
  // Ragnar Modif : freeze_time
  if(game_state->freeze_time){
	game_state->pause = false;
  }
  ////////////////////////////////////////////////

}

void draw_panel(bool all){

  SDL_Rect s;

  if((!all) && (panel_cliprect.w==0)&&(panel_cliprect.h==0)) return;
  
  erase_panel(&panel_cliprect);

  s.x = PANEL_PLAYER_INFO_X;
  s.y = PANEL_PLAYER_INFO_Y;
  s.w = PANEL_PLAYER_INFO_WIDTH;
  s.h = PANEL_PLAYER_INFO_HEIGHT;

  if(panel_info && panel_info->visible  ){
		draw_panel_player_info(all);
  }
  else {
		erase_panel(&s);
  }
  
  s.x = PANEL_MINUTES_X; 
  s.y = PANEL_MINUTES_Y; 
  s.w = PANEL_MINUTES_WIDTH; 
  s.h = PANEL_MINUTES_HEIGHT; 
  if(all || game_state->update_time || rect_into_rect(s,panel_cliprect)) draw_digit(game_state->remaining_time/60,&s,fonts[PANEL_TIME_FONT],panel->image);
  
  s.x = PANEL_SECONDS_X; 
  s.y = PANEL_SECONDS_Y; 
  s.w = PANEL_SECONDS_WIDTH; 
  s.h = PANEL_SECONDS_HEIGHT; 
  if(all || game_state->update_time || rect_into_rect(s,panel_cliprect)) draw_number(game_state->remaining_time%60,&s,fonts[PANEL_TIME_FONT],panel->image,2 );
  
  s.x = PANEL_HOME_REROLL_X; 
  s.y = PANEL_HOME_REROLL_Y; 
  s.w = PANEL_HOME_REROLL_WIDTH; 
  s.h = PANEL_HOME_REROLL_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) draw_digit(game_state->team[HOME]->get_reroll(),&s,fonts[PANEL_REROLL_FONT],panel->image);
  
  s.x = PANEL_VISITOR_REROLL_X; 
  s.y = PANEL_VISITOR_REROLL_Y; 
  s.w = PANEL_VISITOR_REROLL_WIDTH; 
  s.h = PANEL_VISITOR_REROLL_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) draw_digit(game_state->team[VISITOR]->get_reroll(),&s,fonts[PANEL_REROLL_FONT],panel->image);

  s.x = PANEL_HOME_SCORE_X; 
  s.y = PANEL_HOME_SCORE_Y; 
  s.w = PANEL_HOME_SCORE_WIDTH; 
  s.h = PANEL_HOME_SCORE_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) draw_digit(game_state->team[HOME]->get_score(),&s,fonts[PANEL_SCORE_FONT],panel->image);
  
  s.x = PANEL_VISITOR_SCORE_X; 
  s.y = PANEL_VISITOR_SCORE_Y; 
  s.w = PANEL_VISITOR_SCORE_WIDTH; 
  s.h = PANEL_VISITOR_SCORE_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) draw_digit(game_state->team[VISITOR]->get_score(),&s,fonts[PANEL_SCORE_FONT],panel->image);
  
  s.x = PANEL_HOME_TURN_X; 
  s.y = PANEL_HOME_TURN_Y; 
  s.w = 8*PANEL_TURN_WIDTH; 
  s.h = PANEL_TURN_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
     
  if(game_state->team[HOME]->get_turn()!=0) {
    s.x = PANEL_HOME_TURN_X + (game_state->team[HOME]->get_turn()-1)*PANEL_TURN_WIDTH; 
    s.y = PANEL_HOME_TURN_Y; 
    s.w = PANEL_TURN_WIDTH; 
    s.h = PANEL_TURN_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(turn_pawn,NULL,panel->image,&s);
  }
  
  s.x = PANEL_VISITOR_TURN_X; 
  s.y = PANEL_VISITOR_TURN_Y; 
  s.w = 8*PANEL_TURN_WIDTH; 
  s.h = PANEL_TURN_HEIGHT;
  if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);

  if(game_state->team[VISITOR]->get_turn()!=0) {
    s.x = PANEL_VISITOR_TURN_X + (game_state->team[VISITOR]->get_turn()-1)*PANEL_TURN_WIDTH; 
    s.y = PANEL_VISITOR_TURN_Y;
    s.w = PANEL_TURN_WIDTH; 
    s.h = PANEL_TURN_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(turn_pawn,NULL,panel->image,&s);
  }
  
  if(game_state->active_team!=NONE){
    SDL_Rect d;
    s.x = (game_state->frame%(PANEL_WHEELS_FRAMES-1))*PANEL_WHEELS_WIDTH;
    s.y = 0;
    s.w = PANEL_WHEELS_WIDTH;
    s.h = PANEL_WHEELS_HEIGHT;
    d.x = PANEL_WHEELS_X; 
    d.y = PANEL_WHEELS_Y; 
    d.w = s.w; 
    d.h = s.h;
    if(all || rect_into_rect(d,panel_cliprect)) BlitSurface(wheels,&s,panel->image,&d);
  }

  if((game_state->current_mode==MODE_TEAM_PLACEMENT && game_state->team_in_placement==HOME) || (game_state->current_mode==MODE_PLAYING && game_state->active_team==HOME) || (game_state->current_mode==MODE_SURPRISE && game_state->team_in_placement==HOME) ){
    s.x = PANEL_VISITOR_TURN_INDIC_X;
    s.y = PANEL_VISITOR_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
    s.x = PANEL_HOME_TURN_INDIC_X;
    s.y = PANEL_HOME_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(turn_indicator,NULL,panel->image,&s);
  }
  else if((game_state->current_mode==MODE_TEAM_PLACEMENT && game_state->team_in_placement==VISITOR) || (game_state->current_mode==MODE_PLAYING && game_state->active_team==VISITOR) || (game_state->current_mode==MODE_SURPRISE && game_state->team_in_placement==VISITOR)){
    s.x = PANEL_HOME_TURN_INDIC_X;
    s.y = PANEL_HOME_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
    s.x = PANEL_VISITOR_TURN_INDIC_X;
    s.y = PANEL_VISITOR_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(turn_indicator,NULL,panel->image,&s);
  }
  else if( update_indicator ){
	blinking = !blinking;

	s.x = -1;
	s.y = -1;
	s.w = PANEL_TURN_INDIC_WIDTH; 
	s.h = PANEL_TURN_INDIC_HEIGHT;

	if ( game_state->current_mode==MODE_NONE && game_state->kick_off_team==HOME && !game_state->team[HOME]->is_placed() ) { 
		s.x = PANEL_HOME_TURN_INDIC_X;
		s.y = PANEL_HOME_TURN_INDIC_Y;
	}
	else if ( game_state->current_mode==MODE_NONE && game_state->kick_off_team==VISITOR && !game_state->team[VISITOR]->is_placed()) { 
		s.x = PANEL_VISITOR_TURN_INDIC_X;
		s.y = PANEL_VISITOR_TURN_INDIC_Y;
	}
	else if ( game_state->current_mode==MODE_TEAM_PLACEMENT && game_state->kick_off_team==VISITOR && game_state->team[VISITOR]->is_placed() ) { 
		s.x = PANEL_HOME_TURN_INDIC_X;
		s.y = PANEL_HOME_TURN_INDIC_Y;
	}
	else if ( game_state->current_mode==MODE_TEAM_PLACEMENT && game_state->kick_off_team==HOME && game_state->team[HOME]->is_placed()) { 
		s.x = PANEL_VISITOR_TURN_INDIC_X;
		s.y = PANEL_VISITOR_TURN_INDIC_Y;
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->old_active_team==VISITOR){
		s.x = PANEL_HOME_TURN_INDIC_X;
		s.y = PANEL_HOME_TURN_INDIC_Y;	
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->old_active_team==HOME){
		s.x = PANEL_VISITOR_TURN_INDIC_X;
		s.y = PANEL_VISITOR_TURN_INDIC_Y;	
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->team[HOME]->has_free_turn() ) {
		s.x = PANEL_HOME_TURN_INDIC_X;
		s.y = PANEL_HOME_TURN_INDIC_Y;	
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->team[VISITOR]->has_free_turn() ) {
		s.x = PANEL_VISITOR_TURN_INDIC_X;
		s.y = PANEL_VISITOR_TURN_INDIC_Y;	
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->kick_off_team==HOME ) {
		s.x = PANEL_VISITOR_TURN_INDIC_X;
		s.y = PANEL_VISITOR_TURN_INDIC_Y;	
	}
	else if ( game_state->current_mode==MODE_PLAYING && game_state->kick_off_team==VISITOR ) {
		s.x = PANEL_HOME_TURN_INDIC_X;
		s.y = PANEL_HOME_TURN_INDIC_Y;	
	}

	if( s.x != -1 && s.y !=-1 ){
		if(blinking){
			if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(blink_turn_indicator,NULL,panel->image,&s);
		}
		else {
			if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
		}
	}
		
	update_indicator = false;
  }
  else if( update_indicator ){
  	blinking = !blinking;
	
	s.w = PANEL_TURN_INDIC_WIDTH; 
	s.h = PANEL_TURN_INDIC_HEIGHT;
	if(blinking){
		if(all || rect_into_rect(s,panel_cliprect)) BlitSurface(blink_turn_indicator,NULL,panel->image,&s);
	}
	else {
		if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
	}	
	update_indicator = false;
  }
  else {
    s.x = PANEL_VISITOR_TURN_INDIC_X;
    s.y = PANEL_VISITOR_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH+2; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
    s.x = PANEL_HOME_TURN_INDIC_X;
    s.y = PANEL_HOME_TURN_INDIC_Y;
    s.w = PANEL_TURN_INDIC_WIDTH; 
    s.h = PANEL_TURN_INDIC_HEIGHT;
    if(all || rect_into_rect(s,panel_cliprect)) erase_panel(&s);
  }
  
  draw_object_into(panel,screen,RIGHT_FRAME,panel->x,panel->y);

  SDL_Rect frame_separator; 
  frame_separator.x = FRAME_LIMIT-FRAME_LINE;
  frame_separator.y = 0;
  frame_separator.w = FRAME_LINE;
  frame_separator.h = Config::get_screen_h(); 
  if(all || rect_into_rect(frame_separator,panel_cliprect)) SDL_FillRect(screen,&frame_separator,0);
}

void draw_playground(){
  if(game_state->zoom_mode) {
    SDL_Rect s,d;
    if(pg_zoomed==NULL)
      pg_zoomed = zoom_surface(pg->image,ZOOM_FACTOR,ZOOM_FACTOR,SMOOTHING_ON);
    
	d.x = 0;
    d.y = 0;
    d.w = FRAME_LIMIT;
    d.h = Config::get_screen_h();
    
	SDL_FillRect(screen,&d,0);

    s.x = 0;
    s.y = 0;
    s.w = public_img->w;
    s.h = public_img->h;
    
    d.x = 0;
    d.y = (Config::get_screen_h() - s.h)/2;
    d.w = s.w;
    d.h = s.h;
    BlitSurface(public_img,&s,screen,&d);

    s.x = 0;
    s.y = 0;
    s.w = pg_zoomed->w;
    s.h = pg_zoomed->h;
    
    d.x = public_img->w;
    d.y = 0;
    d.w = s.w;
    d.h = s.h;
    BlitSurface(pg_zoomed,&s,screen,&d);  
  }
  else {
		SDL_FreeSurface(pg_zoomed);
		pg_zoomed = NULL;
		draw_object_into(pg,screen,LEFT_FRAME,pg->x,pg->y);
  }
}

void draw_actions_menu(){

  SDL_Rect s,d;
  s.x = 0;
  s.y = 0;
  s.w = ACTIONS_MENU_WIDTH;
  s.h = ACTIONS_MENU_HEIGHT;
  
  d.x = actions_menu->x;
  d.y = actions_menu->y;
  d.w = s.w;
  d.h = s.h;
  BlitSurface(actions_menu->image,&s, pg->image, &d);
}

void draw_ball(){
  SDL_Rect s,d ;

  s.x = 0;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;

  d.x = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_x());
  d.y = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_y());
  d.w = s.w;
  d.h = s.h;
  
  BlitSurface(ball_img,&s,pg->image,&d);
}

void draw_player(Player *p,bool all){

  SDL_Rect r,s;

  if(p->get_status()<KO && p->get_square()) { /* je suis sur l'air de jeu  */

    r.x = SQUARE_TO_PIXEL(p->get_square()->get_x());
    r.y = SQUARE_TO_PIXEL(p->get_square()->get_y());
    r.w = SQUARE_SIZE;
    r.h = SQUARE_SIZE;
    
	if(!all && !rect_intersect_rect(r,pg_cliprect)) return;
  	
   	s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
	s.y = 0;
    s.w = SQUARE_SIZE;
    s.h = SQUARE_SIZE;
    BlitSurface(pawn_img,&s,pg->image, &r);

	r.x = SQUARE_TO_PIXEL(p->get_square()->get_x());
    r.y = SQUARE_TO_PIXEL(p->get_square()->get_y());
    r.w = SQUARE_SIZE;
    r.h = SQUARE_SIZE;
    
	if(p->get_position_id()<100){
		s.x = (p->get_position_id()*SQUARE_SIZE*2) + ((p->get_team()==HOME)?0:SQUARE_SIZE);
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		BlitSurface(player_img[p->get_team()],&s,pg->image, &r);
    }
	else if (p->get_position_id()>99 && p->get_position_id()<200){
		s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		BlitSurface(starplayer_img,&s,pg->image, &r);
	}
	else if (p->get_position_id()>199){
		s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		BlitSurface(bigguys_img,&s,pg->image, &r);
	}

	if((!p->has_played() && game_state->active_team == p->get_team())||
       (!p->has_played() && game_state->team_in_placement == p->get_team() && game_state->current_mode==MODE_SURPRISE  )) {
      s.x = 0;
      s.y = 0;
      s.w = SQUARE_SIZE;
      s.h = SQUARE_SIZE;
      r.x = SQUARE_TO_PIXEL(p->get_square()->get_x());
      r.y = SQUARE_TO_PIXEL(p->get_square()->get_y());
      r.w = s.w;
      r.h = s.h;
      
      if( p->is_selected() ){ 
		s.x = ((game_state->frame/3)%CIRCLE_FRAME) * SQUARE_SIZE;
      }
      
      if( game_state->current_mode!=MODE_BALL_PLACEMENT) BlitSurface(circle,&s,pg->image, &r);
    } 
    
    r.x = SQUARE_TO_PIXEL(p->get_square()->get_x());
    r.y = SQUARE_TO_PIXEL(p->get_square()->get_y()) + SQUARE_SIZE/2;
    r.w = SQUARE_SIZE/2;
    r.h = SQUARE_SIZE/2;
    
	s.x = (p->get_number()-1)*SQUARE_SIZE/2;
	s.y = 0;
    s.w = SQUARE_SIZE/2;
    s.h = SQUARE_SIZE/2;
    if(game_state->number_drawing_mode) BlitSurface(player_num_img,&s,pg->image, &r);
    if(game_state->tackle_zone_drawing_mode==p->get_team() || game_state->tackle_zone_drawing_mode==BOTH) draw_tackle_zone(p);

    switch(p->get_status()){
    case OK:
      if(p->has_got_ball()){
		r.x = SQUARE_TO_PIXEL(p->get_square()->get_x()) + (SQUARE_SIZE/2); 
		r.y = SQUARE_TO_PIXEL(p->get_square()->get_y()) + (SQUARE_SIZE/2); 
		r.w = SQUARE_SIZE/2;
		r.h = SQUARE_SIZE/2;
		s.x = STATUS_BALL;
		s.y = 0;
		s.w = SQUARE_SIZE/2;
		s.h = SQUARE_SIZE/2;
		BlitSurface(status,&s,pg->image, &r);
      }
      break;
    case GROUND:
      // etoile jaune
      r.x = SQUARE_TO_PIXEL(p->get_square()->get_x()) + (SQUARE_SIZE/2); 
      r.y = SQUARE_TO_PIXEL(p->get_square()->get_y()) + (SQUARE_SIZE/2); 
      r.w = SQUARE_SIZE/2;
      r.h = SQUARE_SIZE/2;
      s.x = STATUS_GROUND;
      s.y = 0;
      s.w = SQUARE_SIZE/2;
      s.h = SQUARE_SIZE/2;
      BlitSurface(status,&s,pg->image, &r);
      break;
    case DOWN:
      // etoile rouge
      r.x = SQUARE_TO_PIXEL(p->get_square()->get_x()) + (SQUARE_SIZE/2); 
      r.y = SQUARE_TO_PIXEL(p->get_square()->get_y()) + (SQUARE_SIZE/2); 
      r.w = SQUARE_SIZE/2;
      r.h = SQUARE_SIZE/2;
      s.x = STATUS_DOWN;
      s.y = 0;
      s.w = SQUARE_SIZE/2;
      s.h = SQUARE_SIZE/2;
      BlitSurface(status,&s,pg->image, &r);
      break;
    }
  }
  else {
    r.w = SQUARE_SIZE;
    r.h = SQUARE_SIZE;

    if(p->get_position_id()<100){
		s.x = (p->get_position_id()*SQUARE_SIZE*2) + ((p->get_team()==HOME)?0:SQUARE_SIZE);
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
	}
    else {
		s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
	}

    SDL_Rect t,u;
    
    t.w = SQUARE_SIZE/2;
    t.h = SQUARE_SIZE/2;
    u.y = 0;
    u.w = SQUARE_SIZE/2;
    u.h = SQUARE_SIZE/2;
    
    int x_in_box=1,y_in_box=1;
    int p_rx;
    int p_ry;
    switch(p->get_status()){
    case KO: 
      //draw player dans la case ko 8-9
	  game_state->team[p->get_team()]->inc_ko();	
      r.x = (p->get_team()==HOME)?HOME_KO_BOX_X:VISITOR_KO_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_KO_BOX_Y:VISITOR_KO_BOX_Y;
      if(game_state->team[p->get_team()]->get_ko()>4){
		r.x += (((p->get_team()==HOME)?HOME_KO_BOX_W/2:VISITOR_KO_BOX_W/2) - SQUARE_SIZE/2);
		r.y += (((p->get_team()==HOME)?HOME_KO_BOX_H/2:VISITOR_KO_BOX_H/2) - SQUARE_SIZE/2);
      }
      else{
		x_in_box = (game_state->team[p->get_team()]->get_ko()>2)?0:1;
		y_in_box = ((game_state->team[p->get_team()]->get_ko()%2)==0)?0:1;
		r.x += x_in_box * ((p->get_team()==HOME)?HOME_KO_BOX_W-SQUARE_SIZE:VISITOR_KO_BOX_W-SQUARE_SIZE);
		r.y += y_in_box * ((p->get_team()==HOME)?HOME_KO_BOX_H-SQUARE_SIZE:VISITOR_KO_BOX_H-SQUARE_SIZE);
	  }
      
      u.x = STATUS_DOWN; 
      break;
    case TOUCHED:
      //draw player dans la case out 10
      game_state->team[p->get_team()]->inc_out();	
      r.x = (p->get_team()==HOME)?HOME_OUT_BOX_X:VISITOR_OUT_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_OUT_BOX_Y:VISITOR_OUT_BOX_Y;
      if(game_state->team[p->get_team()]->get_out()>4){
		r.x += (((p->get_team()==HOME)?HOME_OUT_BOX_W/2:VISITOR_OUT_BOX_W/2) - SQUARE_SIZE/2);
		r.y += (((p->get_team()==HOME)?HOME_OUT_BOX_H/2:VISITOR_OUT_BOX_H/2) - SQUARE_SIZE/2);
      }
      else{
		x_in_box = (game_state->team[p->get_team()]->get_out()>2)?0:1;
		y_in_box = ((game_state->team[p->get_team()]->get_out()%2)==0)?0:1;
		r.x += x_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_W-SQUARE_SIZE:VISITOR_OUT_BOX_W-SQUARE_SIZE);
		r.y += y_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_H-SQUARE_SIZE:VISITOR_OUT_BOX_H-SQUARE_SIZE);
      }
      
      u.x = STATUS_TOUCHED;
      break;
    case INJURED:
      //draw player dans la case out 11
      game_state->team[p->get_team()]->inc_out();	
      r.x = (p->get_team()==HOME)?HOME_OUT_BOX_X:VISITOR_OUT_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_OUT_BOX_Y:VISITOR_OUT_BOX_Y;
      if(game_state->team[p->get_team()]->get_out()>4){
		r.x += (((p->get_team()==HOME)?HOME_OUT_BOX_W/2:VISITOR_OUT_BOX_W/2) - SQUARE_SIZE/2);
		r.y += (((p->get_team()==HOME)?HOME_OUT_BOX_H/2:VISITOR_OUT_BOX_H/2) - SQUARE_SIZE/2);
      }
      else{
		x_in_box = (game_state->team[p->get_team()]->get_out()>2)?0:1;
		y_in_box = ((game_state->team[p->get_team()]->get_out()%2)==0)?0:1;
		r.x += x_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_W-SQUARE_SIZE:VISITOR_OUT_BOX_W-SQUARE_SIZE);
		r.y += y_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_H-SQUARE_SIZE:VISITOR_OUT_BOX_H-SQUARE_SIZE);
      }
      
      u.x = STATUS_INJURED;
      break;
    case DEAD:
      //draw player dans la case out 12
      game_state->team[p->get_team()]->inc_out();	
      r.x = (p->get_team()==HOME)?HOME_OUT_BOX_X:VISITOR_OUT_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_OUT_BOX_Y:VISITOR_OUT_BOX_Y;
      if(game_state->team[p->get_team()]->get_out()>4){
		r.x += (((p->get_team()==HOME)?HOME_OUT_BOX_W/2:VISITOR_OUT_BOX_W/2) - SQUARE_SIZE/2);
		r.y += (((p->get_team()==HOME)?HOME_OUT_BOX_H/2:VISITOR_OUT_BOX_H/2) - SQUARE_SIZE/2);
      }
      else{
		x_in_box = (game_state->team[p->get_team()]->get_out()>2)?0:1;
		y_in_box = ((game_state->team[p->get_team()]->get_out()%2)==0)?0:1;
		r.x += x_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_W-SQUARE_SIZE:VISITOR_OUT_BOX_W-SQUARE_SIZE);
		r.y += y_in_box * ((p->get_team()==HOME)?HOME_OUT_BOX_H-SQUARE_SIZE:VISITOR_OUT_BOX_H-SQUARE_SIZE);
      }
      
      u.x = STATUS_DEAD;
      break;
    case EJECTED:
      //draw player dans la case ejected
      game_state->team[p->get_team()]->inc_ejected();	
      r.x = (p->get_team()==HOME)?HOME_EJECTED_BOX_X:VISITOR_EJECTED_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_EJECTED_BOX_Y:VISITOR_EJECTED_BOX_Y;
      if(game_state->team[p->get_team()]->get_ejected()>4){
		r.x += (((p->get_team()==HOME)?HOME_EJECTED_BOX_W/2:VISITOR_EJECTED_BOX_W/2) - SQUARE_SIZE/2);
		r.y += (((p->get_team()==HOME)?HOME_EJECTED_BOX_H/2:VISITOR_EJECTED_BOX_H/2) - SQUARE_SIZE/2);
      }
      else{
		x_in_box = (game_state->team[p->get_team()]->get_ejected()>2)?0:1;
		y_in_box = ((game_state->team[p->get_team()]->get_ejected()%2)==0)?0:1;
		r.x += x_in_box * ((p->get_team()==HOME)?HOME_EJECTED_BOX_W-SQUARE_SIZE:VISITOR_EJECTED_BOX_W-SQUARE_SIZE);
		r.y += y_in_box * ((p->get_team()==HOME)?HOME_EJECTED_BOX_H-SQUARE_SIZE:VISITOR_EJECTED_BOX_H-SQUARE_SIZE);
      }
      
      break;
    case RESERVE:
      //draw player dans la case des remplacants
      game_state->team[p->get_team()]->inc_reserve();	
      r.x = (p->get_team()==HOME)?HOME_RESERVE_BOX_X:VISITOR_RESERVE_BOX_X;
      r.y = (p->get_team()==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y;
      p_rx = p->get_reserve_square()?p->get_reserve_square()->get_x():-1;
      p_ry = p->get_reserve_square()?p->get_reserve_square()->get_y():-1;
      
      if( game_state->reserve_page[p->get_team()] == p_rx/2 && p_rx!=-1 && p_ry!=-1) {
		r.x += (p_rx%2 * SQUARE_SIZE);
		r.y += (p_ry * SQUARE_SIZE);
      }
      else {
		x_in_box = -1;
		y_in_box = -1;
      }
      
      if(x_in_box>0 || y_in_box>0) {
		SDL_Rect r_save = r;
		s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		BlitSurface(pawn_img,&s,reserve, &r_save);
		r_save = r;

		if(p->get_position_id()<100){
			s.x = (p->get_position_id()*SQUARE_SIZE*2) + ((p->get_team()==HOME)?0:SQUARE_SIZE);
			s.y = 0;
			s.w = SQUARE_SIZE;
			s.h = SQUARE_SIZE;
			BlitSurface(player_img[p->get_team()],&s,reserve, &r_save);
		}
		else if(p->get_position_id()>99 && p->get_position_id()<200){
			s.x = ((p->get_team()==HOME)?0:SQUARE_SIZE);
			s.y = 0;
			s.w = SQUARE_SIZE;
			s.h = SQUARE_SIZE;
			BlitSurface(starplayer_img,&s,reserve, &r_save);
		}
		else if (p->get_position_id()>199){
			s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
			s.y = 0;
			s.w = SQUARE_SIZE;
			s.h = SQUARE_SIZE;
			BlitSurface(bigguys_img,&s,reserve, &r_save);
		}

		r_save = r;

		r_save.x = r.x;
		r_save.y = r.y + SQUARE_SIZE/2;
		r_save.w = SQUARE_SIZE/2;
		r_save.h = SQUARE_SIZE/2;
    
		s.x = (p->get_number()-1)*SQUARE_SIZE/2;
		s.y = 0;
		s.w = SQUARE_SIZE/2;
		s.h = SQUARE_SIZE/2;
		if(game_state->number_drawing_mode) BlitSurface(player_num_img,&s,reserve, &r_save);
	  }

      break;
	  default:
		r.x = -SQUARE_SIZE;
		r.y = -SQUARE_SIZE;
		x_in_box = -1;
		y_in_box = -1; 
		break;
    } 
    
    if(p->get_status()!=RESERVE  ) {
		if(all || rect_intersect_rect(r,pg_cliprect)) {
			SDL_Rect r_bis = r;
			BlitSurface(pawn_img,&s,reserve, &r_bis);
		    r_bis = r;
			if(p->get_position_id()<100){
				s.x = (p->get_position_id()*SQUARE_SIZE*2) + ((p->get_team()==HOME)?0:SQUARE_SIZE);
				s.y = 0;
				s.w = SQUARE_SIZE;
				s.h = SQUARE_SIZE;
				BlitSurface(player_img[p->get_team()],&s,pg->image, &r_bis);
			}
			else if (p->get_position_id()>99 && p->get_position_id()<200){
				s.x = ((p->get_team()==HOME)?0:SQUARE_SIZE);
				s.y = 0;
				s.w = SQUARE_SIZE;
				s.h = SQUARE_SIZE;
				BlitSurface(starplayer_img,&s,pg->image, &r_bis);
			} 
			else if (p->get_position_id()>199){
				s.x = (p->get_team()==HOME)?0:SQUARE_SIZE;
				s.y = 0;
				s.w = SQUARE_SIZE;
				s.h = SQUARE_SIZE;
				BlitSurface(bigguys_img,&s,pg->image, &r_bis);
			}   
			if(p->get_status()!=EJECTED){
				t.x = r.x + (SQUARE_SIZE/2);
				t.y = r.y + (SQUARE_SIZE/2);	
				BlitSurface(status,&u,pg->image, &t);
			}

			r_bis = r;

			r_bis.x = r.x;
			r_bis.y = r.y + SQUARE_SIZE/2;
			r_bis.w = SQUARE_SIZE/2;
			r_bis.h = SQUARE_SIZE/2;
    
			s.x = (p->get_number()-1)*SQUARE_SIZE/2;
			s.y = 0;
			s.w = SQUARE_SIZE/2;
			s.h = SQUARE_SIZE/2;
			if(game_state->number_drawing_mode) BlitSurface(player_num_img,&s,pg->image, &r_bis);
		}	
	}
  } 
}

void draw_future_tackle_zone(Player *pl,Square *sq){
  SDL_Rect s,r;
  r.x = SQUARE_TO_PIXEL(sq->get_x());
  r.y = SQUARE_TO_PIXEL(sq->get_y());
  r.w = SQUARE_SIZE;
  r.h = SQUARE_SIZE;
  
  s.x = pl->get_team()==HOME?BLUE_INDEX:RED_INDEX;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  
  int i,j;
  int x = sq->get_x();
  int y = sq->get_y();
  for(i=x-1;i<=x+1;i++){
    for(j=y-1;j<=y+1;j++){
      if(i>=0 &&
	 j>=0 &&
	 i<PLAYGROUND_WIDTH && 
	 j<PLAYGROUND_HEIGHT && 
	 !(i==x && j==y)){
	
	r.x = SQUARE_TO_PIXEL(i);
	r.y = SQUARE_TO_PIXEL(j);
	
	if ( !Shared::get_playground(i,j) || ( Shared::get_playground(i,j) && Shared::get_playground(i,j)->get_team() != pl->get_team())) BlitSurface(colored_squares,&s,pg->image, &r);
      }
    }
  }
}


void draw_tackle_zone(Player *p){
  if( p->get_status() == OK ) {
    SDL_Rect s,r;
    r.x = SQUARE_TO_PIXEL(p->get_square()->get_x());
    r.y = SQUARE_TO_PIXEL(p->get_square()->get_y());
    r.w = SQUARE_SIZE;
    r.h = SQUARE_SIZE;
    
    s.x = p->get_team()==HOME?BLUE_INDEX:RED_INDEX;
    s.y = 0;
    s.w = SQUARE_SIZE;
    s.h = SQUARE_SIZE;

    int i,j;
    int x = p->get_square()->get_x();
    int y = p->get_square()->get_y();
    for(i=x-1;i<=x+1;i++){
      for(j=y-1;j<=y+1;j++){
		if(i>=0 &&
			j>=0 &&
			i<PLAYGROUND_WIDTH && 
			j<PLAYGROUND_HEIGHT && 
			!(i==x && j==y)){
	  
				r.x = SQUARE_TO_PIXEL(i);
				r.y = SQUARE_TO_PIXEL(j);
	
				if ( !Shared::get_playground(i,j) || ( Shared::get_playground(i,j) && Shared::get_playground(i,j)->get_team() != p->get_team())) BlitSurface(colored_squares,&s,pg->image, &r);
			}
		}
	}
  }
}

void draw_tackle_zone(Team *t){
	std::map<int,Player*> ::iterator it;
	map<int,Player*> *players = t->get_players();
	for(it=players->begin();it!=players->end();it++)
		draw_tackle_zone((*it).second);
}

void draw_team(Team* t,bool all){

  std::map<int,Player*> ::iterator it;
  map<int,Player*> *players = t->get_players();
  
  t->set_ejected(0);
  t->set_ko(0);
  t->set_out(0);
  t->set_reserve(0);
  
  for(it=players->begin();it!=players->end();it++){
		draw_player((*it).second,all);
  }

}

void draw_reserve_navigator(){
  SDL_Rect r,d;
  
  for(int i=HOME;i<=VISITOR;i++){
    game_state->reserve_page_count[i] = 2;
	  
    r.y = game_state->y_dock + ((i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y);
    r.w = reserve_nav[i][0]->image->w;
    r.h = reserve_nav[i][0]->image->h;
  
    if(game_state->reserve_page[i] < game_state->reserve_page_count[i]) { /* + */
      r.x = game_state->x_dock + ((i==HOME)?(HOME_RESERVE_BOX_X + RESERVE_BOX_W - 2):(VISITOR_RESERVE_BOX_X + RESERVE_BOX_W - 2));
      set_object_position(reserve_nav[i][1],r.x,r.y);
      r.x = (i==HOME)?(HOME_RESERVE_BOX_X + RESERVE_BOX_W - 2):(VISITOR_RESERVE_BOX_X + RESERVE_BOX_W - 2);
      r.y = (i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y;
      BlitSurface(reserve_nav[i][1]->image,NULL,reserve, &r);
    }
    else {
      set_object_position(reserve_nav[i][1],-1,-1);
    }
    
    r.y = game_state->y_dock + ((i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y);
    if(game_state->reserve_page[i] > 0) { /* - */
      r.x = game_state->x_dock + ((i==HOME)?(HOME_RESERVE_BOX_X - reserve_nav[i][0]->image->w - 1):(VISITOR_RESERVE_BOX_X - reserve_nav[i][0]->image->w - 1));
      set_object_position(reserve_nav[i][0],r.x,r.y);
      r.x = (i==HOME)?(HOME_RESERVE_BOX_X - reserve_nav[i][0]->image->w - 1):(VISITOR_RESERVE_BOX_X - reserve_nav[i][0]->image->w - 1);
      r.y = (i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y;
      BlitSurface(reserve_nav[i][0]->image,NULL,reserve, &r);
    }
    else {
      set_object_position(reserve_nav[i][0],-1,-1);
    }
  
	r.x = ((i==HOME)?HOME_RESERVE_BOX_X:VISITOR_RESERVE_BOX_X)-2;
    r.y = ((i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y) + RESERVE_BOX_H;
    r.w = RESERVE_BOX_W;
	r.h = 5;

	SDL_FillRect(reserve, &r,(i==HOME)?SDL_MapRGB(screen->format,150,150,175):SDL_MapRGB(screen->format,175,150,150));

	r.x = ((i==HOME)?HOME_RESERVE_BOX_X:VISITOR_RESERVE_BOX_X)+ (game_state->reserve_page[i]*RESERVE_BOX_W/3) - 1 ;
    r.y = ((i==HOME)?HOME_RESERVE_BOX_Y:VISITOR_RESERVE_BOX_Y) + RESERVE_BOX_H;
    r.w = RESERVE_BOX_W/3 - 2;
	r.h = 4;

	SDL_FillRect(reserve, &r,(i==HOME)?SDL_MapRGB(screen->format,50,50,150):SDL_MapRGB(screen->format,150,50,50));
  }

}

void draw_pass_arrow(graphical_object *obj){
  if(!(obj && obj->image)) return;
  SDL_Rect s,d;
  s.x = 0;
  s.y = 0;
  s.w = obj->image->w;
  s.h = obj->image->h;

  d.x = obj->x;
  d.y = obj->y;
  d.w = s.w;
  d.h = s.h;
  
  pass_arrow_rect = d;

  BlitSurface(obj->image,&s,pg->image,&d);
}

void draw_selection(){
  draw_target(game_state->selection->get_x(), game_state->selection->get_y(),BLACK_INDEX);
}

void draw_square(Square *sq, int color_index){
  SDL_Rect r,s;
  s.x = color_index;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  r.x = SQUARE_TO_PIXEL(sq->get_x());
  r.y = SQUARE_TO_PIXEL(sq->get_y());
  r.w = SQUARE_SIZE;
  r.h = SQUARE_SIZE;
  BlitSurface(colored_squares,&s,pg->image, &r);
}

void draw_cross(Square *sq, int color_index){
  SDL_Rect r,s;
  s.x = color_index;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  r.x = SQUARE_TO_PIXEL(sq->get_x());
  r.y = SQUARE_TO_PIXEL(sq->get_y());
  r.w = SQUARE_SIZE;
  r.h = SQUARE_SIZE;
  BlitSurface(colored_crosses,&s,pg->image, &r);
}

void draw_into_square(SDL_Surface *surf, Square *sq, int img_index){
  SDL_Rect r,s;
  s.x = img_index;
  s.y = 0;
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  r.x = SQUARE_TO_PIXEL(sq->get_x());
  r.y = SQUARE_TO_PIXEL(sq->get_y());
  r.w = SQUARE_SIZE;
  r.h = SQUARE_SIZE;
  BlitSurface(surf,&s,pg->image, &r);
}

void erase_square(Square *sq){
  SDL_Rect s,d;
  s.x = SQUARE_TO_PIXEL(sq->get_x());
  s.y = SQUARE_TO_PIXEL(sq->get_y());
  s.w = SQUARE_SIZE;
  s.h = SQUARE_SIZE;
  d.x = s.x;
  d.y = s.y;
  d.w = s.w;
  d.h = s.h;

  BlitSurface(pg_empty,&s, pg->image, &d);
}

void erase_playground(bool all){
  if(all) BlitSurface(pg_empty,NULL,pg->image,NULL);
  else BlitSurface(pg_empty,&pg_cliprect,pg->image,&pg_cliprect);
}

void erase_dock(void){
  BlitSurface(reserve_empty,NULL,reserve,NULL);
}

void draw_push_square_choice(){  
  for(int i=0;i<game_state->push_square_count;i++)
    draw_into_square(push,game_state->push_squares[i],PUSH_OFF);
}

void draw_indirect_push_square_choice(){  
  for(int i=0;i<game_state->indirect_push_square_count;i++)
    draw_into_square(push,game_state->indirect_push_squares[i],PUSH_OFF);
}

void draw_double_indirect_push_square_choice(){  
  for(int i=0;i<game_state->double_indirect_push_square_count;i++)
    draw_into_square(push,game_state->double_indirect_push_squares[i],PUSH_OFF);
}


void draw_ticks(){
  int i,j;
  SDL_Rect r;
  for(i=0;i<=PLAYGROUND_WIDTH;i++){
    for(j=0;j<=PLAYGROUND_HEIGHT;j++){
      r.w = 1;
      r.h = 1;
      r.x = i*SQUARE_SIZE + MARGIN_SIZE;
      r.y = j*SQUARE_SIZE + MARGIN_SIZE;
      SDL_FillRect(pg->image, &r, 0);
      if(i>0) { 
		r.x = i*SQUARE_SIZE + MARGIN_SIZE - 2;
		r.w = 2;
		SDL_FillRect(pg->image, &r, 0);
      }
      if(i<PLAYGROUND_WIDTH) { 
		r.x = i*SQUARE_SIZE + MARGIN_SIZE + 1;
		r.w = 2;
		SDL_FillRect(pg->image, &r, 0);
      }
      
      r.x = i*SQUARE_SIZE + MARGIN_SIZE;
      r.w = 1;
      
      if(j>0) { 
		r.y = j*SQUARE_SIZE + MARGIN_SIZE - 2;
		r.h = 2;
		SDL_FillRect(pg->image, &r, 0);
      }
      if(j<PLAYGROUND_HEIGHT) { 
		r.y = j*SQUARE_SIZE + MARGIN_SIZE + 1;
		r.h = 2;
		SDL_FillRect(pg->image, &r, 0);
      }

    }
  }
}

void draw_dock(void){
  SDL_Rect s,d; 
  s.x = 0;
  s.y = 0;
  s.w = DOCK_W;
  s.h = DOCK_H;
  d.x = game_state->x_dock; 
  d.y = game_state->y_dock;
  d.w = s.w;
  d.h = s.h;

  if(game_state->current_mode==MODE_TEAM_PLACEMENT && (d.x!=DOCK_X || d.y!=DOCK_Y || game_state->drag_dock)){
	SDL_Rect r;
	r.x = 0;
    r.y = 0;
    r.w = DOCK_W; 
    r.h = 1;
    SDL_FillRect(reserve,&r,0);
	r.x = 0;
    r.y = 0;
    r.w = 1; 
    r.h = DOCK_H;
    SDL_FillRect(reserve,&r,0);
	r.x = 0;
    r.y = DOCK_H-1;
    r.w = DOCK_W; 
    r.h = 1;
    SDL_FillRect(reserve,&r,0);
	r.x = DOCK_W-1;
    r.y = 0;
    r.w = 1; 
    r.h = DOCK_H;
    SDL_FillRect(reserve,&r,0);
  }

  SDL_SetAlpha(reserve, ALPHA_FLAGS, (game_state->drag_dock)?100:230); 
  BlitSurface(reserve,&s,pg->image,&d);
}

void draw_pause_screen(void){
  SDL_FillRect(screen,NULL,0);
  SDL_Rect d;
  d.x = Config::get_screen_w()/2;
  d.y = Config::get_screen_h()/2-20;
  d.w = Config::get_screen_w();
  d.h = Config::get_screen_h();
  draw_string("PAUSE",&d,fonts[PANEL_LOWER_FONT],fonts[PANEL_UPPER_FONT],screen);
  d.x = Config::get_screen_w()/2;
  d.y = Config::get_screen_h()/2+20;
  d.w = Config::get_screen_w();
  d.h = Config::get_screen_h();
  draw_string("Press p to resume game",&d,fonts[PANEL_LOWER_FONT],fonts[PANEL_UPPER_FONT],screen);
}

bool rect_intersect_rect(SDL_Rect first,SDL_Rect second){
	if(rect_into_rect(first,second) || rect_into_rect(second,first)) return true;
	/* haut gauche*/if ( (first.x >= second.x) && (first.x <= (second.x+second.w)) && (first.y >= second.y) && (first.y <= (second.y+second.h)) ) return true;
	/* haut droit*/if (((first.x+first.w) >= second.x) && ((first.x+first.w) <= (second.x+second.w)) && (first.y >= second.y) && (first.y <= (second.y+second.h)) ) return true;
	/* bas gauche*/if ((first.x >= second.x) && (first.x <= (second.x+second.w)) && ((first.y+first.h) >= second.y) && ((first.y+first.h) <= (second.y+second.h)) ) return true;
	/* bas droit*/if (((first.x+first.w) >= second.x) && ((first.x+first.w) <= (second.x+second.w)) && ((first.y+first.h) >= second.y) && ((first.y+first.h) <= (second.y+second.h)) ) return true;
	return false;
}

bool rect_into_rect(SDL_Rect small,SDL_Rect big){
  bool r;
  
  if((small.x>=big.x) && (small.x<=(big.x+big.w)) && (small.y>=big.y) && (small.y<=(big.y+big.h)) && (small.w<=big.w) && (small.h<=big.h)) r=true;
  else r=false;
  
  return r;
}

SDL_Rect rect_union(SDL_Rect a,SDL_Rect b){
  SDL_Rect c;
  
  if(a.w!=0&&b.w!=0){
    c.x = MIN(a.x,b.x);
    c.y = MIN(a.y,b.y);
    c.w = a.w + b.w;
    c.h = a.h + b.h;
    if(a.x<b.x){
      if((a.x+a.w)<b.x) c.w += (b.x-(a.x+a.w));
    }
    if(a.y<b.y){
      if((a.y+a.h)<b.y) c.h += (b.y-(a.y+a.h));
    }
    if(b.x<=a.x){
      if((b.x+b.w)<a.x) c.w += (a.x-(b.x+b.w));
    }
    if(b.y<=a.y){
      if((b.y+b.h)<a.y) c.h += (a.y-(b.y+b.h));
    }
  }
  else if(a.w==0){
    c = b;
  }
  else if(b.w==0){
    c = a;
  }
  
  return c;
}

void update_cliprects(bool all){
  
  if(all){
    SDL_SetClipRect(screen,NULL);
    SDL_SetClipRect(pg_empty,NULL);
    SDL_SetClipRect(pg->image,NULL);
    SDL_SetClipRect(panel->image,NULL);
    SDL_SetClipRect(panel_empty,NULL);    
  }
  else {
    SDL_Rect r_tmp,s_tmp;
    
    if(game_state->weather!=SHOWER /*&& game_state->weather!=BLIZZARD*/){
      if(game_state->active_team!=NONE && game_state->selected_player && !game_state->throw_team_mate_anim && !game_state->pass_anim && !game_state->target_anim && !game_state->throw_in_anim && !game_state->autocenter_anim && game_state->current_action!=ACTIONS_CHOOSE_INTERCEPTION_SQUARE && game_state->current_action!=ACTIONS_MOVE && game_state->current_action!=ACTIONS_MOVE_PLUS){
		r_tmp.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
		r_tmp.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
		r_tmp.w = SQUARE_SIZE;
		r_tmp.h = SQUARE_SIZE;
		pg_cliprect = rect_union(r_tmp,pg_cliprect);
      }
      else if(game_state->pass_anim){
		pg_cliprect = rect_union(pass_d,old_pass_d);      
      }
	  else if(game_state->kick_off_anim){
		pg_cliprect = rect_union(kick_off_ball_d,old_kick_off_ball_d);      
      }
	  else if(game_state->throw_team_mate_anim){
		pg_cliprect = rect_union(team_mate_img_d,old_team_mate_img_d);      
      }
      else if(game_state->throw_in_anim){
		if(game_state->autocenter_anim){
			pg_cliprect.x = -pg->x;
			pg_cliprect.y = -pg->y;
			pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
			pg_cliprect.h = Config::get_screen_h();
		}
		else {
			pg_cliprect = rect_union(throw_in_ball_d,pg_cliprect);
			pg_cliprect = rect_union(old_throw_in_ball_d,pg_cliprect);
		} 
      }

	  if(console->get_visible() && update_console){
		r_tmp.x = CONSOLE_X - pg->x;
		r_tmp.y = console->get_y() - pg->y;
		r_tmp.w = CONSOLE_WIDTH;
		r_tmp.h = console->get_height();
		pg_cliprect = rect_union(r_tmp,pg_cliprect);
	  }


    }
    else{
      pg_cliprect.x = -pg->x;
      pg_cliprect.y = -pg->y;
      pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
      pg_cliprect.h = Config::get_screen_h();
    }
    
	if( update_indicator ){
		r_tmp.x = PANEL_HOME_TURN_INDIC_X;
		r_tmp.y = PANEL_HOME_TURN_INDIC_Y;
		r_tmp.w = PANEL_TURN_INDIC_WIDTH+2;
		r_tmp.h = PANEL_TURN_INDIC_HEIGHT*2+10;
		panel_cliprect = rect_union(r_tmp,panel_cliprect);
	}

    if((panel_cliprect.w != 0)&&(pg_cliprect.w!=0)){
      r_tmp.x = panel_cliprect.x + FRAME_LIMIT;
      r_tmp.y = panel_cliprect.y;
      r_tmp.w = panel_cliprect.w;
      r_tmp.h = panel_cliprect.h;
      s_tmp.x = pg_cliprect.x + pg->x;
      s_tmp.y = pg_cliprect.y + pg->y;
      s_tmp.w = pg_cliprect.w;
      s_tmp.h = pg_cliprect.h;
      screen_cliprect = rect_union(s_tmp,r_tmp);
    }
    else if(panel_cliprect.w==0){
      screen_cliprect.x = pg_cliprect.x + pg->x;
      screen_cliprect.y = pg_cliprect.y + pg->y;
      screen_cliprect.w = pg_cliprect.w;
      screen_cliprect.h = pg_cliprect.h;
    }
    else if(pg_cliprect.w==0){
      screen_cliprect.x = panel_cliprect.x + FRAME_LIMIT;
      screen_cliprect.y = panel_cliprect.y;
      screen_cliprect.w = panel_cliprect.w;
      screen_cliprect.h = panel_cliprect.h;
    }
    else {
      screen_cliprect.x = 0;
      screen_cliprect.y = 0;
      screen_cliprect.w = 0;
      screen_cliprect.h = 0;
    }

    SDL_SetClipRect(screen,&screen_cliprect);
    SDL_SetClipRect(pg_empty,&pg_cliprect);
    SDL_SetClipRect(pg->image,&pg_cliprect);
    SDL_SetClipRect(panel->image,&panel_cliprect);
    SDL_SetClipRect(panel_empty,&panel_cliprect);
  }
}

void draw_all(bool all){

  update_cliprects(all);

  if(all) SDL_FillRect(screen,NULL,0);

  if(game_state->pause){
    draw_pause_screen();
    SDL_Flip(screen);
    game_state->frame++;
    wait_for_next_frame();
    return;
  }
 
  switch(game_state->current_mode){
  case MODE_SURPRISE:
    erase_playground(all);
    erase_dock();
    draw_panel(all);
    draw_team(game_state->team[HOME],all);
    draw_team(game_state->team[VISITOR],all);
    if(game_state->ticks_drawing_mode) 
		draw_ticks();
    if(game_state->target)
		draw_cross(game_state->target, BLACK_INDEX);
	if(game_state->ball->get_square())
		draw_cross(game_state->ball->get_square(), BLACK_INDEX);
    draw_dock();
    draw_playground();
    break;
  case MODE_CHOOSE_BALL_OWNER:
    erase_playground(all);
    erase_dock();
    draw_panel(all);
    draw_team(game_state->team[HOME],all);
    draw_team(game_state->team[VISITOR],all);
    if(game_state->ticks_drawing_mode) 
      draw_ticks();
    if(game_state->target)
      draw_into_square(ball_img,game_state->target,0);
	draw_dock();
    draw_playground();
    break;
  case MODE_BALL_PLACEMENT:
    erase_playground(all);
    erase_dock();
    draw_panel(all);
    draw_team(game_state->team[HOME],all);
    draw_team(game_state->team[VISITOR],all);
    if(game_state->ticks_drawing_mode) 
      draw_ticks();
    if(game_state->ball->is_visible()) 
      draw_ball();
    else if ( game_state->kick_off_anim ){
		if(game_state->target)
			draw_cross(game_state->target, BLACK_INDEX);
		
		BlitSurface(kick_off_ball,&kick_off_ball_s,pg->image,&kick_off_ball_d);
	}
	else if(game_state->target){
      if(game_state->target_anim)
		draw_cross(game_state->target, BLACK_INDEX);
	  else draw_into_square(ball_img,game_state->target,0);
	}	 
	draw_dock();
    draw_playground();
    break;
  case MODE_NONE:
    //break;
  case MODE_TEAM_PLACEMENT:
    erase_playground(all);
    erase_dock();
    draw_panel(all);
    draw_team(game_state->team[HOME],all);
    draw_team(game_state->team[VISITOR],all);
    draw_reserve_navigator();
    
    if(game_state->target && game_state->autocenter_anim && !Shared::get_playground(game_state->target->get_x(),game_state->target->get_y()) ) 
      draw_cross(game_state->target, BLACK_INDEX);   
    if(game_state->ticks_drawing_mode) 
      draw_ticks();
    
    draw_dock();
    
    if(game_state->player_to_place && game_state->location_square){ 
      if(game_state->tackle_zone_drawing_mode==game_state->player_to_place->get_team() || game_state->tackle_zone_drawing_mode==BOTH) draw_future_tackle_zone(game_state->player_to_place,game_state->location_square);
      else draw_square(game_state->location_square,game_state->player_to_place->get_team()==HOME?BLUE_INDEX:RED_INDEX);
    }
    if(game_state->player_to_place){
      SDL_Rect r,s;
      r.x = game_state->player_to_place_x;
      r.y = game_state->player_to_place_y;
      r.w = SQUARE_SIZE;
      r.h = SQUARE_SIZE;
	 
	  if(game_state->player_to_place->get_position_id()<100){  
		s.x = (game_state->player_to_place->get_position_id()*SQUARE_SIZE*2) + ((game_state->player_to_place->get_team()==HOME)?0:SQUARE_SIZE);
		s.y = 0;
		s.w = r.w;
		s.h = r.h;
		BlitSurface(player_img[game_state->player_to_place->get_team()],&s,pg->image, &r);
	  }
	  else if (game_state->player_to_place->get_position_id()>99 && game_state->player_to_place->get_position_id()<200){
		s.x = ((game_state->player_to_place->get_team()==HOME)?0:SQUARE_SIZE);
		s.y = 0;
		s.w = r.w;
		s.h = r.h;
		BlitSurface(starplayer_img,&s,pg->image, &r);	
	  }
	  else if (game_state->player_to_place->get_position_id()>199){
		s.x = ((game_state->player_to_place->get_team()==HOME)?0:SQUARE_SIZE);
		s.y = 0;
		s.w = r.w;
		s.h = r.h;
		BlitSurface(bigguys_img,&s,pg->image, &r);	
	  }

	}

    if(game_state->kick_off_result==KICKOFF_ROCK || game_state->kick_off_result==KICKOFF_INVASION){
      SDL_Rect s;
      for(int i=0;i<game_state->max_victims;i++){
		s.x = 0;
		s.y = 0;
		s.w = SQUARE_SIZE;
		s.h = SQUARE_SIZE;
		BlitSurface(push,&s,pg->image,&victims_rect[i]);
      }
    }

    if(game_state->kick_off_result==KICKOFF_DEFENSE ){
		draw_cross(game_state->ball->get_square(), BLACK_INDEX);   
	}
	
	draw_playground();
    break;
  case MODE_PLAYING:

    erase_playground(all);
    erase_dock();
    draw_panel(all);
    draw_team(game_state->team[HOME],all);
    draw_team(game_state->team[VISITOR],all);
	draw_reserve_navigator();

	if(game_state->ticks_drawing_mode) 
      draw_ticks();
    
	if(game_state->ball && game_state->ball->is_visible()) 
      draw_ball();
	
	if(game_state->selection && game_state->autocenter_anim && !Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y()) && !( (game_state->selection->get_x()==game_state->ball->get_square()->get_x()) && (game_state->selection->get_y()==game_state->ball->get_square()->get_y()) ) ) 
      draw_cross(game_state->selection, BLACK_INDEX);
	
	if(game_state->target && game_state->current_action!=ACTIONS_THROW && game_state->current_action!=ACTIONS_THROW_TEAM_MATE && game_state->current_action!=ACTIONS_CHOOSE_PUSH_SQUARE && game_state->current_action!=ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE )
      draw_cross(game_state->target, BLACK_INDEX);

	if(game_state->path) 
      draw_path(game_state->path,all);

	if(game_state->team_mate && game_state->team_mate->get_square() && game_state->current_action==ACTIONS_THROW_TEAM_MATE)
		draw_into_square(intercept_img,game_state->team_mate->get_square(),INTERCEPT_OFF);

	if(game_state->current_action==ACTIONS_THROW || game_state->current_action==ACTIONS_THROW_TEAM_MATE) {
		if((game_state->target && !Shared::get_playground(game_state->target->get_x(),game_state->target->get_y())) || (game_state->target && !pass_arrow) ) 
			draw_cross(game_state->target, BLACK_INDEX);

		if(pass_arrow) 
			draw_pass_arrow(pass_arrow);
		if (game_state->current_action!=ACTIONS_THROW_TEAM_MATE) 
			draw_interception_squares();
		else if (game_state->throw_team_mate_fumble && game_state->target)
			draw_into_square(push,game_state->target,PUSH_OFF);		
	}

    if(game_state->current_action==ACTIONS_CHOOSE_INTERCEPTION_SQUARE) 
      draw_interception_squares();

    if(game_state->current_action==ACTIONS_CHOOSE_PUSH_SQUARE || 
       game_state->current_action==ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE)
      draw_push_square_choice();

    if(game_state->current_action==ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE ||
       game_state->current_action==ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE ) 
      draw_indirect_push_square_choice();
    
	if(game_state->current_action==ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE ||
       game_state->current_action==ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE ) 
      draw_double_indirect_push_square_choice();
    
    if(game_state->interception_square){
      draw_into_square(intercept_img,game_state->interception_square,INTERCEPT_ON);
    }

    if(game_state->push_square){
      draw_into_square(push,game_state->push_square,PUSH_ON);
    }

    if(game_state->indirect_push_square){
      draw_into_square(push,game_state->indirect_push_square,PUSH_ON);
    }

	if(game_state->double_indirect_push_square){
      draw_into_square(push,game_state->double_indirect_push_square,PUSH_ON);
    }

    if(game_state->transmit_square){
      draw_cross(game_state->transmit_square, BLACK_INDEX);
    }

    if(game_state->throw_in_anim)
		BlitSurface(throw_in_ball,&throw_in_ball_s,pg->image,&throw_in_ball_d);

	if(game_state->throw_team_mate_anim)
		BlitSurface(team_mate_img,&team_mate_img_s,pg->image,&team_mate_img_d);

    if(game_state->pass_anim)
      BlitSurface(pass_ball_img,&pass_s,pg->image,&pass_d);
 
	if(game_state->contextual_info->visible)
		draw_contextual_info(all);

    draw_dock();
    
    draw_weather_effects();
    
    if(actions_menu->visible)
      draw_actions_menu();
    
	draw_playground();

    break;
  }
  
  if(all || ((screen_cliprect.w!=0) && (screen_cliprect.h!=0))){
    
	if(console->get_visible()/* && (update_console || all) */){
		console->draw();
		update_console = false;
	}

	SDL_Flip(screen);
  }
  game_state->frame++;

  if(!all){
    pg_cliprect.x = -1;
    pg_cliprect.y = -1;
    pg_cliprect.w = 0;
    pg_cliprect.h = 0;
    panel_cliprect.x = -1;
    panel_cliprect.y = -1;
    panel_cliprect.w = 0;
    panel_cliprect.h = 0;
  }

  wait_for_next_frame();
}

void draw_weather_effects(){
  SDL_Rect s,d;
  s.y = 0;
  s.w = FRAME_LIMIT - FRAME_LINE;
  s.h = Config::get_screen_h();
  
  d.x = -pg->x;
  d.y = -pg->y;
  d.w = s.w;
  d.h = s.h;
  
  switch(game_state->weather){ 
  case SHOWER:
    s.x = (game_state->frame%RAIN_FRAME) * rain->w/3;
    BlitSurface(rain,&s,pg->image,&d);
    break;
  } 
}

void select_none(Team *t){
	std::map<int,Player*> ::iterator it;
  map<int,Player*> *players = t->get_players();
  for(it=players->begin();it!=players->end();it++){
    ((*it).second)->set_selected(false);
  }
}

void select_none(){
  select_none(game_state->team[HOME]);
  select_none(game_state->team[VISITOR]);
}

void toggle_grab_mouse_mode(bool b){
  game_state->grab_mouse_mode = b;
  SDL_WM_GrabInput((game_state->grab_mouse_mode)?SDL_GRAB_ON:SDL_GRAB_OFF);
}

void set_tackle_zone_drawing_mode(int b){
	game_state->tackle_zone_drawing_mode = b;  
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();	
}

void toggle_tackle_zone_drawing_mode(void){
  game_state->tackle_zone_drawing_mode++;
  
  if(game_state->tackle_zone_drawing_mode>BOTH)
	game_state->tackle_zone_drawing_mode=NONE;
  
  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();
  DEBUG( printf("tackle_zone_drawing mode = %d\n", game_state->tackle_zone_drawing_mode); );
} 

void set_ticks_drawing_mode(bool b){
	game_state->ticks_drawing_mode = b;  
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();	
}

void set_number_drawing_mode(bool b){
	game_state->number_drawing_mode = b;  
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();	
	DEBUG( printf("number_drawing mode = %d\n", game_state->number_drawing_mode); );
}

void toggle_number_drawing_mode(){
	game_state->number_drawing_mode = !game_state->number_drawing_mode;
	pg_cliprect.x = -pg->x;
	pg_cliprect.y = -pg->y;
	pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
	pg_cliprect.h = Config::get_screen_h();
	DEBUG( printf("number_drawing mode = %d\n", game_state->number_drawing_mode); );
}

void toggle_ticks_drawing_mode(void){
  game_state->ticks_drawing_mode = !game_state->ticks_drawing_mode;
  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();
  DEBUG( printf("ticks_drawing mode = %d\n", game_state->ticks_drawing_mode); );
}

bool move_player(Player *pl, Path* pa){
	std::list<Square*>* squares = pa->get_path_squares();
	std::list<Square*>::iterator it;
	int x_diff=0;
	int y_diff=0;
	bool complete = true;
	for(it=squares->begin();(it!=squares->end())&&(pl->get_status()==OK);it++){
		if (*it){
			x_diff = (*it)->get_x() - pl->get_square()->get_x();
			y_diff = (*it)->get_y() - pl->get_square()->get_y();
    
			int goal = pl->move((*it)->get_x() , (*it)->get_y());
      
    move_player_dodge_begining:
     
      int roll = d6->roll();
     
      int result = SUCCESS;
      if (roll!=6 && (roll==1 || roll<goal) && pl->get_tackle_zone() != 0){
		result = (pl->get_move_reroll_used())?TOOBAD:FAIL;
      }
      else result = SUCCESS;
     
	  if(game_state->dices_roll && pl->get_tackle_zone()>0) console->print("Dodge roll : %i  (%c%i)", roll, results[result], goal);

      switch(result){
      case SUCCESS:
		pl->place((*it)->get_x(),(*it)->get_y());
		pl->inc_move_count();
		
		//SOUND - TALID	
		#ifndef NOSOUND
		
		if(game_state->weather==SHOWER){
			if(Config::is_sound_enabled()){
					sp->play_sound(SND_WATER, FX0_CHANNEL);	
			}
		}
		if(game_state->weather==BLIZZARD){
			if(Config::is_sound_enabled()){
					sp->play_sound(SND_SNOW, FX0_CHANNEL);
			}
		}
		if(game_state->weather!=SHOWER && game_state->weather!=BLIZZARD){
			if(Config::is_sound_enabled()){	
				sp->play_sound(SND_WALK, FX0_CHANNEL);
			}
		}
		#endif


		pa->inc_dist_done();
		
		if(pl->has_got_ball()) {
			game_state->ball->place((*it)->get_x(),(*it)->get_y());
		}
		else if( (pl->get_square()->get_x() == game_state->ball->get_square()->get_x())&&(pl->get_square()->get_y() == game_state->ball->get_square()->get_y())){
			verify_ball_placement();
		}
		
		if( game_state->current_action == ACTIONS_NONE ) return false;

		if(touchdown()) return false;
	break;
      case FAIL: 
	DEBUG( printf("fail! (cad rate mais avec possibilite de relance) \n"); );	
	
	if(pl->has_got_skill(DODGE) && ( !pl->neighbours_has_got_skill(TACKLE) ) ){
	  // open_info
	  draw_all(true);
	  dialog_box->open_info(screen,ICONS_INFO,MSG_MOVE_FREE_REROLL,false,game_state->team[pl->get_team()]->get_name());
	  pl->set_move_reroll_used(true);
	  draw_all(true);
	  goto move_player_dodge_begining;
	}

	////////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[pl->get_team()]->can_reroll()) goto move_player_toobad;
    else if(!game_state->team[pl->get_team()]->can_reroll() || pl->has_got_skill(BIG_GUY) || game_state->active_team!=pl->get_team()) goto move_player_toobad;
    ////////////////////////////////////////////
	
	draw_all(true);
	switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_MOVE_REROLL_QUESTION,game_state->team[pl->get_team()]->get_name())){
	case YES:
	  game_state->team[pl->get_team()]->set_reroll_used(true);
	  pl->set_move_reroll_used(true);
	  draw_all(true);
	  goto move_player_dodge_begining;
	  break;
	case NO:
	  draw_all(true);
	  goto move_player_toobad;
	  break;
	}
	
      case TOOBAD: 
      move_player_toobad:
	DEBUG( printf("toobad! (tu l'as dans le cul)\n"); );
	complete = false;

	game_state->path = NULL;

	///////////////////////////////////////
	// Ragnar Modif3 : stand firm
	if (pl->has_got_skill(STAND_FIRM)){
		if(game_state->dices_roll) console->print("Skill Stand Firm : dodge failed but doesn't fall");
		draw_all(true);
		dialog_box->open_info_i(screen,ICONS_INFO,MSG_SKILL_STAND_FIRM_DODGE,false,game_state->team[pl->get_team()]->get_name(),pl->get_number());
		draw_all(true);
		///////////////////////////////////////////////////////
		// Ragnar Modif4 : reste debout dans la case de départ
		// supprimer les lignes en remarque
		//pl->place((*it)->get_x(),(*it)->get_y());
		//if(pl->has_got_ball()) {
		//game_state->ball->place((*it)->get_x(),(*it)->get_y());
		//}
		//else if( (pl->get_square()->get_x() == game_state->ball->get_square()->get_x())&&(pl->get_square()->get_y() == game_state->ball->get_square()->get_y())){
		//verify_ball_placement();
		//}
		pl->set_has_played(true);
		//if(touchdown()) return false;
		///////////////////////////////////////////////////////
		complete = false;
	}
	else {
		tackle_player(pl, 
				  NULL,
				  (*it)->get_x() - pl->get_square()->get_x(),
				  (*it)->get_y() - pl->get_square()->get_y(),
				  true);
	}
	////////////////////////////////////////

	game_state->current_action = ACTIONS_NONE;
	delete pa;
	break;
      }
   
      if( pl && pl->get_square() ) select_square(pl->get_square()->get_x(),pl->get_square()->get_y());
	  draw_all(false);
	}
  }
 
  DEBUG( printf("<- game_state->selection = (%d,%d)\n", (game_state->selection)?game_state->selection->get_x():-1, (game_state->selection)?game_state->selection->get_y():-1 ); ); 
  return complete;
}

void fill_panel_player_info(Player *pl){

	panel_info->name = pl->get_name();
	panel_info->picture = pl->get_picture();
	panel_info->ma = pl->get_ma();
	panel_info->st = pl->get_st();
	panel_info->ag = pl->get_ag();
	panel_info->av = pl->get_av();
	panel_info->cost = pl->get_cost();
	panel_info->skills = pl->get_skills();
	panel_info->xps = pl->get_xps();
	panel_info->number = pl->get_number();
	panel_info->position = pl->get_position();
    panel_info->team = pl->get_team();
	/*
	DEBUG ( 
		printf(" PANEL PLAYER INFO\n");
		printf("\tname=%s\n",panel_info->name);
		printf("\tma=%i\n",panel_info->ma);
		printf("\tst=%i\n",panel_info->st);
		printf("\tag=%i\n",panel_info->ag);
		printf("\tav=%i\n",panel_info->av);
		printf("\tcost=%i\n",panel_info->cost);
		printf("\txps=%i\n",panel_info->xps);
		printf("\tnumber=%i\n",panel_info->number);
		printf("\tposition=%s\n",panel_info->position); 
	);
	*/

	panel_cliprect.x = PANEL_PLAYER_INFO_X;
	panel_cliprect.y = PANEL_PLAYER_INFO_Y;
	panel_cliprect.w = PANEL_PLAYER_INFO_WIDTH;
	panel_cliprect.h = PANEL_PLAYER_INFO_HEIGHT;

	panel_info->visible = true;
}

void draw_digit(int digit,SDL_Rect* placement,SDL_Surface* font, SDL_Surface* where){
  SDL_Rect s,d;
  s.x = digit*font->w/10;
  s.y = 0;
  s.w = font->w/10;
  s.h = font->h;
  d.x = placement->x + placement->w/2 - font->w/20;
  d.y = placement->y + placement->h/2 - font->h/2; 
  d.w = s.w;
  d.h = s.h;

  erase_panel(&d);
  BlitSurface(font,&s,where,&d);
}

void draw_number(int digit,SDL_Rect* placement,SDL_Surface* font, SDL_Surface* where,int digit_count){
  char str[8];
  SDL_Rect s;
  
  if(digit_count!=NO_LIMIT && digit<(digit_count*10)){
    sprintf(str,"%.2d",digit);
  }
  else sprintf(str,"%d",digit);
  int str_len = strlen(str);
  
  s.w = font->w/10;
  s.h = font->h;
  erase_panel(placement);
  for(int i=0;str[i]!='\0';i++){  
    s.x = placement->x + placement->w/2 - str_len*font->w/20 + i*font->w/10;
    s.y = placement->y + placement->h/2 - font->h/2;
    draw_digit(str[i]-'0',&s,font,where);
  }
}

void draw_string(char* str,SDL_Rect* placement,SDL_Surface* lower_font, SDL_Surface* upper_font, SDL_Surface* where){
  SDL_Rect s,d;
  int str_len = strlen(str);
  int i;

  if((where)==(panel->image) || game_state->pause ) erase_panel(placement);

  for(i=0;str[i]!='\0';i++){
    if((str[i]-'a') >= 0){
      s.x = (str[i] - 'a')*lower_font->w/26;
      s.y = 0;
      s.w = lower_font->w/26;
      s.h = lower_font->h;
      d.w = s.w;
      d.h = d.h;
      d.x = placement->x + placement->w/2 - str_len*lower_font->w/52 + i*lower_font->w/26;
      d.y = placement->y + placement->h/2 - lower_font->h/2;
      BlitSurface(lower_font,&s,where,&d);
    }
    else if( (str[i]-'A') >=0 ){
      s.x = (str[i] - 'A')*upper_font->w/26;
      s.y = 0;
      s.w = upper_font->w/26;
      s.h = upper_font->h;
      d.w = s.w;
      d.h = d.h;
      d.x = placement->x + placement->w/2 - str_len*upper_font->w/52 + i*upper_font->w/26;
      d.y = placement->y + placement->h/2 - upper_font->h/2;
      BlitSurface(upper_font,&s,where,&d);
    }
    else if( str[i]==DOTDOTDOT_KEYCODE ){
      d.w = 1;
      d.h = 1;
      for(int j=0;j<3;j++){
	d.x = placement->x + placement->w/2 - str_len*upper_font->w/52 + i*upper_font->w/26 + j*2*(upper_font->w/(26*4));
	d.y = placement->y + placement->h/2 - upper_font->h/2 + upper_font->h - 4*d.h;
	SDL_FillRect(where,&d,SDL_MapRGB(where->format,255,255,255));
      }
      break;
    }
  }
}

void draw_panel_player_info(bool all){
  
	SDL_Rect s,d;
 
	if(panel_info->picture){
		s.x = 0;
		s.y = 0;
		s.w = panel_info->picture->w;
		s.h = panel_info->picture->h;
		d.x = PANEL_PICTURE_X;
		d.y = PANEL_PICTURE_Y;
		d.w = s.w;
		d.h = s.h; 
		BlitSurface(panel_info->picture,&s,panel->image,&d);
		d.x = PANEL_PICTURE_X + panel_info->picture->w - copyright->w;
		d.y = PANEL_PICTURE_Y;
		d.w = copyright->w;
		d.h = copyright->h; 
		BlitSurface(copyright,NULL,panel->image,&d);
	}
  
	d.x = PANEL_MA_X;
	d.y = PANEL_MA_Y;
	d.w = PANEL_CARAC_WIDTH;
	d.h = PANEL_CARAC_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) {
		if( (game_state->current_action==ACTIONS_MOVE || game_state->current_action==ACTIONS_MOVE_PLUS) && 
			game_state->selected_player && 
			game_state->selected_player->get_team()==panel_info->team && 
			game_state->selected_player->get_number()==panel_info->number){
			
			d.x = PANEL_MA_X + 5;
			d.y = PANEL_MA_Y;
			d.w = PANEL_CARAC_WIDTH / 2; 
			d.h = PANEL_CARAC_HEIGHT;
			draw_number(panel_info->ma,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);

			d.x = (PANEL_MA_X) + ((PANEL_CARAC_WIDTH)/2);
			d.y = PANEL_MA_Y;
			d.w = PANEL_CARAC_WIDTH / 2 - 5; 
			d.h = PANEL_CARAC_HEIGHT;

			int movement_left = 0;

			if(game_state->current_action==ACTIONS_MOVE){
				movement_left = game_state->selected_player->movement_left();
				if(game_state->path) movement_left -= (game_state->path->get_path_squares()->size() - game_state->path->get_dist_done() );
			}
			else if(game_state->current_action==ACTIONS_MOVE_PLUS){
				movement_left = game_state->selected_player->over_movement_left();
				if(game_state->path) movement_left -= game_state->path->get_path_squares()->size();
			}

			draw_number(movement_left,&d,fonts[PANEL_TIME_FONT],panel->image,NO_LIMIT);
		}
		else {
			draw_number(panel_info->ma,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);
		}
	}
  
	d.x = PANEL_ST_X;
	d.y = PANEL_ST_Y;
	d.w = PANEL_CARAC_WIDTH;
	d.h = PANEL_CARAC_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) draw_number(panel_info->st,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);
  
	d.x = PANEL_AG_X;
	d.y = PANEL_AG_Y;
	d.w = PANEL_CARAC_WIDTH;
	d.h = PANEL_CARAC_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) draw_number(panel_info->ag,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);
  
	d.x = PANEL_AV_X;
	d.y = PANEL_AV_Y;
	d.w = PANEL_CARAC_WIDTH;
	d.h = PANEL_CARAC_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) draw_number(panel_info->av,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);

	d.x = PANEL_COST_X;
	d.y = PANEL_COST_Y;
	d.w = PANEL_COST_WIDTH;
	d.h = PANEL_COST_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) draw_number(panel_info->cost,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);

	d.x = PANEL_MISC_X + ((panel_info->number<10)?10:3);
	d.y = PANEL_MISC_Y+(PANEL_MISC_HEIGHT/2)-(sharp_img->h/2);
	d.w = sharp_img->w;
	d.h = sharp_img->h;
	if(all || rect_into_rect(d,panel_cliprect)) BlitSurface(sharp_img, NULL, panel->image, &d );
  
	d.x = PANEL_MISC_X+sharp_img->w + ((panel_info->number<10)?10:3);
	d.y = PANEL_MISC_Y;
	d.w = PANEL_MISC_WIDTH-sharp_img->w - 2*((panel_info->number<10)?10:3);
	d.h = PANEL_MISC_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) draw_number(panel_info->number,&d,fonts[PANEL_CARAC_FONT],panel->image,NO_LIMIT);

	d.x = PANEL_NAME_X;
	d.y = PANEL_NAME_Y + 2;
	d.w = PANEL_NAME_WIDTH;
	d.h = fonts[PANEL_UPPER_FONT]->h;
	if(all || rect_into_rect(d,panel_cliprect)) draw_string(panel_info->name,&d,fonts[PANEL_LOWER_FONT],fonts[PANEL_UPPER_FONT],panel->image);

	d.x = PANEL_NAME_X;
	d.y = PANEL_NAME_Y + PANEL_NAME_HEIGHT - fonts[PANEL_SKILLS_FONT]->h - 1;
	d.w = PANEL_NAME_WIDTH;
	d.h = fonts[PANEL_SKILLS_FONT]->h;
	if(all || rect_into_rect(d,panel_cliprect)) draw_string(panel_info->position,&d,fonts[PANEL_SKILLS_FONT],fonts[PANEL_SKILLS_FONT],panel->image);

	// affichages des skills
	d.x = PANEL_SKILLS_X;
	d.y = PANEL_SKILLS_Y;
	d.w = PANEL_SKILLS_WIDTH;
	d.h = PANEL_SKILLS_HEIGHT;
	if(all || rect_into_rect(d,panel_cliprect)) erase_panel(&d);

	if(panel_info->skills){
		char *tmp;
		std::list<char*>::iterator it;
		int i = 0;
		unsigned int l_max = (PANEL_SKILLS_WIDTH/(fonts[PANEL_SKILLS_FONT]->w/26)) + 1;
		for(it=panel_info->skills->begin();it!=panel_info->skills->end();it++){
			/*string s = (*it); 
		
			memset(tmp,0,32*sizeof(char));
			unsigned int j;
			for(j=0;j<s.size();j++){
				tmp[j] = s[j];
			}
			tmp[j]='\0';
			*/

			tmp = (char*) malloc( CHAR_32 );
			sprintf(tmp,"%s",(*it));

			if( strlen(tmp) > l_max ) {
				tmp[l_max-1] = DOTDOTDOT_KEYCODE;
				tmp[l_max] = '\0';
			}

			d.x = PANEL_SKILLS_X; 
			d.y = PANEL_SKILLS_Y + i*fonts[PANEL_SKILLS_FONT]->h + (5-MIN(panel_info->skills->size(),5))*(PANEL_SKILLS_HEIGHT/10 ) + fonts[PANEL_SKILLS_FONT]->h/2 - 4;
			d.w = MIN(strlen(tmp)*(fonts[PANEL_SKILLS_FONT]->w/26),PANEL_SKILLS_WIDTH);
			d.h = fonts[PANEL_SKILLS_FONT]->h;
			
			if(all || rect_into_rect(d,panel_cliprect)) draw_string(tmp,&d,fonts[PANEL_SKILLS_FONT],fonts[PANEL_SKILLS_FONT],panel->image);
			i++;
			free(tmp);
			if( (i*fonts[PANEL_SKILLS_FONT]->h)>PANEL_SKILLS_HEIGHT ) break;
		}
	}
}

void autocenter(int x_square, int y_square){
  int x = FRAME_LIMIT/2 - SQUARE_TO_PIXEL(x_square) - SQUARE_SIZE/2;
  int y = Config::get_screen_h()/2 - SQUARE_TO_PIXEL(y_square) - SQUARE_SIZE/2;
  
  if ( x > 0 ) x = 0;
  else if ( x < (-pg->image->w+FRAME_LIMIT) ) x = -pg->image->w+FRAME_LIMIT;
  if ( y > 0 ) y = 0;
  else if ( y < (-pg->image->h+Config::get_screen_h()) ) y = -pg->image->h+Config::get_screen_h();
  
  int x_diff = x-pg->x;
  int y_diff = y-pg->y;
  double dist = hypot(x_diff,y_diff);
  double x_step = x_diff/(dist/KEY_STEP);
  double y_step = y_diff/(dist/KEY_STEP);
  
  double x_anim = pg->x;
  double y_anim = pg->y;
  
  int old_x_dock = game_state->x_dock;
  int old_y_dock = game_state->y_dock;

  game_state->autocenter_anim = true;
  
  for(double d = 0; d<(dist-KEY_STEP); d+=KEY_STEP){
    x_anim+=x_step;
    y_anim+=y_step;
    
    if(game_state->current_mode==MODE_TEAM_PLACEMENT) {
		game_state->x_dock -= (int)floor(x_step+.5);
		game_state->y_dock -= (int)floor(y_step+.5);
	
		if ( game_state->x_dock < 0 ) game_state->x_dock = 0;
		else if ( game_state->x_dock > (pg->image->w-DOCK_W) ) game_state->x_dock = pg->image->w-DOCK_W;
		if ( game_state->y_dock < 0 ) game_state->y_dock = 0;
		else if ( game_state->y_dock > (pg->image->h-DOCK_H) ) game_state->y_dock = pg->image->h-DOCK_H;
    }
    DEBUG( printf("anim (%f,%f) (%d,%d)\n", x_anim, y_anim, x, y); );
    
    set_object_position(pg,(int)x_anim,(int)y_anim);
    
    pg_cliprect.x = -pg->x;
    pg_cliprect.y = -pg->y;
    pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
    pg_cliprect.h = Config::get_screen_h();
    
    draw_all(false);
  }

  if(game_state->current_mode==MODE_TEAM_PLACEMENT) {
	game_state->x_dock = old_x_dock-x_diff;
	game_state->y_dock = old_y_dock-y_diff;
  }

  set_object_position(pg,x,y);
  
  pg_cliprect.x = -pg->x;
  pg_cliprect.y = -pg->y;
  pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
  pg_cliprect.h = Config::get_screen_h();

  game_state->autocenter_anim = false;
}

void select_square(int x_square,int y_square){
  select_none();
  if( Shared::get_playground(x_square,y_square) ){
    
    if( game_state->selected_player && 
		game_state->selected_player->get_square() && 
		(game_state->selected_player->get_square()->get_x()!=x_square || game_state->selected_player->get_square()->get_y()!=y_square) &&
		Shared::get_playground(x_square,y_square)->get_team()==game_state->active_team && 
		game_state->selected_player->has_done_something() && 
		!game_state->selected_player->has_played()){

		if(game_state->old_selected_player) game_state->old_selected_player->set_xy(game_state->selected_player->get_square()->get_x(),game_state->selected_player->get_square()->get_y());
        else game_state->old_selected_player = new Square(game_state->selected_player->get_square()->get_x(),game_state->selected_player->get_square()->get_y());
	}
    
    game_state->selected_player = Shared::get_playground(x_square,y_square);
    
    Shared::get_playground(x_square,y_square)->set_selected(true);
    fill_panel_player_info(Shared::get_playground(x_square,y_square));
  }
  else {
    erase_panel_player_info();
  }
  
  if(game_state->selection) game_state->selection->set_xy(x_square,y_square);
  else game_state->selection = new Square(x_square,y_square);

  if(game_state->autocenter_mode){
    autocenter(x_square, y_square);
  }
  else {
    pg_cliprect.x = -pg->x;
    pg_cliprect.y = -pg->y;
    pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
    pg_cliprect.h = Config::get_screen_h();
  }
}

void draw_pass_anim(Player*p, Square *sq){

  game_state->ball->set_visible(false);
  game_state->freeze_interaction = true;

  int x_start = SQUARE_TO_PIXEL( ( p->get_square()->get_x() ) );
  int y_start = SQUARE_TO_PIXEL( ( p->get_square()->get_y() ) );
  int x_end = SQUARE_TO_PIXEL( ( sq->get_x() ) );
  int y_end = SQUARE_TO_PIXEL( ( sq->get_y() ) );
  
  DEBUG( printf("pass de (%d,%d) a (%d,%d) \n", x_start,y_start,x_end,y_end); );

  int x_diff = x_end - x_start;
  int y_diff = y_end - y_start;
  double dist = hypot(x_diff,y_diff);
  double dist_done = 0;
  double x_step = x_diff/(dist/PASS_STEP);
  double y_step = y_diff/(dist/PASS_STEP);
  
  double x_anim = x_start;
  double y_anim = y_start;
        
  double ball_anim_zoom = 1;
  double pass_angle = acos(x_diff/dist);
  if(y_diff>0) pass_angle = -pass_angle; 
  
  double ball_anim_angle = M_PI/4 + pass_angle;
 
  DEBUG(printf("angle %f\n",ball_anim_angle ); );
  
	SDL_Surface *ball_ball = SDL_CreateRGBSurface(SDL_SWSURFACE, ball_img->w, ball_img->h, 32, ball_img->format->Rmask, ball_img->format->Gmask, ball_img->format->Bmask, 0xff000000);
	BlitSurface(ball_img,NULL,ball_ball,NULL);
	
	pass_ball_img = roto_zoom_surface(ball_ball, ball_anim_angle*180/M_PI, 1/*zoom*/,0);
	pass_s.x = 0;
	pass_s.y = 0;
	pass_s.w = pass_ball_img->w;
	pass_s.h = pass_ball_img->h;
    
	double dist_to_interceptor = (game_state->interception_attempt)?hypot(x_start-SQUARE_TO_PIXEL(game_state->interception_square->get_x()),y_start-SQUARE_TO_PIXEL(game_state->interception_square->get_y())):0.0; 

	game_state->pass_anim = true;

	for(double i = 0; i<(dist-PASS_STEP); i+=PASS_STEP){
		x_anim+=x_step;
		y_anim+=y_step;
   
	    dist_done = hypot(x_anim-x_start, y_anim-y_start);	

		if(game_state->interception_attempt && dist_done>dist_to_interceptor ){
			bool interception = intercept_pass(Shared::get_playground(game_state->interception_square->get_x(),game_state->interception_square->get_y()));
			if(interception) {
				game_state->pass_anim = false;
				game_state->freeze_interaction = false;
				game_state->interception_attempt = false;
				game_state->interception_square_count = 0;
				game_state->interception_square = NULL;
				SDL_FreeSurface(ball_ball);
				return;
			}
			game_state->interception_attempt = false;
			game_state->interception_square_count = 0;
			game_state->interception_square = NULL;
		}
    
	ball_anim_zoom = 1 + sin( (dist_done*M_PI)/dist );

	pass_ball_img = roto_zoom_surface(ball_ball, ball_anim_angle*180/M_PI, ball_anim_zoom, 0);
	pass_s.x = 0;
	pass_s.y = 0;
	pass_s.w = pass_ball_img->w;
	pass_s.h = pass_ball_img->h;
    
    old_pass_d = pass_d;
    pass_d.x = (Sint16)x_anim - (pass_ball_img->w - SQUARE_SIZE)/2;
    pass_d.y = (Sint16)y_anim - (pass_ball_img->h - SQUARE_SIZE)/2;
    pass_d.w = pass_s.w;
    pass_d.h = pass_s.h;
   
    draw_all(false);
  }
   
  game_state->ball->place(sq->get_x(),sq->get_y());
 
  game_state->freeze_interaction = false;
  game_state->pass_anim = false;
  SDL_FreeSurface(ball_ball);
}

void draw_throw_team_mate_anim(Player* p,Player* team_mate,Square* sq){

	DEBUG( printf("-> draw_throw_team_mate_anim\n"); );


////---------------------////
  
  game_state->freeze_interaction = true;
  
  Square *old_square = new Square(*team_mate->get_square());

  DEBUG( printf("old square = %d %d\n",old_square->get_x(),old_square->get_y()); );

	DEBUG( printf("-> draw_throw_team_mate_anim 1\n"); );
  team_mate->set_square(NULL); // comme ca je n'affiche plus le gars durant le vol
	DEBUG( printf("-> draw_throw_team_mate_anim 2\n"); );

	DEBUG( printf("s=%d\n",team_mate->get_square()); );

	DEBUG( printf("old square = %d %d\n",old_square->get_x(),old_square->get_y()); );

  int x_start = SQUARE_TO_PIXEL( (p->get_square()->get_x() ) );
  int y_start = SQUARE_TO_PIXEL( (p->get_square()->get_y() ) );
  int x_end = SQUARE_TO_PIXEL( (sq->get_x() ));
  int y_end = SQUARE_TO_PIXEL( (sq->get_y() ));
  
  DEBUG( printf("pass de (%d,%d) a (%d,%d) \n", x_start,y_start,x_end,y_end); );

  int x_diff = x_end - x_start;
  int y_diff = y_end - y_start;
  double dist = hypot(x_diff,y_diff);
  double dist_done = 0;
  double x_step = x_diff/(dist/PASS_STEP);
  double y_step = y_diff/(dist/PASS_STEP);
  
  double x_anim = x_start;
  double y_anim = y_start;
    
  double ball_anim_zoom = 1;
  double ball_anim_angle = 0;
 
  DEBUG(printf("angle %f\n",ball_anim_angle ); );
  
	SDL_Surface *team_mate_pic = SDL_CreateRGBSurface(SDL_SWSURFACE, SQUARE_SIZE, SQUARE_SIZE, 32, player_img[team_mate->get_team()]->format->Rmask, player_img[team_mate->get_team()]->format->Gmask, player_img[team_mate->get_team()]->format->Bmask, 0xff000000);
	SDL_Rect s,d;
	s.x = (team_mate->get_position_id()*SQUARE_SIZE*2) + ((team_mate->get_team()==HOME)?0:SQUARE_SIZE);
    s.y = 0;
    s.w = SQUARE_SIZE;
    s.h = SQUARE_SIZE;
	BlitSurface(player_img[team_mate->get_team()],&s,team_mate_pic, NULL);
	
	if(team_mate->has_got_ball()){
		d.x = d.y = d.w = d.h = SQUARE_SIZE/2; 
		s.x = STATUS_BALL;
		s.y = 0;
		s.w = SQUARE_SIZE/2;
		s.h = SQUARE_SIZE/2;
		BlitSurface(status,&s,team_mate_pic, &d);
	}

	team_mate_img = roto_zoom_surface(team_mate_pic, ball_anim_angle, ball_anim_zoom,0);
	team_mate_img_s.x = 0;
	team_mate_img_s.y = 0;
	team_mate_img_s.w = team_mate_img->w;
	team_mate_img_s.h = team_mate_img->h;

	game_state->throw_team_mate_anim = true;

	draw_all(true);
		
	for(double i = 0; i<(dist-PASS_STEP); i+=PASS_STEP){
		x_anim+=x_step;
		y_anim+=y_step;
   
	    dist_done = hypot(x_anim-x_start, y_anim-y_start);	

		ball_anim_zoom = 1 + sin( (dist_done*M_PI)/dist );
		ball_anim_angle+=0.2;

		team_mate_img = roto_zoom_surface(team_mate_pic, ball_anim_angle*180/M_PI, ball_anim_zoom, 0);
		team_mate_img_s.x = 0;
		team_mate_img_s.y = 0;
		team_mate_img_s.w = team_mate_img->w;
		team_mate_img_s.h = team_mate_img->h;
    
		old_team_mate_img_d = team_mate_img_d;
		team_mate_img_d.x = (Sint16)x_anim - (team_mate_img->w - SQUARE_SIZE)/2;
		team_mate_img_d.y = (Sint16)y_anim - (team_mate_img->h - SQUARE_SIZE)/2;
		team_mate_img_d.w = team_mate_img_s.w;
		team_mate_img_d.h = team_mate_img_s.h;
   
		draw_all(false);
  }

	DEBUG( printf("old square = %d %d\n",old_square->get_x(),old_square->get_y()); );

  game_state->team_mate->set_square(old_square); 

	DEBUG( printf("old square = %d %d\n",old_square->get_x(),old_square->get_y()); );
	DEBUG( printf("ball = %d %d\n",game_state->ball->get_square()->get_x(),game_state->ball->get_square()->get_y()); );

  game_state->freeze_interaction = false;
  game_state->throw_team_mate_anim = false;
  SDL_FreeSurface(team_mate_pic);
	delete old_square;

	DEBUG( printf("<- draw_throw_team_mate_anim\n"); );

////--------------------/////
}

void draw_kick_off_anim(Square* sq){
////---------------------////
  
  game_state->freeze_interaction = true;

  int x_start = SQUARE_TO_PIXEL((PLAYGROUND_WIDTH/2));
  int y_start = (game_state->kick_off_team==HOME)?(SQUARE_TO_PIXEL((PLAYGROUND_HEIGHT/4))):(SQUARE_TO_PIXEL((3*PLAYGROUND_HEIGHT/4)));
  int x_end = SQUARE_TO_PIXEL ( sq->get_x() ); 
  int y_end = SQUARE_TO_PIXEL ( sq->get_y() );
  
  DEBUG( printf("kickoff de (%d,%d) a (%d,%d) \n", x_start,y_start,x_end,y_end); );

  int x_diff = x_end - x_start;
  int y_diff = y_end - y_start;
  double dist = hypot(x_diff,y_diff);
  double dist_done = 0;
  double x_step = x_diff/(dist/PASS_STEP);
  double y_step = y_diff/(dist/PASS_STEP);
  
  double x_anim = x_start;
  double y_anim = y_start;
    
  double ball_anim_zoom = 1;
  double ball_anim_angle = 0;
 
	SDL_Surface *ball_ball = SDL_CreateRGBSurface(SDL_SWSURFACE, ball_img->w, ball_img->h, 32, ball_img->format->Rmask, ball_img->format->Gmask, ball_img->format->Bmask, 0xff000000);
	BlitSurface(ball_img,NULL,ball_ball,NULL);
	
	kick_off_ball = roto_zoom_surface(ball_ball, ball_anim_angle, ball_anim_zoom,0);
	kick_off_ball_s.x = 0;
	kick_off_ball_s.y = 0;
	kick_off_ball_s.w = ball_ball->w;
	kick_off_ball_s.h = ball_ball->h;
    
	game_state->kick_off_anim = true;
	draw_all(true);

	for(double i = 0; i<(dist-PASS_STEP); i+=PASS_STEP){
		x_anim+=x_step;
		y_anim+=y_step;
   
	    dist_done = hypot(x_anim-x_start, y_anim-y_start);	

		ball_anim_zoom = 1 + 2*sin( (dist_done*M_PI)/dist );
		ball_anim_angle+=0.2;

		kick_off_ball = roto_zoom_surface(ball_ball, ball_anim_angle*180/M_PI, ball_anim_zoom, 0);
		kick_off_ball_s.x = 0;
		kick_off_ball_s.y = 0;
		kick_off_ball_s.w = kick_off_ball->w;
		kick_off_ball_s.h = kick_off_ball->h;
    
		old_kick_off_ball_d = kick_off_ball_d;
		kick_off_ball_d.x = (Sint16)x_anim - (kick_off_ball->w - SQUARE_SIZE)/2;
		kick_off_ball_d.y = (Sint16)y_anim - (kick_off_ball->h - SQUARE_SIZE)/2;
		kick_off_ball_d.w = kick_off_ball_s.w;
		kick_off_ball_d.h = kick_off_ball_s.h;
   
		draw_all(false);
  }

  game_state->ball->place(sq); 
  game_state->freeze_interaction = false;
  game_state->kick_off_anim = false;
  SDL_FreeSurface(ball_ball);

////--------------------/////
}


Square* random_move_target(Square *s){
  switch(game_state->team[HOME]->get_kick_off_direction() ){
  case N: s->move(0,-1);break; 
  case S: s->move(0,+1);break; 
  case E: s->move(+1,0);break; 
  case W: s->move(-1,0);break; 
  case NE: s->move(+1,-1);break; 
  case NW: s->move(-1,-1);break; 
  case SE: s->move(+1,+1);break; 
  case SW: s->move(-1,+1);break;
  }
  return s;
}

Square* random_move_target(int x, int y){
  Square *s = new Square(x,y);
  switch(game_state->team[HOME]->get_kick_off_direction() ){
  case N: s->move(0,-1);break; 
  case S: s->move(0,+1);break; 
  case E: s->move(+1,0);break; 
  case W: s->move(-1,0);break; 
  case NE: s->move(+1,-1);break; 
  case NW: s->move(-1,-1);break; 
  case SE: s->move(+1,+1);break; 
  case SW: s->move(-1,+1);break;
  }
  return s;
}

void transmission(Player *p, Player* r){
  
  check_for_multi_play();

  bool reroll_done = false;
  int goal = (r->receive_transmission()) + ((game_state->weather==SHOWER)?1:0);
  r->set_receive_done(true);
  game_state->team[p->get_team()]->set_transmit_done(true);
transmission_begining:
  int roll = d6->roll();

  int result;
  
  if (roll!=6 && (roll==1 || roll<goal)) {
    result = (reroll_done)?TOOBAD:FAIL;
  }
  else result = SUCCESS;
  
  if(game_state->dices_roll) console->print("Transmission roll : %i  (%c%i)", roll, results[result], goal);

  DEBUG(printf("\t resultat du receive transmission : goal=%d   roll=%d   result=%d => ", goal, roll, result); );
    
  switch(result){
  case SUCCESS:
    
	//SOUND - TALID    
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_PICKUP, FX0_CHANNEL);
	}
    #endif
  
    DEBUG(printf("Cool, transmission ok\n"); );
    p->set_has_ball(false);
    r->set_has_ball(true);
    game_state->ball->place(r->get_square()->get_x(),r->get_square()->get_y());
    break;
  case FAIL:
    DEBUG(printf("Dommage, mais tu as une relance\n"); );

    if(r->has_got_skill(CATCH)){
      // open_info
      draw_all(true);
      dialog_box->open_info(screen,ICONS_INFO,MSG_TRANSMISSION_FREE_REROLL,false,game_state->team[r->get_team()]->get_name());
      reroll_done = true;
      draw_all(true);
      goto transmission_begining;
    }   
	////////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[p->get_team()]->can_reroll()) goto transmission_case_toobad;
    else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) goto transmission_case_toobad;
    ////////////////////////////////////////////


    draw_all(true);
    switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_TRANSMISSION_REROLL_QUESTION,game_state->team[r->get_team()]->get_name())){
    case YES:
      game_state->team[p->get_team()]->set_reroll_used(true);
      reroll_done = true;
      draw_all(true);
      goto transmission_begining;
      break;
    case NO:
      draw_all(true);
      goto transmission_case_toobad;
      break;
    }
  case TOOBAD:
  transmission_case_toobad:
    DEBUG(printf("Tu l'as dans le cul : "); );
    p->set_has_ball(false);
    game_state->old_ball_owner_team = p->get_team();
    game_state->ball->place(r->get_square()->get_x(),r->get_square()->get_y());
    game_state->ball->bounce();
    game_state->ball->set_has_bounced(true);
    verify_ball_placement();
    if(!r->has_got_ball()) r->set_has_played(true);
    
    break;      
  }
  
  if(touchdown()) return; // why not ?!

}

void pass(Player *p, Square *destination){
 
  double pass_dist = hypot(destination->get_x() - p->get_square()->get_x(),destination->get_y() - p->get_square()->get_y())*SQUARE_SIZE;
 
  int pass_id = BOMB_PASS;
  
  if(pass_dist<=FLASH_PASS_SIZE) pass_id = FLASH_PASS;
  else if(pass_dist<=NORMAL_PASS_SIZE) pass_id = NORMAL_PASS;
  else if(pass_dist<=LONG_PASS_SIZE) pass_id = LONG_PASS;
  else pass_id = BOMB_PASS;
  
  /////////////////////////////////////////////////////////
  // Ragnar Modif4
  // compétence costaud
  if (p->has_got_skill(STRONG_ARM) && !p->has_got_skill(STUNTY)){
	if (pass_id == FLASH_PASS) pass_id = FLASH_PASS;
	else if (pass_id == NORMAL_PASS) pass_id = FLASH_PASS;
	else if (pass_id == LONG_PASS) pass_id = NORMAL_PASS;
	else if (pass_id == BOMB_PASS) pass_id = LONG_PASS;
  }
  /////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////
  // Ragnar Modif4
  // compétence minus
  if (p->has_got_skill(STUNTY) && !p->has_got_skill(STRONG_ARM)){
	if (pass_id == FLASH_PASS) pass_id = NORMAL_PASS;
	else if (pass_id == NORMAL_PASS) pass_id = LONG_PASS;
	else if (pass_id == LONG_PASS) pass_id = BOMB_PASS;
  }
  /////////////////////////////////////////////////////////

  game_state->team[p->get_team()]->set_throw_done(true);

  int pass_goal = (p->throw_ball(pass_id)) + ((game_state->weather==SUNNY)?1:0);
	p->set_throw_done(true);
  bool reroll_done = false;

 pass_begining:
  
  int pass_roll = d6->roll();
  
  int pass_result;
  
  if (pass_roll==1) 
    pass_result = (!reroll_done)?TOOBAD:FUMBLE;
  else if (pass_roll<pass_goal && pass_roll != 6) 
    pass_result = (!reroll_done)?TOOBAD:FAIL;
  else 
    pass_result = SUCCESS;
  
  if(game_state->dices_roll) console->print("Throw ball roll : %i  (%c%i)", pass_roll, results[pass_result], pass_goal);

  DEBUG( printf("\tresultat du jet de passe : %d pour un but de  %d \n", pass_roll, pass_goal); );

  switch(pass_result){
  case SUCCESS:
    DEBUG( printf("success! U did it! Passe parfaite !\n"); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_PERFECT_PASS,false,game_state->team[p->get_team()]->get_name());
    draw_all(true);
    p->set_has_ball(false);
    game_state->old_ball_owner_team = p->get_team();
    game_state->perfect_pass = true;
    draw_pass_anim(p,destination);
    verify_ball_placement();
    game_state->perfect_pass = false;
	p->set_has_played(true);
    break;
  case FAIL: 
    DEBUG( printf("fail! passe deviee  \n"); );
   
    goto incomplete_pass_actions;
 
    break;
  case TOOBAD: 
    DEBUG( printf("toobad! \n"); );
   
    if(p->has_got_skill(PASS)){ 
      draw_all(true);
      switch(dialog_box->open_yesno(screen,ICONS_QUESTION, (pass_roll==1)?MSG_FUMBLE_PASS_FREE_REROLL:MSG_INCOMPLETE_PASS_FREE_REROLL, game_state->team[p->get_team()]->get_name())){
      case YES:
	game_state->team[p->get_team()]->set_reroll_used(true);
	reroll_done = true;
	draw_all(true);
	goto pass_begining;
	break;
      case NO:
	draw_all(true);
	if(pass_roll==1) 
	  goto fumble;
	else 
	  goto incomplete_pass_actions;
	break;
      }
    }
   	////////////////////////////////////////////
	// Ragnar Modif5 : big guy + pas relance pendant le tour adverse
	//else if(!game_state->team[p->get_team()]->can_reroll()) { 
    else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY) || game_state->is_a_blitz_dump_off || game_state->is_a_dump_off) { 
	////////////////////////////////////////////
      if(pass_roll==1)
		goto fumble;
      else 
		goto incomplete_pass_actions;
    }
   
    draw_all(true);
    switch(dialog_box->open_yesno(screen,ICONS_QUESTION, (pass_roll==1)?MSG_FUMBLE_PASS_REROLL_QUESTION:MSG_INCOMPLETE_PASS_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
    case YES:
      game_state->team[p->get_team()]->set_reroll_used(true);
      reroll_done = true;
      draw_all(true);
      goto pass_begining;
      break;
    case NO:
      draw_all(true);
      if(pass_roll==1) goto fumble;
      break;
    }

  incomplete_pass_actions:
    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_INCOMPLETE_PASS,false,game_state->team[p->get_team()]->get_name());

	//SOUND - TALID
    #ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_THROW, FX0_CHANNEL);
	}
    #endif
	
	draw_all(true);

    p->set_has_ball(false);
    game_state->old_ball_owner_team = p->get_team();
    game_state->perfect_pass = false;
 
    game_state->target_anim = true;
    // 3 deviations sur game_state->target
    int i;
    for(i=0;i<3;i++){
      destination = random_move_target(destination);
      pg_cliprect.x = SQUARE_TO_PIXEL(destination->get_x())-SQUARE_SIZE;
      pg_cliprect.y = SQUARE_TO_PIXEL(destination->get_y())-SQUARE_SIZE;
      pg_cliprect.w = SQUARE_SIZE*3;
      pg_cliprect.h = SQUARE_SIZE*3;
      draw_all(false);
    }
    game_state->target_anim = false;
    
    draw_pass_anim(p,destination);

//SOUND - TALID - BETTER GAME PLAY IF SET (Must remove in very_ball_placement sound)
//	#ifndef NOSOUND
//	if(Config::is_sound_enabled()){
//		sp->play_sound(SND_DROP, FX0_CHANNEL);
//	}
//    #endif

    verify_ball_placement();
  
    p->set_has_played(true);
   
	break;
  case FUMBLE:
  fumble:
    DEBUG( printf("fumble! grosse merde ! \n"); );

    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_FUMBLE,false,game_state->team[p->get_team()]->get_name());
    draw_all(true);
    
    p->set_has_ball(false);
    game_state->old_ball_owner_team = p->get_team();
    game_state->ball->bounce();
    game_state->ball->set_has_bounced(true);
    verify_ball_placement();
    
    p->set_has_played(true);

	////////////////////////////////////////////////////
	// Ragnar Modif : pas de turnover pour un fumble à la passe
	// lors d'un dump-off
    //if(p->get_team()==game_state->active_team) {
	if(!game_state->is_a_dump_off && !game_state->is_a_blitz_dump_off && p->get_team()==game_state->active_team) {
		turnover(p->get_team(),6);
    } 
    
	break;
  }

  if (touchdown()) return;

}

void throw_team_mate(Player* p, Player* team_mate, Square* destination){
	/////---------------------------------------///////

DEBUG( printf("-> throw_team_mate\n"); );

  double pass_dist = hypot(destination->get_x() - p->get_square()->get_x(),destination->get_y() - p->get_square()->get_y())*SQUARE_SIZE;
 
  int pass_id = BOMB_PASS;
  
  if(pass_dist<=FLASH_PASS_SIZE) pass_id = NORMAL_PASS;
  else if(pass_dist<=NORMAL_PASS_SIZE) pass_id = LONG_PASS;
  else pass_id = BOMB_PASS;
  
  game_state->team[p->get_team()]->set_throw_team_mate_done(true);

  int pass_goal = (p->throw_team_mate(pass_id)) + ((game_state->weather==SUNNY)?1:0);
  p->set_throw_team_mate_done(true);
  bool reroll_done = false;

 throw_team_mate_begining:
  
  game_state->throw_team_mate_fumble = false;
  int pass_roll = d6->roll();
  
  int pass_result;
  
  if (pass_roll==1) 
    pass_result = (!reroll_done)?TOOBAD:FUMBLE;
  else if (pass_roll<pass_goal && pass_roll != 6) 
    pass_result = (!reroll_done)?TOOBAD:FAIL;
  else 
    pass_result = SUCCESS;
  
  if(game_state->dices_roll) console->print("Throw team mate roll : %i  (%c%i)", pass_roll, results[pass_result], pass_goal);

  DEBUG( printf("\tresultat du jet de passe d'un coequipier : %d pour un but de  %d \n", pass_roll, pass_goal); );

  switch(pass_result){
  case SUCCESS:
    DEBUG( printf("success! U did it! Passe parfaite !\n"); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_PERFECT_PASS,false,game_state->team[p->get_team()]->get_name());
    
	
	//SOUND - TALID    
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_THROW, FX0_CHANNEL);
	}
    #endif

	
	draw_all(true);
    game_state->perfect_pass = true;
    draw_throw_team_mate_anim(p,team_mate,destination);
    switch_action(ACTIONS_LANDING);
    game_state->perfect_pass = false;
    p->set_has_played(true);
    
	break;
  case FAIL: 
    DEBUG( printf("fail! passe deviee  \n"); );
   
    goto incomplete_throw_team_mate_actions;
 
    break;
  case TOOBAD: 
    DEBUG( printf("toobad! \n"); );
   
    if(p->has_got_skill(PASS)){ 
      draw_all(true);
      switch(dialog_box->open_yesno(screen,ICONS_QUESTION, (pass_roll==1)?MSG_FUMBLE_PASS_FREE_REROLL:MSG_INCOMPLETE_PASS_FREE_REROLL,game_state->team[p->get_team()]->get_name())){
      case YES:
	game_state->team[p->get_team()]->set_reroll_used(true);
	reroll_done = true;
	draw_all(true);
	goto throw_team_mate_begining;
	break;
      case NO:
	draw_all(true);
	if(pass_roll==1) 
	  goto throw_team_mate_fumble;
	else 
	  goto incomplete_throw_team_mate_actions;
	break;
      }
    }
    ////////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[p->get_team()]->can_reroll()) { 
    else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) { 
	////////////////////////////////////////////

      if(pass_roll==1)
	goto throw_team_mate_fumble;
      else 
	goto incomplete_throw_team_mate_actions;
    }
   
    draw_all(true);
    switch(dialog_box->open_yesno(screen,ICONS_QUESTION, (pass_roll==1)?MSG_FUMBLE_PASS_REROLL_QUESTION:MSG_INCOMPLETE_PASS_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
    case YES:
      game_state->team[p->get_team()]->set_reroll_used(true);
      reroll_done = true;
      draw_all(true);
      goto throw_team_mate_begining;
      break;
    case NO:
      draw_all(true);
      if(pass_roll==1) goto throw_team_mate_fumble;
      break;
    }

  incomplete_throw_team_mate_actions:
    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_INCOMPLETE_PASS,false,game_state->team[p->get_team()]->get_name());
    draw_all(true);

    game_state->perfect_pass = false;
 
    game_state->target_anim = true;
    // 3 deviations sur game_state->target
    int i;
    for(i=0;i<3;i++){
      destination = random_move_target(destination);
      pg_cliprect.x = SQUARE_TO_PIXEL(destination->get_x())-SQUARE_SIZE;
      pg_cliprect.y = SQUARE_TO_PIXEL(destination->get_y())-SQUARE_SIZE;
      pg_cliprect.w = SQUARE_SIZE*3;
      pg_cliprect.h = SQUARE_SIZE*3;
      draw_all(false);
    }
    game_state->target_anim = false;
    draw_throw_team_mate_anim(p,team_mate,destination);
	switch_action(ACTIONS_LANDING);
    
	p->set_has_played(true);
    
    break;
  case FUMBLE:
  throw_team_mate_fumble:
    DEBUG( printf("fumble! grosse merde ! \n"); );

	game_state->throw_team_mate_fumble = true;
	if(game_state->target){
		delete game_state->target;
		game_state->target = NULL;
	}
	game_state->target = random_move_target(p->get_square()->get_x(),p->get_square()->get_y());

	draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_FUMBLE,false,game_state->team[p->get_team()]->get_name());
    draw_all(true);
  
	switch_action(ACTIONS_LANDING);

    p->set_has_played(true);
    if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),7);
    } 
    break;
  }

  if (touchdown()) return;

	/////--------------------------------------/////////

DEBUG( printf("<- throw_team_mate\n"); );
}

void leap(Player* p, Square *destination){
	int goal = 7-p->get_ag();
	int result;
	int roll;
	bool reroll_done = game_state->team[p->get_team()]->is_reroll_used();
leap_begining:
	roll = d6->roll();
	if (roll!=6 && (roll==1 || roll<goal)) 
		result = (reroll_done)?TOOBAD:FAIL;
	else result = SUCCESS;

	if(game_state->dices_roll) console->print("Leap roll : %i  (%c%i)", roll, results[result], goal);


	//SOUND - TALID    
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_LEAP, FX0_CHANNEL);
	}
    #endif

	switch(result){
		case SUCCESS:
			DEBUG( printf("leap::success!\n"); );
			p->inc_move_count(2);
			p->place(destination);
			select_square(destination->get_x(),destination->get_y());

			// Ragnar Modif6 : dispersion de la balle
			// si le joueur saute sur la balle, il peut tenter de la ramasser
			if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
				p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
				verify_ball_placement();
			}
			/////////////////////////////////////////

			delete game_state->target;
			game_state->target = NULL;
			break;
		case FAIL:
			draw_all(true);
			switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_LEAP_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
				case YES: 
					game_state->team[p->get_team()]->set_reroll_used(true);
					reroll_done = true;
					draw_all(true);
					goto leap_begining;
					break;
				case NO:
					draw_all(true);
					break;
			}
		case TOOBAD: 
			DEBUG( printf("leap::toobad! (tu l'as dans le cul)\n"); );
			p->place(destination);
			select_square(destination->get_x(),destination->get_y());
			delete game_state->target;
			game_state->target = NULL;
			tackle_player(p,NULL,0,0,true);
		break;
	}
}

bool intercept_pass(Player *p){
  
  int goal = (p->try_to_intercept()) + ((game_state->weather==SHOWER)?1:0);
  bool reroll_done = false;

 intercept_pass_begining:
  
  int roll = d6->roll();

  int result;
  
  if (roll!=6 && (roll==1 || roll<goal)) {
    result = (reroll_done)?TOOBAD:FAIL;
  }
  else result = SUCCESS;

  if(game_state->dices_roll) console->print("Interception roll : %i  (%c%i)", roll, results[result], goal);

  DEBUG(printf("\t resultat de intercept : goal=%d   roll=%d   result=%d => ", goal, roll, result); );
    
  switch(result){
  case SUCCESS:
    DEBUG(printf("Cool, tu as le ballon\n"); );
    game_state->ball->set_visible(false);
    game_state->ball->place(p->get_square()->get_x(), p->get_square()->get_y());
    p->set_has_ball(true);
    select_square(p->get_square()->get_x(),p->get_square()->get_y() );

    draw_all(true);
    dialog_box->open_info(screen,ICONS_AFRAID, MSG_INTERCEPTION,false,game_state->team[p->get_team()]->get_name());
    draw_all(true); 
    
	//SOUND - TALID
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_PICKUP, FX0_CHANNEL);
	}
	#endif

    if(touchdown()) return true;
    
    //////////////////////////////////////////////////////
	// Ragnar Modif : pas de turnover pour interception 
	// réussie lors d'un dump-off
	if(game_state->active_team!=p->get_team() && !game_state->is_a_dump_off && !game_state->is_a_blitz_dump_off) {
	//if(game_state->active_team!=p->get_team()) {
		turnover(game_state->active_team,8);
    }
    return true;
    break;
  case FAIL:
    DEBUG(printf("Dommage, mais tu as une relance\n"); );
     
    if(p->has_got_skill(CATCH)){
      // open_info
      draw_all(true);
      dialog_box->open_info(screen,ICONS_INFO,MSG_INTERCEPTION_FREE_REROLL,false,game_state->team[p->get_team()]->get_name());
      reroll_done = true;
      draw_all(true);
      goto intercept_pass_begining;
    }    
	////////////////////////////////////////////
	// Ragnar Modif5 : big guy
	//else if(!game_state->team[p->get_team()]->can_reroll()) goto interception_case_toobad; 
    else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY) || p->get_team()!=game_state->active_team) goto interception_case_toobad; 
	////////////////////////////////////////////


    draw_all(true);
    switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_INTERCEPTION_PASS_REROLL_QUESTION,game_state->team[p->get_team()]->get_name())){
    case YES:
      game_state->team[p->get_team()]->set_reroll_used(true);
      reroll_done = true;
      draw_all(true);
      goto intercept_pass_begining;
      break;
    case NO:
      draw_all(true);
      break;
    }
    
  case TOOBAD:
  interception_case_toobad:
    DEBUG(printf("Tu l'as dans le cul mais c pas grave...\n "); );
    break;      
  }

  return false;
}

void injure_player(Player* p,int hit_throw,bool aggression_by_public){

	DEBUG( printf("\ntiens, prend ca dans ta gueule (score=%d)! \n", hit_throw); );
 
  if(game_state->dices_roll) console->print("Injury roll : %i", hit_throw);

  draw_all(true);

  ////////////////////////////////////////////////////
	// Ragnar Modif3 : nouvelle table de blessures
	if (hit_throw==8 || hit_throw==9){
		if( p->has_got_skill(THICK_SKULL) ){
			int roll = d6->roll();
			if(game_state->dices_roll) console->print("Thick skull roll : %i  (%c4)", roll, (roll>=4)?'>':'<');
			if(roll>=4) goto down;
		}
		//////////////////////////////////////////////////////
		// Ragnar Modif5 : apothecary
		dialog_box->open_info_i(screen,ICONS_KO, MSG_PLAYER_KO,false,game_state->team[p->get_team()]->get_name(), p->get_number());	
		if(!aggression_by_public && game_state->team[p->get_team()]->get_apothecary()>0){
			int apothecary_roll = d6->roll();
			draw_all(true);
			switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_APOTHECARY,game_state->team[p->get_team()]->get_name())){
				case YES: 
					if(game_state->dices_roll) console->print("Apothecary roll : %i  (success floor = 2)", apothecary_roll);
					draw_all(true);
					if(apothecary_roll>=2){
						dialog_box->open_info_i(screen,ICONS_SMILEY, MSG_APOTHECARY_SUCCESS,false,game_state->team[p->get_team()]->get_name(), p->get_number());
						draw_all(true);
						game_state->team[p->get_team()]->set_apothecary(0);
						goto down;
					}
					else{
						dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_APOTHECARY_FAIL,false,game_state->team[p->get_team()]->get_name(), p->get_number());
						draw_all(true);
						game_state->team[p->get_team()]->set_apothecary(0);
					}
					draw_all(true);
					break;
				case NO:
					draw_all(true);
					break;
			}
		}
		p->set_status(KO);
		//////////////////////////////////////////////////////
	}
	// 10+ -> sortie puis jet de 1D6 sans modificateurs
	else if (hit_throw >= 10){
		int hit_throw2 = d6->roll();

		if(game_state->dices_roll) console->print("Injury roll (second table) : %i  ", hit_throw2);
		draw_all(true);
		if(hit_throw2 <= 3){
			if( p->has_got_skill(REGENERATE) ){
				int roll = d6->roll();
				if(game_state->dices_roll) console->print("Regenerate roll : %i  (%c3)", roll, (roll>=3)?'>':'<');
				if(roll>=3){
					p->place_in_reserve();
					dialog_box->open_info_i(screen,ICONS_RESERVE, MSG_PLAYER_RESERVE,false,game_state->team[p->get_team()]->get_name(),p->get_number()); // mise en reserve	
					goto end;
				}
			}
			
			//////////////////////////////////////////////////////
			// Ragnar Modif5 : apothecary
			draw_all(true);
			dialog_box->open_info_i(screen,ICONS_TOUCHED, MSG_PLAYER_TOUCHED,false,game_state->team[p->get_team()]->get_name(),p->get_number());	
			if(!aggression_by_public && game_state->team[p->get_team()]->get_apothecary()>0){
				int apothecary_roll = d6->roll();
				draw_all(true);
				switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_APOTHECARY,game_state->team[p->get_team()]->get_name())){
					case YES: 
						if(game_state->dices_roll) console->print("Apothecary roll : %i  (success floor = 2)", apothecary_roll);
						draw_all(true);
						if(apothecary_roll>=2){
							dialog_box->open_info_i(screen,ICONS_SMILEY, MSG_APOTHECARY_SUCCESS,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
							goto down;
						}
						else{
							dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_APOTHECARY_FAIL,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
						}
						draw_all(true);
						break;
					case NO:
						draw_all(true);
						break;
				}
			}
			p->set_status(TOUCHED);
			//////////////////////////////////////////////////////
			
			goto end;
		}
		if(hit_throw2==4 || hit_throw2==5){
			if( p->has_got_skill(REGENERATE) ){
				int roll = d6->roll();
				if(game_state->dices_roll) console->print("Regenerate roll : %i  (%c3)", roll, (roll>=3)?'>':'<');
				if(roll>=3){
					p->place_in_reserve();
					dialog_box->open_info_i(screen,ICONS_RESERVE, MSG_PLAYER_RESERVE,false,game_state->team[p->get_team()]->get_name(), p->get_number()); // mise en reserve	
					goto end;
				}
			}
			//////////////////////////////////////////////////////
			// Ragnar Modif5 : apothecary
			draw_all(true);
			dialog_box->open_info_i(screen,ICONS_INJURED, MSG_PLAYER_INJURED,false,game_state->team[p->get_team()]->get_name(),p->get_number());
			if(!aggression_by_public && game_state->team[p->get_team()]->get_apothecary()>0){
				int apothecary_roll = d6->roll();
				draw_all(true);
				switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_APOTHECARY,game_state->team[p->get_team()]->get_name())){
					case YES: 
						if(game_state->dices_roll) console->print("Apothecary roll : %i  (success floor = 2)", apothecary_roll);
						draw_all(true);
						if(apothecary_roll>=2){
							dialog_box->open_info_i(screen,ICONS_SMILEY, MSG_APOTHECARY_SUCCESS,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
							goto down;
						}
						else{
							dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_APOTHECARY_FAIL,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
						}
						draw_all(true);
						break;
					case NO:
						draw_all(true);
						break;
				}
			}
			p->set_status(INJURED);
			//////////////////////////////////////////////////////			
			goto end;
		}
		if(hit_throw2==6){ // c'est le 6 qui tue...
			if( p->has_got_skill(REGENERATE) ){
				int roll = d6->roll();
				if(game_state->dices_roll) console->print("Regenerate roll : %i  (%c3)", roll, (roll>=3)?'>':'<');
				if(roll>=3){
					p->place_in_reserve();
					dialog_box->open_info_i(screen,ICONS_RESERVE, MSG_PLAYER_RESERVE,false,game_state->team[p->get_team()]->get_name(), p->get_number()); // mise en reserve	
					goto end;
				}
			}
		
			//////////////////////////////////////////////////////
			// Ragnar Modif5 : apothecary
			dialog_box->open_info_i(screen,ICONS_DEAD, MSG_PLAYER_DEAD,false,game_state->team[p->get_team()]->get_name(),p->get_number());
			if(!aggression_by_public && game_state->team[p->get_team()]->get_apothecary()>0){
				int apothecary_roll = d6->roll();
				draw_all(true);
				switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_APOTHECARY,game_state->team[p->get_team()]->get_name())){
					case YES: 
						if(game_state->dices_roll) console->print("Apothecary roll : %i  (success floor = 2)", apothecary_roll);
						draw_all(true);
						if(apothecary_roll>=2){
							dialog_box->open_info_i(screen,ICONS_SMILEY, MSG_APOTHECARY_SUCCESS,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
							goto down;
						}
						else{
							dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_APOTHECARY_FAIL,false,game_state->team[p->get_team()]->get_name(), p->get_number());
							draw_all(true);
							game_state->team[p->get_team()]->set_apothecary(0);
						}
						draw_all(true);
						break;
					case NO:
						draw_all(true);
						break;
				}
			}
			p->set_status(DEAD);
			
			//SOUND - TALID
			#ifndef NOSOUND
				if(Config::is_sound_enabled()){
				sp->play_sound(SND_DEAD, FX0_CHANNEL);
				}
			#endif
		
				//////////////////////////////////////////////////////	
			goto end;
		}
	}
	else{
		down:
		if(aggression_by_public){
			p->place_in_reserve();
			dialog_box->open_info_i(screen,ICONS_RESERVE, MSG_PLAYER_RESERVE,false,game_state->team[p->get_team()]->get_name(),p->get_number()); // mise en reserve
		}
		else {
			p->set_status(DOWN);
			dialog_box->open_info_i(screen,ICONS_DOWN, MSG_PLAYER_DOWN,false,game_state->team[p->get_team()]->get_name(),p->get_number());
		}
    }
	
	end:
	////////////////////////////////////////////////////////////
	draw_all(true);

}

void aggress_player(Player*p, Player* other){
  int aggress_goal = p->aggress(other);
  p->set_aggress_done(true);
  game_state->team[p->get_team()]->set_aggress_done(true);
  p->set_team_aggress_done(true);
  p->set_has_played(true);
  DEBUG( printf("\tscore a atteindre pour reussir aggression : %d\n", aggress_goal); );
  int d1 = d6->roll();
  int d2 = d6->roll();

	///////////////////////////////////////////////////////////
	// Ragnar Modif3 : vicieux, +2 à l'armure OU à la blessure
	// tout le monde a un +1 à l'armure, le vicieux peut avoir un +1
	// additionnel si nécessaire mais n'aura plus alors le +2 à la
	// blessure
	int bonus=1;
	/////////////////////////////////////////////////
	// Ragnar Modif 7 : vicieux +1 +2 = +3 à l'armure
	//if (d1+d2+bonus==aggress_goal && p->has_got_skill(DIRTY_PLAYER)){
		//bonus++;
	if ((d1+d2+bonus==aggress_goal || d1+d2+bonus==aggress_goal-1) && p->has_got_skill(DIRTY_PLAYER)){	
		bonus+=2;
		p->set_dirty_player_used(true);
		if(game_state->dices_roll) console->print("Skill dirty player used for armour roll");
	}
	///////////////////////////////////////////////////////////

  /////////////////////////////////////////////
  // Ragnar Modif4 : agression
  int aggress_roll = ((d1+d2+bonus)>aggress_goal)?(d1==d2)?SUCCESS_BUT_DOUBLE:SUCCESS:(d1==d2)?FAIL_AND_DOUBLE:FAIL;
  DEBUG( printf("\tresultat du jet d'aggression : %d %d \n", d1, d2); );

  if(bonus==1 && game_state->dices_roll) console->print("Aggression roll : %i (%i+%i+1)  (%c%i)", d1+d2+1,d1,d2,results[aggress_roll], aggress_goal);
  if(bonus==/*RM7 2*/3/*RM7*/ && game_state->dices_roll) console->print("Aggression roll (dirty player): %i (%i+%i+2)  (%c%i)", d1+d2+2,d1,d2,results[aggress_roll], aggress_goal);
  /////////////////////////////////////////////

  int hit_throw = 0;
  switch(aggress_roll){
  case SUCCESS_BUT_DOUBLE:
    
    if( game_state->team[p->get_team()]->has_intimidated_referee() ) goto case_aggress_success;

    DEBUG( printf("\t C'est bien mais tu t'es fais gauller\n"); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_AGGRESS_SUCCESS,false,game_state->team[p->get_team()]->get_name());
    delete game_state->target;
	game_state->target = NULL;

	//SOUND - TALID
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_AGGRESS, FX0_CHANNEL);
	}
	#endif

	draw_all(true);
    hit_throw = p->hit(other);
	if(p->has_got_skill(DIRTY_PLAYER) /*RM6*/ && !p->is_dirty_player_used() /*RM6*/){
		///////////////////////////////////////////////
		// Ragnar Modif3
		// vicelard bénéficie d'un +2 (et non +1)
		// à la blessure
		hit_throw+=2;
		if(game_state->dices_roll) console->print("Skill dirty player : +2 to injury roll");
		///////////////////////////////////////////////
		// Ragnar Modif3 : stunty
		if (other->has_got_skill(STUNTY)) {
			hit_throw++;
			if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
		}
		/////////////////////////////////////////////////
	}
	injure_player(other,hit_throw,false);

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_WHISTLE, FX0_CHANNEL);
	}
#endif

	draw_all(true);
    switch(dialog_box->open_info_i(screen,ICONS_REFEREE, MSG_PLAYER_EJECTED, game_state->team[p->get_team()]->can_complain(),game_state->team[p->get_team()]->get_name(), p->get_number())){
    case NOT_AGREE:
      
      switch(game_state->team[p->get_team()]->buy_referee()){
      case TOOBAD:
	game_state->team[p->get_team()]->set_can_complain(false);
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_REFEREE_RULES,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	p->set_has_played(true); 

	if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	}

	p->set_status(EJECTED);
	
	if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),9);
	}
	break;
      case SUCCESS:
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_TEAM_RULES,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	break;
      case FAIL:
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_REFEREE_DESPISE,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	p->set_has_played(true); 
	
	if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	}
	
	p->set_status(EJECTED);
	if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),10);
	}
	
	break;
      }
      
      break;

    case CLOSE:
      draw_all(true);
      p->set_has_played(true); 

	  if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	  }

      p->set_status(EJECTED);
      if(p->get_team()==game_state->active_team) {
		  turnover(p->get_team(),11);
      }
    }
   
    break;
  case SUCCESS:
  case_aggress_success:
    DEBUG( printf("\t Yeah!!! U did it !!!\n"); );
    
	//SOUND - TALID
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_AGGRESS, FX0_CHANNEL);
	}
	#endif

	draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_AGGRESS_SUCCESS,false,game_state->team[p->get_team()]->get_name());
    delete game_state->target;
	game_state->target = NULL;
	draw_all(true);
    hit_throw = p->hit(other);
   	if(p->has_got_skill(DIRTY_PLAYER) /*RM6*/ && !p->is_dirty_player_used() /*RM6*/){
		///////////////////////////////////////////////
		// Ragnar Modif3
		// vicelard bénéficie d'un +2 (et non +1)
		// à la blessure
		hit_throw+=2;
		if(game_state->dices_roll) console->print("Skill dirty player : +2 to injury roll");
		///////////////////////////////////////////////
		// Ragnar Modif3 : stunty
		if (other->has_got_skill(STUNTY)){
			hit_throw++;
			if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
		}
		/////////////////////////////////////////////////
	}
	injure_player(other,hit_throw,false);
    break;
  case FAIL_AND_DOUBLE:
    
    if( game_state->team[p->get_team()]->has_intimidated_referee() ) goto case_aggress_fail;
    
    DEBUG( printf("\t T'es vraiment une grosse merde ! En plus tu viens de te faire chopper\n"); );
    
    draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_AGGRESS_FAILED,false,game_state->team[p->get_team()]->get_name());
    delete game_state->target;
	game_state->target = NULL;
	draw_all(true);

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_WHISTLE, FX0_CHANNEL);
	}
#endif

    switch(dialog_box->open_info_i(screen,ICONS_REFEREE, MSG_PLAYER_EJECTED, game_state->team[p->get_team()]->can_complain(),game_state->team[p->get_team()]->get_name(), p->get_number())){
    case NOT_AGREE:
      
      switch(game_state->team[p->get_team()]->buy_referee()){
      case TOOBAD:
	game_state->team[p->get_team()]->set_can_complain(false);
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_REFEREE_RULES,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	p->set_has_played(true); 

	if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	}

	p->set_status(EJECTED);
	if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),12);
	}
	break;
      case SUCCESS:
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_TEAM_RULES,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	break;
      case FAIL:
	draw_all(true);
	dialog_box->open_info(screen,ICONS_REFEREE, MSG_REFEREE_DESPISE,false,game_state->team[p->get_team()]->get_name());
	draw_all(true);
	p->set_has_played(true); 
	
	if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	}
	
	p->set_status(EJECTED);
	if(p->get_team()==game_state->active_team) {
		turnover(p->get_team(),13);
	}
	break;
      }
      break;
    case CLOSE:
      draw_all(true);
      p->set_has_played(true); 
      
	  if(p->has_got_ball()) {
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->place(p->get_square());
			game_state->ball->set_visible(true);
	  }

	  // virer l'aggresseur
	  p->set_status(EJECTED);

      if(p->get_team()==game_state->active_team) {
		  turnover(p->get_team(),14);
      }
    }   
    break;
  case FAIL:
  case_aggress_fail:
    
    DEBUG( printf("\t Try again\n"); );
    draw_all(true);
    dialog_box->open_info(screen,ICONS_INFO, MSG_AGGRESS_FAILED,false,game_state->team[p->get_team()]->get_name());
	delete game_state->target;
	game_state->target = NULL;
    draw_all(true);
    break;
  }
  
}

/////////////////////////////////////////////////////
// Ragnar Rq :
// vs plaque p
/////////////////////////////////////////////////////
void tackle_player(Player* p, Player*vs, int x_diff, int y_diff, bool must_test_armour){
  	if(x_diff!=0 || y_diff!=0 ) {
		p->place(p->get_square()->get_x() + x_diff,p->get_square()->get_y() + y_diff);
		if(p->has_got_ball()) game_state->ball->place(p->get_square());
	}
  
  if(p->has_got_ball()) {
    p->set_has_ball(false);
    game_state->old_ball_owner_team = p->get_team();
    game_state->ball->bounce();
    game_state->ball->set_has_bounced(true);
    verify_ball_placement();
  }
  else{
    if(p->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
       p->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
      game_state->ball->bounce();
      game_state->ball->set_has_bounced(true);
      verify_ball_placement();
    }
  }
  
  p->set_has_played(true);
  
	//SOUND - TALID 
	#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_FALL, FX0_CHANNEL);
	}
	#endif

  if( must_test_armour ){
	int armour_throw = d6->roll(2);
	
	//////////////////////////////////////////////////////
	// Ragnar Modif3
	// compétences de meule
	//claws s'applique systématiquement
	if(vs && vs->has_got_skill(CLAWS) ){ 
		armour_throw += 2;
		if(game_state->dices_roll) console->print("Skill Claws : +2 to armour roll");
	}
	// cas où le joueur a chataigne ou écrasement
	else if(vs && (vs->has_got_skill(MIGHTY_BLOW) || vs->has_got_skill(PILLING_ON))){ 
		// si le joueur n'a "que" chataigne
		if(!vs->has_got_skill(PILLING_ON)){
			if( armour_throw == p->get_av()){
				armour_throw += 1;
				vs->set_mighty_blow_used(true);
				if(game_state->dices_roll) console->print("Skill Mighty Blow : +1 to armour roll");
				goto finished;
			}
		}
		// si le joueur n'a "que" écrasement
		else if (!vs->has_got_skill(MIGHTY_BLOW)){
			// sur un "skull and star" il faut avoir blocage pour utiliser écrasement
			if (!game_state->is_a_skull_and_star || vs->has_got_skill(BLOCK)){
				if( armour_throw + vs->get_st() > p->get_av() && armour_throw <= p->get_av()) 
					goto skill_pilling_on;
			}
		}
		// si le joueur a les deux...
		else{
			// cas où chataigne suffit, mais il peut le garder pour la blessure 
			if(armour_throw == p->get_av()){
				bool use_mighty_blow = false;
				//s'il peut utiliser écrasement, on lui donne le choix
				if (!game_state->is_a_skull_and_star || vs->has_got_skill(BLOCK)){
					switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_SKILL_MIGHTY_OR_PILLING_ON,game_state->team[vs->get_team()]->get_name())){
						case YES: 
							use_mighty_blow = true;
							draw_all(true);
							break;
						case NO:
							use_mighty_blow = false;
							draw_all(true);
							break;
					}
				}
				else use_mighty_blow =true;// s'il ne peut pas utiliser écrasement (il se fait meuler aussi) il utilise chataigne
				if (use_mighty_blow){
					armour_throw += 1;
					vs->set_mighty_blow_used(true);
					if(game_state->dices_roll) console->print("Skill Mighty Blow : +1 to armour roll");
					goto finished;
				}
				else goto skill_pilling_on;
			}

			// cas où il doit nécessairement écraser pour percer
			if(armour_throw + vs->get_st() > p->get_av() && armour_throw < p->get_av()){
				
skill_pilling_on:

				//boite de dialogue pour proposer d'écraser
				bool use_pilling_on = false;
				if (!game_state->is_a_skull_and_star || vs->has_got_skill(BLOCK)){
					switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_SKILL_PILLING_ON,game_state->team[vs->get_team()]->get_name())){
						case YES: 
							use_pilling_on = true;
							draw_all(true);
							break;
						case NO:
							use_pilling_on = false;
							draw_all(true);
							break;
					}
				}
				//on écrase
				if (use_pilling_on){
					vs->set_pilling_on_used(true);
					armour_throw=armour_throw + vs->get_st();
					if(game_state->dices_roll) console->print("Skill Pilling On : +%i to armor roll ", vs->get_st());
					// le joueur qui écrase se retrouve au sol et lache la balle s'il la tenait
					// le code correspondant se trouve dans block_player pour le cas "skull and star"
					// et au momment de poursuivre dans "ACTION_PUSH_AND_HIT" pour repoussé et plaqué
				}
			}
		}
	} 

finished:
	//////////////////////////////////////////////////////

	if(game_state->dices_roll) console->print("Armor roll : %i  (%c%i)", armour_throw, (armour_throw>p->get_av())?'>':'<',p->get_av() /*RM6-pour afficher le score à atteindre-*/+1/*RM6*/);

	DEBUG( printf("\tjet d'armure a %d contre une armure de %d\n",armour_throw, p->get_av()); );
	if( armour_throw > p->get_av() ){ 
		int hit_throw = (vs)?(vs->hit(p)):(d6->roll(2)); 
		
		/////////////////////////////////////////////////
		// Ragnar Modif3
		if (vs){
			if ( vs->has_got_skill(RAZOR_SHARP) ) {
				hit_throw+=2;
				if(game_state->dices_roll) console->print("Skill Razor Sharp : +2 to injury roll");
			}
			else if( vs->has_got_skill(MIGHTY_BLOW) && !vs->is_mighty_blow_used()){
				hit_throw+=1;
				if(game_state->dices_roll) console->print("Skill Mighty Blow : +1 to injury roll");
			}
		}
		/////////////////////////////////////////////////
		// Ragnar Modif3 : stunty
		if (p->has_got_skill(STUNTY)) {
			hit_throw++;
			if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
		}
		/////////////////////////////////////////////////

		injure_player(p,hit_throw,false);
	}
	else {
		delete game_state->target;
		game_state->target = NULL;
		draw_all(true);
		p->set_status(GROUND);
		dialog_box->open_info_i(screen,ICONS_GROUND, MSG_PLAYER_GROUND,false,game_state->team[p->get_team()]->get_name(),p->get_number());
		draw_all(true);
	}
  }
  else { // on fait juste que tomber mais on ne se fait pas mal, comme pour mettre le paquet par ex.
		delete game_state->target;
		game_state->target = NULL;
		draw_all(true);
		p->set_status(GROUND);
		dialog_box->open_info_i(screen,ICONS_GROUND, MSG_PLAYER_GROUND,false,game_state->team[p->get_team()]->get_name(),p->get_number());
		draw_all(true);
  }

  if(touchdown()) return;

  if(p->get_team() == game_state->active_team) {
    delete game_state->path;
	game_state->path = NULL;
	delete game_state->target;
	game_state->target = NULL;
	turnover(p->get_team(),15);
  }
}

void block_player(Player*p, Player* other){
  int dices_to_roll = p->block(other);

  ///////////////////////////////////////
  // Ragnar Modif3
  if( p->has_got_skill(DAUNTLESS) && ( p->get_st() < other->get_st() ) ){
	  int roll = d6->roll(2);
	  if(game_state->dices_roll) console->print("Skill dauntless roll : %i",roll);
	  if( roll > other->get_st() ){
		dialog_box->open_info_i(screen,ICONS_INFO,MSG_SKILL_DAUNTLESS_SUCCESS,false,game_state->team[p->get_team()]->get_name(),p->get_number());
		draw_all(true);
		int initial_st = p->get_st();
		p->set_st(other->get_st());
		dices_to_roll = p->block(other);
		p->set_st(initial_st);
	}
	else {
		dialog_box->open_info_i(screen,ICONS_INFO,MSG_SKILL_DAUNTLESS_FAILURE,false,game_state->team[p->get_team()]->get_name(),p->get_number());
		draw_all(true);
	}
  }
  ///////////////////////////////////////

 block_player_begininig:
  
  int block_dices[3] = {-1,-1,-1};
  DEBUG( printf("\tnombre de des a jeter : %d, mais c'est %s qui choisit\n",abs(dices_to_roll),dices_to_roll>0?"attaquant":"defenseur" ); );
  
  if(game_state->dices_roll) console->print("Block dices count : %i  =>  %s team must choose!", abs(dices_to_roll), dices_to_roll>0?"active":"passive");
  
	for(int i=0;i<abs(dices_to_roll);i++){
		block_dices[i] = dblock->roll();
		DEBUG( printf("\t\t des[%d] = %d\n", i, block_dices[i]); );
	}

  int user_choice = 0;
  
  draw_all(true);

  ///////////////////////////////////
  // Ragnar Modif5 : big guy
  switch( dialog_box->open_block(screen,block_dices,(dices_to_roll>0)?ATTACKER:DEFENDER,(game_state->team[p->get_team()]->can_reroll() && !p->has_got_skill(BIG_GUY)), game_state->team[ ( dices_to_roll>0 )?( p->get_team() ):( 1 - p->get_team() ) ]->get_name()) ){
  ///////////////////////////////////
  case FIRST_DICE:
    user_choice = block_dices[0];
    break;
  case SECOND_DICE:
    user_choice = block_dices[1];
    break;
  case THIRD_DICE:
    user_choice = block_dices[2];
    break;
  case REROLL:
	game_state->team[p->get_team()]->set_reroll_used(true);
    draw_all(true);
    goto block_player_begininig;
    break;
  }
   
  draw_all(true);

  game_state->x_push = other->get_square()->get_x() - p->get_square()->get_x();
  game_state->y_push = other->get_square()->get_y() - p->get_square()->get_y();

  if(game_state->target) game_state->target->set_xy(other->get_square()->get_x(),other->get_square()->get_y() );
  else game_state->target = new Square(other->get_square()->get_x(),other->get_square()->get_y() );

  switch(user_choice){
  case SKULL_AND_STAR: 
    DEBUG( printf("crane + etoile\n"); );
    // tous plaque si non blocage
	////////////////////////////////////////////////
	// Ragnar Modif3 : pilling on
	// De plus on change l'ordre pour d'abord meuler le défenseur
	game_state->is_a_skull_and_star = true;
    if(!other->has_got_skill(BLOCK)) tackle_player(other,p,0,0, true); // other se fait taper par p
    if (p->is_pilling_on_used()){
		p->set_status(GROUND);
		if(p->has_got_ball()){
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->bounce();
			game_state->ball->set_has_bounced(true);
			verify_ball_placement();
		}
		
		/////////////////////////////////////////////
		// Ragnar Modif4 : son action se termine là !
		p->set_has_played(true);
		/////////////////////////////////////////////
		
		draw_all(true);
	}
	if(!p->has_got_skill(BLOCK)) tackle_player(p,other,0,0, true); // p se fait taper par other 
    ////////////////////////////////////////////////

    delete game_state->target;
	game_state->target = NULL;
    game_state->current_action = ACTIONS_NONE;
    break;
  case SKULL:
    DEBUG( printf("crane\n"); );
    // attaquant plaque
    tackle_player(p,other,0,0, true);
    delete game_state->target;
	game_state->target = NULL;
    game_state->current_action = ACTIONS_NONE;
    break;
  case STAR_IF:
    DEBUG( printf("etoile + i\n"); );
    // repousse et plaque si pas esquive + poursuite
    if( other->has_got_skill(DODGE) && !p->has_got_skill(TACKLE) ) goto case_arrow;
    else goto case_star ;
    break;
  case ARROW_1:
  case ARROW_2:
  case_arrow:
  DEBUG( printf("fleche\n"); );
  // choix de la case de repoussage

  //////////////////////////////////
  // Ragnar Modif3 : stand firm
  if (other->has_got_skill(STAND_FIRM)){
	  if(game_state->dices_roll) console->print("Skill Stand Firm : defensor is not pushed");
	  dialog_box->open_info_i(screen,ICONS_INFO,MSG_SKILL_STAND_FIRM_PUSH,false,game_state->team[p->get_team()]->get_name(),other->get_number());
	  draw_all(true);
	  if(other->has_got_ball() && p->has_got_skill(STRIP_BALL) && !other->has_got_skill(SURE_HANDS)) {
		  if(game_state->dices_roll) console->print("Skill Strip ball : defensor looses the ball");		
		  other->set_has_ball(false);
		  game_state->old_ball_owner_team = other->get_team();
	      game_state->ball->bounce();
		  /////////////////////////////////////////
		  // Ragnar Modif3 : le ballon doit rebondir
		  //game_state->ball->set_has_bounced(true);
		  /////////////////////////////////////////
		  verify_ball_placement();
	  }
	  delete game_state->target;
	  game_state->target = NULL;
	  game_state->current_action = ACTIONS_NONE;
	  break;
  }
  //////////////////////////////////

  game_state->direct_push = true;

  update_push_squares(game_state->direct_push);

  if(game_state->push_square_count==0) {
    bool push_in_touch = check_if_can_push_in_touch();

    if( !push_in_touch ) {
      game_state->direct_push = false;
      update_push_squares(game_state->direct_push);
    }
    if(push_in_touch || game_state->push_square_count==0){
      // pas de case libre, ni de case occupe donc c'est direct en touche
      
	  if(game_state->push_square) game_state->push_square->set_xy(other->get_square()->get_x()+game_state->x_push,other->get_square()->get_y()+game_state->y_push);
      else game_state->push_square = new Square(other->get_square()->get_x()+game_state->x_push,other->get_square()->get_y()+game_state->y_push);
      switch_action(ACTIONS_PUSH_PLAYER_OUT);
    }
    else {
      // il n'y a pas de case vide alors je vais faire chier tlm autour
      game_state->current_action = ACTIONS_CHOOSE_PUSH_SQUARE;
    }
  }
  else {
    // ok, il y a une case vide alors je peux pousser
    game_state->current_action = ACTIONS_CHOOSE_PUSH_SQUARE;
  }
 
  break;
  
  case STAR:
  case_star:
  DEBUG( printf("etoile\n"); );

  //////////////////////////////////
  // Ragnar Modif3 : stand firm
  if (other->has_got_skill(STAND_FIRM)){
	  if(game_state->dices_roll) console->print("Skill Stand Firm : defensor is not pushed");
	  dialog_box->open_info_i(screen,ICONS_INFO,MSG_SKILL_STAND_FIRM_PUSH,false,game_state->team[p->get_team()]->get_name(),other->get_number());
	  draw_all(true);
	  tackle_player(other,p,0,0, true); // other se fait taper par p
	  
	  if (p->is_pilling_on_used()){
		p->set_status(GROUND);
		if(p->has_got_ball()){
			p->set_has_ball(false);
			game_state->old_ball_owner_team = p->get_team();
			game_state->ball->bounce();
			game_state->ball->set_has_bounced(true);
			verify_ball_placement();
		}
		
		/////////////////////////////////////////////
		// Ragnar Modif4 : son action se termine là !
		p->set_has_played(true);
		/////////////////////////////////////////////
		
		draw_all(true);
	  }
	  delete game_state->target;
	  game_state->target = NULL;
      game_state->current_action = ACTIONS_NONE;
	  break;
  }
  //////////////////////////////////

  // choix de la case de repoussage
  game_state->direct_push = true;
  update_push_squares(game_state->direct_push);
  if(game_state->push_square_count==0) {
    bool push_in_touch = check_if_can_push_in_touch();
    if( !push_in_touch ) {
      game_state->direct_push = false;
      update_push_squares(game_state->direct_push);
    }
    if(push_in_touch || game_state->push_square_count==0){
      // pas de case libre, ni de case occupe donc c'est direct en touche

	  if(game_state->push_square) game_state->push_square->set_xy(other->get_square()->get_x()+game_state->x_push,other->get_square()->get_y()+game_state->y_push);
      else game_state->push_square = new Square(other->get_square()->get_x()+game_state->x_push,other->get_square()->get_y()+game_state->y_push);
 
      switch_action(ACTIONS_PUSH_PLAYER_OUT);
	  }
    else {
      // il n'y a pas de case vide alors je vais faire chier tlm autour
      game_state->current_action = ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE; 
    }
  }
  else {
    // ok, il y a une case vide alors je peux pousser
    game_state->current_action = ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE; 
  }
  
  break;
  }

  if(touchdown()) return; // why not ?! 

}

bool check_if_can_push_in_touch(){
  
  // repoussage de bas a haut ou inversement
  if(game_state->x_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->target->get_x()+i;
      int p_y = game_state->target->get_y()+game_state->y_push;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)){
	return true;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->target->get_x()+game_state->x_push;
      int p_y = game_state->target->get_y()+i;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)){
	return true;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_push!=0 && game_state->y_push!=0){
    if(!SQUARE_OVER_PLAYGROUND(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()+game_state->y_push)) {
      return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->target->get_x()+game_state->x_push,game_state->target->get_y())) {
      return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->target->get_x(),game_state->target->get_y()+game_state->y_push)) {
      return true;
    }
  }
  return false;
}

bool check_if_can_indirect_push_in_touch(){
 
  // repoussage de bas a haut ou inversement
  if(game_state->x_indirect_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->push_square->get_x()+i;
      int p_y = game_state->push_square->get_y()+game_state->y_indirect_push;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)) {
	return true;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_indirect_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->push_square->get_x()+game_state->x_indirect_push;
      int p_y = game_state->push_square->get_y()+i;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)) {
	return true;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_indirect_push!=0 && game_state->y_indirect_push!=0){
    if(!SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push) ) {
      return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()) ) {
     return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x(),game_state->push_square->get_y()+game_state->y_indirect_push) ) {
     return true;
    }
  }
  return false;
}

bool check_if_can_double_indirect_push_in_touch(){
 
  // repoussage de bas a haut ou inversement
  if(game_state->x_double_indirect_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->indirect_push_square->get_x()+i;
      int p_y = game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)) {
		return true;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_double_indirect_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push;
      int p_y = game_state->indirect_push_square->get_y()+i;
      if(!SQUARE_OVER_PLAYGROUND(p_x,p_y)) {
		return true;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_double_indirect_push!=0 && game_state->y_double_indirect_push!=0){
    if(!SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push) ) {
      return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()) ) {
     return true;
    }
    if(!SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push) ) {
     return true;
    }
  }
  return false;
}


void update_push_squares(bool direct){
  game_state->push_square_count = 0;
  

  ///////////////////////////////////////////
  // Ragnar Modif3 : repoussage avec side step
  if(direct && Shared::get_playground(game_state->target->get_x(),game_state->target->get_y())->has_got_skill(SIDE_STEP_SKILL)) {
    //if (game_state->dices_roll) console->print("Defensor chooses push square (side step)"); 
	dialog_box->open_info(screen,ICONS_INFO,MSG_SKILL_SIDE_STEP,false,game_state->team[Shared::get_playground(game_state->target->get_x(),game_state->target->get_y())->get_team()]->get_name());
	draw_all(true);
	int i,j;
	for(i=-1;i<=1;i++){
		for(j=-1;j<=1;j++){
      int p_x = game_state->target->get_x()+i;
      int p_y = game_state->target->get_y()+j;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && !Shared::get_playground(p_x,p_y)) {
		game_state->push_squares[game_state->push_square_count] = new Square(p_x,p_y);
		game_state->push_square_count++;
      }
		}
	}
	return;
  }
  ///////////////////////////////////////////

  // repoussage de bas a haut ou inversement
  if(game_state->x_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->target->get_x()+i;
      int p_y = game_state->target->get_y()+game_state->y_push;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && ( !direct || !Shared::get_playground(p_x,p_y) )) {
		if(game_state->push_squares[game_state->push_square_count]) game_state->push_squares[game_state->push_square_count]->set_xy(p_x,p_y);
		else game_state->push_squares[game_state->push_square_count] = new Square(p_x,p_y);
		game_state->push_square_count++;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->target->get_x()+game_state->x_push;
      int p_y = game_state->target->get_y()+i;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && (!direct || !Shared::get_playground(p_x,p_y))){
		  if(game_state->push_squares[game_state->push_square_count]) game_state->push_squares[game_state->push_square_count]->set_xy(p_x,p_y);
		  else game_state->push_squares[game_state->push_square_count] = new Square(p_x,p_y);
		  game_state->push_square_count++;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_push!=0 && game_state->y_push!=0){
    if(SQUARE_OVER_PLAYGROUND(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()+game_state->y_push) && (!direct || !Shared::get_playground(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()+game_state->y_push)) ) {
      if( game_state->push_squares[game_state->push_square_count]) game_state->push_squares[game_state->push_square_count]->set_xy(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()+game_state->y_push);
	  else game_state->push_squares[game_state->push_square_count] = new Square(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()+game_state->y_push);
      game_state->push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->target->get_x()+game_state->x_push,game_state->target->get_y()) && (!direct || !Shared::get_playground(game_state->target->get_x()+game_state->x_push,game_state->target->get_y())) ) {
      if(game_state->push_squares[game_state->push_square_count]) game_state->push_squares[game_state->push_square_count]->set_xy(game_state->target->get_x()+game_state->x_push,game_state->target->get_y());
	  else game_state->push_squares[game_state->push_square_count] = new Square(game_state->target->get_x()+game_state->x_push,game_state->target->get_y());
      game_state->push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->target->get_x(),game_state->target->get_y()+game_state->y_push) && (!direct || !Shared::get_playground(game_state->target->get_x(),game_state->target->get_y()+game_state->y_push)) ) {
      if( game_state->push_squares[game_state->push_square_count]) game_state->push_squares[game_state->push_square_count]->set_xy(game_state->target->get_x(),game_state->target->get_y()+game_state->y_push);
	  else game_state->push_squares[game_state->push_square_count] = new Square(game_state->target->get_x(),game_state->target->get_y()+game_state->y_push);
      game_state->push_square_count++;
    }
  }
}

void update_indirect_push_squares(bool direct){
  
  game_state->indirect_push_square_count = 0;
  
  // repoussage de bas a haut ou inversement
  if(game_state->x_indirect_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->push_square->get_x()+i;
      int p_y = game_state->push_square->get_y()+game_state->y_indirect_push;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && ( !direct || !Shared::get_playground(p_x,p_y) )) {
		if(game_state->indirect_push_squares[game_state->indirect_push_square_count]) game_state->indirect_push_squares[game_state->indirect_push_square_count]->set_xy(p_x,p_y);
		else game_state->indirect_push_squares[game_state->indirect_push_square_count] = new Square(p_x,p_y);
		game_state->indirect_push_square_count++;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_indirect_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->push_square->get_x()+game_state->x_indirect_push;
      int p_y = game_state->push_square->get_y()+i;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && (!direct || !Shared::get_playground(p_x,p_y))){
		if(game_state->indirect_push_squares[game_state->indirect_push_square_count]) game_state->indirect_push_squares[game_state->indirect_push_square_count]->set_xy(p_x,p_y);
		else game_state->indirect_push_squares[game_state->indirect_push_square_count] = new Square(p_x,p_y);
		game_state->indirect_push_square_count++;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_indirect_push!=0 && game_state->y_indirect_push!=0){
    if(SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push) && (!direct || !Shared::get_playground(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push)) ) {
      if(game_state->indirect_push_squares[game_state->indirect_push_square_count]) game_state->indirect_push_squares[game_state->indirect_push_square_count]->set_xy(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
	  else game_state->indirect_push_squares[game_state->indirect_push_square_count] = new Square(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()+game_state->y_indirect_push);
      game_state->indirect_push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y()) && (!direct || !Shared::get_playground(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y())) ) {
      if(game_state->indirect_push_squares[game_state->indirect_push_square_count]) game_state->indirect_push_squares[game_state->indirect_push_square_count]->set_xy(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y());
	  else game_state->indirect_push_squares[game_state->indirect_push_square_count] = new Square(game_state->push_square->get_x()+game_state->x_indirect_push,game_state->push_square->get_y());
      game_state->indirect_push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->push_square->get_x(),game_state->push_square->get_y()+game_state->y_indirect_push) && (!direct || !Shared::get_playground(game_state->push_square->get_x(),game_state->push_square->get_y()+game_state->y_indirect_push)) ) {
      if(game_state->indirect_push_squares[game_state->indirect_push_square_count]) game_state->indirect_push_squares[game_state->indirect_push_square_count]->set_xy(game_state->push_square->get_x(),game_state->push_square->get_y()+game_state->y_indirect_push);
	  else game_state->indirect_push_squares[game_state->indirect_push_square_count] = new Square(game_state->push_square->get_x(),game_state->push_square->get_y()+game_state->y_indirect_push);
      game_state->indirect_push_square_count++;
    }
  }

}

void update_double_indirect_push_squares(bool direct){
  game_state->double_indirect_push_square_count = 0;
  
  // repoussage de bas a haut ou inversement
  if(game_state->x_double_indirect_push==0) {
    for(int i=-1;i<=1;i++){
      int p_x = game_state->indirect_push_square->get_x()+i;
      int p_y = game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && ( !direct || !Shared::get_playground(p_x,p_y) )) {
		if(game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]) game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]->set_xy(p_x,p_y);
		else game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count] = new Square(p_x,p_y);
		game_state->double_indirect_push_square_count++;
      }
    }
  }
  // repoussage de gauche a droite ou inversement
  if(game_state->y_double_indirect_push==0){
    for(int i=-1;i<=1;i++){
      int p_x = game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push;
      int p_y = game_state->indirect_push_square->get_y()+i;
      if(SQUARE_OVER_PLAYGROUND(p_x,p_y) && (!direct || !Shared::get_playground(p_x,p_y))){
		if(game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]) game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]->set_xy(p_x,p_y);
		else game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count] = new Square(p_x,p_y);
		game_state->double_indirect_push_square_count++;
      }
    }
  }
  
  // repoussage en diagonale
  if(game_state->x_double_indirect_push!=0 && game_state->y_double_indirect_push!=0){
    if(SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push) && (!direct || !Shared::get_playground(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push)) ) {
      if(game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]) game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]->set_xy(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
	  else game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count] = new Square(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
      game_state->double_indirect_push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y()) && (!direct || !Shared::get_playground(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y())) ) {
      if(game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]) game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]->set_xy(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y());
	  else game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count] = new Square(game_state->indirect_push_square->get_x()+game_state->x_double_indirect_push,game_state->indirect_push_square->get_y());
      game_state->double_indirect_push_square_count++;
    }
    if(SQUARE_OVER_PLAYGROUND(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push) && (!direct || !Shared::get_playground(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push)) ) {
      if(game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]) game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count]->set_xy(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
	  else game_state->double_indirect_push_squares[game_state->double_indirect_push_square_count] = new Square(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y()+game_state->y_double_indirect_push);
      game_state->double_indirect_push_square_count++;
    }
  }

}

void move_playground(int direction, int step){
  int x = pg->x;
  int y = pg->y;
  
  switch(direction){
  case N: y+=step; break;
  case S: y-=step; break;
  case E: x-=step; break;
  case W: x+=step; break;
  }
  
  if ( x > 0 ) {
    x = 0;
    slide_playground = NONE;
  }
  else if ( x < (-pg->image->w+FRAME_LIMIT) ) {
    x = -pg->image->w + FRAME_LIMIT;
    slide_playground = NONE;
  }
  if ( y > 0 ) {
    y = 0;
    slide_playground = NONE;
  }
  else if ( y < (-pg->image->h+Config::get_screen_h()) ) {
    y = -pg->image->h + Config::get_screen_h();
    slide_playground = NONE;
  }
  
  if(game_state->current_mode==MODE_TEAM_PLACEMENT){
	int x_d = game_state->x_dock + (pg->x-x);
	int y_d = game_state->y_dock + (pg->y-y);
    if ( x_d < 0 ) x_d = 0;
	else if ( x_d > (pg->image->w-DOCK_W) ) x_d = pg->image->w-DOCK_W;
	if ( y_d < 0 ) y_d = 0;
	else if ( game_state->y_dock > (pg->image->h-DOCK_H) ) y_d = pg->image->h-DOCK_H;
  	
	game_state->x_dock = x_d;
	game_state->y_dock = y_d;
  }
  
  set_object_position(pg,x,y);

  pg_cliprect.x = 0;
  pg_cliprect.y = 0;
  pg_cliprect.w = pg->image->w;
  pg_cliprect.h = pg->image->h;
}

void toggle_zoom_playground(bool b){
  game_state->zoom_mode = b;

  pg_cliprect.x = 0;
  pg_cliprect.y = 0;
  pg_cliprect.w = pg->image->w;
  pg_cliprect.h = pg->image->h;
  
  game_state->freeze_interaction = game_state->zoom_mode; 

  DEBUG( printf("zoom mode = %d\n", game_state->zoom_mode); ); 
}

void toggle_autocenter_mode(){
  game_state->autocenter_mode = !game_state->autocenter_mode;
  DEBUG( printf("autocenter mode = %d\n", game_state->autocenter_mode); ); 
}

void kick_off(Square *sq){
	  
	if(!sq && game_state->ball->get_square()){
		if( game_state->target) game_state->target->set_xy(game_state->ball->get_square()->get_x(),game_state->ball->get_square()->get_y());
		else game_state->target = new Square(game_state->ball->get_square()->get_x(),game_state->ball->get_square()->get_y());
		sq = game_state->target;
	}

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_KICKOFF, FX0_CHANNEL);
	}
#endif

  int distance = game_state->team[game_state->kick_off_team]->get_kick_off_distance();

    /////////////////////////////////////////////
  // Ragnar Modif3 : skill kick
  if(game_state->team[game_state->kick_off_team]->can_use_kick_skill()){
	  dialog_box->open_info(screen,ICONS_INFO,MSG_SKILL_KICK,false, "");
	  draw_all(true);
	  distance = (int) (distance / 2);
  }
  /////////////////////////////////////////////

  int direction = game_state->team[game_state->kick_off_team]->get_kick_off_direction();
  
  if(game_state->dices_roll) console->print("Kick off : distance = %i, direction = %i", distance, direction);
  
  int x_diff=0, y_diff=0;
  SDL_Rect b_tmp;
  
  b_tmp.x = SQUARE_TO_PIXEL(sq->get_x());
  b_tmp.y = SQUARE_TO_PIXEL(sq->get_y());
  b_tmp.w = SQUARE_SIZE;
  b_tmp.h = SQUARE_SIZE;
  pg_cliprect = rect_union(b_tmp,pg_cliprect);
  draw_all(false);

  switch(direction){
  case N: x_diff = 0; y_diff = -1;break; 
  case S: x_diff = 0; y_diff = 1;break; 
  case E: x_diff = 1; y_diff = 0;break; 
  case W: x_diff = -1; y_diff = 0;break; 
  case NE: x_diff = 1; y_diff = -1;break; 
  case NW: x_diff = -1; y_diff = -1;break; 
  case SE: x_diff = 1; y_diff = 1;break; 
  case SW: x_diff = -1; y_diff = 1;break;
  }
  
  game_state->target_anim = true;

  for(int i=0;i<distance;i++){
    b_tmp.x = SQUARE_TO_PIXEL(sq->get_x());
    b_tmp.y = SQUARE_TO_PIXEL(sq->get_y());
    b_tmp.w = SQUARE_SIZE;
    b_tmp.h = SQUARE_SIZE;
    pg_cliprect = rect_union(b_tmp,pg_cliprect);
    sq->move(x_diff,y_diff);
	b_tmp.x = SQUARE_TO_PIXEL(sq->get_x());
    b_tmp.y = SQUARE_TO_PIXEL(sq->get_y());
    b_tmp.w = SQUARE_SIZE;
    b_tmp.h = SQUARE_SIZE;
    pg_cliprect = rect_union(b_tmp,pg_cliprect);
    draw_all(false);
  }

  game_state->target_anim = false;

  draw_kick_off_anim(sq);
  int x_ball = game_state->ball->get_square()->get_x();
  int y_ball = game_state->ball->get_square()->get_y();

	//SOUND - TALID - BETTER GAME PLAY IF SET (Must remove in very_ball_placement sound)
	//#ifndef NOSOUND
	//	if(Config::is_sound_enabled()){
	//		sp->play_sound(SND_DROP, FX0_CHANNEL);
	//	}
	//#endif


  autocenter(x_ball, y_ball);

  delete game_state->target;
  game_state->target = NULL;

  if(x_ball >=0 && x_ball < PLAYGROUND_WIDTH && ( (game_state->kick_off_team==VISITOR && y_ball>=0 && y_ball<PLAYGROUND_HEIGHT/2) || ( game_state->kick_off_team==HOME && y_ball>=PLAYGROUND_HEIGHT/2 && y_ball<PLAYGROUND_HEIGHT ) ) ){
    if( !Shared::get_playground(x_ball,y_ball) ){      
      b_tmp.x = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_x());
      b_tmp.y = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_y());
      b_tmp.w = SQUARE_SIZE;
      b_tmp.h = SQUARE_SIZE;
      pg_cliprect = rect_union(b_tmp,pg_cliprect);
      game_state->ball->bounce();
	  game_state->ball->set_has_bounced(true);
      b_tmp.x = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_x());
      b_tmp.y = SQUARE_TO_PIXEL(game_state->ball->get_square()->get_y());
      b_tmp.w = SQUARE_SIZE;
      b_tmp.h = SQUARE_SIZE;
      pg_cliprect = rect_union(b_tmp,pg_cliprect);
      draw_all(false);
      x_ball = game_state->ball->get_square()->get_x();
      y_ball = game_state->ball->get_square()->get_y();
      
	  if(x_ball >=0 && x_ball < PLAYGROUND_WIDTH && ( (game_state->kick_off_team==VISITOR && y_ball>=0 && y_ball<PLAYGROUND_HEIGHT/2) || ( game_state->kick_off_team==HOME && y_ball>=PLAYGROUND_HEIGHT/2 && y_ball<PLAYGROUND_HEIGHT ) ) ){
		  game_state->active_team = 1 - game_state->kick_off_team;
		  game_state->ball->set_visible(true);
		  verify_ball_placement();
		  game_state->active_team = NONE;
		  switch_mode(MODE_PLAYING);
	  }
	  else {

#ifndef NOSOUND
		if(Config::is_sound_enabled()){	
			sp->play_sound(SND_WHISTLE, FX0_CHANNEL);
		}
#endif

		  switch_mode(MODE_CHOOSE_BALL_OWNER);
	  }
    }
    else { 
		game_state->active_team = 1 - game_state->kick_off_team;
		game_state->ball->set_visible(true);
		verify_ball_placement();
		game_state->active_team = NONE;
		switch_mode(MODE_PLAYING);
	}
  }
  else {

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_WHISTLE, FX0_CHANNEL);
	}
#endif

    switch_mode(MODE_CHOOSE_BALL_OWNER);
  }

}

void toss(){
  draw_all(true);

  switch(dialog_box->open_toss(screen,game_state->team[HOME]->get_name(),game_state->team[VISITOR]->get_name())){
  case HOME_KICK:
    game_state->kick_off_team = HOME;
    break;
  case VISITOR_KICK:
    game_state->kick_off_team = VISITOR;
    break;
  }

  game_state->first_half_kick_off_team = game_state->kick_off_team;

  draw_all(true);
 
  switch_mode(MODE_NONE); 
}

void toggle_pause(bool p){
  if(game_state->current_mode!=MODE_PLAYING) return;
  
  game_state->pause = p;
  
  if(game_state->pause){
    game_state->pause_begining_time = SDL_GetTicks();
	draw_all(true);
  }
  else {
    game_state->turn_begining_time += (SDL_GetTicks()-game_state->pause_begining_time);
    draw_all(true);
  }
}

int main_loop(){

  bool done=false;
  int x_mouse=0,y_mouse=0,x_square=0,y_square=0;
  bool menu_allowed = true;
  bool movement_completed;
  Player *p;
 
  game_state->t0 = SDL_GetTicks(); 

  while(!done){

    handle_time();

#ifndef NONET
	if(net) handle_network_msg();
#endif

    if(!game_state->pause){
      if(slide_playground!=NONE && focus_on_game ) move_playground(slide_playground,SIDE_STEP);
      draw_all(false);
    }
    else SDL_Delay(PAUSE_DELAY);

    while(SDL_PollEvent(&event)) {
      
	  if( game_state->pause || dialog_box->is_visible() || screens->is_visible()) break;
      
	  if( (console->get_focus()) && (event.type==SDL_KEYDOWN) ){
		int console_y = console->get_y();
		console->handle_event(&event);
		update_console = true;
		if( console->get_y() != console_y ) draw_all(true);
		continue;
	  }

      switch (event.type) {
      case SDL_KEYDOWN:
	switch(event.key.keysym.sym){
	case SDLK_t: if(!game_state->freeze_interaction) toggle_tackle_zone_drawing_mode();
	  break;
	case SDLK_UP: if(!game_state->freeze_interaction) move_playground(N,KEY_STEP);
	  break;
	case SDLK_DOWN: if(!game_state->freeze_interaction) move_playground(S,KEY_STEP);
	  break;
	case SDLK_LEFT: if(!game_state->freeze_interaction) move_playground(W,KEY_STEP);
	  break;
	case SDLK_RIGHT: if(!game_state->freeze_interaction) move_playground(E,KEY_STEP);
	  break;
	case SDLK_w:
	case SDLK_z: toggle_zoom_playground(!game_state->zoom_mode);
	  break;
	case SDLK_n: if(!game_state->freeze_interaction) toggle_number_drawing_mode();
	  break;
	case SDLK_s: if(!game_state->freeze_interaction) toggle_ticks_drawing_mode();
	  break;
	case SDLK_q:
	case SDLK_i: if(!game_state->freeze_interaction) toggle_contextual_info_mode();
		break;
	case SDLK_a: if(!game_state->freeze_interaction) toggle_autocenter_mode();
	  break;
	case SDLK_r: draw_all(true); // refresh screen si merdes a l'affichage
	  break;
	default:
	  break;
	}
	break;
      case SDL_MOUSEBUTTONDOWN:
	DEBUG( printf("Bouton souris appuye %d\n",event.button.button); );

	if(game_state->freeze_interaction) break;

	x_mouse = event.button.x - pg->x - MARGIN_SIZE;
	y_mouse = event.button.y - pg->y - MARGIN_SIZE;
	x_square = x_mouse/SQUARE_SIZE;
	y_square = y_mouse/SQUARE_SIZE;
	
	if(game_state->selection && Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y()) ) 
		p = Shared::get_playground(game_state->selection->get_x(),game_state->selection->get_y());
	else 
		p = NULL;

	switch(event.button.button){
	case LEFT_BUTTON: 
	  // clic gauche
	  
	  switch(game_state->current_mode){
	  case MODE_SURPRISE:
	    if (OVER_PLAYGROUND(x_mouse,y_mouse) && event.button.x<(FRAME_LIMIT-FRAME_LINE)) {
	      if(game_state->target && game_state->selected_player){
		SDL_Rect tmp;
		tmp.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
		tmp.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
		tmp.w = SQUARE_SIZE;
		tmp.h = SQUARE_SIZE;
		pg_cliprect = rect_union(pg_cliprect,tmp);
		
		game_state->selected_player->place(game_state->target->get_x(),game_state->target->get_y());
		game_state->selected_player->set_has_played(true);
		
		tmp.x = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_x());
		tmp.y = SQUARE_TO_PIXEL(game_state->selected_player->get_square()->get_y());
		tmp.w = SQUARE_SIZE;
		tmp.h = SQUARE_SIZE;
		pg_cliprect = rect_union(pg_cliprect,tmp);
		game_state->selected_player = NULL;
		erase_panel_player_info();
		delete game_state->target;
		game_state->target = NULL;
	      }
	      else if( Shared::get_playground(x_square,y_square) && !Shared::get_playground(x_square,y_square)->has_played() && game_state->team_in_placement==Shared::get_playground(x_square,y_square)->get_team() ){
			select_square(x_square,y_square);
			delete game_state->target;
			game_state->target = NULL;
	      }
	      else if( !Shared::get_playground(x_square,y_square) || (Shared::get_playground(x_square,y_square)&&game_state->team_in_placement!=Shared::get_playground(x_square,y_square)->get_team())){
			if(game_state->target) game_state->target->set_xy(x_square, y_square); 
			else game_state->target = new Square(x_square, y_square); 
			game_state->selected_player = NULL;
			erase_panel_player_info();
			if(game_state->autocenter_mode) autocenter(x_square,y_square);
			delete game_state->target;
			game_state->target = NULL;
	      }
	    }
	    
	    if( OVER_PANEL(event.button.x,event.button.y) ){
	      if( PANEL_CLIC_INTO_RECT(PANEL_HOME_TURN_INDIC_X,
				       PANEL_HOME_TURN_INDIC_Y,
				       PANEL_TURN_INDIC_WIDTH,
				       PANEL_TURN_INDIC_HEIGHT) ){
			  if(game_state->team_in_placement==HOME) {
				  game_state->current_mode = MODE_BALL_PLACEMENT;
				  kick_off(game_state->target);
			  } 
	      }
	      else if( PANEL_CLIC_INTO_RECT(PANEL_VISITOR_TURN_INDIC_X,
					    PANEL_VISITOR_TURN_INDIC_Y,
					    PANEL_TURN_INDIC_WIDTH,
					    PANEL_TURN_INDIC_HEIGHT) ){
			  if(game_state->team_in_placement==VISITOR) {
				  game_state->current_mode = MODE_BALL_PLACEMENT;
				  kick_off(game_state->target); 
			  }
	      }
	    }
	    
	    break;
	  case MODE_CHOOSE_BALL_OWNER:
	    if (OVER_PLAYGROUND(x_mouse,y_mouse) && game_state->target ){
	      game_state->ball->set_visible(false);
	      game_state->ball->place(game_state->target);
	      Shared::get_playground(game_state->target->get_x(),game_state->target->get_y())->set_has_ball(true);
	      delete game_state->target;
		  game_state->target = NULL;
	      switch_mode(MODE_PLAYING);
	    }
	    break;
	  case MODE_BALL_PLACEMENT:
	    if (OVER_PLAYGROUND(x_mouse,y_mouse) && game_state->target ){
			game_state->ball->place(game_state->target->get_x(),game_state->target->get_y());
			handle_kick_off_event();
	    }
	    break;
	  case MODE_NONE:
	    if (!OVER_PLAYGROUND(x_mouse,y_mouse) && event.button.x<(FRAME_LIMIT-FRAME_LINE) ){
	      for(int i=HOME; i<=VISITOR; i++){
		for(int j=0;j<=1;j++){
		  if( REL_CLIC_OVER_RECT(reserve_nav[i][j]->x,
					 reserve_nav[i][j]->y,
					 reserve_nav[i][j]->image->w,
					 reserve_nav[i][j]->image->h) ){
		    (j==0)?(game_state->reserve_page[i]--):(game_state->reserve_page[i]++);
		    pg_cliprect.x = game_state->x_dock;
		    pg_cliprect.y = game_state->y_dock;
		    pg_cliprect.w = DOCK_W;
		    pg_cliprect.h = DOCK_H;
		  }
		}
	      }
	    }
	    
	    if( OVER_PANEL(event.button.x,event.button.y) ){
	      if( PANEL_CLIC_INTO_RECT(PANEL_HOME_TURN_INDIC_X,
				       PANEL_HOME_TURN_INDIC_Y,
				       PANEL_TURN_INDIC_WIDTH,
				       PANEL_TURN_INDIC_HEIGHT) ){
		if(game_state->kick_off_team==HOME) start_placement(HOME);
	      }
	      else if( PANEL_CLIC_INTO_RECT(PANEL_VISITOR_TURN_INDIC_X,
					    PANEL_VISITOR_TURN_INDIC_Y,
					    PANEL_TURN_INDIC_WIDTH,
					    PANEL_TURN_INDIC_HEIGHT) ){
		if(game_state->kick_off_team==VISITOR) start_placement(VISITOR);
	      }
	      else if( PANEL_CLIC_INTO_RECT(PANEL_URL_X,
					    PANEL_URL_Y,
					    PANEL_URL_WIDTH,
					    PANEL_URL_HEIGHT) ){
		draw_all(true);
		dialog_box->open_info(screen,ICONS_SMILEY,MSG_GO_TO_WEB,false,"");
		draw_all(true);
	      }
	    }
	    
	    if(OVER_HOME_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) && event.button.x<(FRAME_LIMIT-FRAME_LINE) ) {
			
		  int x_r = (x_mouse-game_state->x_dock-HOME_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[HOME]*2;
	      int y_r = (y_mouse-game_state->y_dock-HOME_RESERVE_BOX_Y)/SQUARE_SIZE;
	      
		  if(Shared::get_reserve_box(HOME,y_r,x_r)){
			fill_panel_player_info(Shared::get_reserve_box(HOME,y_r,x_r));
		  } 
	      else {
			erase_panel_player_info();
	      }
	    }
	    else if(OVER_VISITOR_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) &&  event.button.x<(FRAME_LIMIT-FRAME_LINE)) {
	      int x_r = (x_mouse-game_state->x_dock-VISITOR_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[VISITOR]*2;
	      int y_r = (y_mouse-game_state->y_dock-VISITOR_RESERVE_BOX_Y)/SQUARE_SIZE;
	      if(Shared::get_reserve_box(VISITOR,y_r,x_r)){
			fill_panel_player_info(Shared::get_reserve_box(VISITOR,y_r,x_r));
	      } 
	      else {
			erase_panel_player_info();
	      }
	    }
	    
	    break;
	  case MODE_TEAM_PLACEMENT:
	    if(REL_CLIC_OVER_RECT(game_state->x_dock,game_state->y_dock+RESERVE_BOX_H+HOME_RESERVE_BOX_Y,DOCK_W,RESERVE_BOX_H/3) && event.button.x<(FRAME_LIMIT-FRAME_LINE)){
		  game_state->drag_dock = true;
		  SDL_Rect r_tmp;
		  r_tmp.x = game_state->x_dock;
		  r_tmp.y = game_state->y_dock;
		  r_tmp.w = DOCK_W;
		  r_tmp.h = DOCK_H;
		  pg_cliprect = rect_union(r_tmp,pg_cliprect);
	      break;
	    }

		int i;
	    for(i=HOME; i<=VISITOR; i++){
	      for(int j=0;j<=1;j++){
		if( REL_CLIC_OVER_RECT(reserve_nav[i][j]->x,
				       reserve_nav[i][j]->y,
				       reserve_nav[i][j]->image->w,
				       reserve_nav[i][j]->image->h) ){
		  (j==0)?(game_state->reserve_page[i]--):(game_state->reserve_page[i]++);
		  pg_cliprect.x = game_state->x_dock;
		  pg_cliprect.y = game_state->y_dock;
		  pg_cliprect.w = DOCK_W;
		  pg_cliprect.h = DOCK_H;
		}
	      }
	    }
	    
	    if( OVER_PANEL(event.button.x,event.button.y) ){
	      if( PANEL_CLIC_INTO_RECT(PANEL_HOME_TURN_INDIC_X,
				       PANEL_HOME_TURN_INDIC_Y,
				       PANEL_TURN_INDIC_WIDTH,
				       PANEL_TURN_INDIC_HEIGHT) && !game_state->player_to_place){
			if(game_state->team_in_placement==HOME && is_good_formation(HOME) ) stop_placement();
			else if(game_state->team_in_placement==NONE && game_state->kick_off_team==VISITOR) start_placement(HOME);
		  }
	      else if( PANEL_CLIC_INTO_RECT(PANEL_VISITOR_TURN_INDIC_X,
					    PANEL_VISITOR_TURN_INDIC_Y,
					    PANEL_TURN_INDIC_WIDTH,
					    PANEL_TURN_INDIC_HEIGHT) && !game_state->player_to_place){
			if(game_state->team_in_placement==VISITOR && is_good_formation(VISITOR)) stop_placement();
			else if(game_state->team_in_placement==NONE && game_state->kick_off_team==HOME) start_placement(VISITOR);
		
		  }
	      else if( PANEL_CLIC_INTO_RECT(PANEL_URL_X,
					    PANEL_URL_Y,
					    PANEL_URL_WIDTH,
					    PANEL_URL_HEIGHT) ){
			draw_all(true);
			dialog_box->open_info(screen,ICONS_SMILEY,MSG_GO_TO_WEB,false,"");
			draw_all(true);
	      }
		
	    }
   
	    if(OVER_PLAYGROUND(x_mouse,y_mouse) && !OVER_DOCK(x_mouse,y_mouse) ) {
	      if(game_state->player_to_place && game_state->location_square){
			game_state->player_to_place->place(game_state->location_square);

		game_state->player_to_place = NULL;
		erase_panel_player_info();
		delete game_state->location_square;
		game_state->location_square = NULL;
		
		pg_cliprect.x = -pg->x;
		pg_cliprect.y = -pg->y;
		pg_cliprect.w = FRAME_LIMIT-FRAME_LINE;
		pg_cliprect.h = Config::get_screen_h();
	      }
	      else if(!game_state->player_to_place && Shared::get_playground(x_square,y_square) && game_state->team_in_placement==Shared::get_playground(x_square,y_square)->get_team() ){
		game_state->player_to_place = Shared::get_playground(x_square,y_square);
		  
		game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		game_state->y_player_clic = y_mouse+MARGIN_SIZE;

		game_state->player_to_place_x = SQUARE_TO_PIXEL(x_square); 
		game_state->player_to_place_y = SQUARE_TO_PIXEL(y_square);
		Shared::set_playground(x_square,y_square, NULL);
		game_state->player_to_place->set_square(NULL);
		game_state->player_to_place->set_reserve_square(NULL);
		fill_panel_player_info(game_state->player_to_place);
	      }
	      else if(!game_state->player_to_place && event.button.x<(FRAME_LIMIT-FRAME_LINE) && !OVER_DOCK(x_mouse,y_mouse) ){
			if(game_state->target) game_state->target->set_xy(x_square, y_square);
			else game_state->target = new Square(x_square, y_square); 
			if(game_state->autocenter_mode) autocenter(x_square,y_square);
	      }
	    }
	    else if(OVER_HOME_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) && game_state->team_in_placement==HOME && event.button.x<(FRAME_LIMIT-FRAME_LINE)  ) {
	      int x_r = (x_mouse-game_state->x_dock-HOME_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[HOME]*2;
	      int y_r = (y_mouse-game_state->y_dock-HOME_RESERVE_BOX_Y)/SQUARE_SIZE;
	      if(game_state->player_to_place && !Shared::get_reserve_box(HOME,y_r,x_r)){
			game_state->player_to_place->place_in_reserve(x_r,y_r);
			game_state->player_to_place = NULL;
			erase_panel_player_info();
			delete game_state->location_square;
			game_state->location_square = NULL;
	      }
	      else if(!game_state->player_to_place && Shared::get_reserve_box(HOME,y_r,x_r)){
		game_state->player_to_place = Shared::get_reserve_box(HOME,y_r,x_r);
		  
		game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		game_state->y_player_clic = y_mouse+MARGIN_SIZE;
		
		Shared::set_reserve_box(HOME,y_r,x_r,NULL);
		game_state->player_to_place_x = game_state->x_dock + HOME_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
		game_state->player_to_place_y = game_state->y_dock + HOME_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
		game_state->player_to_place->set_reserve_square(NULL);
		
		if(game_state->player_to_place){
		  fill_panel_player_info(game_state->player_to_place);
		}
	      }
	      else if(game_state->player_to_place && Shared::get_reserve_box(HOME,y_r,x_r)){
		Player*p_save = game_state->player_to_place;
		game_state->player_to_place = Shared::get_reserve_box(HOME,y_r,x_r);
		
		game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		game_state->y_player_clic = y_mouse+MARGIN_SIZE;
		
		game_state->player_to_place_x = game_state->x_dock + HOME_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
		game_state->player_to_place_y = game_state->y_dock + HOME_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
		Shared::set_reserve_box(HOME,y_r,x_r,NULL);
		game_state->player_to_place->set_square(NULL);
		game_state->player_to_place->set_reserve_square(NULL);
		fill_panel_player_info(game_state->player_to_place);
		p_save->place_in_reserve(x_r,y_r);	
	      }
	      pg_cliprect.x = game_state->x_dock;
	      pg_cliprect.y = game_state->y_dock;
	      pg_cliprect.w = DOCK_W;
	      pg_cliprect.h = DOCK_H;
	    }
	    else if(OVER_VISITOR_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) && game_state->team_in_placement==VISITOR && event.button.x<(FRAME_LIMIT-FRAME_LINE)) {
	      int x_r = (x_mouse-game_state->x_dock-VISITOR_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[VISITOR]*2;
	      int y_r = (y_mouse-game_state->y_dock-VISITOR_RESERVE_BOX_Y)/SQUARE_SIZE;
	      if(game_state->player_to_place && !Shared::get_reserve_box(VISITOR,y_r,x_r)){
			game_state->player_to_place->place_in_reserve(x_r,y_r);
			game_state->player_to_place = NULL;
			erase_panel_player_info();
			delete game_state->location_square;
			game_state->location_square = NULL;
	      }
	      else if(!game_state->player_to_place && Shared::get_reserve_box(VISITOR,y_r,x_r)){
			game_state->player_to_place = Shared::get_reserve_box(VISITOR,y_r,x_r);
			
			game_state->x_player_clic = x_mouse+MARGIN_SIZE;
			game_state->y_player_clic = y_mouse+MARGIN_SIZE;
			
			game_state->player_to_place_x = game_state->x_dock + VISITOR_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
			game_state->player_to_place_y = game_state->y_dock + VISITOR_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
			Shared::set_reserve_box(VISITOR,y_r,x_r,NULL);
			game_state->player_to_place->set_reserve_square(NULL);
			if(game_state->player_to_place){
			  fill_panel_player_info(game_state->player_to_place);
			}
	      }
	      else if(game_state->player_to_place && Shared::get_reserve_box(VISITOR,y_r,x_r)){
		Player*p_save = game_state->player_to_place;
		game_state->player_to_place = Shared::get_reserve_box(VISITOR,y_r,x_r);
		
		game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		game_state->y_player_clic = y_mouse+MARGIN_SIZE;
		
		game_state->player_to_place_x = game_state->x_dock + VISITOR_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
		game_state->player_to_place_y = game_state->y_dock + VISITOR_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
		Shared::set_reserve_box(VISITOR,y_r,x_r,NULL);
		game_state->player_to_place->set_square(NULL);
		game_state->player_to_place->set_reserve_square(NULL);
		fill_panel_player_info(game_state->player_to_place);
		p_save->place_in_reserve(x_r,y_r);	
	      } 
	      pg_cliprect.x = game_state->x_dock;
	      pg_cliprect.y = game_state->y_dock;
	      pg_cliprect.w = DOCK_W;
	      pg_cliprect.h = DOCK_H;
	    }
	    break;
	  case MODE_PLAYING:

	    if (!OVER_PLAYGROUND(x_mouse,y_mouse) && event.button.x<(FRAME_LIMIT-FRAME_LINE) ){
	      for(int i=HOME; i<=VISITOR; i++){
		for(int j=0;j<=1;j++){
		  if( REL_CLIC_OVER_RECT(reserve_nav[i][j]->x,
					 reserve_nav[i][j]->y,
					 reserve_nav[i][j]->image->w,
					 reserve_nav[i][j]->image->h) ){
		    (j==0)?(game_state->reserve_page[i]--):(game_state->reserve_page[i]++);
		    pg_cliprect.x = game_state->x_dock;
		    pg_cliprect.y = game_state->y_dock;
		    pg_cliprect.w = DOCK_W;
		    pg_cliprect.h = DOCK_H;
		  }
		}
	      }
	    }

	    if( OVER_PANEL(event.button.x,event.button.y) ){
	      
	      if( PANEL_CLIC_INTO_RECT(PANEL_HOME_TURN_INDIC_X,
				       PANEL_HOME_TURN_INDIC_Y,
				       PANEL_TURN_INDIC_WIDTH,
				       PANEL_TURN_INDIC_HEIGHT) ){
			if(game_state->active_team==HOME) stop_turn();
	      } 
	      
	      if( PANEL_CLIC_INTO_RECT(PANEL_VISITOR_TURN_INDIC_X,
				       PANEL_VISITOR_TURN_INDIC_Y,
				       PANEL_TURN_INDIC_WIDTH,
				       PANEL_TURN_INDIC_HEIGHT) ){
			if(game_state->active_team==VISITOR) stop_turn();
	      } 
	      
	      if( (game_state->active_team!=HOME) &&
		  (PANEL_CLIC_INTO_RECT(PANEL_HOME_TURN_X+game_state->team[HOME]->get_turn()*PANEL_TURN_WIDTH,
					PANEL_HOME_TURN_Y,
					PANEL_TURN_WIDTH,
					PANEL_TURN_HEIGHT))){
			if(game_state->active_team==NONE && (game_state->old_active_team==NONE||game_state->team[HOME]->has_free_turn()) && ((game_state->kick_off_team==VISITOR&&(!game_state->team[VISITOR]->has_free_turn())) || (game_state->kick_off_team==HOME && game_state->team[HOME]->has_free_turn()) )) start_turn(HOME);
			if(game_state->old_active_team==VISITOR) start_turn(HOME);
	      }
	      
	      if( (game_state->active_team!=VISITOR) &&
		  (PANEL_CLIC_INTO_RECT(PANEL_VISITOR_TURN_X+game_state->team[VISITOR]->get_turn()*PANEL_TURN_WIDTH,
					PANEL_VISITOR_TURN_Y,
					PANEL_TURN_WIDTH,
					PANEL_TURN_HEIGHT))){
			if(game_state->active_team==NONE && (game_state->old_active_team==NONE||game_state->team[VISITOR]->has_free_turn()) && ((game_state->kick_off_team==HOME&&(!game_state->team[HOME]->has_free_turn())) || (game_state->kick_off_team==VISITOR && game_state->team[VISITOR]->has_free_turn()) )) start_turn(VISITOR);
			if(game_state->old_active_team==HOME) start_turn(VISITOR);
	      }
	      
	      if( PANEL_CLIC_INTO_RECT(PANEL_URL_X,
				 PANEL_URL_Y,
				 PANEL_URL_WIDTH,
				 PANEL_URL_HEIGHT) ){
			draw_all(true);
			dialog_box->open_info(screen,ICONS_SMILEY,MSG_GO_TO_WEB,false,"");
			draw_all(true);
	      }
	    }
	
		if(OVER_HOME_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) && event.button.x<(FRAME_LIMIT-FRAME_LINE) ) {
		  int x_r = (x_mouse-game_state->x_dock-HOME_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[HOME]*2;
	      int y_r = (y_mouse-game_state->y_dock-HOME_RESERVE_BOX_Y)/SQUARE_SIZE;
		  if(Shared::get_reserve_box(HOME,y_r,x_r)){
				fill_panel_player_info(Shared::get_reserve_box(HOME,y_r,x_r));
		  }	 
	      else {
				erase_panel_player_info();
	      }
	    }
	    else if(OVER_VISITOR_RESERVE(x_mouse-game_state->x_dock,y_mouse-game_state->y_dock) &&  event.button.x<(FRAME_LIMIT-FRAME_LINE)) {
			int x_r = (x_mouse-game_state->x_dock-VISITOR_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[VISITOR]*2;
			int y_r = (y_mouse-game_state->y_dock-VISITOR_RESERVE_BOX_Y)/SQUARE_SIZE;
			if(Shared::get_reserve_box(VISITOR,y_r,x_r)){
				fill_panel_player_info(Shared::get_reserve_box(VISITOR,y_r,x_r));
			} 
			else {
				erase_panel_player_info();
			}
	    }

	    switch(game_state->current_action){
		case ACTIONS_LEAP:
		if(game_state->target){
			DEBUG( printf("clique gauche action leap\n"); );	
			unset_contextual_info();
			check_for_multi_play();
			leap(p, game_state->target);
			delete game_state->target;
			game_state->target = NULL;
			game_state->current_action = ACTIONS_NONE;	
		}
			break;
	    case ACTIONS_CHOOSE_TRANSMIT_SQUARE:
	      if(game_state->transmit_square){
		DEBUG( printf("je transmets la balle\n"); );
		unset_contextual_info();
		SDL_Rect tmp;
		tmp.x = SQUARE_TO_PIXEL(p->get_square()->get_x())-SQUARE_SIZE;
		tmp.y = SQUARE_TO_PIXEL(p->get_square()->get_y())-SQUARE_SIZE;
		tmp.w = SQUARE_SIZE*3;
		tmp.h = SQUARE_SIZE*3;
		pg_cliprect = rect_union(pg_cliprect, tmp);
		transmission(p,Shared::get_playground(game_state->transmit_square->get_x(),game_state->transmit_square->get_y()));
		game_state->transmit_square_count = 0;
		game_state->transmit_square = NULL;
		game_state->current_action = ACTIONS_NONE;
	      }
	      break;
	    case ACTIONS_CHOOSE_TEAM_MATE:
	      if(game_state->target){
		DEBUG( printf("je prends le gars\n"); );
		unset_contextual_info();
		SDL_Rect tmp;
		tmp.x = SQUARE_TO_PIXEL(p->get_square()->get_x())-SQUARE_SIZE;
		tmp.y = SQUARE_TO_PIXEL(p->get_square()->get_y())-SQUARE_SIZE;
		tmp.w = SQUARE_SIZE*3;
		tmp.h = SQUARE_SIZE*3;
		pg_cliprect = rect_union(pg_cliprect, tmp);
		
		game_state->team_mate = Shared::get_playground(game_state->target->get_x(),game_state->target->get_y());

		delete game_state->target;
		game_state->target = NULL;

		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// Ragnar Modif6 : always hungry
		if (!game_state->selected_player->has_got_skill(ALWAYS_HUNGRY))
			switch_action(ACTIONS_THROW_TEAM_MATE);
		else {
			int roll1 = d6->roll();
			if (game_state->dices_roll) console->print("Always Hungry first roll : %i",roll1);
			
			if (roll1>1) switch_action(ACTIONS_THROW_TEAM_MATE); // tout se passe bien
			
			else { // le gros veut manger le petit
				game_state->selected_player->set_has_played(true); // le tour du lanceur est terminé
				int roll2 = d6->roll();
				if (game_state->dices_roll) console->print("Always Hungry second roll : %i",roll2);
				
				if (roll2>1) { // le petit s'en sort
					
					draw_all(true); // on affiche la boite de dialogue
					dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_ALWAYS_HUNGRY_ESCAPE,false,game_state->team[game_state->team_mate->get_team()]->get_name(),game_state->team_mate->get_number());
					draw_all(true);
										
					if(game_state->target){ // on regarde où atterit le petit
						delete game_state->target;
						game_state->target = NULL;
					}
					game_state->target = random_move_target(game_state->selected_player->get_square()->get_x(),game_state->selected_player->get_square()->get_y());
					
					// code similaire à l'atterissage
					int x_target = (game_state->target)?game_state->target->get_x():0;
					int y_target = (game_state->target)?game_state->target->get_y():0;
					bool ball_out = false;

					pg_cliprect.x = SQUARE_TO_PIXEL(x_target)-SQUARE_SIZE;
					pg_cliprect.y = SQUARE_TO_PIXEL(y_target)-SQUARE_SIZE;
					pg_cliprect.w = SQUARE_SIZE*3;
					pg_cliprect.h = SQUARE_SIZE*3;

					draw_all(false);
					
					// tombe hors du terrain
					if(x_target < 0 || x_target >= PLAYGROUND_WIDTH || y_target < 0 || y_target >= PLAYGROUND_HEIGHT ){	
						game_state->team_mate->place(NULL);
						if(game_state->team_mate->has_got_ball()) {
							game_state->ball->place(x_target,y_target);
							ball_out = true;
						}
						int roll3 = game_state->audience->aggress_player();
						if (game_state->team_mate->has_got_skill(STUNTY)) {
							roll3++;
							if(game_state->dices_roll) console->print("Skill Stunty : +1 to injury roll");
						}	
						injure_player(game_state->team_mate, roll3, true);
						if(ball_out) {
							game_state->old_ball_owner_team = game_state->team_mate->get_team();
							verify_ball_placement();
						}
						if(x_target < 0) x_target = 0;
						else if(x_target >= PLAYGROUND_WIDTH) x_target = PLAYGROUND_WIDTH-1;
						if(y_target < 0) y_target = 0;
						else if(y_target>= PLAYGROUND_HEIGHT) y_target = PLAYGROUND_HEIGHT-1;
						select_square(x_target,y_target);
					}
					
					// tombe sur un joueur (autre que le lanceur)
					else if( Shared::get_playground(x_target,y_target) && 
							 !(x_target == game_state->selected_player->get_square()->get_x() && 
							 y_target == game_state->selected_player->get_square()->get_y())
							 ) {
						// ATTENTION : POSSIBILITE DE BUGGER ICI SI LE GARS SUR QUI ON TOMBE ET ENTOURE D'AUTRES GARS
						Player *under = Shared::get_playground(x_target,y_target);
						Square *go_to = NULL; 
						do{
							go_to = random_move_target(x_target,y_target);
						} while ( go_to->get_x() < 0 || go_to->get_x() >= PLAYGROUND_WIDTH || go_to->get_y() < 0 || go_to->get_y() >= PLAYGROUND_HEIGHT || Shared::get_playground(go_to->get_x(),go_to->get_y()));	
						under->place(go_to);
						delete go_to;
						game_state->team_mate->place(x_target,y_target);
						if(game_state->team_mate->has_got_ball()) {
							game_state->ball->place(x_target,y_target);
						}
						under->set_status(GROUND); // le joueur se retrouve à terre
						select_square(x_target,y_target);
						game_state->team_mate->set_status(OK); // le petit n'a rien (???)
						verify_ball_placement(); // au cas où il serait tombé sur la balle
					}		
					
					// tombe sur une case vide
					else {
						game_state->team_mate->place(x_target,y_target);	
						if(game_state->team_mate->has_got_ball()) {
							game_state->ball->place(x_target,y_target);
						}
						verify_ball_placement(); // au cas où il serait tombé sur la balle

						delete game_state->target;
						game_state->target = NULL;
						
						select_square(x_target,y_target);
						game_state->team_mate->set_status(OK); // le petit n'a rien (???)
					}

					game_state->team_mate = NULL;
					delete game_state->target;
					game_state->target = NULL;
					game_state->current_action = ACTIONS_NONE;
					draw_all(true);
				}
				else { // le petit se fait bouffer
					draw_all(true);
					dialog_box->open_info_i(screen,ICONS_AFRAID, MSG_ALWAYS_HUNGRY_DEATH,false,game_state->team[game_state->team_mate->get_team()]->get_name(),game_state->team_mate->get_number());
					draw_all(true);
					dialog_box->open_info_i(screen,ICONS_DEAD, MSG_PLAYER_DEAD,false,game_state->team[game_state->team_mate->get_team()]->get_name(),game_state->team_mate->get_number());
					draw_all(true);
					// ne pas utiliser injure player pour ne pas avoir à gerer l'apothicaire
					// pb de où on repose le petit
					//injure_player(game_state->team_mate,12,false);
					game_state->team_mate->set_status(DEAD);
					game_state->selected_player->set_has_played(true);
				}
			}
		}
	// fin always hungry
	///////////////////////////////////////////////////////////////////////////////////////////////////////////

	 }
	 break;

		case ACTIONS_CHOOSE_INTERCEPTION_SQUARE:
	      if(game_state->interception_square){
		DEBUG( printf("je veux intercepter\n"); );
		unset_contextual_info();
		pass(p,game_state->target);
		delete game_state->target;
		game_state->target = NULL;
		game_state->interception_square_count = 0;
		game_state->interception_square = NULL;
		game_state->interception_attempt = false;
		///////////////////////////////////////////////////
		// Ragnar Modif
		// s'il y a eu un dump off, on reprend au blocage
		if (game_state->is_a_dump_off){
			goto reprise_du_blocage;
		}
		if (game_state->is_a_blitz_dump_off){
			goto reprise_du_blitz;
		}
		///////////////////////////////////////////////////
		game_state->current_action = ACTIONS_NONE;
	      }
	      break;
	      
	    case ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE:

case_actions_choose_indirect_push_square:

	      if(game_state->indirect_push_square){
			if(game_state->direct_indirect_push){
			  DEBUG( printf("je deplace les gars et je switch vers ACTIONS_PUSH_PLAYER\n"); );
			  unset_contextual_info();
			  Player *p_tmp = Shared::get_playground(game_state->push_square->get_x(),game_state->push_square->get_y());
			  p_tmp->place(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y());
			  if(p_tmp->has_got_ball()) 
				game_state->ball->place(p_tmp->get_square()->get_x(),p_tmp->get_square()->get_y());

			  // Ragnar Modif6 : dispersion de la balle
			  // si le joueur est repoussé sur la balle
			  else {
				if(p_tmp->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					p_tmp->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					game_state->ball->bounce();
					game_state->ball->set_has_bounced(true);
					verify_ball_placement();
				}
			  }
			  /////////////////////////////////////////


			  game_state->indirect_push_square = NULL;
			  game_state->indirect_push_square_count = 0;
			  
			DEBUG( printf("ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE: j'ai bougé le second gars, je passe la main a PUSH_PLAYER\n"); );

			  switch_action(ACTIONS_PUSH_PLAYER);
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE ca serait bien de bouger le gars en dessous encore une fois \n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_DOUBLE_INDIRECT_PUSH);
			}
	      }
	      break;
	    case ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE:

case_actions_choose_indirect_push_and_hit_square:

	      if(game_state->indirect_push_square){
			if(game_state->direct_indirect_push){
			  DEBUG( printf("je bouge le gars et je switch vers ACTIONS_PUSH_AND_HIT_PLAYER\n"); );
			  unset_contextual_info();
			  Player *p_tmp = Shared::get_playground(game_state->push_square->get_x(),game_state->push_square->get_y());
			  p_tmp->place(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y());
			  if(p_tmp->has_got_ball()) 
				game_state->ball->place(p_tmp->get_square()->get_x(),p_tmp->get_square()->get_y());
			  // Ragnar Modif6 : dispersion de la balle
			  // si le joueur est repoussé sur la balle
			  else {
				if(p_tmp->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					p_tmp->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					game_state->ball->bounce();
					game_state->ball->set_has_bounced(true);
					verify_ball_placement();
				}
			  }
			  /////////////////////////////////////////


			  game_state->indirect_push_square = NULL;
			  game_state->indirect_push_square_count = 0;
			
			  DEBUG( printf("ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE: j'ai bougé le second gars, je passe la main a PUSH_AND_HIT_PLAYER\n"); );
			  
			  switch_action(ACTIONS_PUSH_AND_HIT_PLAYER);
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE ca serait bien de bouger le gars en dessous encore une fois \n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_DOUBLE_INDIRECT_PUSH_AND_HIT);
			}
	      }
	      break;

		case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE:
	      if(game_state->double_indirect_push_square){
			if(game_state->direct_double_indirect_push){
			  DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE je deplace les gars et je switch vers ACTIONS_INDIRECT_PUSH\n"); );
			  unset_contextual_info();
			  Player *p_tmp = Shared::get_playground(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y());
			  p_tmp->place(game_state->double_indirect_push_square->get_x(),game_state->double_indirect_push_square->get_y());
			  if(p_tmp->has_got_ball()) 
				game_state->ball->place(p_tmp->get_square()->get_x(),p_tmp->get_square()->get_y());
			  // Ragnar Modif6 : dispersion de la balle
			  // si le joueur est repoussé sur la balle
			  else {
				if(p_tmp->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					p_tmp->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					game_state->ball->bounce();
					game_state->ball->set_has_bounced(true);
					verify_ball_placement();
				}
			  }
			  /////////////////////////////////////////
			  
			  game_state->double_indirect_push_square = NULL;
			  game_state->double_indirect_push_square_count = 0;
			  
				DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE: j'ai bougé le premier gars, je passe la main a case_actions_choose_indirect_push_square\n"); );

				game_state->direct_indirect_push = true;
				goto case_actions_choose_indirect_push_square;

			  //switch_action(ACTIONS_INDIRECT_PUSH); // PAS SUR
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE ca serait bien de bouger le gars en dessous encore une fois \n"); );
			  ;;
			}
	      }
	      break;
	    case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE:
	      if(game_state->double_indirect_push_square){
			if(game_state->direct_double_indirect_push){
			  DEBUG( printf("je bouge le gars et je switch vers ACTIONS_INDIRECT_PUSH_AND_HIT\n"); );
			  unset_contextual_info();
			  Player *p_tmp = Shared::get_playground(game_state->indirect_push_square->get_x(),game_state->indirect_push_square->get_y());
			  p_tmp->place(game_state->double_indirect_push_square->get_x(),game_state->double_indirect_push_square->get_y());
			  if(p_tmp->has_got_ball()) 
				game_state->ball->place(p_tmp->get_square()->get_x(),p_tmp->get_square()->get_y());
			  // Ragnar Modif6 : dispersion de la balle
			  // si le joueur est repoussé sur la balle
			  else {
				if(p_tmp->get_square()->get_x() == game_state->ball->get_square()->get_x() &&
					p_tmp->get_square()->get_y() == game_state->ball->get_square()->get_y() ) {
					game_state->ball->bounce();
					game_state->ball->set_has_bounced(true);
					verify_ball_placement();
				}
			  }
			  /////////////////////////////////////////

			  game_state->double_indirect_push_square = NULL;
			  game_state->double_indirect_push_square_count = 0;

			  DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE: j'ai bougé le premier gars, je passe la main a case_actions_choose_indirect_push_and_hit_square\n"); );

			  game_state->direct_indirect_push = true;
			  goto case_actions_choose_indirect_push_and_hit_square;

			  // switch_action(ACTIONS_INDIRECT_PUSH_AND_HIT); // PAS SUR
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE:ca serait bien de bouger le gars en dessous encore une fois \n"); );
			  ;;
			}
	      }
	      break;


	    case ACTIONS_CHOOSE_PUSH_SQUARE:
	      if(game_state->push_square){
			if(game_state->direct_push){
			  DEBUG( printf("je switch vers ACTIONS_PUSH_PLAYER\n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_PUSH_PLAYER);
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_PUSH_SQUARE ca serait bien de bouger le gars en dessous\n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_INDIRECT_PUSH);
			}
	      }
	      break;
	    case ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE:
	      if(game_state->push_square){
			if(game_state->direct_push){
			  DEBUG( printf("je switch vers ACTIONS_PUSH_AND_HIT_PLAYER\n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_PUSH_AND_HIT_PLAYER);
			}
			else{
			  DEBUG( printf("ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE ca serait bien de bouger le gars en dessous\n"); );
			  unset_contextual_info();
			  switch_action(ACTIONS_INDIRECT_PUSH_AND_HIT);
			}
	      }
	      break;
	    case ACTIONS_MOVE:
	      DEBUG( printf("clic gauche move\n"); );
	      if(game_state->path && game_state->path->is_ok()){
			unset_contextual_info();
			check_for_multi_play();
		
			game_state->player_is_moving = true;
			movement_completed = move_player(p, game_state->path);
			game_state->player_is_moving = false;
			delete game_state->path;
			game_state->path = NULL;

			if (movement_completed){
				game_state->current_action = (p->can_move())?ACTIONS_MOVE:ACTIONS_NONE; 	
				if(!p->can_do_something_more(game_state->ball->get_square())){
					p->set_has_played(true);
				}
			}
	      }
	      break;
	    case ACTIONS_MOVE_PLUS:
	
		  DEBUG( printf("clic gauche move plus\n"); );
	      if(game_state->path && game_state->path->is_ok()){

			  unset_contextual_info();

		check_for_multi_play();
		
		int goal = p->overmove((game_state->weather==BLIZZARD)?true:false);
		int reroll_done = false;
	      actions_move_plus_begining:

		int roll = d6->roll();
		int result ;
		if (roll!=6 && (roll==1 || roll<goal)) {
			result = (reroll_done)?TOOBAD:FAIL;
		}
		else result = SUCCESS;

		if(game_state->dices_roll) console->print("Move extra square roll : %i  (%c%i)", roll, results[result], goal);
		
		DEBUG( printf("resultat de mettre le paquet: %d - ", result); );
		switch(result){
		case SUCCESS:
		  DEBUG( printf("succes move+!\n"); );
		  game_state->player_is_moving = true;
		  move_player(p, game_state->path);
		  p->inc_overmove_count();
		  game_state->player_is_moving = false;
		  delete game_state->path;
		  game_state->path = NULL;
		  game_state->current_action = ACTIONS_NONE;
		  break;
		case FAIL: 
		
		    if(p->has_got_skill(SURE_FEET)){
				draw_all(true);
			    dialog_box->open_info(screen,ICONS_INFO,MSG_MOVE_PLUS_FREE_REROLL,false,game_state->team[p->get_team()]->get_name());
				reroll_done = true;
				draw_all(true);
				goto actions_move_plus_begining;
			}
			////////////////////////////////////////////
			// Ragnar Modif5 : big guy
			//else if(!game_state->team[p->get_team()]->can_reroll()) goto actions_move_plus_case_toobad;
			else if(!game_state->team[p->get_team()]->can_reroll() || p->has_got_skill(BIG_GUY)) goto actions_move_plus_case_toobad;
			////////////////////////////////////////////
     

			draw_all(true);
			switch(dialog_box->open_yesno(screen,ICONS_QUESTION, MSG_MOVE_PLUS_REROLL_QUESTION, game_state->team[p->get_team()]->get_name())){
				case YES: 
				game_state->team[p->get_team()]->set_reroll_used(true);
				reroll_done = true;
				draw_all(true);
				goto actions_move_plus_begining;
				break;
				case NO:
				draw_all(true);
				break;
			}
		  
		case TOOBAD: 
		actions_move_plus_case_toobad:
			DEBUG( printf("toobad! (tu l'as dans le cul)\n"); );
		
			Square *s = *((game_state->path->get_path_squares())->begin());
		  
			tackle_player(p,NULL,s->get_x() - p->get_square()->get_x() ,
				s->get_y() - p->get_square()->get_y(), false); // false, car il ne se fait pas mal
			delete game_state->path;
			game_state->path = NULL;
		
			game_state->current_action = ACTIONS_NONE;
			break;
		}
	
		if(!p->can_do_something_more(game_state->ball->get_square())){
		  p->set_has_played(true);
		}  
	      }
      break;
	    case ACTIONS_BLOCK:
	      DEBUG( printf("clic gauche block\n"); );
	      if(game_state->target) {
			unset_contextual_info();  
			check_for_multi_play();
			
			
////////////////////////////////////////////////////////
			// Ragnar Modif3
			// compétence dump off (passe rapide)				
	
			reprise_du_blocage:	

			bool dump_off_done = game_state->is_a_dump_off;
			int attack_team = game_state->active_team;
			if (dump_off_done){
				//on remet tout comme c'était avant...
				game_state->target = p->get_square(); //le joueur qui a fait la passe rapide redevient la target du blocage
				game_state->selection = game_state->selection_save;
				game_state->selection_save = NULL;
				p = game_state->player_save;
				game_state->player_save = NULL;
				game_state->selected_player = p;
				//repermute l'équipe active
				attack_team = game_state->old_active_team;
				game_state->old_active_team = game_state->active_team;
				game_state->active_team = attack_team;
				game_state->current_action = ACTIONS_BLOCK;
				game_state->is_a_dump_off = false;
				game_state->freeze_time = false;
			}
			
			Player* vs=Shared::get_playground(game_state->target->get_x(),game_state->target->get_y());
			
			if (!dump_off_done && vs->has_got_ball() && vs->has_got_skill(DUMP_OFF)){
				if(game_state->dices_roll) console->print("Defensor can try a dump off...");
				draw_all(true);
				bool try_pass=false;
				// boite de dialogue pour savoir si le défenseur tente la passe 
				switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_SKILL_DUMP_OFF,game_state->team[vs->get_team()]->get_name())){
					case YES: 
						try_pass = true;
						draw_all(true);
						break;
					case NO:
						try_pass = false;
						draw_all(true);
						break;
				}
				if(try_pass){		

					game_state->is_a_dump_off = true;
					game_state->freeze_time = true;
					game_state->selection_save = game_state->selection;
					game_state->player_save = game_state->selected_player;
					p=vs;
					game_state->selected_player = vs;
					game_state->selection = game_state->target;
					//RM7 ce delete fait planter le dump off// delete game_state->target;
					//game_state->target = NULL;
					//permute l'équipe active
					game_state->active_team = game_state->old_active_team;
					game_state->old_active_team = attack_team;

					///////////////////////////////////////////////////
					// Ragnar Modif5 : petite correction pour que le coach qui fait le dump off
					// ne puisse pas jouer d'autre joueur que celui qui fait la passe rapide
					std::map<int,Player*> ::iterator it;
					map<int,Player*> *players = game_state->team[game_state->active_team]->get_players();
					for(it=players->begin();it!=players->end();it++){
							((*it).second)->set_has_played(true);
					}
					///////////////////////////////////////////////////

					game_state->select_throw_target = true;
					game_state->current_action = ACTIONS_THROW;
					draw_all(true);
					break;
			
				}
			}
			////////////////////////////////////////////////////////			

			block_player(p,vs);
			p->set_block_done(true);
			if(!p->can_do_something_more(game_state->ball->get_square())){
				p->set_has_played(true);
			} 
		  }
	      break;
	
		case ACTIONS_THROW_TEAM_MATE:
	      DEBUG( printf("clic gauche throw team mate\n"); );
	      
	      if(game_state->target && pass_arrow){
			unset_contextual_info();
			game_state->select_throw_target = false;
			free(pass_arrow);
			pass_arrow = NULL;
			check_for_multi_play();
			throw_team_mate(p, game_state->team_mate, game_state->target);
		    delete game_state->target;
			game_state->target = NULL;
			free(pass_arrow);
			pass_arrow = NULL;
			game_state->team_mate = NULL;
		    game_state->current_action = ACTIONS_NONE;
		}
		break;
		
		case ACTIONS_THROW:
	      DEBUG( printf("clic gauche throw\n"); );
	      
	      if(game_state->target && pass_arrow){
		unset_contextual_info();
			  game_state->select_throw_target = false;
		free(pass_arrow);
		pass_arrow = NULL;
		check_for_multi_play();

		game_state->interception_attempt = false;

		if(game_state->interception_square_count!=0){
		  draw_all(true);
		  switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_INTERCEPTION_ATTEMPT_QUESTION,game_state->team[1-game_state->active_team]->get_name())){
		  case YES: 
		    game_state->interception_attempt = true;
		    draw_all(true);
		    dialog_box->open_info(screen,ICONS_INFO,MSG_CHOOSE_INTERCEPTOR,false,game_state->team[1-game_state->active_team]->get_name());
		    draw_all(true);
		    break;
		  case NO:
		    game_state->interception_attempt = false;
		    game_state->interception_square_count=0;
		    draw_all(true);
		    break;
		  }
		}
		
		////////////////////////////////////
		// Ragnar Modif2 : safe throw
		// une petite boite de dialogue d'info serait ici bienvenue
		if(game_state->interception_attempt && p->has_got_skill(SAFE_THROW)){
			if (d6->roll() > 1){
				game_state->interception_attempt = false;
				if(game_state->dices_roll) console->print("Thrower uses safe throw : interception attempt cancelled!");
			}
			else{
				if(game_state->dices_roll) console->print("Safe throw skill failed : interception attempt");
			}
		}
		////////////////////////////////////
		
		if(game_state->interception_attempt){
		  switch_action(ACTIONS_CHOOSE_INTERCEPTION_SQUARE);
		}
		else {
		  pass(p,game_state->target);
		  game_state->interception_square_count = 0;
		  game_state->interception_square = NULL;
		  game_state->interception_attempt = false;
		  delete game_state->target;
		  game_state->target = NULL;

		  ///////////////////////////////////////////////////
		  // Ragnar Modif
		  // s'il y a eu un dump off, on reprend au blocage
		  if (game_state->is_a_dump_off){
			  goto reprise_du_blocage;
		  }
		  if (game_state->is_a_blitz_dump_off){
			goto reprise_du_blitz;
		  }
		  ///////////////////////////////////////////////////
	
		  game_state->current_action = ACTIONS_NONE;
		}
	      }
	      break;

	    case ACTIONS_AGGRESS:
	      DEBUG( printf("clic gauche aggress\n"); );
	      if(game_state->target) {
		unset_contextual_info();
			  check_for_multi_play();
		aggress_player(p,Shared::get_playground(game_state->target->get_x(),game_state->target->get_y()));
		delete game_state->target;
		game_state->target = NULL;
		game_state->current_action = ACTIONS_NONE;
	      }
	      break;

	    case ACTIONS_BLITZ:
	      DEBUG( printf("clic gauche blitz\n"); );
	      
	      if(game_state->target) {

			unset_contextual_info();
			  
		check_for_multi_play();

				////////////////////////////////////////////////////////
		// Ragnar Modif3
		// compétence dump off (passe rapide)				
	
		reprise_du_blitz:	

		bool dump_off_done = game_state->is_a_blitz_dump_off;
		int attack_team = game_state->active_team;
		if (dump_off_done){
			//on remet tout comme c'était avant...
			game_state->target = p->get_square(); //le joueur qui a fait la passe rapide redevient la target du blocage
			game_state->selection = game_state->selection_save;
			game_state->selection_save = NULL;
			p = game_state->player_save;
			game_state->player_save = NULL;
			game_state->selected_player = p;
			//repermute l'équipe active
			attack_team = game_state->old_active_team;
			game_state->old_active_team = game_state->active_team;
			game_state->active_team = attack_team;
			game_state->current_action = ACTIONS_BLITZ;
			game_state->is_a_blitz_dump_off = false;
			game_state->freeze_time = false;
		}
			
		Player* vs=Shared::get_playground(game_state->target->get_x(),game_state->target->get_y());
			
		if (!dump_off_done && vs->has_got_ball() && vs->has_got_skill(DUMP_OFF)){
			if(game_state->dices_roll) console->print("Defensor can try a dump off...");
			draw_all(true);
			bool try_pass=false;
			// boite de dialogue pour savoir si le défenseur
			// tente la passe (message à modifier)...
			switch(dialog_box->open_yesno(screen,ICONS_QUESTION,MSG_SKILL_DUMP_OFF,game_state->team[vs->get_team()]->get_name())){
				case YES: 
					try_pass = true;
					draw_all(true);
					break;
				case NO:
					try_pass = false;
					draw_all(true);
					break;
			}
			if(try_pass){		

				game_state->is_a_blitz_dump_off = true;
				game_state->freeze_time = true;
				game_state->selection_save = game_state->selection;
				game_state->player_save = game_state->selected_player;
				p=vs;
				game_state->selected_player = vs;
				game_state->selection = game_state->target;
				//RM7 ce delete fait planter le dump off// delete game_state->target;
				//game_state->target = NULL;
				//permute l'équipe active
				game_state->active_team = game_state->old_active_team;
				game_state->old_active_team = attack_team;

				///////////////////////////////////////////////////
				// Ragnar Modif5 : petite correction pour que le coach qui fait le dump off
				// ne puisse pas jouer d'autre joueur que celui qui fait la passe rapide
				std::map<int,Player*> ::iterator it;
				map<int,Player*> *players = game_state->team[game_state->active_team]->get_players();
				for(it=players->begin();it!=players->end();it++){
						((*it).second)->set_has_played(true);
				}
				///////////////////////////////////////////////////

				game_state->select_throw_target = true;
				game_state->current_action = ACTIONS_THROW;
				draw_all(true);
				break;
			
			}
		}
		////////////////////////////////////////////////////////			

		p->set_blitz_done(true);
		game_state->team[p->get_team()]->set_blitz_done(true);
		////////////////////////////////////////////////////////
		// Ragnar Modif2 : l'ordre des 2 lignes suivantes a été
		// interverti pour que le décompte des cases parcourues 
		// avant le blitz soit correctement évalué (HORNS)
		block_player(p,Shared::get_playground(game_state->target->get_x(),game_state->target->get_y()));
		(p->movement_left()>0)?p->inc_move_count():p->inc_overmove_count();
		////////////////////////////////////////////////////////
		if(!p->can_do_something_more(game_state->ball->get_square())){
		  p->set_has_played(true);
		} 
	      }
	      
	      break;

	    case ACTIONS_NONE:
	      if(actions_menu->visible ){	
			  
			///////////////////////////////
			// Ragnar Modif6 : bone head et really stupid
			if (game_state->selected_player) {
				test_stupidness(game_state->selected_player);
			}
			///////////////////////////////
			show_actions_menu(false,x_mouse+MARGIN_SIZE,y_mouse+MARGIN_SIZE,x_square,y_square); 
	      }
	      else {
			if( OVER_PLAYGROUND(x_mouse+MARGIN_SIZE,y_mouse+MARGIN_SIZE) && event.button.x<(FRAME_LIMIT-FRAME_LINE) && !( game_state->selection && game_state->selection->get_x() == x_square && game_state->selection->get_y() == y_square ) ) {
				DEBUG( printf("la case selectionnee est en (%d,%d)\n",x_square,y_square); ); 
				select_square(x_square,y_square);
			}
	      }
	      break;
	    } // switch_current_action
	    break;
	  } // switch_current_mode
	  break;
	  
	case RIGHT_BUTTON:
	  // clic droit  

	  if(game_state->freeze_interaction) break;

	  menu_allowed = true;

	  switch(game_state->current_mode){
	  case MODE_SURPRISE:
	    if(game_state->selected_player){
		  game_state->selected_player = NULL;
	      erase_panel_player_info();
	      delete game_state->target;
		  game_state->target = NULL;
	    }
	    break;
	  case MODE_NONE:
	    break;
	  case MODE_TEAM_PLACEMENT:
	    if(game_state->player_to_place) {
	      game_state->player_to_place->place_in_reserve();
	      game_state->player_to_place = NULL;
	    }
	    erase_panel_player_info();
	    delete game_state->location_square;
		game_state->location_square = NULL;
	    break;
	  case MODE_PLAYING:	  
	    switch(game_state->current_action){
		case ACTIONS_LEAP:
		  DEBUG( printf("clic droit leapn"); );
	      unset_contextual_info();
		  delete game_state->target;
		  game_state->target = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_MOVE:
	      DEBUG( printf("clic droit move\n"); );
	      unset_contextual_info();
		  delete game_state->path;
		  game_state->path = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_MOVE_PLUS:
	      DEBUG( printf("clic droit move plus\n"); );
	      unset_contextual_info();
		  delete game_state->path;
		  game_state->path = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_BLOCK:
	      DEBUG( printf("clic droit block\n"); );
		  unset_contextual_info();
		  delete game_state->target;
		  game_state->target = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_THROW:
	      DEBUG( printf("clic droit throw\n"); );
	      unset_contextual_info();
		  game_state->select_throw_target  = false;
	      delete game_state->target;
		  game_state->target = NULL;
	      free(pass_arrow);
		  pass_arrow = NULL;

		  ///////////////////////////////////////////////////
		  // Ragnar Modif5 : en cas de clic droit lors d'un dump off on reprend au blocage
		  if (game_state->is_a_dump_off){
			  goto reprise_du_blocage;
		  }
		  if (game_state->is_a_blitz_dump_off){
			goto reprise_du_blitz;
		  }
		  ///////////////////////////////////////////////////

	      game_state->current_action = ACTIONS_NONE;
	      break;
		case ACTIONS_THROW_TEAM_MATE:
	      DEBUG( printf("clic droit throw team mate\n"); );
	      unset_contextual_info();
		  game_state->select_throw_target  = false;
	      delete game_state->target;
		  game_state->target = NULL;
	      free(pass_arrow);
		  pass_arrow = NULL;
		  game_state->team_mate= NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
		case ACTIONS_CHOOSE_TEAM_MATE:
		  unset_contextual_info();
		  delete game_state->target;
		  game_state->target = NULL;
	      game_state->current_action = ACTIONS_NONE;
		  break;
	    case ACTIONS_AGGRESS:
	      DEBUG( printf("clic droite aggress\n"); );
	      unset_contextual_info();
		  delete game_state->target;
		  game_state->target = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_BLITZ:
	      DEBUG( printf("clic droit blitz\n"); );
		  unset_contextual_info();
	      delete game_state->target;
		  game_state->target = NULL;
	      game_state->current_action = ACTIONS_NONE;
	      break;
	    case ACTIONS_CHOOSE_PUSH_SQUARE:
	      menu_allowed = false;
	      break;
	    case ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE:
	      menu_allowed = false;
	      break;
	    case ACTIONS_CHOOSE_INTERCEPTION_SQUARE:
	      menu_allowed = false;
	      break;
	    case ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE:
	      menu_allowed = false;
	      break; 
	    case ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE:
	      menu_allowed = false;
	      break; 
		case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE:
	      menu_allowed = false;
	      break; 
	    case ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE:
	      menu_allowed = false;
	      break; 
	    case ACTIONS_CHOOSE_TRANSMIT_SQUARE:
			unset_contextual_info();
			game_state->transmit_square = NULL;
			game_state->current_action = ACTIONS_NONE;
			menu_allowed = false;
			break;
	    }
	   	    
	    //  clic droite -> apparition du menu
	    if( OVER_PLAYGROUND(x_mouse+MARGIN_SIZE,y_mouse+MARGIN_SIZE) && event.button.x<(FRAME_LIMIT-FRAME_LINE) && Shared::get_playground(x_square,y_square) && menu_allowed) {
	      
	      if ( (!Shared::get_playground(x_square,y_square)->has_played()||(Shared::get_playground(x_square,y_square)->can_transmit()&& !game_state->team[Shared::get_playground(x_square,y_square)->get_team()]->is_transmit_done())) && game_state->active_team == Shared::get_playground(x_square,y_square)->get_team() )
		show_actions_menu(true,x_mouse+MARGIN_SIZE,y_mouse+MARGIN_SIZE,x_square,y_square);

	      bool tmp = game_state->autocenter_mode;
	      game_state->autocenter_mode = false;
	      select_square(x_square,y_square);
	      game_state->autocenter_mode = tmp;
	      
	    }
	    
	    break;
	  }
	  draw_all(true);
	  break;
	case WHEEL_UP:
	  if( event.button.x<(FRAME_LIMIT-FRAME_LINE) && (!game_state->freeze_interaction)) {
	    move_playground(S,MOUSE_STEP);
	  }
	  break;
	case WHEEL_DOWN:
	  if( event.button.x<(FRAME_LIMIT-FRAME_LINE)  && (!game_state->freeze_interaction)) {
	    move_playground(N,MOUSE_STEP);
	  }
	  break;

	case MIDDLE_BUTTON:
		if( event.button.x<(FRAME_LIMIT-FRAME_LINE)  && (!game_state->freeze_interaction)) {
			game_state->drag_playground = true;
		}
		break;
	}
	break;
      case SDL_MOUSEBUTTONUP:
	
	if(game_state->freeze_interaction) break;
	
	DEBUG( printf("Bouton souris relache %d\n",event.button.button); );
	x_mouse = event.button.x - pg->x - MARGIN_SIZE;
	y_mouse = event.button.y - pg->y - MARGIN_SIZE;
	x_square = x_mouse/SQUARE_SIZE;
	y_square = y_mouse/SQUARE_SIZE;
	
	switch(event.button.button){
	case MIDDLE_BUTTON:
			game_state->drag_playground = false;
	break;
	
	case LEFT_BUTTON:

	  switch(game_state->current_mode){
	  case MODE_TEAM_PLACEMENT:
		SDL_Rect r_tmp;
	    game_state->drag_dock = false;
        r_tmp.x = game_state->x_dock;
		r_tmp.y = game_state->y_dock;
		r_tmp.w = DOCK_W;
		r_tmp.h = DOCK_H;
		pg_cliprect = rect_union(r_tmp,pg_cliprect);

	    if(game_state->x_player_clic!=(x_mouse+MARGIN_SIZE)&&game_state->y_player_clic!=(y_mouse+MARGIN_SIZE) && game_state->player_to_place){
	    
	      if(OVER_PLAYGROUND(x_mouse,y_mouse)) {
		if(game_state->player_to_place && game_state->location_square){
		  game_state->player_to_place->place(game_state->location_square);
		  
		  game_state->player_to_place = NULL;
		  erase_panel_player_info();
		  delete game_state->location_square;
		  game_state->location_square = NULL;
		}
	      }
	      else if(OVER_HOME_RESERVE(x_mouse,y_mouse) && game_state->team_in_placement==HOME && event.button.x<(FRAME_LIMIT-FRAME_LINE)  ) {
		int x_r = (x_mouse-HOME_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[HOME]*2;
		int y_r = (y_mouse-HOME_RESERVE_BOX_Y)/SQUARE_SIZE;
		if(!Shared::get_reserve_box(HOME,y_r,x_r)){
		  game_state->player_to_place->place_in_reserve(x_r,y_r);
		  game_state->player_to_place = NULL;
		  erase_panel_player_info();
		  delete game_state->location_square;
		  game_state->location_square = NULL;
		}
		else if(Shared::get_reserve_box(HOME,y_r,x_r)){
		  Player*p_save = game_state->player_to_place;
		  game_state->player_to_place = Shared::get_reserve_box(HOME,y_r,x_r);
		
		  game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		  game_state->y_player_clic = y_mouse+MARGIN_SIZE;
		
		  game_state->player_to_place_x = HOME_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
		  game_state->player_to_place_y = HOME_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
		  Shared::set_reserve_box(HOME,y_r,x_r,NULL);
		  game_state->player_to_place->set_square(NULL);
		  game_state->player_to_place->set_reserve_square(NULL);
		  fill_panel_player_info(game_state->player_to_place);
		  p_save->place_in_reserve(x_r,y_r);	
		}
	      } 
	      else if(OVER_VISITOR_RESERVE(x_mouse,y_mouse) && game_state->team_in_placement==VISITOR && event.button.x<(FRAME_LIMIT-FRAME_LINE)) {
		int x_r = (x_mouse-VISITOR_RESERVE_BOX_X)/SQUARE_SIZE + game_state->reserve_page[VISITOR]*2;
		int y_r = (y_mouse-VISITOR_RESERVE_BOX_Y)/SQUARE_SIZE;
		if(!Shared::get_reserve_box(VISITOR,y_r,x_r)){
		  game_state->player_to_place->place_in_reserve(x_r,y_r);
		  game_state->player_to_place = NULL;
		  erase_panel_player_info();
		  delete game_state->location_square;
		  game_state->location_square = NULL;
		}
		else if(Shared::get_reserve_box(VISITOR,y_r,x_r)){
		  Player*p_save = game_state->player_to_place;
		  game_state->player_to_place = Shared::get_reserve_box(VISITOR,y_r,x_r);
		  
		  game_state->x_player_clic = x_mouse+MARGIN_SIZE;
		  game_state->y_player_clic = y_mouse+MARGIN_SIZE;
		  
		  game_state->player_to_place_x = VISITOR_RESERVE_BOX_X + (x_r%2)*SQUARE_SIZE; 
		  game_state->player_to_place_y = VISITOR_RESERVE_BOX_Y + y_r*SQUARE_SIZE;
		  Shared::set_reserve_box(VISITOR,y_r,x_r,NULL);
		  game_state->player_to_place->set_square(NULL);
		  game_state->player_to_place->set_reserve_square(NULL);
		  fill_panel_player_info(game_state->player_to_place);
		  p_save->place_in_reserve(x_r,y_r);	
		}
	      }
	    }
	    break;
	  }
	  break;
	  
	case RIGHT_BUTTON:
	  
	  switch(game_state->current_action){   
	  case ACTIONS_NONE:
	    // clic droite relache -> menu disparait
	    if(actions_menu->visible && game_state->x_menu_clic!=(x_mouse+MARGIN_SIZE)&&game_state->y_menu_clic!=(y_mouse+MARGIN_SIZE) )
	      show_actions_menu(false,x_mouse+MARGIN_SIZE,y_mouse+MARGIN_SIZE,x_square,y_square); 
	    break;
	  } 
	  break;
	}
	break;
      }
    }
  }

  return 0;
}

void quit_game(){

	if(game_state) free_game_data();

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->stop_sound();
	}
#endif

  switch(screens->open_end()){
  case BACK:
    switch_screens();
    break;
  case EXIT:
	free_minimum_data();
	exit(0);
    break;
  default:
    break;
  }
}

void quit_game_box(){
	draw_all(true);
    switch(dialog_box->open_yesno(screen,ICONS_AFRAID, MSG_QUIT, "")){
    case YES: 
      quit_game();
      break;
    case NO:
      draw_all(true);
      break;
    } 
}

void switch_screens(void){

opponent_t *opponent = NULL;
team_summary_t* home;
team_summary_t* visitor;
State *loaded_state;
team_list_t *team_list;
int i,j; 
int alea;

char* file;
 title:
  switch(screens->open_title()){
  case QUICK_GAME:

	DEBUG( printf("-> QUICK_GAME before get_team_list\n"); );

    team_list = get_team_list(TEAM_PATH);
	if( !team_list ){
	  DEBUG( printf("No available team in %s\n",TEAM_PATH); );
	  goto title;
	} 
	
	DEBUG( printf("-> QUICK_GAME after get_team_list\n"); );

	srand(time(0));

	alea = ((int) (((double)team_list->nb)*rand()/(RAND_MAX+1.0)));
	home = team_list->teams[alea];
    
	DEBUG( printf("-> QUICK_GAME j'ai home\n"); );

	alea = ((int) (((double)team_list->nb)*rand()/(RAND_MAX+1.0)));
	visitor = team_list->teams[alea];
	
	
	DEBUG( printf("-> QUICK_GAME j'ai visitor\n"); );

	DEBUG( printf("-> QUICK_GAME before init_game\n"); );
    init_game(home,visitor);
	DEBUG( printf("-> QUICK_GAME after init_game\n"); );

	for(i=0;i<team_list->nb;i++)
		free(team_list->teams[i]);
	free(team_list);


	#ifndef NOSOUND
//SOUND - TALID	
	if(game_state->weather==SHOWER){
		if(Config::is_sound_enabled()){
				sp->stop_sound();
				sp->loop_sound(SND_SHOWER, BGM_CHANNEL);
		}
	}
	if(game_state->weather==BLIZZARD){
		if(Config::is_sound_enabled()){
			sp->stop_sound();
			sp->loop_sound(SND_BLIZZARD, BGM_CHANNEL);
		}
	}
	if(game_state->weather!=SHOWER && game_state->weather!=BLIZZARD){
		if(Config::is_sound_enabled()){	
			sp->stop_sound();
			sp->loop_sound(SND_CROWD, BGM_CHANNEL);
		}
	}
	
	#endif

	DEBUG( printf("-> QUICK_GAME before toss\n"); );
	toss();
	DEBUG( printf("-> QUICK_GAME after toss\n"); );
	DEBUG( printf("-> QUICK_GAME before main_loop\n"); );
    main_loop();
	DEBUG( printf("-> QUICK_GAME after main_loop\n"); );
    break;
  case EXHIBITION:
	team_list = get_team_list(TEAM_PATH);
	if(!team_list){
	  DEBUG( printf("No available team in %s\n",TEAM_PATH); );
	  goto title;
	} 

	opponent = screens->open_team_selector(team_list);

	if(!opponent) {
	  DEBUG( printf("No available opponent...\n"); );
	  for(i=0;i<team_list->nb;i++)
		free(team_list->teams[i]);
	  free(team_list);
	  goto title;
	}

	init_game(opponent->home,opponent->visitor);

	for(i=0;i<team_list->nb;i++)
		free(team_list->teams[i]);
	free(team_list);

	free(opponent);

	#ifndef NOSOUND
// SOUND - TALID	
	if(game_state->weather==SHOWER){
		if(Config::is_sound_enabled()){
				sp->stop_sound();
				sp->loop_sound(SND_SHOWER, BGM_CHANNEL);
		}
	}
	if(game_state->weather==BLIZZARD){
		if(Config::is_sound_enabled()){
			sp->stop_sound();
			sp->loop_sound(SND_BLIZZARD, BGM_CHANNEL);
		}
	}
    if(game_state->weather!=SHOWER && game_state->weather!=BLIZZARD){
		if(Config::is_sound_enabled()){	
			sp->stop_sound();
			sp->loop_sound(SND_CROWD, BGM_CHANNEL);
		}
	}
	#endif


	toss();
    main_loop();
	break;
  
#ifndef NONET
  case NETWORK:
	team_list = get_team_list(DEFAULT_TEAM_PATH);
	if(!team_list){
	  DEBUG( printf("No available team in %s\n",DEFAULT_TEAM_PATH); );
	  goto title;
	} 
	
	opponent = screens->open_network(team_list, net);
	
	if(!opponent) {
	  DEBUG( printf("No available opponent...\n"); );
	  for(i=0;i<team_list->nb;i++)
		free(team_list->teams[i]);
	  free(team_list);
	  
	  if(net) {
		;;
	  }
	  goto title;
	}

	init_game(opponent->home,opponent->visitor);
	
	for(i=0;i<team_list->nb;i++)
		free(team_list->teams[i]);
	free(team_list);

	free(opponent);

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->stop_sound();
		sp->loop_sound(SND_CROWD, BGM_CHANNEL);
	}
#endif

	toss();
    main_loop();

	break;
  
#endif

  case LOAD_GAME:
		for(i=0;i<PLAYGROUND_WIDTH;i++){
			for(j=0;j<PLAYGROUND_HEIGHT;j++){
				Shared::set_playground(i,j,NULL);
			}
		}

		for(i=0;i<RESERVE_PAGE_W*RESERVE_PAGE_COUNT;i++){
			for(j=0;j<RESERVE_PAGE_H;j++){
				Shared::set_reserve_box(HOME,j,i,NULL);
				Shared::set_reserve_box(VISITOR,j,i,NULL);
			}
		}

		file = screens->open_load_input(NULL);

		if(!file) {
			goto title;
			break;
		} 
		else {
			char tmp[36];
			sprintf(tmp,"%s/%s.xml",SAVES_PATH,file);
			free(file);
			loaded_state = load_game(tmp);
			if(loaded_state){
				init_game_from_save(loaded_state);

#ifndef NOSOUND
				if(Config::is_sound_enabled()){
					sp->stop_sound();
					sp->loop_sound(SND_CROWD, BGM_CHANNEL);
				}
#endif

				main_loop();
			}
			else {
				screens->open_load_input("No such file");
				goto title;
			}
		}
		break;
  case CREDITS:
    switch(screens->open_credits()){
    case BACK:		
		goto title;
      break;
    case EXIT:
      quit_game();
      break;
    default:
      break;
    }
    break;
  case OPTIONS:
    switch(screens->open_options()){
    case BACK:
      
	/*	
		const SDL_VideoInfo *vi;
		vi = SDL_GetVideoInfo();
		
		Config::reload();

		if (!(screen=SDL_SetVideoMode(Config::get_screen_w(),Config::get_screen_h(),vi->vfmt->BitsPerPixel,SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_ANYFORMAT)) ){
			fprintf(stderr, "Couldn't set %d %d: %s\n",Config::get_screen_w(),
			Config::get_screen_h(), SDL_GetError());
			exit(1);
		}
		
		draw_all(true); // refresh screen si merdes a l'affichage
	*/

		goto title;
      break;
    case EXIT:
      quit_game();
      break;
    default:
      break;
    }
    break;
  case EXIT:
    quit_game();
    break;
  default:
    break;
  }
}

/////////////////////////////////////////////////
	// Ragnar Modif6 : bone head et really stupid
	void test_stupidness(Player* p){ 
		// bone head
		if (p->has_got_skill(BONE_HEAD) && !p->is_bone_head_tested()) {
			int bone_head_roll=d6->roll();
			if(game_state->dices_roll) console->print("Bone Head roll : %i", bone_head_roll);
			if (bone_head_roll==1){
				draw_all(true);
				dialog_box->open_info_i(screen,ICONS_AFRAID,MSG_BONE_HEAD,false,game_state->team[p->get_team()]->get_name(),p->get_number());
				draw_all(true);
				game_state->current_action = ACTIONS_NONE;
				p->set_has_played(true);
			}
			p->set_bone_head_tested(true);
		}
		
		// really stupid
		if (p->has_got_skill(REALLY_STUPID) && !p->is_really_stupid_tested()) {
			int really_stupid_roll=d6->roll();

			//vérifie si un de ses potes peut l'aider
			int bonus = 0;
			std::list<Player*>* neighbour = p->get_neighbours();
			std::list<Player*> ::iterator it;
			for(it=neighbour->begin();it!=neighbour->end();it++)
			  if( (*it)
			  && (*it) != p
			  && (*it)->get_status()==OK
			  && (*it)->get_team() == p->get_team()
			  && !(*it)->has_got_skill(REALLY_STUPID)
			  && !(*it)->has_got_skill(BONE_HEAD)
			  ) bonus=2;
			delete neighbour;
			//fin de la vérification

			if(game_state->dices_roll && bonus==0) console->print("Really Stupid roll : %i (no assistance)", really_stupid_roll);
			if(game_state->dices_roll && bonus==2) console->print("Really Stupid roll : %i + 2 = %i (assistance)", really_stupid_roll,really_stupid_roll+2);
			really_stupid_roll+=bonus;
			if (really_stupid_roll<=3){
				draw_all(true);
				dialog_box->open_info_i(screen,ICONS_AFRAID,MSG_REALLY_STUPID,false,game_state->team[p->get_team()]->get_name(),p->get_number());
				draw_all(true);
				game_state->current_action = ACTIONS_NONE;
				p->set_has_played(true);
			}
			p->set_really_stupid_tested(true);
		}
	}
///////////////////////////////////////////////////////////////////////////////////////


int get_weather(void){
	return game_state->weather;
}

void set_debug(bool b){
	game_state->debug = b;
}

void show_dices_roll(bool b){
	game_state->dices_roll = b;
}

void set_contextual_info_mode(bool b){
	game_state->contextual_info->visible = b;
}

void toggle_contextual_info_mode(void){
	game_state->contextual_info->visible = !game_state->contextual_info->visible;
}

#ifndef NOSOUND

void sp_volume(int i){
	if(Config::is_sound_enabled()){
		sp->set_volume(i);
	}
}

void sp_enable(bool b){
	if(Config::is_sound_enabled()){
		sp->set_enabled(b);
	}
}

#endif

int save_game(const char*filename){
	int r;
	r = xml_save_game(game_state, filename);
	return r;
}

State* load_game(const char*filename){
	return xml_load_game(filename);
}

#ifndef NONET
int net_send_msg(char * msg){
	if(!net) {
		if(screens && screens->get_type()==SCREEN_NETWORK) {
			screens->net_send_msg(msg);
		}
		else { 
			return -1;
		}
	}
	else {
		net->send_msg("C:%s",msg);
		console->print("%s: %s",net->get_nickname(),msg);
	}

	return 0;
}

int handle_network_msg(void){
	if(!net) return -1; // safety test
	
	char* msg = net->rcv_msg(10); // 10 ms d'attente;
	if(msg && strlen(msg)>0 )
		console->print("%s: %s", net->get_adversary_nickname(), msg+2);
	return 0; 
}
#endif //NONET

int main(int argc, char ** argv){
  
	init();

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->play_sound(SND_ROAR,FX0_CHANNEL);
	}
#endif

#ifndef NOVIDEO
	if(Config::is_video_enabled()){
		mp->play_video(MOV_INTRO, screen);
	}
#endif

#ifndef NOSOUND
	if(Config::is_sound_enabled()){
		sp->stop_sound(FX0_CHANNEL);
		sp->play_sound(SND_FANFARE,FX0_CHANNEL);
	}
#endif

  switch_screens();
  return 0;
}

