#include <math.h>
#include "main.h"
#include "tilemap.h"
#include "sprite.h"
#include "s_blood.h"
#include "log.h"



SPRITE *spawn_blood(SPRITE *sprite, float radius, float maxspeed) {

 SPRITE *newsprite = spawn_sprite(sprite);
 float r, a;

 newsprite->life = 1;

 newsprite->type = SPRITE_TYPE_BLOOD;

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

 newsprite->zv = RND(1.9999) - 0.99995;

 r = sqrt(1.0 - newsprite->zv * newsprite->zv);
 a = RND(2 * M_PI);

 newsprite->xv = r * cos(a);
 newsprite->yv = r * sin(a);

 r = RND(maxspeed);

 newsprite->xv *= r;
 newsprite->yv *= r;
 newsprite->zv *= r;

 newsprite->xv += sprite->xv;
 newsprite->yv += sprite->yv;
 newsprite->zv += sprite->zv;

 newsprite->r = radius;

 return newsprite;
}



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

 int red = makecol(192, 0, 0);

 (void)cth;

 if (sprite->xrad > 2.0) {
  if (sprite->yrad > 2.0) {
   ellipsefill(bmp, (int)floor(sprite->xview), (int)floor(sprite->yview),
                    (int)floor(sprite->xrad), (int)floor(sprite->yrad), red);
  } else {
   hline(bmp, (int)floor(sprite->xview - sprite->xrad),
              (int)floor(sprite->yview),
              (int)floor(sprite->xview + sprite->xrad), red);
  }
 } else {
  if (sprite->yrad > 2.0) {
   vline(bmp, (int)floor(sprite->xview),
              (int)floor(sprite->yview - sprite->yrad),
              (int)floor(sprite->yview + sprite->yrad), red);
  } else {
   putpixel(bmp, (int)floor(sprite->xview), (int)floor(sprite->yview), red);
  }
 }
}



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

 float x, y, z;
 int xi, yi;
 TILE *tile;
 float factor;

 sprite->zv -= 0.001;

 sprite->x += sprite->xv;
 sprite->y += sprite->yv;
 sprite->z += sprite->zv;

 x = floor(sprite->x);
 y = floor(sprite->y);

 xi = (int)x;
 yi = (int)y;

#define BLOOD_INCREASE (10.0 * sprite->r * sprite->r)

#define OUTER_WALL_FACTOR 0.1
#define MIN_FACTOR 0.1

 /* They should hit the walls */
 if (xi < 0) {
  map->tile[MID(0, yi, map->h-1)][0].blood.s[TILE_WALL_L] += OUTER_WALL_FACTOR * BLOOD_INCREASE;
  sprite->life = 0;
  return;
 }

 if (xi >= map->w) {
  map->tile[MID(0, yi, map->h-1)][map->w-1].blood.s[TILE_WALL_R] += OUTER_WALL_FACTOR * BLOOD_INCREASE;
  sprite->life = 0;
  return;
 }

 if (yi < 0) {
  map->tile[0][xi].blood.s[TILE_WALL_T] += OUTER_WALL_FACTOR * BLOOD_INCREASE;
  sprite->life = 0;
  return;
 }

 if (yi >= map->h) {
  map->tile[map->h-1][xi].blood.s[TILE_WALL_B] += OUTER_WALL_FACTOR * BLOOD_INCREASE;
  sprite->life = 0;
  return;
 }

 tile = &map->tile[yi][xi];

 if (sprite->z < tile->z) {

  x = sprite->x - x;
  y = sprite->y - y;

  z = tile->z - sprite->z;

  /* First Blood of War */
  if (z < x && z < 1.0 - x && z < y && z < 1.0 - y) {
   tile->blood.s[TILE_SURFACE] += BLOOD_INCREASE;
  } else {
   if (y < x) {
    if (y < 1.0 - x) {
     if (yi > 0) {
      factor = tile->z - map->tile[yi-1][xi].z;
      factor = BLOOD_INCREASE / MAX(factor, MIN_FACTOR);
      tile->blood.s[TILE_WALL_T] += factor;
     } else {
      tile->blood.s[TILE_SURFACE] += BLOOD_INCREASE;
     }
    } else {
     if (xi < map->w - 1) {
      factor = tile->z - map->tile[yi][xi+1].z;
      factor = BLOOD_INCREASE / MAX(factor, MIN_FACTOR);
      tile->blood.s[TILE_WALL_R] += factor;
     } else {
      tile->blood.s[TILE_SURFACE] += BLOOD_INCREASE;
     }
    }
   } else {
    if (y < 1.0 - x) {
     if (xi > 0) {
      factor = tile->z - map->tile[yi][xi-1].z;
      factor = BLOOD_INCREASE / MAX(factor, MIN_FACTOR);
      tile->blood.s[TILE_WALL_L] += factor;
     } else {
      tile->blood.s[TILE_SURFACE] += BLOOD_INCREASE;
     }
    } else {
     if (yi < map->h - 1) {
      factor = tile->z - map->tile[yi+1][xi].z;
      factor = BLOOD_INCREASE / MAX(factor, MIN_FACTOR);
      tile->blood.s[TILE_WALL_B] += factor;
     } else {
      tile->blood.s[TILE_SURFACE] += BLOOD_INCREASE;
     }
    }
   }
  }

  sprite->life = 0;
 }
}
