/* Bob */

#include <math.h>
#include "main.h"
#include "tilemap.h"
#include "sprite.h"
#include "sprhelp.h"
#include "player.h"
#include "collide.h"
#include "log.h"
#include "s_player.h"
#include "s_animal.h"
#include "s_pwrup.h"
#include "player.h"
#include "timeloop.h"
#include "s_exps.h"

#define SQDIST3(x, y, z) ((x)*(x) + (y)*(y) + (z)*(z))
#define SQ(x) ((x)*(x))

#define MAX_POWERUPS 25
int NumPowerups = 0;


const int powerup_freq[N_POWER_UPS] = {
	17,
	 4,
	 7,
	 2,
	25,
	14,
	 5,
	13,
	 9,
	 5,
	 9
};
/*
#define POWERUP_NONE            0
#define POWERUP_MYSTERY         1
#define POWERUP_HEALTH          2
#define POWERUP_INVULNERABILITY 3
#define POWERUP_BOMB            4
#define POWERUP_SPEED_BOOST     5
#define POWERUP_JUMP            6
#define POWERUP_MAGBOMBS        7
#define POWERUP_BOMB_LAUNCHER   8
#define POWERUP_SEEKING_BOMB    9
#define POWERUP_MINE_BOMB      10
*/

char *powerup_names[N_POWER_UPS];


/* Assumes sprite passed is an animal. */
void spawn_powerup(SPRITE *sprite) {

	SPRITE *newsprite;
	POWERUP *p;

	if (NumPowerups >= MAX_POWERUPS)
		return;

	newsprite = spawn_sprite(sprite);
	NumPowerups++;

	ASSERT(sprite->type == SPRITE_TYPE_ANIMAL);

	newsprite->life = 1; /* Alive - not really, but like it that way ;) */

	newsprite->type = SPRITE_TYPE_PWRUP;

	newsprite->th = RND(2 * M_PI);

	newsprite->x = sprite->x;
	newsprite->y = sprite->y;
	newsprite->z = sprite->z;

	newsprite->xv = 0;
	newsprite->yv = 0;
	newsprite->zv = 0.01;
	newsprite->thv = 0;

	newsprite->r = 0.01;

	newsprite->cur_frame = 0;
	newsprite->num_frames = N_POWERUP_ANIM_FRAMES;
	newsprite->anim = Powerup[((ANIMAL*)sprite->data)->powerup];
	newsprite->anim_speed = 4300;

	p = newsprite->data = malloc(sizeof(POWERUP));
    if (!p) exit(37);
	p->powerup = ((ANIMAL*)sprite->data)->powerup;

	/* Make explosive powerup */
	if ((random() % 10) < 1)
		p->explosive = -1;
	else
		p->explosive = 0;
}



void draw_powerup(BITMAP *bmp, SPRITE *sprite, float cth) {

	/* POWERUP *powerup = ((POWERUP*)sprite->data); */

	(void)cth;

	draw_generic_sprite(bmp, sprite, sprite->anim[sprite->cur_frame >> 16], POLYTYPE_ATEX_MASK);
}



/* sprite_tilemap_collision() callback; see collide.h. */
static void stc_powerup(TILEMAP *map,
                       SPRITE *sprite,
                       float xi, float yi, float zi,
                       float iv,
                       int xt, int yt,
                       TILE *tile, TILE_SURFACES *hit) {

 (void)xi; (void)yi; (void)zi;

 if (xt >= 0) {
  /* This is not perfect at all */
  create_disturbance(map->ripple_info,
                     tile->ripples,
                     sprite->x - xt, sprite->y - yt, sprite->r, -1000000*iv*hit->s[TILE_SURFACE]);
 }
}



void update_powerup(TILEMAP *map, SPRITE *sprite) {

	/* POWERUP *powerup = sprite->data; */
    if (sprite->r < 0.4) {
	    sprite->r += 0.01;
	    if (sprite->r > 0.4)
		    sprite->r = 0.4;
        sprite_tilemap_collision(map, sprite, NULL);
    }

	sprite->zv -= 0.001;

	extrapolate_sprite(sprite);
	sprite_tilemap_collision(map, sprite, stc_powerup);

	sprite->cur_frame += sprite->anim_speed;
	if (sprite->cur_frame >= itofix(sprite->num_frames))
		sprite->cur_frame = 0;
}


void free_powerup_data(void *p) {

	free(p);
	NumPowerups--;

	if (NumPowerups < 0) 
		LOG(ERROR "s_pwrup::free_powerup: Consistency error, freed more than created!\n");
}


/* Powerup-player interaction */
void si_player_powerup(TILEMAP *map, SPRITE *spr1, SPRITE *spr2) {

	SPRITE *powerup, *player;
	float d;

	(void)map;

	/* Find out who's who */
	if (spr1->type == SPRITE_TYPE_PWRUP) {
		powerup = spr1;
		player = spr2;
	}
	else {
		powerup = spr2;
		player = spr1;
	}

	if (powerup->r < 0.4)
		return;

	/* Distance check */
	d = SQDIST3(spr1->x - spr2->x, spr1->y - spr2->y, spr1->z - spr2->z);

	/* Collision? */
	if (d <= SQ(spr1->r + spr2->r)*2) {
		POWERUP *p = ((POWERUP*)powerup->data);
		PLAYER *p2 = ((PLAYER*)player->data);

		/* Player already has stuff - abort */
		if (p2->held_powerup)
			return;

		/* Remove poweup */
		powerup->life = 0;

		p2->points += 25;

		/* Check gained powerup */
		if (p->explosive) {
			/* Suckered - exploding powerup! */
            create_explosion(player, 50);
		}
		else {
			/* Give powerup to player */
			p2->held_powerup = p->powerup;

			if (p->powerup == POWERUP_MYSTERY)
				p2->held_powerup = (random() % (N_POWER_UPS - 2)) + 2;

			p2->powerup_time = game_time;
		}
	}
}


void init_powerups() {

	int i;
	const char *names[N_POWER_UPS] = {
		"None", "Mystery", "Health", "Invulnerability", "ExtraBombs",
		"SpeedBoost", "Jump", "MagBomb", "BombLauncher", "SeekingBomb", "MineBomb"}
	;

	for (i = 0; i < N_POWER_UPS; i++)
		powerup_names[i] = (char*)translate(names[i]);

	return;
}
