/* MegaZeux
 *
 * Copyright (C) 1996 Greg Janson
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

// Dialogs for the world editor.

#include <string.h>

#include "../helpsys.h"
#include "../intake.h"
#include "../graphics.h"
#include "../window.h"
#include "../data.h"
#include "../idput.h"
#include "../const.h"
#include "../world_struct.h"
#include "../error.h"
#include "../counter.h"
#include "../board.h"
#include "../world.h"

#include "board.h"
#include "edit.h"
#include "edit_di.h"
#include "robo_ed.h"
#include "window.h"

// The 8th bit set indicates that it's a color, not a char
static const int char_values[8][24] =
{
  {
    0,
    1,
    2,
    3,
    6,
    8,
    9,
    11,
    13,
    14,
    15,
    16,
    20,
    21,
    22,
    23,
    24,
    27,
    28,
    29,
    30,
    31,
    32,
    33
  },
  {
    34,
    36,
    38,
    39,
    40,
    43,
    44,
    47,
    48,
    50,
    55,
    57,
    58,
    60,
    65,
    67,
    68,
    69,
    70,
    71,
    73,
    80,
    81,
    82
  },
  {
    83,
    84,
    85,
    86,
    87,
    88,
    89,
    90,
    91,
    94,
    95,
    125,
    126,
    160,
    161,
    162,
    163,
    164,
    165,
    166,
    167,
    168,
    169, // Special
    176 | 512
  },
  {
    177 | 512,
    178 | 512,
    179 | 512,
    180 | 512,
    181 | 512,
    182 | 512,
    183 | 512,
    184 | 512,
    185 | 512,
    186 | 512,
    187 | 512,
    188, // Special
    189, // Special
    198, // Special
    200, // Special
    190,
    191,
    192,
    193,
    194,
    195,
    196,
    197,
    230
  },
  {
    231,
    232,
    233,
    234,
    235,
    236,
    237,
    238,
    239,
    240,
    241,
    242,
    243,
    244,
    245,
    246,
    247,
    248,
    249,
    250,
    251,
    252,
    253,
    254
  },
  {
    255,
    256,
    257,
    258,
    259,
    260,
    261,
    262,
    263,
    264,
    265,
    266,
    267,
    268,
    269,
    270,
    271,
    272 | 512,
    273 | 512,
    274 | 512,
    275 | 512,
    276 | 512,
    277 | 512,
    278
  },
  {
    279,
    280,
    281,
    282 | 512,
    283 | 512,
    284 | 512,
    285 | 512,
    286,
    287,
    288,
    289,
    290,
    291,
    292 | 512,
    293 | 512,
    294,
    295,
    296,
    297,
    298 | 512,
    299 | 512,
    300 | 512,
    301 | 512,
    302 | 512
  },
  {
    303 | 512,
    304 | 512,
    305 | 512,
    306,
    307,
    308,
    309,
    310,
    311,
    312,
    313,
    314,
    315,
    316,
    317,
    318,
    319,
    320,
    321,
    322 | 512,
    323 | 512,
    324 | 512,
    325 | 512,
    326 | 512
  }
};

// Info for char funcs, 192 selections (24 per func, 8 funcs)
static const char *const char_strs[8][24] =
{
  {
    "Space (000)-",
    "Normal (001)-",
    "Solid (002)-",
    "Tree (003)-",
    "Breakaway (006)-",
    "Boulder (008)-",
    "Crate (009)-",
    "Box (011)-",
    "Fake (013)-",
    "Carpet (014)-",
    "Floor (015)-",
    "Tiles (016)-",
    "Still Water (020)-",
    "N Water (021)-",
    "S Water (022)-",
    "E Water (023)-",
    "W Water (024)-",
    "Chest (027)-",
    "Gem (028)-",
    "Magic Gem (029)-",
    "Health (030)-",
    "Ring (031)-",
    "Potion (032)-",
    "Energizer (033)-"
  },
  {
    "Goop (034)-",
    "Bomb (036)-",
    "Explosion (038)-",
    "Key (039)-",
    "Lock (040)-",
    "Stairs (043)-",
    "Cave (044)-",
    "Gate (047)-",
    "Open Gate (048)-",
    "Coin (050)-",
    "Pouch (055)-",
    "Slider NS (057)-",
    "Slider EW (058)-",
    "Lazer Gun (060)-",
    "Forest (065)-",
    "Whirlpool 1 (067)-",
    "Whirlpool 2 (068)-",
    "Whirlpool 3 (069)-",
    "Whirlpool 4 (070)-",
    "Invis. Wall (071)-",
    "Ricochet (073)-",
    "Snake (080)-",
    "Eye (081)-",
    "Thief (082)-"
  },
  {
    "Slime Blob (083)-",
    "Runner (084)-",
    "Ghost (085)-",
    "Dragon (086)-",
    "Fish (087)-",
    "Shark (088)-",
    "Spider (089)-",
    "Goblin (090)-",
    "Spitting Tiger (091)-",
    "Bear (094)-",
    "Bear Cub (095)-",
    "Sign (125)-",
    "Scroll (126)-",
    "Blank Ice (160)-",
    "Ice Anim 1 (161)-",
    "Ice Anim 2 (162)-",
    "Ice Anim 3 (163)-",
    "Lava Anim 1 (164)-",
    "Lava Anim 2 (165)-",
    "Lava Anim 3 (166)-",
    "Small Ammo (167)-",
    "Large Ammo (168)-",
    "Lit Bomb Anim 1 (169)-", // Special
    "Energizer Color 1 (176)-"
  },
  {
    "Energizer Color 2 (177)-",
    "Energizer Color 3 (178)-",
    "Energizer Color 4 (179)-",
    "Energizer Color 5 (180)-",
    "Energizer Color 6 (181)-",
    "Energizer Color 7 (182)-",
    "Energizer Color 8 (183)-",
    "Explosion Stage 1 (184)-",
    "Explosion Stage 2 (185)-",
    "Explosion Stage 3 (186)-",
    "Explosion Stage 4 (187)-",
    "Horizontal Door (\?\?\?)-",//Special
    "Vertical Door (\?\?\?)-",//Special
    "Diagonal Door / (\?\?\?)-",//Special
    "Diagonal Door \\ (\?\?\?)-",//Special
    "CW Anim 1 (190)-",
    "CW Anim 2 (191)-",
    "CW Anim 3 (192)-",
    "CW Anim 4 (193)-",
    "CCW Anim 1 (194)-",
    "CCW Anim 2 (195)-",
    "CCW Anim 3 (196)-",
    "CCW Anim 4 (197)-",
    "N Transport Anim 1 (230)-"
  },
  {
    "N Transport Anim 2 (231)-",
    "N Transport Anim 3 (232)-",
    "N Transport Anim 4 (233)-",
    "S Transport Anim 1 (234)-",
    "S Transport Anim 2 (235)-",
    "S Transport Anim 3 (236)-",
    "S Transport Anim 4 (237)-",
    "E Transport Anim 1 (238)-",
    "E Transport Anim 2 (239)-",
    "E Transport Anim 3 (240)-",
    "E Transport Anim 4 (241)-",
    "W Transport Anim 1 (242)-",
    "W Transport Anim 2 (243)-",
    "W Transport Anim 3 (244)-",
    "W Transport Anim 4 (245)-",
    "A.Transport Anim 1 (246)-",
    "A.Transport Anim 2 (247)-",
    "A.Transport Anim 3 (248)-",
    "A.Transport Anim 4 (249)-",
    "N Thick Arrow (250)-",
    "S Thick Arrow (251)-",
    "E Thick Arrow (252)-",
    "W Thick Arrow (253)-",
    "N Thin Arrow (254)-"
  },
  {
    "S Thin Arrow (255)-",
    "E Thin Arrow (256)-",
    "W Thin Arrow (257)-",
    "Horiz Lazer Anim 1 (258)-",
    "Horiz Lazer Anim 2 (259)-",
    "Horiz Lazer Anim 3 (260)-",
    "Horiz Lazer Anim 4 (261)-",
    "Vert Lazer Anim 1 (262)-",
    "Vert Lazer Anim 2 (263)-",
    "Vert Lazer Anim 3 (264)-",
    "Vert Lazer Anim 4 (265)-",
    "Fire Anim 1 (266)-",
    "Fire Anim 2 (267)-",
    "Fire Anim 3 (268)-",
    "Fire Anim 4 (269)-",
    "Fire Anim 5 (270)-",
    "Fire Anim 6 (271)-",
    "Fire Color 1 (272)-",
    "Fire Color 2 (273)-",
    "Fire Color 3 (274)-",
    "Fire Color 4 (275)-",
    "Fire Color 5 (276)-",
    "Fire Color 6 (277)-",
    "Life Anim 1 (278)-"
  },
  {
    "Life Anim 2 (279)-",
    "Life Anim 3 (280)-",
    "Life Anim 4 (281)-",
    "Life Color 1 (282)-",
    "Life Color 2 (283)-",
    "Life Color 3 (284)-",
    "Life Color 4 (285)-",
    "Ricochet Panel \\ (286)-",
    "Ricochet Panel / (287)-",
    "Mine Anim 1 (288)-",
    "Mine Anim 2 (289)-",
    "Spit Fire Anim 1 (290)-",
    "Spit Fire Anim 2 (291)-",
    "Spit Fire Color 1 (292)-",
    "Spit Fire Color 2 (293)-",
    "Seeker Anim 1 (294)-",
    "Seeker Anim 2 (295)-",
    "Seeker Anim 3 (296)-",
    "Seeker Anim 4 (297)-",
    "Seeker Color 1 (298)-",
    "Seeker Color 2 (299)-",
    "Seeker Color 3 (300)-",
    "Seeker Color 4 (301)-",
    "Whirlpool Color 1 (302)-"
  },
  {
    "Whirlpool Color 2 (303)-",
    "Whirlpool Color 3 (304)-",
    "Whirlpool Color 4 (305)-",
    "N Player Bullet (306)-",
    "S Player Bullet (307)-",
    "E Player Bullet (308)-",
    "W Player Bullet (309)-",
    "N Neutral Bullet (310)-",
    "S Neutral Bullet (311)-",
    "E Neutral Bullet (312)-",
    "W Neutral Bullet (313)-",
    "N Enemy Bullet (314)-",
    "S Enemy Bullet (315)-",
    "E Enemy Bullet (316)-",
    "W Enemy Bullet (317)-",
    "N Player Char (318)-",
    "S Player Char (319)-",
    "E Player Char (320)-",
    "W Player Char (321)-",
    "Player Color (322)-",
    "Missile Color (323)-",
    "Player Bullet Color (324)-",
    "Neutral Bullet Color (325)-",
    "Enemy Bullet Color (326)-"
  }
};

// Info for damage editing
static const char dmg_ids[22] =
{
  26,
  38,
  59,
  61,
  62,
  63,
  75,
  76,
  78,
  79,
  80,
  83,
  84,
  85,
  86,
  87,
  88,
  89,
  90,
  91,
  94,
  95
};

static const char *const dmg_strs[22] =
{
  "Lava-",
  "Explosion-",
  "Lazer-",
  "Bullet-",
  "Missile-",
  "Fire-",
  "Spike-",
  "Custom Hurt-",
  "Shooting Fire-",
  "Seeker-",
  "Snake-",
  "Slime Blob-",
  "Runner-",
  "Ghost-",
  "Dragon-",
  "Fish-",
  "Shark-",
  "Spider-",
  "Goblin-",
  "Spitting Tiger-",
  "Bear-",
  "Bear Cub-"
};

void set_confirm_buttons(struct element **elements)
{
  elements[0] = construct_button(15, 15, "OK", 0);
  elements[1] = construct_button(37, 15, "Cancel", 1);
}

void status_counter_info(struct world *mzx_world)
{
  struct dialog di;
  struct element *elements[2 + NUM_STATUS_COUNTERS];
  const char *status_counters_strings[NUM_STATUS_COUNTERS] =
  {
    "Status counter 1: ", "2: ", "3: ",
    "4: ", "5: ", "6: "
  };
  int i;

  set_confirm_buttons(elements);
  set_context(82);

  elements[2] = construct_input_box(12, 5,
   status_counters_strings[0], COUNTER_NAME_SIZE - 1, 0,
   mzx_world->status_counters_shown[0]);

  for(i = 1; i < NUM_STATUS_COUNTERS; i++)
  {
    elements[i + 2] = construct_input_box(27, 5 + i,
     status_counters_strings[i], COUNTER_NAME_SIZE - 1, 0,
     mzx_world->status_counters_shown[i]);
  }

  construct_dialog(&di, "Status Counters", 10, 4, 60, 18,
   elements, 2 + NUM_STATUS_COUNTERS, 2);

  run_dialog(mzx_world, &di);
  destruct_dialog(&di);

  pop_context();
}

void board_exits(struct world *mzx_world)
{
  struct dialog di;
  struct element *elements[6];
  struct board *src_board = mzx_world->current_board;
  int dialog_result;
  int exits[4];

  memcpy(exits, src_board->board_dir, sizeof(int) * 4);

  set_confirm_buttons(elements);
  set_context(83);

  elements[2] = construct_board_list(12, 4, "Board to north:",
   1, exits + 0);
  elements[3] = construct_board_list(12, 6, "Board to south:",
   1, exits + 1);
  elements[4] = construct_board_list(12, 8, "Board to east:",
   1, exits + 2);
  elements[5] = construct_board_list(12, 10, "Board to west:",
   1, exits + 3);
  construct_dialog(&di, "Board Exits", 10, 4, 60, 18,
   elements, 6, 2);

  dialog_result = run_dialog(mzx_world, &di);
  destruct_dialog(&di);

  if(!dialog_result)
  {
    memcpy(src_board->board_dir, exits, sizeof(int) * 4);
  }

  pop_context();
}

// Size/pos of board/viewport
void size_pos(struct world *mzx_world)
{
  struct board *src_board = mzx_world->current_board;
  int dialog_result;
  struct element *elements[8];
  struct dialog di;

  int redo = 1;

  int results[6] =
  {
    src_board->viewport_x, src_board->viewport_y,
    src_board->viewport_width, src_board->viewport_height,
    src_board->board_width, src_board->board_height
  };

  set_context(84);

  do
  {
    elements[0] = construct_button(15, 15, "OK", 0);
    elements[1] = construct_button(37, 15, "Center", 1);
    elements[2] = construct_number_box(15, 4, "Viewport X pos: ",
     0, 79, 0, results + 0);
    elements[3] = construct_number_box(15, 5, "Viewport Y pos: ",
     0, 24, 0, results + 1);
    elements[4] = construct_number_box(15, 6, "Viewport Width: ",
     1, 80, 0, results + 2);
    elements[5] = construct_number_box(15, 7, "Viewport Height:",
     1, 25, 0, results + 3);
    elements[6] = construct_number_box(15, 11, "Board Width:    ",
     1, 32767, 0, results + 4);
    elements[7] = construct_number_box(15, 12, "Board Height:   ",
     1, 32767, 0, results + 5);

    construct_dialog(&di, "Board Sizes/Positions", 10, 4, 60, 18,
     elements, 8, 2);

    dialog_result = run_dialog(mzx_world, &di);
    destruct_dialog(&di);

    // Fix sizes
    if(results[2] > results[4])
      results[2] = results[4];
    if(results[3] > results[5])
      results[3] = results[5];
    if((results[2] + results[0]) > 80)
      results[2] = 80 - results[0];
    if((results[3] + results[1]) > 25)
      results[3] = 25 - results[1];

    switch(dialog_result)
    {
      default:
      {
        // Center
        results[0] = 40 - (results[2] / 2);
        results[1] = 12 - (results[3] / 2);
        break;
      }

      case -1:
      {
        redo = 0;
        break;
      }

      case 0:
      {
        // Change the size; if it's not an enlargement, make sure
        // the player confirms first.

        // Hack to prevent multiplies of 256, for now - only relevant
        // with overlay off, but we want to avoid complications if
        // the user turns the overlay off later
        if((results[4] % 256) == 0)
          results[4]++;

        if((results[4] * results[5]) > MAX_BOARD_SIZE)
        {
          if(results[4] > results[5])
            results[5] = MAX_BOARD_SIZE / results[4];
          else
            results[4] = MAX_BOARD_SIZE / results[5];
        }

        if(((results[4] >= src_board->board_width) &&
          (results[5] >= src_board->board_height)) ||
          !confirm(mzx_world, "Reduce board size- Are you sure?"))
        {
          redo = 0;
          change_board_size(src_board, results[4], results[5]);
          src_board->viewport_x = results[0];
          src_board->viewport_y = results[1];
          src_board->viewport_width = results[2];
          src_board->viewport_height = results[3];
        }
        break;
      }
    }
  } while(redo);

  pop_context();
}

//Dialog- (board info)
//----------------------------------------------------------
//        Board name- __________________________
//    [ ] Can shoot               ( ) Explosions to space
//    [ ] Can bomb                ( ) Explosions to ash
//    [ ] Fire burns space        ( ) Explosions to fire
//    [ ] Fire burns fakes
//    [ ] Fire burns trees        ( ) Can save
//    [ ] Fire burns brown        ( ) Can't save
//    [ ] Forest to floor         ( ) Can save on sensors
//    [ ] Collect bombs
//    [ ] Fire burns forever      ( ) No overlay
//    [ ] Restart if hurt         ( ) Normal overlay
//                                ( ) Static overlay
//    Time limit- _00000__!__!_   ( ) Transparent overlay
//
//              _OK_                  _Cancel_
//
//----------------------------------------------------------

// Board info
void board_info(struct world *mzx_world)
{
  struct board *src_board = mzx_world->current_board;
  int dialog_result;
  struct element *elements[8];
  struct dialog di;
  int check_box_results[13] =
  {
    src_board->can_shoot, src_board->can_bomb,
    src_board->fire_burn_space, src_board->fire_burn_fakes,
    src_board->fire_burn_trees, src_board->fire_burn_brown,
    src_board->forest_becomes, src_board->collect_bombs,
    src_board->fire_burns, src_board->restart_if_zapped,
    src_board->player_ns_locked, src_board->player_ew_locked,
    src_board->player_attack_locked
  };
  const char *check_box_strings[] =
  {
    "Can shoot", "Can bomb", "Fire burns space",
    "Fire burns fakes", "Fire burns trees", "Fire burns brown",
    "Forest to floor", "Collect bombs", "Fire burns forever",
    "Restart if hurt", "Player locked N/S", "Player locked E/W",
    "Player attack locked"
  };
  const char *radio_strings_1[] =
  {
    "Explosions to space", "Explosions to ash",
    "Explosions to fire"
  };
  const char *radio_strings_2[] =
  {
    "Can save", "Can't save", "Can save on sensors"
  };
  const char *radio_strings_3[] =
  {
    "No overlay", "Normal overlay", "Static overlay",
    "Transparent overlay"
  };
  int radio_result_1 = src_board->explosions_leave;
  int radio_result_2 = src_board->save_mode;
  int radio_result_3 = src_board->overlay_mode;
  int time_limit = src_board->time_limit;
  char title_string[BOARD_NAME_SIZE];

  set_context(85);

  strcpy(title_string, src_board->board_name);

  elements[0] = construct_button(15, 18, "OK", 0);
  elements[1] = construct_button(37, 18, "Cancel", 1);
  elements[2] = construct_input_box(9, 1, "Board name- ",
   BOARD_NAME_SIZE - 1, 0, title_string);
  elements[3] = construct_check_box(5, 2, check_box_strings,
   13, 20, check_box_results);
  elements[4] = construct_number_box(5, 16, "Time limit- ",
   0, 32767, 0, &time_limit);
  elements[5] = construct_radio_button(33, 3, radio_strings_1,
   3, 19, &radio_result_1);
  elements[6] = construct_radio_button(33, 8, radio_strings_2,
   3, 19, &radio_result_2);
  elements[7] = construct_radio_button(33, 13, radio_strings_3,
   4, 19, &radio_result_3);

  construct_dialog(&di, "Board Settings", 10, 2, 60, 21,
   elements, 8, 2);

  dialog_result = run_dialog(mzx_world, &di);

  if(!dialog_result)
  {
    strcpy(src_board->board_name, title_string);
    src_board->can_shoot = check_box_results[0];
    src_board->can_bomb = check_box_results[1];
    src_board->fire_burn_space = check_box_results[2];
    src_board->fire_burn_fakes = check_box_results[3];
    src_board->fire_burn_trees = check_box_results[4];
    src_board->fire_burn_brown = check_box_results[5];
    src_board->forest_becomes = check_box_results[6];
    src_board->collect_bombs = check_box_results[7];
    src_board->fire_burns = check_box_results[8];
    src_board->restart_if_zapped = check_box_results[9];
    src_board->player_ns_locked = check_box_results[10];
    src_board->player_ew_locked = check_box_results[11];
    src_board->player_attack_locked = check_box_results[12];
    src_board->explosions_leave = radio_result_1;
    src_board->save_mode = radio_result_2;

    if(src_board->overlay_mode != radio_result_3)
    {
      setup_overlay(src_board, radio_result_3);
      src_board->overlay_mode = radio_result_3;
    }

    src_board->time_limit = time_limit;
  }

  destruct_dialog(&di);
  pop_context();
}

// Chars #1-8
static void global_chars(struct world *mzx_world)
{
  int i;
  int current_id, dialog_result;
  int current_menu = 0;
  int results[24];
  struct element *elements[27];
  struct dialog di;
  set_context(89);

  do
  {
    elements[0] = construct_button(15, 15, "Next", 1);
    elements[1] = construct_button(25, 15, "Previous", 2);
    elements[2] = construct_button(39, 15, "Done", 3);

    for(i = 0; i < 12; i++)
    {
      if(char_values[current_menu][i] & 512)
      {
        elements[i + 3] = construct_color_box(2 +
         (25 - strlen(char_strs[current_menu][i])), 2 + i,
         char_strs[current_menu][i], 0, results + i);
      }
      else
      {
        elements[i + 3] = construct_char_box(2 +
         (25 - strlen(char_strs[current_menu][i])), 2 + i,
         char_strs[current_menu][i],
         char_values[current_menu][i] > 127, results + i);
      }

      current_id = char_values[current_menu][i] & 511;
      if(current_id == 323)
        results[i] = missile_color;
      else

      if((current_id >= 324) && (current_id <= 326))
        results[i] = bullet_color[current_id - 324];
      else
        results[i] = id_chars[current_id];
    }

    for(; i < 24; i++)
    {
      if(char_values[current_menu][i] & 512)
      {
        elements[i + 3] = construct_color_box(32 +
         (25 - strlen(char_strs[current_menu][i])), i - 10,
         char_strs[current_menu][i], 0, results + i);
      }
      else
      {
        elements[i + 3] = construct_char_box(32 +
         (25 - strlen(char_strs[current_menu][i])), i - 10,
         char_strs[current_menu][i],
         char_values[current_menu][i] > 127, results + i);
      }

      current_id = char_values[current_menu][i] & 511;
      if(current_id == 323)
        results[i] = missile_color;
      else

      if((current_id >= 324) && (current_id <= 326))
        results[i] = bullet_color[current_id - 324];
      else
        results[i] = id_chars[current_id];
    }

    construct_dialog(&di, "Edit Characters", 9, 4, 62, 18,
     elements, 27, 3);

    // Run
    dialog_result = run_dialog(mzx_world, &di);
    destruct_dialog(&di);

    if(dialog_result == -1)
      break;

    // Get from storage
    for(i = 0; i < 24; i++)
    {
      current_id = char_values[current_menu][i] & 511;
      if(current_id == 323)
        missile_color = results[i];
      else

      if((current_id >= 324) && (current_id <= 326))
        bullet_color[current_id - 324] = results[i];
      else
        id_chars[current_id] = results[i];
    }

    // Setup lit bomb sequence or doors
    if(current_menu == 2)
    {
      id_chars[170] = id_chars[169] - 1;
      id_chars[171] = id_chars[170] - 1;
      id_chars[172] = id_chars[171] - 1;
      id_chars[173] = id_chars[172] - 1;
      id_chars[174] = id_chars[173] - 1;
      id_chars[175] = id_chars[174] - 1;
    }
    else

    if(current_menu == 3)
    {
      // Doors
      id_chars[199] = id_chars[198]; // '/'
      id_chars[201] = id_chars[200]; // '\'
      id_chars[202] = id_chars[200]; // '\'
      id_chars[203] = id_chars[200]; // '\'
      id_chars[204] = id_chars[198]; // '/'
      id_chars[205] = id_chars[198]; // '/'
      id_chars[206] = id_chars[189]; // '|'
      id_chars[207] = id_chars[188]; // '-'
      id_chars[208] = id_chars[189]; // '|'
      id_chars[209] = id_chars[188]; // '-'
      id_chars[210] = id_chars[189]; // '|'
      id_chars[211] = id_chars[188]; // '-'
      id_chars[212] = id_chars[189]; // '|'
      id_chars[213] = id_chars[188]; // '-'
      id_chars[214] = id_chars[189]; // '|'
      id_chars[215] = id_chars[188]; // '-'
      id_chars[216] = id_chars[189]; // '|'
      id_chars[217] = id_chars[188]; // '-'
      id_chars[218] = id_chars[189]; // '|'
      id_chars[219] = id_chars[188]; // '-'
      id_chars[220] = id_chars[189]; // '|'
      id_chars[221] = id_chars[188]; // '-'
      id_chars[222] = id_chars[198]; // '/'
      id_chars[223] = id_chars[198]; // '/'
      id_chars[224] = id_chars[200]; // '\'
      id_chars[225] = id_chars[200]; // '\'
      id_chars[226] = id_chars[200]; // '\'
      id_chars[227] = id_chars[200]; // '\'
      id_chars[228] = id_chars[198]; // '/'
      id_chars[229] = id_chars[198]; // '/'
    }

    // Next, prev, or done
    if(dialog_result == 1)
    {
      current_menu++;
      if((current_menu) > 7)
        current_menu = 0;
    }
    else

    if(dialog_result == 2)
    {
      current_menu--;

      if((current_menu) < 0)
        current_menu = 7;
    }
  } while((dialog_result == 1) || (dialog_result == 2));

  pop_context();
}

static void global_dmg(struct world *mzx_world)
{
  int dialog_result;
  struct element *elements[24];
  struct dialog di;
  int results[22];
  int i;

  set_context(90);
  set_confirm_buttons(elements);

  for(i = 0; i < 11; i++)
  {
    results[i] = id_dmg[(int)dmg_ids[i]];
    elements[i + 2] = construct_number_box(2 +
     (14 - strlen(dmg_strs[i])), 2 + i,
     dmg_strs[i], 0, 255, 0, results + i);
  }

  for(; i < 22; i++)
  {
    results[i] = id_dmg[(int)dmg_ids[i]];
    elements[i + 2] = construct_number_box(31 +
     (14 - strlen(dmg_strs[i])), i - 9,
     dmg_strs[i], 0, 255, 0, results + i);
  }

  construct_dialog(&di, "Edit Damage", 10, 4, 60, 18,
   elements, 24, 2);

  dialog_result = run_dialog(mzx_world, &di);
  destruct_dialog(&di);

  if(!dialog_result)
  {
    for(i = 0; i < 22; i++)
    {
      id_dmg[(int)dmg_ids[i]] = results[i];
    }
  }
  pop_context();
}

void global_info(struct world *mzx_world)
{
  int death_board = mzx_world->death_board;
  int endgame_board = mzx_world->endgame_board;
  int death_x = mzx_world->death_x;
  int death_y = mzx_world->death_y;
  int endgame_x = mzx_world->endgame_x;
  int endgame_y = mzx_world->endgame_y;
  int first_board = mzx_world->first_board;
  int edge_color = mzx_world->edge_color;
  int starting_lives = mzx_world->starting_lives;
  int lives_limit = mzx_world->lives_limit;
  int starting_health = mzx_world->starting_health;
  int health_limit = mzx_world->health_limit;
  int radio_result_1 = 2;
  int radio_result_2 = 1;
  int check_box_results_1[1] = { mzx_world->game_over_sfx };
  int check_box_results_2[3] =
  {
    mzx_world->enemy_hurt_enemy, mzx_world->clear_on_exit,
    mzx_world->only_from_swap
  };
  const char *radio_strings_1[] =
  {
    "Death- Same position", "Death- Restart board",
    "Death- Teleport"
  };
  const char *radio_strings_2[] =
  {
    "Endgame- Game over", "Endgame- Teleport"
  };
  const char *check_box_strings_1[] = { "Play game over sfx" };
  const char *check_box_strings_2[] =
  {
    "Enemies' bullets hurt other enemies",
    "Clear messages and projectiles on exit",
    "Can only play world from a 'SWAP WORLD'"
  };
  struct dialog a_di;
  struct dialog b_di;
  struct element *a_elements[15];
  struct element *b_elements[10];
  int dialog_result;
  int redo = 0;

  do
  {
    set_confirm_buttons(a_elements);
    a_elements[2] = construct_board_list(1, 2, "Death board-",
     0, &death_board);
    a_elements[3] = construct_number_box(1, 5, "Death X- ",
     0, 32767, 0, &death_x);
    a_elements[4] = construct_number_box(1, 6, "Death Y- ",
     0, 32767, 0, &death_y);
    a_elements[5] = construct_radio_button(1, 8, radio_strings_1,
     3, 20, &radio_result_1);
    a_elements[6] = construct_board_list(30, 2, "Endgame board-",
     0, &endgame_board);
    a_elements[7] = construct_number_box(30, 5, "Endgame X- ",
     0, 32767, 0, &endgame_x);
    a_elements[8] = construct_number_box(30, 6, "Endgame Y- ",
     0, 32767, 0, &endgame_y);
    a_elements[9] = construct_radio_button(30, 8, radio_strings_2,
     2, 18, &radio_result_2);
    a_elements[10] = construct_check_box(30, 11, check_box_strings_1,
     1, 18, check_box_results_1);
    a_elements[11] = construct_button(5, 13, "More", 2);
    a_elements[12] = construct_button(12, 13, "Edit Chars", 3);
    a_elements[13] = construct_button(25, 13, "Edit Dmg", 4);
    a_elements[14] = construct_button(36, 13, "Edit Global Robot", 5);

    construct_dialog(&a_di, "Global Settings", 10, 4, 60, 18,
     a_elements, 15, 2);

    redo = 0;
    set_context(86);

    if(death_board == DEATH_SAME_POS)
    {
      death_board = 0;
      radio_result_1 = 0;
    }

    if(death_board == NO_DEATH_BOARD)
    {
      death_board = 0;
      radio_result_1 = 1;
    }

    if(endgame_board == NO_ENDGAME_BOARD)
    {
      endgame_board = 0;
      radio_result_2 = 0;
    }

    dialog_result = run_dialog(mzx_world, &a_di);
    destruct_dialog(&a_di);

    switch(dialog_result)
    {
      case 2:
      {
        // Returns 1 for previous
        set_context(88);

        set_confirm_buttons(b_elements);
        b_elements[2] = construct_board_list(6, 2, "First board-",
         0, &first_board);
        b_elements[3] = construct_color_box(38, 3, "Edging color- ",
         0, &edge_color);
        b_elements[4] = construct_number_box(6, 5, "Starting lives-  ",
         1, 32767, 0, &starting_lives);
        b_elements[5] = construct_number_box(6, 6, "Maximum lives-   ",
         1, 32767, 0, &lives_limit);
        b_elements[6] = construct_number_box(6, 8, "Starting health- ",
         1, 32767, 0, &starting_health);
        b_elements[7] = construct_number_box(6, 9, "Maximum health-  ",
         1, 32767, 0, &health_limit);
        b_elements[8] = construct_button(38, 9, "Previous", 2);
        b_elements[9] = construct_check_box(6, 11, check_box_strings_2,
         3, 39, check_box_results_2);

        construct_dialog(&b_di, "Global Settings (Continued)", 10, 4,
         60, 18, b_elements, 10, 2);

        dialog_result = run_dialog(mzx_world, &b_di);
        destruct_dialog(&b_di);

        pop_context();

        if(dialog_result == 2)
        {
          redo = 1;
          break;
        }

        // If okay, fall through and apply settings
        if(dialog_result == 1)
          break;
      }

      case 0:
      {
        if(radio_result_1 == 2)
          mzx_world->death_board = death_board;
        else

        if(radio_result_1 == 1)
          mzx_world->death_board = NO_DEATH_BOARD;

        else
          mzx_world->death_board = DEATH_SAME_POS;

        if(radio_result_2 == 1)
          mzx_world->endgame_board = endgame_board;
        else
          mzx_world->endgame_board = NO_ENDGAME_BOARD;

        mzx_world->death_x = death_x;
        mzx_world->endgame_x = endgame_x;
        mzx_world->death_y = death_y;
        mzx_world->endgame_y = endgame_y;
        mzx_world->game_over_sfx = check_box_results_1[0];

        mzx_world->first_board = first_board;
        mzx_world->edge_color = edge_color;

        // These are the only parts of the default global data
        // that the editor can change, so it has to be updated
        // so testing won't screw things up.
        set_counter(mzx_world, "LIVES", starting_lives, 0);
        set_counter(mzx_world, "HEALTH", starting_health, 0);

        mzx_world->starting_lives = starting_lives;
        mzx_world->lives_limit = lives_limit;
        mzx_world->starting_health = starting_health;
        mzx_world->health_limit = health_limit;
        mzx_world->enemy_hurt_enemy = check_box_results_2[0];
        mzx_world->clear_on_exit = check_box_results_2[1];
        mzx_world->only_from_swap = check_box_results_2[2];

        if(starting_lives > lives_limit)
          mzx_world->starting_lives = lives_limit;

        if(starting_health > health_limit)
          mzx_world->starting_health = health_limit;

        break;
      }

      case 3:
      {
        global_chars(mzx_world); // Chars
        break;
      }

      case 4:
      {
        global_dmg(mzx_world); // Dmg
        break;
      }

      case 5:
      {
        struct robot *cur_robot = &mzx_world->global_robot;
        // First get name...
        m_hide();
        save_screen();
        draw_window_box(16, 12, 50, 14, DI_DEBUG_BOX, DI_DEBUG_BOX_DARK,
         DI_DEBUG_BOX_CORNER, 1, 1);
        write_string("Name for robot:", 18, 13, DI_DEBUG_LABEL, 0);
        m_show();

        if(intake(mzx_world, cur_robot->robot_name,
         14, 34, 13, 15, 1, 0, NULL, 0, NULL) != IKEY_ESCAPE)
        {
          restore_screen();
          set_context(87);
          robot_editor(mzx_world, cur_robot);
          pop_context();
        }
        else
        {
          restore_screen();
        }
      }
    }
  } while(redo);

  pop_context();
}
