/* Spark stuff for Gradient Wars

   By James Stanley

   No license - Use as you wish */

#include "sparks.h"

spark_t *spark_list;
spark_t *last_spark;

void new_spark(fixed x, fixed y, fixed xs, fixed ys, fixed yss, int r, int g, int b, int colspeed, int ttl) {
  spark_t *spark;
  
  spark = malloc(sizeof(spark_t));
  spark->x = x;
  spark->y = y;
  spark->xs = xs + ftofix(((rand()%40)/10.0)-2);
  spark->ys = ys + ftofix(((rand()%40)/10.0)-2);
  spark->yss = yss;
  spark->r = r;
  spark->g = g;
  spark->b = b;
  spark->colspeed = colspeed;
  spark->ttl = ttl;
  spark->next = NULL;
  
  if(spark_list) {
    spark->prev = last_spark;
    last_spark->next = spark;
  } else {
    spark->prev = NULL;
    spark_list = spark;
  }
  
  last_spark = spark;
}

void del_spark(spark_t *spark) {
  if(spark->next) {//If there's a next spark, update it's prev pointer
    spark->next->prev = spark->prev;
  } else {//spark == last_spark
    last_spark = spark->prev;
    if(last_spark) last_spark->next = NULL;
  }

  if(spark->prev) {
    spark->prev->next = spark->next;
  } else {//spark == spark_list
    spark_list = spark->next;
    if(spark_list) spark_list->prev = NULL;
  }

  free(spark);
}

void new_explosion(fixed x, fixed y) {
  fixed angle;
  
  for(angle = 0; angle < itofix(256); angle += itofix(4)) {
    new_spark(x, y, fixcos(angle)*5, fixsin(angle)*5, ftofix(0.25), 255, 255, 512, 24, 25);
  }
}

void new_thrust(fixed x, fixed y, fixed ang) {
  fixed angle;
  
  for(angle = ang-itofix(8); angle <= (ang+itofix(8)); angle += itofix(4)) {
    new_spark(x, y, fixcos(angle)*5, fixsin(angle)*5, 0, 255, 255, 255, 48, 10);
  }
}

void update_sparks(void) {
  spark_t *spark;
  spark_t *spark_next;
  
  for(spark = spark_list; spark; spark = spark_next) {
    spark_next = spark->next;
    
    if(spark->b > 0) spark->b -= spark->colspeed;
    else if(spark->g > 0) spark->g -= spark->colspeed;
    else if(spark->r > 0) spark->r -= spark->colspeed;
    
    spark->ys += spark->yss;
    
    spark->ttl--;
    if(spark->ttl < 0) {
      del_spark(spark);
    } else {
      if(spark->b < 0) spark->b = 0;
      if(spark->g < 0) spark->g = 0;
      spark->x += spark->xs;
      spark->y += spark->ys;
    }
  }
}

void draw_sparks(BITMAP *canvas, int menu) {
  spark_t *spark;
  int ox, oy;
  
  if(menu) {
    ox = 0;
    oy = 0;
  } else {
    ox = offsetx;
    oy = offsety;
  }
  
  for(spark = spark_list; spark; spark = spark->next) {
    line(canvas, ox+fixtoi(spark->x), oy+fixtoi(spark->y), ox+fixtoi(spark->x + (spark->xs*2)), oy+fixtoi(spark->y + (spark->ys*2)), mymakecol(spark->r, spark->g, MIN(spark->b, 255)));
    //circlefill(canvas, ox+fixtoi(spark->x), oy+fixtoi(spark->y), 4, mymakecol(spark->r, spark->g, MIN(spark->b, 255)));
    //circle(canvas, ox+fixtoi(spark->x), oy+fixtoi(spark->y), 4, mymakecol(spark->r, spark->g, MIN(spark->b, 255)));
    //rect(canvas, ox+fixtoi(spark->x), oy+fixtoi(spark->y), ox+fixtoi(spark->x + (spark->xs*4)), oy+fixtoi(spark->y + (spark->ys*4)), mymakecol(spark->r, spark->g, MIN(spark->b, 255)));
    //rectfill(canvas, ox+fixtoi(spark->x), oy+fixtoi(spark->y), ox+fixtoi(spark->x + (spark->xs*4)), oy+fixtoi(spark->y + (spark->ys*4)), mymakecol(spark->r, spark->g, MIN(spark->b, 255)));
  }
}
