#include "ranges.h"

extern void animate_units(int forced);
extern void draw_tiles(int scrollx, int scrolly, int editing, int x1, int y1, int w, int h, int keep_units);
extern void draw_tiles(int scrollx, int scrolly, int editing, int keep_units);
extern void fill_pathmap_for_unit(int plyr, int mtype, int ox, int oy);
extern int moves_needed(int mtype, int tx, int ty);
extern int any_unit_here(int tx, int ty);

extern int unitmap[50][50];
extern int mapmovable[20][20];
extern int pathmap[50][50];

int tile_distance(int ax, int ay, int bx, int by)
{
  int dx, dy;
  dx = abs(bx - ax);
  dy = abs(by - ay);
  return dx + dy;
}

int unit_nearby(int pn, int tilex, int tiley)
{
  int a = tilex + 1;
  int b = tilex - 1;
  int c = tiley + 1;
  int d = tiley - 1;
  int z;
  if (a < l)
  {
    z = unitmap[a][tiley];  //in unitmap[][], a result of 0 is player 1, unit 1
    if (z != -1)                //and a result of 247 would be player 3, unit 48
    {
      if (z / 100 == pn)
      {
        return z % 100;
      }
    }
  }
  if (b >= 0)
  {
    z = unitmap[b][tiley];
    if (z != -1)
    {
      if (z / 100 == pn)
      {
        return z % 100;
      }
    }
  }
  if (c < h)
  {
    z = unitmap[tilex][c];
    if (z != -1)
    {
      if (z / 100 == pn)
      {
        return z % 100;
      }
    }
  }
  z = unitmap[tilex][d];
  if (d >= 0)
  {
    if (z != -1)
    {
      if (z / 100 == pn)
      {
        return z % 100;
      }
    }
  }
  return -1;
}

_target enemy_nearby(int pnum, int tilex, int tiley)
{
  return enemy_nearby(pnum, tilex, tiley, 0, 0);
}

_target enemy_nearby(int pnum, int tilex, int tiley, int li, int lj)
{
  int i = li;
  int z;
  _target t;
  if (lj >= 50)
  {
    lj = 0;
    i++;
  }
  while (i < 4)
  {
    if ((player[i].playing == 1) && (i != pnum))
    {
      while (lj < 50)
      {
        if (player[i].unit[lj].exists == 1)
        {
          if (tile_distance(tilex, tiley, player[i].unit[lj].tilex, player[i].unit[lj].tiley) == 1)
          {
            t.player = i;
            t.unit = lj;
            return t;
          }
        }
        lj++;
      }
      lj = 0;
    }
    i++;
  }
  t.player = -1;
  t.unit = -1;
  return t;
}

int get_rangemin(int type)
{
  switch(type)
  {
    case ARTILLERY:
    case B_SHIP:    
      return 2;
      break;
    case MISSILES:
    case ROCKETS:
      return 3;
      break;
  }
}

int get_rangemax(int type)
{
  switch(type)
  {
    case ARTILLERY:
      return 3;
      break;
    case B_SHIP:
      return 6;
      break;
    case MISSILES:
    case ROCKETS:
      return 5;
      break;
  }
}

_target enemy_in_range(int pnum, int tilex, int tiley, int type)
{
  return enemy_in_range(pnum, tilex, tiley, type, 0, 0);
}

_target enemy_in_range(int pnum, int tilex, int tiley, int type, int si, int sj)
{
  int i = si;
  int j = sj;
  int rangemin = get_rangemin(type);
  int rangemax = get_rangemax(type);
  int z;
  _unit t;
  _target targ;
  while (i < 4)
  {
    if ((player[i].playing == 1) && (i != pnum))
    {
      while (j < 50)
      {
        t = player[i].unit[j];
        if (t.exists == 1)
        {
          z = tile_distance(t.tilex, t.tiley, tilex, tiley);
          if ((z >= rangemin) && (z <= rangemax))
          {
            targ.player = i;
            targ.unit = j;
            return targ;
          }
        }
        j++;
      }
      j = 0;
    }
    i++;
  }
  targ.player = -1;
  targ.unit = -1;
  return targ;
}

void draw_attackrange(_unit u)
{
  BITMAP *redbmp = create_bitmap(40, 40);
  clear_to_color(redbmp, RED);
  int rangemin = get_rangemin(u.type);
  int rangemax = get_rangemax(u.type);
  int d;
  int x = u.tilex - rangemax;
  int y = u.tiley - rangemax;
  int max_x = u.tilex + rangemax + 1;
  int max_y = u.tiley + rangemax + 1;
  if (max_x > scroll_x + 16) max_x = scroll_x + 16;
  if (max_y > scroll_y + 12) max_y = scroll_y + 12;
  if (x < 0) x = 0;
  while (x < max_x)
  {
    y = u.tiley - rangemax;
    if (y < 0) y = 0;
    while (y < max_y)
    {
      d = tile_distance(x, y, u.tilex, u.tiley);
      if ((d >= rangemin) && (d <= rangemax))
      {
        draw_trans_sprite(back_buffer, redbmp, (x - scroll_x) * 40, (y - scroll_y) * 40);
        create_dirty(BACK, (x - scroll_x) * 40, (y - scroll_y) * 40, 40, 40);
      }
      y++;
    }
    x++;
  }
  animate_units(1);
  destroy_bitmap(redbmp);
}

void undraw_attackrange(_unit u)
{
  int rangemin = get_rangemin(u.type);
  int rangemax = get_rangemax(u.type);
  int d;
  int x = u.tilex - rangemax;
  int y = u.tiley - rangemax;
  int tx, ty;
  int max_x = u.tilex + rangemax + 1;
  int max_y = u.tiley + rangemax + 1;
  if (max_x > scroll_x + 16) max_x = scroll_x + 16;
  if (max_y > scroll_y + 12) max_y = scroll_y + 12;
  if (x < 0) x = 0;
  while (x < max_x)
  {
    y = u.tiley - rangemax;
    if (y < 0) y = 0;
    while (y < max_y)
    {
      d = tile_distance(x, y, u.tilex, u.tiley);
      if ((d >= rangemin) && (d <= rangemax))
      {
        tx = (x - scroll_x);
        ty = (y - scroll_y);
      }
      y++;
    }
    x++;
  }
  draw_tiles(scroll_x, scroll_y, 0, 1);
}

int in_range(_unit tmpr, int tx, int ty)
{
  return in_range(tmpr.tilex, tmpr.tiley, tx, ty, 0);
}

int in_range(int ox, int oy, int tx, int ty, int d)
{  //this function assumes mapmovable has already been correctly filled in
  int a = ox - tx;
  int b = oy - ty;
  if ((abs(a) <= 10) && (abs(b) <= 10))
  {  //if within mapmovable boundries
    if (mapmovable[10 - a][10 - b] == 1)
    {
      return 1;
    }
  }
  return 0; 
}

int in_range(int plyr, int unitnum, int tx, int ty)
{  
  _unit tmpr = player[plyr].unit[unitnum];
  return in_range(tmpr.tilex, tmpr.tiley, tx, ty, 0);
}

void draw_range(int plyr, int unitnum)
{
  int i;
  int j;
  int zx, zy, tx, ty;
  DATAFILE *glb = (DATAFILE *)graphics[2].dat;
  _unit tmpr = player[plyr].unit[unitnum];
  clear_range();
  fill_pathmap_for_unit(plyr, tmpr.movetype, tmpr.tilex, tmpr.tiley);
  if (tmpr.move > tmpr.gas)
  {
    tmpr.move = tmpr.gas;
  }
  i = 0;
  while (i < 20)
  {
    j = 0;
    while (j < 20)
    {
      tx = tmpr.tilex + (i - 10);
      ty = tmpr.tiley + (j - 10);
      if ((tx > -1) && (tx < l) && (ty > -1) && (ty < h))
      {
        if (pathmap[tx][ty] <= tmpr.move)
        {
          mapmovable[i][j] = 1;
          zx = (tx - scroll_x) * 40;
          zy = (ty - scroll_y) * 40;
          draw_trans_sprite(back_buffer, (BITMAP *)glb[3].dat, zx, zy);
          create_dirty(BACK, zx, zy, 40, 40);
        }
      }
      j++;
    }
    i++;
  }
}

void clear_range()
{
  int i = 0;
  int j;
  while (i < 20)
  {
    j = 0;
    while (j < 20)
    {
      mapmovable[i][j] = -1;
      j++;
    }
    i++;
  }
}
