From 64f929c1d342665304f5171307b37aeddf302bc3 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Thu, 4 Apr 2013 21:04:34 +0100
Subject: [PATCH] [Add] Missions info window.

---
 dat/missions/cargo.lua |   4 +-
 src/menu.c             | 137 ++++++++++++++++++++++++++++++++++++++---
 src/toolkit.h          |   3 +
 3 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/dat/missions/cargo.lua b/dat/missions/cargo.lua
index 0cc9ccd..aea5f3b 100644
--- a/dat/missions/cargo.lua
+++ b/dat/missions/cargo.lua
@@ -28,8 +28,8 @@ end
 function accept()
   if player.freeCargo() < carg_mass then
     tk.msg("Ship is full",
-           string.format("Your ship is too full, You need to make room for \
-                          %d more tons if you want to be able to accept the mission.",
+           string.format(
+           "Your ship is too full, You need to make room for %d more tons if you want to be able to accept the mission.",
                           carg_mass-player.freeCargo()))
     elseif misn.accept() then -- Able to accept the mission, hooks BREAK after accepting.
       player.addCargo(carg_type, carg_mass)
diff --git a/src/menu.c b/src/menu.c
index 013d383..8b5be66 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -9,6 +9,7 @@
 #include "space.h"
 #include "player.h"
 #include "plasmaf.h"
+#include "mission.h"
 #include "menu.h"
 
 #define MAIN_WIDTH          130
@@ -20,8 +21,11 @@
 #define INFO_WIDTH          360
 #define INFO_HEIGHT         280
 
-#define OUTFITS_WIDTH   400
-#define OUTFITS_HEIGHT  200
+#define OUTFITS_WIDTH       400
+#define OUTFITS_HEIGHT      200
+
+#define MISSIONS_WIDTH      600
+#define MISSIONS_HEIGHT     400
 
 #define DEATH_WIDTH         130
 #define DEATH_HEIGHT        150
@@ -34,15 +38,26 @@
 
 int menu_open = 0;
 
+// Main menu.
 static void menu_main_close(void);
 static void menu_main_new(char* str);
+// Small menu.
 static void menu_small_close(char* str);
 static void edit_options(void);
 static void exit_game(void);
+// Information menu.
 static void menu_info_close(char* str);
+// Outfits submenu.
 static void info_outfits_menu(char* str);
-static void info_outfits_menu_close(char* str);
+// Mission submenu.
+static void info_missions_menu(char* str);
+static void mission_menu_abort(char* str);
+static void mission_menu_genList(int first);
+static void mission_menu_update(char* str);
+// Death menu.
 static void menu_death_main(char* str);
+// Generic.
+static void menu_generic_close(char* str);
 
 void menu_main(void) {
   unsigned int bwid, wid;
@@ -178,7 +193,7 @@ void menu_info(void) {
                    "btnCargo", "Cargo", NULL);
   window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
                    BUTTON_WIDTH, BUTTON_HEIGHT,
-                   "btnMissions", "Missions", NULL);
+                   "btnMissions", "Missions", info_missions_menu);
   window_addButton(wid, -20, 20,
                    BUTTON_WIDTH, BUTTON_HEIGHT,
                    "btnClose", "Close", menu_info_close);
@@ -214,11 +229,114 @@ static void info_outfits_menu(char* str) {
 
   window_addButton(wid, -20, 20,
                    BUTTON_WIDTH, BUTTON_HEIGHT,
-                   "closeOutfits", "Close", info_outfits_menu_close);
+                   "closeOutfits", "Close", menu_generic_close);
 }
 
-static void info_outfits_menu_close(char* str) {
-  window_destroy(window_get(str+5)); // closeFoo -> Foo.
+// Show the player's active missions.
+static void info_missions_menu(char* str) {
+  (void)str;
+  unsigned int wid;
+
+  wid = window_create("Missions", -1, -1, MISSIONS_WIDTH, MISSIONS_HEIGHT);
+
+  // Buttons.
+  window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
+                   "closeMissions", "Back", menu_generic_close);
+
+  window_addButton(wid, -20, 40+BUTTON_HEIGHT,
+                   BUTTON_WIDTH, BUTTON_HEIGHT, "btnAbortMission", "Abort",
+                   mission_menu_abort);
+
+  // Text.
+  window_addText(wid, 300+40, -60,
+                 200, 40, 0, "txtSReward",
+                 &gl_smallFont, &cDConsole, "Reward:");
+
+  window_addText(wid, 300+100, -60,
+                 140, 40, 0, "txtReward", &gl_smallFont, &cBlack, NULL);
+
+  window_addText(wid, 300+40, -100,
+                 200, MISSIONS_HEIGHT - BUTTON_WIDTH - 120, 0,
+                 "txtDesc", &gl_smallFont, &cBlack, NULL);
+
+  // List.
+  mission_menu_genList(1);
+}
+
+static void mission_menu_genList(int first) {
+  int i, j;
+  char** misn_names;
+  unsigned int wid;
+
+  wid = window_get("Missions");
+
+  if(!first)
+    window_destroyWidget(wid, "lstMission");
+
+  // List.
+  misn_names = malloc(sizeof(char*) * MISSION_MAX);
+  j = 0;
+  for(i = 0; i < MISSION_MAX; i++)
+    if(player_missions[i].id != 0)
+      misn_names[j++] = strdup(player_missions[i].title);
+  if(j == 0) {
+    // No missions.
+    free(misn_names);
+    misn_names = malloc(sizeof(char*));
+    misn_names[0] = strdup("No Missions");
+    j = 1;
+  }
+  window_addList(wid, 20, -40,
+                 300, MISSIONS_HEIGHT-60,
+                 "lstMission", misn_names, j, 0, mission_menu_update);
+
+  mission_menu_update(NULL);
+}
+
+static void mission_menu_update(char* str) {
+  int i;
+  char* active_misn;
+  unsigned int wid;
+
+  (void)str;
+
+  wid = window_get("Missions");
+
+  active_misn = toolkit_getList(wid, "lstMission");
+  if(strcmp(active_misn, "No Missions")==0) {
+    window_modifyText(wid, "txtReward", "None");
+    window_modifyText(wid, "txtDesc", "You currently have no active missions.");
+    window_disableButton(wid, "btnAbortMission");
+    return;
+  }
+  for(i = 0; i < MISSION_MAX; i++)
+    if(player_missions[i].title &&
+        (strcmp(active_misn, player_missions[i].title)==0)) {
+      window_modifyText(wid, "txtReward", player_missions[i].reward);
+      window_modifyText(wid, "txtDesc", player_missions[i].desc);
+      window_enableButton(wid, "btnAbortMission");
+      return;
+    }
+}
+
+static void mission_menu_abort(char* str) {
+  (void)str;
+  char* selected_misn;
+  unsigned int wid;
+  int i;
+
+  wid = window_get("Missions");
+
+  selected_misn = toolkit_getList(wid, "lstMission");
+
+  if(dialogue_YesNo("Abort Mission", "Are you sure you want to abort this mission?"))
+    for(i = 0; i < MISSION_MAX; i++)
+      if(player_missions[i].title &&
+          (strcmp(selected_misn, player_missions[i].title)==0)) {
+        mission_cleanup(&player_missions[i]);
+        mission_menu_genList(0);
+        break;
+      }
 }
 
 // Pilot dead.
@@ -246,3 +364,8 @@ static void menu_death_main(char* str) {
   menu_main();
 }
 
+// Generic close approach.
+static void menu_generic_close(char* str) {
+  window_destroy(window_get(str+5)); // closeFoo -> Foo.
+}
+
diff --git a/src/toolkit.h b/src/toolkit.h
index 03358a8..af351e2 100644
--- a/src/toolkit.h
+++ b/src/toolkit.h
@@ -44,8 +44,11 @@ void window_addInput(const unsigned int wid,
                      char* name, const int max, const int oneline);
 
 // Popups and alerts.
+
+// Does not pause execution.
 void  dialogue_alert(const char* fmt, ...);
 void  dialogue_msg(char* caption, const char* fmt, ...);
+// Yes = 1, No = 0.
 int   dialogue_YesNo(char* caption, const char* fmt, ...);
 char* dialogue_input(char* title, int min, int max, const char* fmt, ...);