/*   Copyright 2005,2006 Paweł Niegowski
*
*    This file is part of Fenrir.
*
*    Fenrir 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.
*
*    Fenrir 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 Fenrir; if not, write to the Free Software
*    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef PLAYER_H_INCLUDE
#define PLAYER_H_INCLUDE
#include "object.h"
#include <nl.h>
#include <list>
using namespace std;

#define DIR_UP 0
#define DIR_RIGHT 1
#define DIR_DOWN 2
#define DIR_LEFT 3

#define ST_STR 0
#define ST_VIT 1
#define ST_DEX 2
#define ST_AGI 3
#define ST_INT 4
#define ST_WIL 5

#define KEYMAP_UP 0
#define KEYMAP_DOWN 1
#define KEYMAP_LEFT 2
#define KEYMAP_RIGHT 3
//power attack
#define KEYMAP_A 4
//skill
#define KEYMAP_B 5
//L (shift)
#define KEYMAP_L 6
//attack
#define KEYMAP_X 7
//guard / target
#define KEYMAP_Y 8
//R (shift)
#define KEYMAP_R 9
#define KEYMAP_NUM 10


//current number of frames per player
#define SPRITE_MAX  51
#define SPRITE_W 32
#define SPRITE_H 32
#define CLASS_MAX 256
//max different head types (both male and female)
#define HEAD_MAX 32
#define HEAD_W 16
#define HEAD_H 16
//time between combat action and regen ability, in frames
#define REGEN_DELAY 600

struct DATAFILE;
struct BITMAP;
class Ghost;

struct _anim
{
 _anim(int f,int d) : frame(f), duration(d) {}
 int frame;
 int duration;
};

//base class for both Player and OtherPlayer
class PlayerBase : public Object
{
 public:
 PlayerBase();
 virtual ~PlayerBase();
 void setx(int _x) { fx = x = _x; }
 void sety(int _y) { fy = sort_y = y = _y; }
 virtual void think();
 virtual void draw_upper();
 virtual void draw_lower();
 virtual void display_name();
 virtual void reload_sprites(unsigned char *data);
 virtual void attack(int target, Packet *attack_data);
 virtual void combat_hit(int target, Packet *attack_data, int num);
 virtual void evade(int effect_duration);
 virtual void get_dmg(unsigned int dmg, int delay, float _vx, float _vy);
 virtual void load_sprites(int body, int head, int headgear, unsigned int body_pal, unsigned int head_pal, unsigned int headgear_pal);
 void effect_colorize(int color, int l);
 virtual void anim_select();
 bool _is_in_front(Object *o);
 void _turn_to_target(Object *o);

 BITMAP* get_head();
 //returns a bitmap of the character facing south (for menu etc.)
 BITMAP* get_front_sprite();
 BITMAP* get_current_sprite();
 void _draw();
 Ghost *eva_1,*eva_2;
 char name[17];
 list<_anim> anim_queue;
 //a counter for "delaying" movement animation after the character stopped moving
 int move_anim_delay;
 bool moved;
 bool die_blur;
 bool last_frame_moved;
 float fx, fy;
 int walk_anim_counter,walk_anim_frame;
 int anim_current_frame;
 BITMAP *sprites[SPRITE_MAX];
 BITMAP *head_sprite;
 BITMAP *temp_sprite;
 int job;
 //if 0, no colorization is performed
 int colorize_color;
 int colorize_phase;
 int colorize_speed, colorize_timer;
};

class Player : public PlayerBase
{
 public:
 Player(unsigned char *data, int length);
 void think();
 void attack(int target, Packet *attack_data);
 void get_dmg(unsigned int dmg, int delay, float _vx, float _vy);
 void input_attack(int attack_key);
 //sets the camera on player position instantly
 void set_cam();

 int hard_delay, soft_delay;
 NLtime hard_time, soft_time;
 long int range;
 unsigned int hp, mhp, mp, mmp, st, level;
 bool attack_a_pressed,attack_x_pressed;
 unsigned short stat[6];
 protected:

 int stamina_regen_counter;
 int send_packet_timer;
};

class OtherPlayer : public PlayerBase
{
 public:
 OtherPlayer(unsigned char *data, int length);
 void think();
 void get_dmg(unsigned int dmg, int delay, float _vx, float _vy);
 void attack(int target, Packet *attack_data);
};

extern unsigned int free_statpoints;
extern char aura_current[3],aura_target[3];
//regeneration energy
extern char energy;
extern long regen_timer;

extern bool pvp_mode;
//manual guard/attack aim?
extern bool fencing_expert_mode;
extern DATAFILE *player_sprites[CLASS_MAX];
extern DATAFILE *head_sprites[HEAD_MAX];
extern int player_sprites_headx[CLASS_MAX][SPRITE_MAX];
extern int player_sprites_heady[CLASS_MAX][SPRITE_MAX];
extern Player *player;
extern int keymap[KEYMAP_NUM];

void create_player(unsigned char *playerdata, int length);
void player_init();
void player_load_defs();
#endif
