/* 
    TowBowlTactics: Strategy game for X11

    Copyright (C) 2001 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.
*/

#ifndef MAIN_H
#define MAIN_H

#include "global.h"

#include "panel.h"
#include "skills.h"

#include "XmlParser.h"
#include "Team.h"
#include "Ball.h"
#include "Public.h"
#include "DialogBox.h"
#include "Transformation.h"
#include "ProgressBar.h"
#include "Console.h"
#include "Shared.h"
#include "Formation.h"
#include "State.h"
#include "Config.h"

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

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

#include "dir_func.h"

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

#include <SDL/SDL_image.h>
#ifndef _IMG_h
#include <SDL_image.h>
#endif

#define VERSION "version 0.5"
#define CAPTION "Tow Bowl Tactics - toweld@rocketmail.com - " VERSION " (" __DATE__ " " __TIME__") "

#define WIDTH 800
#define HEIGHT 600
#define FPS 15

#define FRAME_LIMIT (Config::get_screen_w() - 300)
#define FRAME_LINE 2

#define PLAYGROUND_X 0
#define PLAYGROUND_Y 0

#define ACTIONS_MENU_WIDTH 120
#define ACTIONS_MENU_HEIGHT 240
#define ACTIONS_MENU_ITEM_HEIGHT 40

#define ACTIONS_MENU_ALPHA_INC 75

#define MODE_TEAM_PLACEMENT 0
#define MODE_BALL_PLACEMENT 1
#define MODE_CHOOSE_BALL_OWNER 2
#define MODE_PLAYING 3
#define MODE_SURPRISE 4

#define ACTIONS_MOVE 0
#define ACTIONS_MOVE_PLUS 1
#define ACTIONS_BLOCK 2
#define ACTIONS_GATHER 3
#define ACTIONS_THROW 4
#define ACTIONS_AGGRESS 5
#define ACTIONS_BLITZ 6
#define ACTIONS_ROLL_OVER 7
#define ACTIONS_GET_UP 8
#define ACTIONS_TRANSMIT 9
#define ACTIONS_CHOOSE_TEAM_MATE 10
#define ACTIONS_LEAP 11
#define ACTIONS_PUSH_PLAYER 12
#define ACTIONS_PUSH_AND_HIT_PLAYER 13
#define ACTIONS_RECEIVE 14
#define ACTIONS_INTERCEPTION_ATTEMPT 15
#define ACTIONS_CHOOSE_INTERCEPTION_SQUARE 16
#define ACTIONS_CHOOSE_INDIRECT_PUSH_SQUARE 17
#define ACTIONS_INDIRECT_PUSH 18
#define ACTIONS_INDIRECT_PUSH_PLAYER_OUT 19
#define ACTIONS_INDIRECT_PUSH_AND_HIT 20
#define ACTIONS_CHOOSE_INDIRECT_PUSH_AND_HIT_SQUARE 21
#define ACTIONS_CHOOSE_TRANSMIT_SQUARE 22
#define ACTIONS_MOVE_AND_BLITZ 23
#define ACTIONS_PUSH_PLAYER_OUT 24
#define ACTIONS_CHOOSE_PUSH_SQUARE 25
#define ACTIONS_THROW_TEAM_MATE 26
#define ACTIONS_LANDING 27
#define ACTIONS_CHOOSE_PUSH_AND_HIT_SQUARE 28
#define ACTIONS_DOUBLE_INDIRECT_PUSH 29
#define ACTIONS_DOUBLE_INDIRECT_PUSH_PLAYER_OUT 30
#define ACTIONS_DOUBLE_INDIRECT_PUSH_AND_HIT 31
#define ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_SQUARE 32
#define ACTIONS_CHOOSE_DOUBLE_INDIRECT_PUSH_AND_HIT_SQUARE 33


#define ACTIONS_MOVE_INDEX 0
#define ACTIONS_BLOCK_INDEX 1
#define ACTIONS_GATHER_INDEX 2
#define ACTIONS_THROW_INDEX 3
#define ACTIONS_AGGRESS_INDEX 4
#define ACTIONS_TRANSMIT_INDEX 5

#define ITEM_OFF 0
#define ITEM_ON 1
#define ITEM_UP 2

#define MARGIN_SIZE 7

#define MAX_DIFFERENT_PLAYER 5

#define OVER_PLAYGROUND(x,y) ((x>MARGIN_SIZE)&&(x<(PLAYGROUND_WIDTH*SQUARE_SIZE+MARGIN_SIZE))&&(y>MARGIN_SIZE)&&(y<(PLAYGROUND_HEIGHT*SQUARE_SIZE+MARGIN_SIZE)))
#define OVER_HOME_RESERVE(x,y) ((x>HOME_RESERVE_BOX_X-MARGIN_SIZE)&&(x<(HOME_RESERVE_BOX_X+RESERVE_BOX_W-4-MARGIN_SIZE))&&(y>HOME_RESERVE_BOX_Y-MARGIN_SIZE)&&(y<(HOME_RESERVE_BOX_Y+RESERVE_BOX_H-MARGIN_SIZE)))
#define OVER_VISITOR_RESERVE(x,y) ((x>VISITOR_RESERVE_BOX_X-MARGIN_SIZE)&&(x<(VISITOR_RESERVE_BOX_X+RESERVE_BOX_W-4-MARGIN_SIZE))&&(y>VISITOR_RESERVE_BOX_Y-MARGIN_SIZE)&&(y<(VISITOR_RESERVE_BOX_Y+RESERVE_BOX_H-MARGIN_SIZE)))
#define SQUARE_OVER_PLAYGROUND(x,y) ((x>=0)&&(x<PLAYGROUND_WIDTH)&&(y>=0)&&(y<PLAYGROUND_HEIGHT))
#define OVER_PANEL(x,y) (x>FRAME_LIMIT)
#define CLIC_INTO_RECT(a,b,c,d) (((event.button.x) > (a)) && ((event.button.x) < ((a)+(c))) && ((event.button.y) > (b)) && ((event.button.y) < ((b)+(d))))
#define FILTER_CLIC_INTO_RECT(a,b,c,d) (((event->button.x) > (a)) && ((event->button.x) < ((a)+(c))) && ((event->button.y) > (b)) && ((event->button.y) < ((b)+(d))))
#define PANEL_CLIC_INTO_RECT(a,b,c,d) (((event.button.x-FRAME_LIMIT) > (a)) && ((event.button.x-FRAME_LIMIT) < ((a)+(c))) && ((event.button.y) > (b)) && ((event.button.y) < ((b)+(d))))
#define MOUSE_OVER_RECT(a,b,c,d) (((event->motion.x) > (a)) && ((event->motion.x) < ((a)+(c))) && ((event->motion.y) > (b)) && ((event->motion.y) < ((b)+(d))))
#define PANEL_MOUSE_OVER_RECT(a,b,c,d) (((event->motion.x-FRAME_LIMIT) > (a)) && ((event->motion.x-FRAME_LIMIT) < ((a)+(c))) && ((event->motion.y) > (b)) && ((event->motion.y) < ((b)+(d))))
#define REL_MOUSE_OVER_RECT(a,b,c,d) (((x_mouse) > (a)) && ((x_mouse) < ((a)+(c))) && ((y_mouse) > (b)) && ((y_mouse) < ((b)+(d))))
#define REL_CLIC_OVER_RECT(a,b,c,d) (((x_mouse+MARGIN_SIZE) > (a)) && ((x_mouse+MARGIN_SIZE) < ((a)+(c))) && ((y_mouse+MARGIN_SIZE) > (b)) && ((y_mouse+MARGIN_SIZE) < ((b)+(d))))

#define NO_FRAME 0
#define LEFT_FRAME 1
#define RIGHT_FRAME 2

#define LEFT_BUTTON 1
#define MIDDLE_BUTTON 2
#define RIGHT_BUTTON 3
#define WHEEL_DOWN 4
#define WHEEL_UP 5

#define SIDE_STEP 25
#define MOUSE_STEP 25
#define KEY_STEP 25
#define PASS_STEP 20
 
#define SIDE_SIZE 5

#define CIRCLE_FRAME 3

#define STATUS_GROUND 0
#define STATUS_DOWN SQUARE_SIZE/2
#define STATUS_TOUCHED SQUARE_SIZE/2
#define STATUS_INJURED 3*SQUARE_SIZE/2
#define STATUS_DEAD 2*SQUARE_SIZE
#define STATUS_BALL 5*SQUARE_SIZE/2

#define RED_INDEX 0
#define GREEN_INDEX SQUARE_SIZE 
#define BLUE_INDEX 2*SQUARE_SIZE
#define BLACK_INDEX 3*SQUARE_SIZE
#define WHITE_INDEX 4*SQUARE_SIZE

#define ALPHA_SQUARES 50
#define ALPHA_DOTS 100
#define ALPHA_CROSSES 150
#define ALPHA_INTERCEPT 220
#define ALPHA_PUSH 220
#define ALPHA_RESERVE_NAV 100
#define ALPHA_RESERVE_NAV_UP 200

#define ALPHA_RAIN 220

#define NO_LIMIT 0
#define PUBLIC_W 87

#define ZOOM_FACTOR ((double)(Config::get_screen_h())/(pg->image->h))

#define PASS_ARROW_END_WIDTH 70

#define FLASH_PASS_INDEX 0
#define NORMAL_PASS_INDEX PASS_ARROW_END_WIDTH
#define LONG_PASS_INDEX 2*PASS_ARROW_END_WIDTH
#define BOMB_PASS_INDEX 3*PASS_ARROW_END_WIDTH

#define PUSH_OFF 0
#define PUSH_ON SQUARE_SIZE

#define INTERCEPT_OFF 0
#define INTERCEPT_ON SQUARE_SIZE
#define INTERCEPT_PIXEL_NEEDED ((SQUARE_SIZE*SQUARE_SIZE)/3) // moitie du player doit se trouver sous le gabarit

#define TURN_DURATION 240 // en secondes

#define HOME_EJECTED_BOX_X 646
#define HOME_EJECTED_BOX_Y 65
#define HOME_EJECTED_BOX_W 50
#define HOME_EJECTED_BOX_H 71

#define HOME_OUT_BOX_X 646
#define HOME_OUT_BOX_Y 154
#define HOME_OUT_BOX_W 50
#define HOME_OUT_BOX_H 83

#define HOME_KO_BOX_X 646
#define HOME_KO_BOX_Y 251
#define HOME_KO_BOX_W 50
#define HOME_KO_BOX_H 80

#define HOME_RESERVE_BOX_X 13 
#define HOME_RESERVE_BOX_Y 10 

#define VISITOR_EJECTED_BOX_X 646
#define VISITOR_EJECTED_BOX_Y 911
#define VISITOR_EJECTED_BOX_W 50
#define VISITOR_EJECTED_BOX_H 80

#define VISITOR_OUT_BOX_X 646
#define VISITOR_OUT_BOX_Y 815
#define VISITOR_OUT_BOX_W 50
#define VISITOR_OUT_BOX_H 83

#define VISITOR_KO_BOX_X 646
#define VISITOR_KO_BOX_Y 722
#define VISITOR_KO_BOX_W 50
#define VISITOR_KO_BOX_H 71

#define VISITOR_RESERVE_BOX_X 13
#define VISITOR_RESERVE_BOX_Y 195

#define RESERVE_BOX_W 80
#define RESERVE_BOX_H 120

#define RAIN_FRAME 3

#define TURN_PER_HALF 8

#define OVER_DOCK(a,b) ((a>(game_state->x_dock-1)) && (a<(game_state->x_dock+DOCK_W+2)) && (b>(game_state->y_dock-1)) && (b<(game_state->y_dock+DOCK_H+2)) ) 

#define SQUARE_TO_PIXEL(x) x*SQUARE_SIZE+MARGIN_SIZE
#define COLOR(x) x-1

#define PAUSE_DELAY 250

#define TOTAL_DATA 30

#define CONSOLE_WIDTH FRAME_LIMIT
#define CONSOLE_HEIGHT 91
#define CONSOLE_X 0
#define CONSOLE_Y ((Config::get_screen_h()) - (CONSOLE_HEIGHT))

typedef struct{
  SDL_Surface *image;
  int x,y;
  bool visible;
} graphical_object;

/* list of prototypes */
int rollover_actions_item(int,int);
SDL_Surface* load_image(char*,int);
int load_image_into(char*,int,graphical_object*);
int set_object_number(graphical_object*, int,int);
int load_game_data(int);
int load_minimum_data(void);
int free_game_data(void);
int free_minimum_data(void);
int filter_events(const SDL_Event*);
int init(void);
int init_game(team_summary_t*,team_summary_t*);
int draw_object_into(graphical_object*,SDL_Surface*,int,int,int);
void wait_for_next_frame(void);
int set_actions_menu(int,int,int);
int rollover_actions_item(int,int);
int build_actions_menu(int,int,int,int);
void show_actions_menu(bool,int,int,int,int);
int main_loop(void);
void toggle_tackle_zone_drawing_mode(void);
void draw_tackle_zone(Team *);
void draw_tackle_zone(Player *);
void draw_panel(bool);
void draw_playground(void);
void draw_actions_menu(void);
void draw_ball(void);
void draw_path(Path*,bool);
void draw_team(Team*,bool);
void draw_player(Player *,bool);
void draw_all(bool);
void draw_push_square_choice(void);
void draw_indirect_push_square_choice(void);
void draw_double_indirect_push_square_choice(void);
void draw_square(Square*, int);
void draw_cross(Square*,int);
void draw_selection(void);
void select_none(void);
void select_none(Team *);
void switch_action(int);
void switch_mode(int);
Path* make_path_to(int,int,int);
bool move_player(void);
void select_square(int,int);
void injure_player(Player*,int,bool);
void aggress_player(Player*,Player*);
void block_player(Player*,Player*);
void tackle_player(Player*,Player*,int,int,bool);
void draw_target(int,int,int);
void erase_panel(SDL_Rect*);
void erase_playground(bool);
void erase_square(Square*);
void move_playground(int, int);
void toggle_zoom_playground(bool);
graphical_object* make_pass_arrow(Square*,Square*,int);
void verify_ball_placement(void);
void draw_into_square(SDL_Surface*,Square,int);
void throw_in(void);
void draw_ticks(void);
void draw_panel_player_info(bool);
void fill_panel_player_info(Player*);
void draw_digit(int,SDL_Rect*,SDL_Surface*,SDL_Surface*);
void draw_number(int,SDL_Rect*,SDL_Surface*,SDL_Surface*,int);
void draw_string(char*,SDL_Rect*,SDL_Surface*,SDL_Surface*,SDL_Surface*);
void start_turn(int);
void stop_turn(void);
void check_for_multi_play(void);
void toggle_autocenter_mode(void);
void toggle_ticks_drawing_mode(void);
void pass(Player*,Square*);
void draw_pass_anim(Player*,Square*);
Square* random_move_target(Square*);
Square* random_move_target(int,int);
void autocenter(int,int);
void change_weather(void);
void draw_progress_bar(void);
void update_pass_arrow_matrix(SDL_Surface*);
void update_interception_squares(graphical_object*);
bool intercept_pass(Player*);
void update_push_squares(bool);
void update_indirect_push_squares(bool);
void update_double_indirect_push_squares(bool);
bool check_if_can_push_in_touch(void);
bool check_if_can_indirect_push_in_touch(void);
bool check_if_can_double_indirect_push_in_touch(void);
void update_transmit_squares(Player*);
void draw_weather_effects(void);
void draw_reserve_navigator(void);
bool is_good_location(Player*,int,int);
bool is_good_formation(int);
void erase_panel_player_info(void);
void draw_future_tackle_zone(Player*,Square*);
void stop_placement(void);
void start_placement(int);
void kick_off(Square*);
bool touchdown(void);
void prepare_for_next_kick_off(void);
void toss(void);
void half_time(void);
bool check_for_end_of_half(void);
void full_time(void);
void turnover(int,int);
void extra_time(void);
bool everybody_has_played(int);
void reset_vars(void);
void toggle_pause(bool);
void quit_game(void);
void quit_game_box(void);
void draw_pause_screen(void);
SDL_Rect rect_union(SDL_Rect,SDL_Rect);
void update_cliprects(bool);
bool rect_into_rect(SDL_Rect,SDL_Rect);
void handle_time(void);
void toggle_grab_mouse_mode(bool);
void handle_kick_off_event(void);
void switch_screens(void);
void set_ticks_drawing_mode(bool);
void set_tackle_zone_drawing_mode(int);
bool rect_intersect_rect(SDL_Rect,SDL_Rect);
void set_debug(bool);
void show_dices_roll(bool);
void change_formation(int, int);
int save_game(const char*);
State* load_game(const char*);
int get_weather(void);
void throw_team_mate(Player*, Player*, Square*);
void draw_throw_team_mate_anim(Player*,Player*,Square*);
void set_weather(int);
void draw_kick_off_anim(Square *);
void toggle_number_drawing_mode(void);
void set_number_drawing_mode(bool);
void set_contextual_info_mode(bool);
void toggle_contextual_info_mode(void);
void set_contextual_info(int,int,char*,...);
void draw_contextual_info(bool);
void unset_contextual_info(void);
int get_rate_of_success(void);
int get_success_floor(void);
int init_game_from_save(State*);
///////////////////////////////
// Ragnar Modif6 : bone head et really stupid
void test_stupidness(Player*);
///////////////////////////////

#ifndef NONET
int net_send_msg(char *);
int handle_network_msg(void);
#endif

#ifndef NOSOUND
void sp_volume(int);
void sp_enable(bool);
#endif


#endif /*MAIN_H*/

