/* Drawing stuff for gradient wars

   By James Stanley

   No license - Use as you wish */

#include "draw.h"

BITMAP *bg;
BITMAP *menu_bg;
BITMAP *player;
BITMAP *plainplayer;
BITMAP *player_mask;
BITMAP *bullet1;
BITMAP *hud;
BITMAP *enemy_img[ENEMIES];
BITMAP *powerup_img[POWERUPS];

FONT *numbers;

unsigned short magic_pink, cyan, yellow;

fixed noise[HEIGHT/8][WIDTH/8];

char text[48][32];
int textdata[48][4];

int offsetx, offsety;
int draw_alg = 0;
int colour[DRAW_ALGS];
int inv_col[DRAW_ALGS];

void init_colours(void) {
  magic_pink = mymakecol(255, 0, 255);
  cyan = mymakecol(0, 255, 255);
  yellow = mymakecol(255, 255, 0);
  colour[REDGRID] = mymakecol(192, 0, 0);
  colour[GREENGRID] = mymakecol(0, 192, 0);
  colour[BLUEGRID] = mymakecol(0, 0, 192);
  inv_col[REDGRID] = mymakecol(64, 0, 0);
  inv_col[GREENGRID] = mymakecol(0, 64, 0);
  inv_col[BLUEGRID] = mymakecol(0, 0, 64);
  inv_col[STARFIELD] = 0;
}

void init_noise(int passes) {
  int x, y, i;
  int x2, y2;
  fixed total;
  int num;
  
  for(y = 0; y < HEIGHT/8; y++) {
    for(x = 0; x < WIDTH/8; x++) {
      noise[y][x] = ITOFIX(rand()%256);
    }
  }
  
  for(i = 0; i < passes; i++) {
    for(y = 0; y < HEIGHT/8; y++) {
      for(x = 0; x < WIDTH/8; x++) {
        //Now get the average from the surroundings
        total = 0;
        num = 0;
        for(y2 = y-1; y2 <= y+1; y2++) {
          for(x2 = x-1; x2 <= x+1; x2++) {
            if((x2 >= 0) && (x2 < WIDTH/8) && (y2 >= 0) && (y2 < HEIGHT/8)) {
              num += 1;
              total += noise[y2][x2];
            }
          }
        }
        if(num) noise[y][x] = total/num;//Fixed's can be divided by int's fine
      }
    }
  }
}

void update_offset(void) {
  offsetx = (SCR_WIDTH/2) - FIXTOI(px);
  offsety = (SCR_HEIGHT/2) - FIXTOI(py);
  if(offsetx > 0) offsetx = 0;
  if(offsetx < (SCR_WIDTH - WIDTH)) offsetx = (SCR_WIDTH - WIDTH);
  if(offsety > 0) offsety = 0;
  if(offsety < (SCR_HEIGHT - HEIGHT)) offsety = (SCR_HEIGHT - HEIGHT);
}

void draw_game(BITMAP *canvas, int menu) {
  blit(bg, canvas, -offsetx, -offsety, 0, 0, SCR_WIDTH, SCR_HEIGHT);
  
  draw_sparks(canvas, menu);
  
  if(!menu) {
    draw_bullets(canvas);
    draw_enemies(canvas);
    draw_powerups(canvas);
    rotate_sprite(canvas, player, offsetx+(FIXTOI(px)-12), offsety+(FIXTOI(py)-12), pangle);
  }
  
  draw_texts(canvas, menu);
}

void update_bg(int menu) {
  int x, y;
  int i;
  int ox, oy, ox2, oy2;
  int ynum;
  int angle;
  static int noise_mul = 128;
  static int noise_mod = -1;
  static int last_alg;
  
  switch(draw_alg) {
    case ORIGINAL:
      noise_mul += noise_mod;
      if(noise_mul <= 32) noise_mod = -noise_mod;
      else if(noise_mul >= 128) noise_mod = -noise_mod;
      
      ox = ((-offsetx)/8)-1;
      oy = ((-offsety)/8)-1;
      ox2 = ox + (SCR_WIDTH/8) + 2;
      oy2 = oy + (SCR_HEIGHT/8) + 2;
      
      if(ox2 > WIDTH/8) ox2 = WIDTH/8;
      if(ox < 0) ox = 0;
      if(oy2 > HEIGHT/8) oy2 = HEIGHT/8;
      if(oy < 0) oy = 0;
      
      angle = FIXTOI(pangle);
      if(angle < 128) angle *= 2;
      else angle = (128-(angle-127))*2;
    
      for(y = oy; y < oy2; y++) {
        ynum = ((y*HEIGHT_SIZE)+angle)/2;
        for(x = ox; x < ox2; x++) {
          rectfill(bg, x<<3, y<<3, ((x<<3) + 7), ((y<<3) + 7), mymakecol(((x*WIDTH_SIZE)+angle)/2, ynum, MIN(FIXTOI((fixsin(noise[y][x])+ITOFIX(1))*noise_mul), 255)));
        }
      }
      
      for(y = 0; y < HEIGHT/8; y++) {
        for(x = 0; x < WIDTH/8; x++) {
          noise[y][x] += ITOFIX(10);
        }
      }
      break;
    case REDGRID:
    case GREENGRID:
    case BLUEGRID:
      if(last_alg != draw_alg) {
        for(y = 0; y < HEIGHT; y += 128) {
          hline(bg, 0, y, WIDTH, colour[draw_alg]);
        }
    
        for(x = 0; x < WIDTH; x += 128) {
          vline(bg, x, 0, HEIGHT, colour[draw_alg]);
        }
      }
      break;
    case STARFIELD:
      if(last_alg != draw_alg) {
        //Draw the stars
        x = (WIDTH * HEIGHT) / 10000;
        for(i = 0; i < x; i++) {
          y = rand()%256;
          myputpixel(bg, rand()%WIDTH, rand()%HEIGHT, mymakecol(y, y, y));
        }
        
        //Now a few random circles
        ynum = (rand()%10) + 4;
        for(i = 0; i < ynum; i++) {
          x = rand()%WIDTH;
          y = rand()%HEIGHT;
          ox = (rand()%30)+20;
          oy = (rand()%30)+20;
          switch(rand()%4) {
            case 0:
              ellipsefill(bg, x, y, ox, oy, mymakecol(rand()%64, rand()%64, rand()%64));
              break;
            case 1:
              ellipse(bg, x, y, ox, oy, mymakecol(rand()%64, rand()%64, rand()%64));
              break;
            case 2:
              rectfill(bg, x, y, x+ox, y+oy, mymakecol(rand()%64, rand()%64, rand()%64));
              break;
            case 3:
              rect(bg, x, y, x+ox, y+oy, mymakecol(rand()%64, rand()%64, rand()%64));
              break;
          }
        }
      }
      break;
  }
  
  last_alg = draw_alg;
  
  if(!menu) rect(bg, 48, 48, WIDTH-48, HEIGHT-48, -1);
}

void update_player_img(void) {
  int x, y;
  int pix;
  int health = MIN(phealth, 20);
  
  for(y = 0; y < 24; y++) {
    for(x = 0; x < 24; x++) {
      pix = mygetpixel(player_mask, x, y);
      if(pix == magic_pink) myputpixel(player, x, y, mymakecol((((24-x)*10)*health)/20, ((y*10)*health)/20, ((FIXTOI(py)/HEIGHT_SIZE_2)*health)/20));
      else if(pix == cyan) myputpixel(player, x, y, mymakecol((24-y)*10, (24-x)*10, FIXTOI(px)/WIDTH_SIZE_2));
      else if(pix == yellow) myputpixel(player, x, y, magic_pink);
      else myputpixel(player, x, y, pix);
    }
  }
  
  if(!plainplayer) {
    plainplayer = create_bitmap(24, 24);
    blit(player, plainplayer, 0, 0, 0, 0, 24, 24);
    powerup_img[LIFE] = plainplayer;
  }
}

void load_images(void) {
  bg = create_bitmap(WIDTH, HEIGHT);
  player = create_bitmap(24, 24);
  clear_to_color(player, mymakecol(255, 0, 255));
  player_mask = load_bitmap("images/player_mask.tga", NULL);
  bullet1 = load_bitmap("images/bullet2.tga", NULL);
  menu_bg = load_bitmap("images/menu_bg.tga", NULL);
  hud = load_bitmap("images/hud.tga", NULL);
  numbers = load_bitmap_font("images/testfont.tga", NULL, NULL);
  enemy_img[DRONE] = load_bitmap("images/drone.tga", NULL);
  enemy_img[DROID] = load_bitmap("images/droid.tga", NULL);
  enemy_img[TURRET] = load_bitmap("images/turret.tga", NULL);
  enemy_img[BULLET] = load_bitmap("images/enemybullet.tga", NULL);
  enemy_img[TURRETDROID] = load_bitmap("images/turretdroid.tga", NULL);
  enemy_img[ROCKET] = load_bitmap("images/rocket.tga", NULL);
  enemy_img[DUMBDRONE] = enemy_img[DRONE];
  enemy_img[ASTEROID] = load_bitmap("images/asteroid.tga", NULL);
  enemy_img[SMALLAST] = load_bitmap("images/smallast.tga", NULL);
  enemy_img[SNAKEHEAD] = load_bitmap("images/snakehead.tga", NULL);
  enemy_img[SNAKEBODY] = load_bitmap("images/snakebody.tga", NULL);
  powerup_img[HUNDRED] = load_bitmap("images/100.tga", NULL);
  powerup_img[LIFE] = plainplayer;
  powerup_img[MG] = load_bitmap("images/mg.tga", NULL);
  powerup_img[FIVE_MG] = load_bitmap("images/5mg.tga", NULL);
  powerup_img[NUKE] = load_bitmap("images/nuke.tga", NULL);
  powerup_img[SPIRAL] = load_bitmap("images/spiral.tga", NULL);
}

void display_text(char *buff, int x, int y) {
  int i;
  
  for(i = 0; textdata[i][USED] && (i < 48); i++);
  if(i >= 48) return;//Hope the player doesn't notice
  
  strncpy(text[i], buff, 32);
  textdata[i][USED] = 1;
  textdata[i][X] = x;
  textdata[i][Y] = y;
  textdata[i][TTL] = 50;
}

void update_texts(void) {
  int i;
  
  for(i = 0; i < 48; i++) {
    if(textdata[i][USED]) {
      if(textdata[i][TTL] <= 0) textdata[i][USED] = 0;
      else {
        textdata[i][TTL]--;
        textdata[i][Y]--;
      }
    }
  }
}

void draw_texts(BITMAP *canvas, int menu) {
  int i;
  int ox, oy;
  
  if(menu) {
    ox = 0;
    oy = 0;
  } else {
    ox = offsetx;
    oy = offsety;
  }
  
  for(i = 0; i < 48; i++) {
    if(textdata[i][USED]) {
      textout_centre_ex(canvas, font, text[i], ox+textdata[i][X], oy+textdata[i][Y], mymakecol(textdata[i][TTL]*5, textdata[i][TTL]*5, 255-(textdata[i][TTL]*5)), -1);
    }
  }
}
