#include "empire.h"

extern void draw_playerstats(int plyr);
extern void text_box(int x, int y, int w, int h, char *ret, int leng, int spaces, string title);
extern int unit_here_thorough(int plyr, int tx, int ty, int ignore_n);
extern int attackable_unit_here(_unit *attacker, int tx, int ty);
extern int attackable_unit_here(_unit *attacker, int tx, int ty, bool ignore_teams);
extern int any_unit_here(int tx, int ty);

extern string unit_name(int type);
extern int unit_type(string name);

void describe_unit(int type);

string do_actionmenu(_unit *u)
{
  int i, tx, ty;
  int q, z;
  static int bnum;
  bool attack;
  bool supply;
  bool load;
  bool merge;
  static _button items[6];
  static int first = 1;
  static int x1, y1, x2, y2;
  string item[6];
  if (first == 1)
  {
    i = 0;
    while (i < 6)
    {
      item[i] = "-";
      i++;
    }
    if ((u->tilex - worldmap.scroll_x) * 40 < 350)
    {
      x1 = 499;
      x2 = 639;
    }
    else
    {
      x1 = 0;
      x2 = 140;
    }
    y1 = 0;
    i = 0;
    load = false;
    q = unit_here_thorough(u->color, u->tilex, u->tiley, u->number);
    if (q != -1)
    {  //if another unit is here, check if it can load the selected unit
      if (player[u->color].unit[q].can_load_unit(u) == 1)
      {  
        load = true;
      }
    }
    if (load == true)
    {
      item[i] = "Load";
      i++;
    }
    merge = false;
    q = unit_here_thorough(u->color, u->tilex, u->tiley, u->number);
    if (q != -1)
    {
      if (load != 1)
      {  //there is another unit here, and it cannot be load, so it must be a merge
        merge = true;
        item[i] = "Merge";
        i++;
      }
    }
    attack = false;
    if (u->ammo > 0)
    {
      if (u->attacktype == DIRECT)
      {
        q = 0;
        while (q < 4)
        {
          switch(q)
          {
            case 0:
              tx = u->tilex + 1;
              ty = u->tiley;
              break;
            case 1:
              tx = u->tilex - 1;
              ty = u->tiley;
              break;
            case 2:
              tx = u->tilex;
              ty = u->tiley - 1;
              break;
            case 3:
              tx = u->tilex;
              ty = u->tiley + 1;
              break;
          }
          if ((tx > -1) && (tx < MAP_MAX_L) && (ty > -1) && (ty < MAP_MAX_H) && (attackable_unit_here(u, tx, ty, true) != -1))
          {
            attack = true;
            q = 4;  //found an attackable enemy, further checks not necessary
          }
          q++;
        }
      }
      else  //if not direct, must either be ranged or -1 and I don't
      {     //have to worry about -1 attacktypes, since their ammo is 0
        if ((enemy_in_range(u) != -1) && (var.movedthisturn == 0))
        {
          attack = true;
        }
      }
    }
    if ((attack == true) && (load == false) && (merge == false))
    {  //unit can't attack when it can be loaded or merged
      item[i] = "Attack";
      i++;
    }
    supply = false;
    if (u->type == APC)
    {
      z = 0;
      while (z < 4)
      {
        switch(z)
        {
          case 0:
            tx = u->tilex + 1;
            ty = u->tiley;
            break;
          case 1:
            tx = u->tilex - 1;
            ty = u->tiley;
            break;
          case 2:
            tx = u->tilex;
            ty = u->tiley - 1;
            break;
          case 3:
            tx = u->tilex;
            ty = u->tiley + 1;
            break;
        }
        q = any_unit_here(tx, ty);
        if ((q != -1) && (q / 100 == u->color))
        {  //if there is a friendly unit adjacent to this APC
          supply = true;
          z = 4;  //found an supply target
        }
        z++;
      }
    }
    if ((supply == true) && (load == false) && (merge == false))
    {  //can't supply either when it can be loaded or merged
      item[i] = "Supply";
      i++;
    }
    if (worldmap.tile[u->tilex][u->tiley].same_type(6, 0))
    {  //if the tile the unit's on is a teleport tile
      if (u->basetype == LAND)
      {
        item[i] = "Teleport";
        i++;
      }
    }
    if (((u->type == INFANTRY) || (u->type == MECH)) && (merge == false))
    {
      if (worldmap.tile[u->tilex][u->tiley].is_building())
      {
        if (!worldmap.tile[u->tilex][u->tiley].owned_by(u->color))
        {  //note: players CAN be jerks and capture allied bases, cities, HQs...
          item[i] = "Capture";
          i++;
        }
      }
    }
    if ((load == false) && (merge == false))
    {
      q = 0;
      while (q < 2)
      {
        if (u->can_unload_unit(q))
        {
          item[i] = "Unload";
          i++;
          q = 2;
        }
        q++;
      }
    }
    if (merge == false)
    {
      if (u->type == SUB)
      {
        if (u->submerged == 1)
        {
          item[i] = "Surface";
        }
        else
        {
          item[i] = "Dive";
        }
        i++;
      }
    }
    if ((load == false) && (merge == false))
    {
      item[i] = "Standby";
      i++;
    }
    item[i] = "Cancel";
    i++;
    i = 0;
    bnum = 0;
    y2 = 2;
    while (i < 6)
    {
      if (item[i] != "-")
      {
        items[i].init(x1 + 2, y2, x2 - x1 - 4, 29, item[i].c_str());
        y2 += 31;
        bnum++;
      }
      else
      {
        i = 6;
      }
      i++;
    }
    position_mouse(x1 + 70, y1 + 15);  //mouse positioned on middle of Standby button
    set_mouse_range(x1, y1, x2, y2);
    first = 0;
  }
  buffer_menuback(x1, y1, x2, y2, DGREY, GREY, LGREY, 0.8);

  i = 0;
  while (i < bnum)
  {
    items[i].check();
    if (items[i].clicked())
    {
      first = 1;
      set_mouse_range(0, 0, 639, 479);  //return the mouse boundries to normal
      return items[i].get_text();
    }
    i++;
  }
  return "-";
}

int do_unitmenu(int type, int tx, int ty, int pturn)
{
  static int first = 1;
  char tempchar[30];
  static int ok[18];  //each ok[] corresponds to a unit type
  static _button items[11];  //maximum number of buttons possible at once is 11
  static int lastitem;
  static int unittype;
  static bool limit;
  int i;
  int j;
  if (first == 1)
  {
    limit = false;
    i = 0;
    while (i < 18)
    {
      ok[i] = 0;
      i++;
    }
    switch(type)
    {
      case BASE:
        ok[ANTI_AIR]  = 1;
        ok[APC]       = 1;
        ok[ARTILLERY] = 1;
        ok[INFANTRY]  = 1;
        ok[MD_TANK]   = 1;
        ok[MECH]      = 1;
        ok[MISSILES]  = 1;
        ok[RECON]     = 1;
        ok[ROCKETS]   = 1;
        ok[TANK]      = 1;
        break;
      case AIRPORT:
        ok[B_COPTER] = 1;
        ok[BOMBER]   = 1;
        ok[FIGHTER]  = 1;
        ok[T_COPTER] = 1;
        break;
      case PORT:
        ok[B_SHIP]  = 1;
        ok[CRUISER] = 1;
        ok[LANDER]  = 1;
        ok[SUB]     = 1;
        break;
    }
    if (player[pturn].units_in_play() >= 50)  //if the player cannot make more units
    {
      i = 0;
      while (i < 18)
      {
        ok[i] = 0;
        i++;
      }
      buffer_textout_ex(normal, "Unit Limit Reached", 50, 290, BLACK);
      limit = true;
    }
    i = 0;
    j = 0;
    while (i < 18)
    {
      if (ok[i] == 1)
      {
        items[j].init(50, 50 + (25 * j), 100, 20, unit_name(i));
        j++;
      }
      i++;
    }
    items[j].init(50, 310, 100, 20, "Cancel");
    lastitem = j;
    set_mouse_range(40, 40, 400, 350);
    position_mouse(220, 195);
    first = 0;
  }
  draw_playerstats(pturn);
  buffer_menuback(40, 40, 400, 350, DGREY, GREY, LGREY, 0.8);

  j = 0;
  i = 0;
  while ((i < lastitem) && (!limit))
  {
    items[i].check();
    i++;
  }
  i = 0;
  while ((i < lastitem) && (!limit))
  {
    if (items[i].mouseover() == 1)
    {
      j = 1;
			buffer_textout_ex(big, unit_name(unittype), 175, 50, BLACK, 0.9);
      unittype = unit_type(items[i].get_text());
      sprintf(tempchar, "Price: %-1d", unit_price[unittype]);
      if (unit_price[unittype] <= player[pturn].cash)
      {
        buffer_textout_ex(normal, tempchar, 175, 75, BLACK);
      }
      else
      {
        buffer_textout_ex(normal, tempchar, 175, 75, RED);
      }
      describe_unit(unittype);
    }
    if (items[i].clicked())
    {
      if (player[pturn].cash >= unit_price[unittype])
      {
        player[pturn].cash -= unit_price[unittype];
        player[pturn].create_unit(unittype, tx, ty, pturn);
        set_mouse_range(0, 0, 639, 479);
        position_mouse(var.oldmx, var.oldmy);
        first = 1;
        return 1;
      }
    }
    i++;
  }
  if (limit)
  {  //the 50-unit limit has been hit
    buffer_textout_ex(normal, "Unit Limit Reached", 50, 290, BLACK);
  }
  items[lastitem].check();
  if (items[lastitem].clicked())  //cancel button
  {
    set_mouse_range(0, 0, 639, 479);
    position_mouse(var.oldmx, var.oldmy);
    first = 1;
    return 1;
  }
  return 0;
}

void describe_unit(int type)
{
  string str = "";
	
  switch(type)
  {
    case ANTI_AIR:
      str = "Takes care of those pesky enemy air units, and works well against Infantry and Mech units too.";
      break;
    case APC:
      str = "Can't attack, but is very helpful due to its ability to resupply other units and transport an Infantry or Mech.";
      break;
    case ARTILLERY:
      str = "A cheap, effective ranged attacker that is perfect for defending your buildings or giving your attacking units a little backup.";
      break;
    case B_COPTER:
      str = "Good for making life hard for enemy land and sea forces, but it will get torn to pieces by Cruisers, Anti-Air, and Fighters, so be careful.";
      break;
    case B_SHIP:
      str = "Keep it safe from Subs and Bombers and this unit will make your enemy's land forces learn to stay far, far away from the coastline.";
      break;
    case BOMBER:
      str = "Expensive, but perfect for getting rid of tanks, infantry, artillery, and just about anything else that doesn't fly or hide underwater.";
      break;
    case CRUISER:
      str = "This unit will swat down flying units and sink submarines with ease, but it is very lightly armored and therefore very bad at withstanding damage.";
      break;
    case FIGHTER:
      str = "It can't hit anything but other air units, but its range and power make it very helpful when faced with Bombers.";
      break;
    case INFANTRY:
      str = "This unit's low cost and ability to capture buildings make it very helpful despite its lack of firepower and overall weakness.";
      break;
    case LANDER:
      str = "A must for any sea-based attack on an enemy land, this unit can hold two land-based units and drop them off at the enemy's doorstep.";
      break;
    case MD_TANK:
      str = "This tank will create large, smoking, tank-cannon-sized holes in any enemy land unit unfortunate enough to be nearby.";
      break;
    case MECH:
      str = "Basically an Infantry with a little less movement and a lot more firepower.";
      break;
    case MISSILES:
      str = "Weak, with little movement, but able to remove any offending air units from your airspace very, very quickly.";
      break;
    case RECON:
      str = "Weak but fast and relatively cheap, it's useful as a way to keep opponents from capturing buildings too easily.";
      break;
    case ROCKETS:
      str = "With an attack range only exceeded by the Battleship, this unit is perfect for blowing up powerful enemy units from a safe distance.";
      break;
    case SUB:
      str = "Destroy enemy Landers and Battleships while safely underwater.  Just be sure there aren't any Cruisers nearby.";
      break;
    case T_COPTER:
      str = "Quick and easy transport for an Infantry or Mech unit, as long as there aren't any Anti-Air units nearby.";
      break;
    case TANK:
      str = "An effective general-purpose land unit that can badly damage anything in its way, except bigger tanks.";
      break;
  }
  multiline_textout_ex(normal, str, 175, 270, 200, BLACK, 1.0);
}

string do_generalmenu()
{
  static _button items[6];
  static int first = 1;
  static int i;
  int j, k;
  if (first == 1)
  {
    i = 0;
    items[0].init(502, 2, 135, 28, "End Turn");
    items[1].init(502, 32, 135, 28, "Quit to Menu");
    if (player[pturn].power == 1000)
    {
      items[2].init(502, 62, 135, 28, "Power");
      i = 1;
    }
    items[2 + i].init(502, 62 + (30 * i), 135, 28, "Save Game");
    items[3 + i].init(502, 92 + (30 * i), 135, 28, "Options");
    items[4 + i].init(502, 122 + (30 * i), 135, 28, "Cancel");
    position_mouse(570, 15);
    set_mouse_range(500, 0, 639, 152 + (30 * i));
    first = 0;
  }
  buffer_menuback(500, 0, 639, 152 + (30 * i), DGREY, GREY, LGREY, 0.8);
  if (player[pturn].power < 1000)
  {
    j = 5;
  }
  else
  {
    j = 6;
  }
  k = 0;
  while (k < j)
  {
    items[k].check();
    if (items[k].clicked())
    {
      set_mouse_range(0, 0, 639, 479);
      first = 1;
      return items[k].get_text();
    }
    k++;
  }
  if (mouse_rclicked() == 1)
  {
    set_mouse_range(0, 0, 639, 479);
    first = 1;
    return "Cancel";
  }
  return "-";
}

int do_unloadmenu(_unit *u)
{
  static _button b[3];
  static int first = 1;
  static int oldmx, oldmy;
  if (first == 1)
  {
    oldmx = mouse_x;
    oldmy = mouse_y;
    if (u->load[0].loaded == 1)
    {
      b[0].init(502, 2, 135, 28, unit_name(u->load[0].type).c_str());
    }
    else
    {
      b[0].init(502, 2, 135, 28, "-");
    }
    if (u->load[1].loaded == 1)
    {
      b[1].init(502, 32, 135, 28, unit_name(u->load[1].type).c_str());
    }
    else
    {
      b[1].init(502, 32, 135, 28, "-");
    }
    b[2].init(502, 62, 135, 28, "Cancel");
    position_mouse(570, 15);
    set_mouse_range(500, 0, 640, 92);
    first = 0;
  }
  buffer_menuback(500, 0, 639, 92, DGREY, GREY, LGREY, 0.8);
  
  b[0].check();
  b[1].check();
  b[2].check();
  if ((b[0].clicked()) && (b[0].get_text() != "-"))
  {
    set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 0;
  }
  if ((b[1].clicked()) && (b[1].get_text() != "-"))
  {
    set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 1;
  }
  if (b[2].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    position_mouse(oldmx, oldmy);
    first = 1;
    return 2;
  }
  return -1;
}

int do_cancelattack_menu()
{
  static _button b[2];
  static int first = 1;
  if (first == 1)
  {
    position_mouse(570, 15);
    set_mouse_range(501, 1, 639, 59);
    b[0].init(502, 2, 135, 28, "Continue Attack");
    b[1].init(502, 32, 135, 28, "Cancel Attack");
    first = 0;
  }
  buffer_menuback(500, 0, 639, 62, DGREY, GREY, LGREY, 0.8);
  
  b[0].check();
  b[1].check();
  if (b[0].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = 1;
    return 0;
  }
  if (b[1].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = 1;
    return 1;
  }
  return -1;
}

int do_cancelunload_menu()
{
  static _button b[2];
  static int first = 1;
  if (first == 1)
  {
    position_mouse(570, 15);
    set_mouse_range(501, 1, 639, 59);
    b[0].init(502, 2, 135, 28, "Continue Unload");
    b[1].init(502, 32, 135, 28, "Cancel Unload");
    first = 0;
  }
  buffer_menuback(500, 0, 639, 62, DGREY, GREY, LGREY, 0.8);
  
  b[0].check();
  b[1].check();
  if (b[0].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = 1;
    return 0;
  }
  if (b[1].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = 1;
    return 1;
  }
  return -1;
}

int do_cancelteleport_menu()
{
  static _button b[2];
  static bool first = true;
  
  if (first)
  {
    position_mouse(570, 15);
    set_mouse_range(501, 1, 639, 59);
    b[0].init(502, 2, 135, 28, "Continue Teleport");
    b[1].init(502, 32, 135, 28, "Cancel Teleport");
    first = false;
  }
  buffer_menuback(500, 0, 639, 62, DGREY, GREY, LGREY, 0.8);
  
  b[0].check();
  b[1].check();
  if (b[0].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = true;
    return 0;
  }
  if (b[1].clicked())
  {
    set_mouse_range(0, 0, 639, 479);
    first = true;
    return 1;
  }
  return -1;
}

int do_savemenu()
{
  static int first = 1;
  static _button slot[10];
  int i;
  char path[10];
  char text[10];
  char name[20] = "";

  if (first == 1)
  {
    buffer_textout_centre_ex(normal, "Choose a save slot", 320, 93, BLACK);
    position_mouse(320, 245);
    set_mouse_range(239, 84, 401, 391);
    i = 0;
    while (i < 9)
    {
      sprintf(path, "saves/game%-1d.sav", i);
      if (exists(path) != 0)
			{
				ifstream n(path);
				n >> text;
				slot[i].init(250, 110 + (i * 25), 140, 20, text);
				n.close();
			}
			else
			{
				slot[i].init(250, 110 + (i * 25), 140, 20, "Empty");
			}
      i++;
    }
    slot[9].init(250, 360, 140, 20, "Cancel");
    first = 0;
  }
  buffer_menuback(239, 84, 401, 391, DGREY, GREY, LGREY, 0.8);
  buffer_textout_centre_ex(normal, "Choose a save slot", 320, 93, BLACK);
  
  i = 0;
  while (i < 10)
  {
    slot[i].check();
    if (slot[i].clicked())
    {
      if (i == 9)  //Cancel was clicked
      {
        first = 1;
        set_mouse_range(0, 0, 639, 479);
        return 0;
      }
      else
      {
        if (slot[i].get_text() != "Empty")
        {
          sprintf(name, slot[i].get_text().c_str());
        }
        text_box(240, 200, 161, 35, name, 15, 0, "Name your saved game");
        if (strcmp(name, "_CANCEL_") == 0)
        {  //if ESC was pressed in text_box, don't save
          first = 1;
          set_mouse_range(0, 0, 639, 479);
          return 0;
        }
        sprintf(path, "saves/game%-1d.sav", i);
        ofstream savefile(path);
        if (!(savefile.bad()))
        {
          savefile << name << "\n" << worldmap.l << "\n" << worldmap.h << "\n";

					save_map_and_players(&savefile);
					
          savefile << "pturn " << pturn << "\n" << gameoptions.funding << "\n";
          savefile << gameoptions.show_damage << "\n" << gameoptions.time << "\n";
          savefile << var.time << "\n" << worldmap.get_name().c_str();
					
					save_currentcharacters(path);
					
          savefile.close();
        }
        first = 1;
        set_mouse_range(0, 0, 639, 479);
        counter = 0;  //the saveprocess might take a while, so reset the counter
        return 0;
      }
    }
    i++;
  }
  return 1;  //returns 1 if it isn't finished
}
