//a class to hold a single weapon type. It handles drawing, rotating, and
//firing of the weapon
class weapon
	{
     private:
     	float x,y;
        int plus_x,plus_y;   //the amount to offset the weapon picture from the
        //centre of the character's picture

        char name[20];
        BITMAP *pic;

        //the real angle is the angle to be used (out of a 256 degree circle)
        //the gun angle is the angle of the gun in relation its starting positon
        int real_angle, gun_angle;

        //the dx and dy to be passed to particles shot
        float p_dx,p_dy;

        float mussle_x, mussle_y;  //represent the position of the tip of the gun
        float shell_x, shell_y;

        //the attribute set to be passed to any particles fired by this weapon
        part_att p_att;

        //the amount of loops left befor eit can be fired again
        int cool_left;
        int ammo;
        int gun_dir;

     public:
     	//creates weapon with given picture, particle attributes, and plus_x,plus_y
     	void init(BITMAP *ppic, part_att att, int px, int py, char nname[20]);
        //draw it on backgr int realtion to s_x, s_y
        void draw(BITMAP *backgr,BITMAP *arm_pic, float s_x, float s_y, float p_x,float p_y);
        //update info (angle, postion, counters, at player postion of px,py
        void update(int dir, float px, float py);
        //aim gun down more
        void down(void);
        //aim gun up more
        void up(void);
        //fires projectile passed to it by the object class
        //and shoots off an empty shell passed to it be the part_set class
        void fire(projectile *proj, part_set *parts);

        //return particle dx and dy
        float send_dx(void);
        float send_dy(void);

        void write_name(BITMAP*backgr,int xx, int yy, int c, FONT *f);

        int send_angle(int n);
        void set_angle(int angle);

        int send_ammo(void);
        void set_ammo(int n);
        int send_cool(void);
        void norm(void);
    };

int weapon::send_cool(void)
	{
     return cool_left;
    }

int weapon::send_ammo(void)
	{
     return ammo;
    }

void weapon::set_ammo(int n)
	{
     ammo=n;
    }

void weapon::set_angle(int angle)
	{
    // if(n==1)
     gun_angle=angle;
    }

int weapon::send_angle(int n)
    {
    if(n==1)
    	return real_angle;
    else if(n==2)
      	return gun_angle;
    }

float weapon::send_dx(void)
	{
     return p_dx;
    }

float weapon::send_dy(void)
	{
     return p_dy;
    }

void weapon::fire(projectile *proj, part_set *parts)
	{
     if(cool_left<=0)//if ready to fire again
       {
        //fires projectile with the weapon's attribute set, starting at
        //the weapon's mussle position.
     	proj->fire(p_att,mussle_x,mussle_y,p_dx,p_dy, real_angle);

        //calculates the delta x and delta y for the shell to be fired
        //at a random angle
        int a=rand()%40;
        a-=20;
        float t_dx,t_dy;
        t_dx= sin( (a*1.40625) *M_PI/180);
     	t_dy=-cos( (a*1.40625) *M_PI/180);

        play_sample(p_att.sound,255,128,1000,FALSE);

        parts->create_new(shell_x,shell_y,64,p_att.shell_pic,1,t_dx,t_dy);
        //destroy_bitmap(temp);

        //sets cool counter to cooldown time from the projectile set
        cool_left = p_att.cool;
       }
    }

void weapon::down(void)
	{
    // if(gun_angle<90)
    //   gun_angle+=5;
    
    gun_angle = 80;
    }
void weapon::up(void)
	{
     //if(gun_angle>25)
     //  gun_angle-=5;
     
     gun_angle = 30;
    }
    
void weapon::norm(void)
    {
     gun_angle=64;
    }

void weapon::update(int dir, float px, float py)
	{
     gun_dir=dir;

     while(gun_angle>256)
       gun_angle-=256;
     while(gun_angle<0)
       gun_angle+=256;

     if(gun_angle < 25)
       gun_angle=25;
     else if(gun_angle >90)
       gun_angle=90;

     //gets real_angle for gun from the gun_angle based on the player's direction
     if(dir==1)
       {
        if(plus_x<0)
          plus_x*=-1;
        real_angle=gun_angle;
       }
     else if(dir==2)
       {
        if(plus_x>0)
        	plus_x*=-1;
        real_angle=256-gun_angle;
       }

     //gets the dx and dy for the projectiles from the real gun angle
     p_dx= sin( (real_angle*1.40625) *M_PI/180);
     p_dy=-cos( (real_angle*1.40625) *M_PI/180);

     //updates the x and y of the gun to the new player's position
     x=px;
     y=py;

     x+=p_dx*17;
     y+=p_dy*17;

     //sets the mussle postion using the player's picture size and the angle of the gun
     mussle_x= x+pic->w/2;//+plus_x-12+(p_dx*10) + pic->w/2;
     mussle_y= y+pic->h/2;//+plus_y-12+(p_dy*10) + pic->h/2;

     //sets the shell postion using the player's picture size and the angle of the gun
     shell_x= x+plus_x-5/*+(p_dx*2)*/ + pic->w/2;
     shell_y= y+plus_y-12/*+(p_dy*2)*/ + pic->h/2;

     if(cool_left>0)
       cool_left--;

     }

void weapon::draw(BITMAP *backgr,BITMAP *arm_pic, float s_x, float s_y, float p_x, float p_y)
	{
     BITMAP *temp_gun, *temp_arm;
     int draw_angle=gun_angle;
     int pivot_y,pivot_x;  //the y position for the gun to pivot about
     int g_p_x,g_p_y;

     int pivot_plus_y;

     pivot_plus_y = arm_pic->h-pic->h;

     temp_gun=create_bitmap(pic->w,pic->h);
     rectfill(temp_gun,0,0,pic->w,pic->h,0);

     temp_arm=create_bitmap(arm_pic->w,arm_pic->h);
     rectfill(temp_arm,0,0,arm_pic->w,arm_pic->h,0);

     draw_angle=gun_angle;

     if(gun_dir==1)
       {
        //facing right, so draw gun & arm onto temp facing normal
     	draw_sprite(temp_gun,pic,0,0);
        draw_sprite(temp_arm,arm_pic,0,0);

        //set the pivot postion for the arm
        pivot_y=arm_pic->h;
        pivot_x=arm_pic->w/2;

        //set the pivot postion for the gun
        g_p_y=pivot_y;
        g_p_x=5;
       }
     else if(gun_dir==2)
       {
        //facing left, so draw gun & arm onto temp upside-down
        //I must invert the pictures becuase it will be drawn at an angle
        //greater that 128 (180), so it must be flipped to appear upright
        draw_sprite_v_flip(temp_gun,pic,0,0);
        draw_sprite_v_flip(temp_arm,arm_pic,0,0);

        pivot_y=3;
        pivot_x=5;

        g_p_y=pivot_y - pivot_plus_y;
        g_p_x=5;

        //adjust the drawing angle to compensate for the gun & arm being
        //drawn upside-down
        if(gun_angle>64)
          {
           draw_angle -= (gun_angle-64) * 2;
          }
        else if(gun_angle<64)
          {
           draw_angle += (64-gun_angle) *2;
          }
       }

	  pivot_sprite(backgr,temp_gun,
             (int)x+plus_x-(int)s_x,
             (int)y+plus_y-(int)s_y,
             g_p_x,g_p_y,
             itofix(draw_angle));

     //draws arm in correct place on person at the same angle as the gun
      pivot_sprite(backgr,temp_arm,
        (int)p_x+14-(int)s_x,(int)p_y+20-(int)s_y,
        pivot_x,pivot_y,
        itofix(draw_angle));
    }

void weapon::init(BITMAP *ppic,part_att att, int px, int py, char nname[20])
	{
     x=0;
     y=0;
     plus_x=px;
     plus_y=py;
     pic=ppic;

     //starting angle of 64 degrees (equivalent of 90 degrees)
     real_angle=64;
     gun_angle=64;

     p_dx=0;
     p_dy=0;

     //sets the attribute set for any fired projectiles
     p_att=att;
     cool_left=0;

     strcpy(name,nname);
    }

void weapon::write_name(BITMAP *backgr, int xx, int yy, int c, FONT *f)
	{
     textprintf_centre(backgr,f,xx,yy,c,"%s",name);
	}
