/*----------------------------------------------------------------------------*
 | This file is part of DEU (Doom Editing Utilities), created by the DEU team:|
 | Raphael Quinet, Brendon Wyber, Ted Vessenes and others.  See README.1ST or |
 | the "about" dialog box for full credits.                                   |
 |                                                                            |
 | DEU is an open project: if you think that you can contribute, please join  |
 | the DEU team.  You will be credited for any code (or ideas) included in    |
 | the next version of the program.                                           |
 |                                                                            |
 | If you want to make any modifications and re-distribute them on your own,  |
 | you must follow the conditions of the DEU license.  Read the file LICENSE  |
 | in this directory or README.1ST in the top directory.  If do not have a    |
 | copy of these files, you can request them from any member of the DEU team, |
 | or by mail: Raphael Quinet, Rue des Martyrs 9, B-4550 Nandrin (Belgium).   |
 |                                                                            |
 | This program comes with absolutely no warranty.  Use it at your own risks! |
 *----------------------------------------------------------------------------*

 B_UI.C - User interface for the Nodes, Reject and BlockMap builders

 Created on Jun 9 1994 by Johannes Plass
 Converted to DEU 5.3 style on Jan 24 1995 by Renaud Paquay

*/

#include "deu.h"
#include "d_misc.h"
#include "d_config.h" /*RP Config */
#include "g_gfx.h"    /*RP ScrMax.. */
#include "g_mouse.h"  /*RP UseMouse, ResetMouseLimits() */
#include "i_dialog.h" /* DrawDialogBox, #defines, ... */
#include "i_menus.h"  /* Notify() */
#include "w_levels.h"
#include "b_bsp.h"
#include "b_ui.h"

/*####################################################################
    Defines
####################################################################*/

#define MENU_X        0
#define MENU_DX       140
#define MENU_DY       135
#define MENU_Y        (ScrMaxY-MENU_DY)

#define OPT_X         (MENU_DX + 10)
#define OPT_DX        205
#define OPT_Y         0
#define OPT_DY        (MENU_DY)

#define SMENU_X       (OPT_X + OPT_DX + 10)
#define SMENU_DX      110
#define SMENU_Y       0
#define SMENU_DY      (MENU_DY)

#define OPT_TEXT_X    (OPT_X + 10)
#define NODE_SPLIT    (OPT_Y + 35)
#define NODE_SLOPE    (OPT_Y + 50)
#define NODE_SPEED    (OPT_Y + 65)

#define T_NODES_X     10
#define T_NODES_Y     33
#define T_REJ_X       (T_NODES_X)
#define T_REJ_Y       48
#define T_BLOCK_X     (T_NODES_X)
#define T_BLOCK_Y     63
#define T_NREJ_X      (OPT_X + 115)
#define T_NREJ_Y      (OPT_Y + 95)
#define T_FREJ_X      (OPT_X + 115)
#define T_FREJ_Y      (OPT_Y + 110)
#define T_PREJ_X      (OPT_X + 10)
#define T_PREJ_Y      (OPT_Y + 110)

#define B_SAVE_X      (SMENU_X+10)
#define B_SAVE_Y      (SMENU_Y+34)
#define B_LOAD_X      (SMENU_X+10)
#define B_LOAD_Y      (SMENU_Y+71)
#define B_DEFAULT_X   (SMENU_X+10)
#define B_DEFAULT_Y   (SMENU_Y+108)
#define B_BUILD_X     25
#define B_BUILD_Y     83
#define B_QUIT_X      25
#define B_QUIT_Y      108

#define FILE_X     0
#define FILE_Y   -40
#define FILE_DY   30


/*####################################################################
   NodeTreeStatistics
####################################################################*/

#define NODESTAT_LX       385
#define NODESTAT_RX       639
#define NODESTAT_UY       (ScrMaxY - 90)
#define NODESTAT_LY       (ScrMaxY)

#define NODESTAT_SPLITS   (NODESTAT_UY+30)
#define NODESTAT_2SPLITS  (NODESTAT_UY+45)
#define NODESTAT_CORRECT  (NODESTAT_UY+60)

#define NODESTAT_TEXT_LX  (NODESTAT_LX+10)
#define NODESTAT_TEXT_RX  (NODESTAT_RX-10)



/*
   Set builder options to default values
*/

/*RP Moved from B_SAVE.C and updated to DEU 5.3 style */

static void BuilderOptionsDefault(va_list *args, DBSC *btn, Bool status)
{
  if (status != RUN)
    return;

  Config.RebuildNodes    = REBUILD_NODES_DEF;
  Config.RebuildReject   = REBUILD_REJECT_DEF;
  Config.RebuildBlockmap = REBUILD_BLOCKMAP_DEF;
  Config.BSP_splitfactor = SPLITFACTOR_DEF;
  Config.BSP_slopefactor = SLOPEFACTOR_DEF;
  Config.BSP_speedfactor = SPEEDFACTOR_DEF;
  Config.RejectOption    = REJECT_OPTION_DEF;
}


/*
  Convert a integer string value to a integer int value.
  The integer value is bounded by min and max params
*/

/*RP Changed int to Bool and converted to deu 5.3 style */

Int16 valueI(char* value, Int16 minI, Int16 maxI, Int16 defI)
{
  Int16 result = atoi(value);

  if ((result < minI) || (result > maxI) )
    result = defI;
  return result;
}


/*
  Convert a boolean string value to a boolean int value
*/

/*RP Changed int to Bool and converted to deu 5.3 style */

Bool valueT(char* value, Bool defT)
{
  Bool result;

  if (stricmp(value, "yes") == 0 || stricmp(value, "true") == 0 ||
       stricmp(value, "on")  == 0 || stricmp(value, "1")    == 0 )
    {
      result=TRUE;
    }
  else if (stricmp(value, "no")  == 0 || stricmp(value, "false") == 0 ||
            stricmp(value, "off") == 0 || stricmp(value, "0")     == 0 )
    {
      result=FALSE;
    }
  else
    result=defT;

  return result;
}


/*
   Load builder options from config file
*/

/*RP Moved from B_SAVE.C and completely changed to use the Config file
     and updated to DEU 5.3 style */

static void BuilderOptionsLoad(va_list *args, DBSC *btn, Bool status)
{
  Int16 vali;

  if (status != RUN)
    return;

  Config.RebuildNodes    = valueT(GetOptionValue("RebuildNodes"),
                                  REBUILD_NODES_DEF);

  Config.RebuildReject   = valueT(GetOptionValue("RebuildReject"),
                                  REBUILD_REJECT_DEF);

  Config.RebuildBlockmap = valueT(GetOptionValue("RebuildBlockmap"),
                                  REBUILD_BLOCKMAP_DEF);

  Config.BSP_splitfactor = valueI(GetOptionValue("SplitFactor"),
                                  SPLITFACTOR_MIN, SPLITFACTOR_MAX,
                                  SPLITFACTOR_DEF);

  Config.BSP_slopefactor = valueI(GetOptionValue("SlopeFactor"),
                                  SLOPEFACTOR_MIN, SLOPEFACTOR_MAX,
                                  SLOPEFACTOR_DEF);

  Config.BSP_speedfactor = valueI(GetOptionValue("SpeedFactor"),
                                  SPEEDFACTOR_MIN, SPEEDFACTOR_MAX,
                                  SPEEDFACTOR_DEF);

  vali = atoi(GetOptionValue ("RejectOption"));
  if (vali == REJECT_NORMAL || vali == REJECT_PEACEFUL || vali == REJECT_FAKE)
    Config.RejectOption = vali;
  else
    Config.RejectOption = REJECT_OPTION_DEF;
}


/*
   Save builder options to config file
*/

/*RP Moved from B_SAVE.C and completely changed to use the Config file
     and updated to DEU 5.3 style */

#define SAVE_B_OPTION(name,opt)                 \
{                                               \
  ChangeOption(name, opt ? "TRUE" : "FALSE");   \
  SaveConfigFileOption(Config.cfgFile, name);   \
}

#define SAVE_I_OPTION(name,opt)                 \
{                                               \
  char str[10];                                 \
  sprintf(str, "%d", opt);                      \
  ChangeOption(name, str);                      \
  SaveConfigFileOption(Config.cfgFile, name);   \
}

void BuilderOptionsSave(va_list *args, DBSC *btn, Bool status)
{
  if (status != RUN)
    return;

  SAVE_B_OPTION("RebuildNodes",    Config.RebuildNodes);
  SAVE_B_OPTION("RebuildReject",   Config.RebuildReject);
  SAVE_B_OPTION("RebuildBlockmap", Config.RebuildBlockmap);
  SAVE_I_OPTION("SplitFactor",     Config.BSP_splitfactor);
  SAVE_I_OPTION("SlopeFactor",     Config.BSP_slopefactor);
  SAVE_I_OPTION("SpeedFactor",     Config.BSP_speedfactor);
  SAVE_I_OPTION("RejectOption",    Config.RejectOption);
}


/*
    Display stats about last nodes built
*/

void NodeTreeStatistics(void)
{
  DrawScreenBox3D(NODESTAT_LX, NODESTAT_UY, NODESTAT_RX, NODESTAT_LY);
  SetColor(BLUE);
  DrawScreenText(NODESTAT_TEXT_LX, NODESTAT_UY + 8, "Node Tree Statistics");
  SetColor(BLACK);
  DrawScreenText(NODESTAT_TEXT_LX, NODESTAT_SPLITS,  "Splits:             %ld", BSP_splits);
  DrawScreenText(NODESTAT_TEXT_LX, NODESTAT_2SPLITS, "2S Splits:          %ld", BSP_2S_splits);
  DrawScreenText(NODESTAT_TEXT_LX, NODESTAT_CORRECT, "Split Corrections:  %ld", BSP_vertex_corrections);
}


/*
    Handle nodes, reject and blockmap builder dialog box
*/

int HandleBuilderMenu(char *outfile)
{
  int   maxlen = 15, tlen;
  char *title = "Destination File:";
  DB   *db_yuck;

  /*!RP Why this line ? */
  UseMouse = TRUE;

  ClearScreen();
  ResetMouseLimits();


  if (strlen(outfile) > maxlen)
    maxlen = strlen(title);
  tlen = TEXT_W*(strlen(title) + maxlen) + 30;

  db_yuck = LoadDialogBox(MENU_X, MENU_Y, MENU_DX, MENU_DY, NULL, 10,
      DBSC_BOX,  SMENU_X, SMENU_Y, '\0', BOX_RAISED, SMENU_DX, SMENU_DY,
      DBSC_BOX,  OPT_X,   OPT_Y,   '\0', BOX_RAISED, OPT_DX,   OPT_DY,
      DBSC_BOX,  FILE_X,  FILE_Y,  '\0', BOX_RAISED, tlen,     FILE_DY,

      DBSC_TEXT,  SMENU_X+27, SMENU_Y+12, '\0', "Setting",     0, BLUE,
      DBSC_TEXT,          10,         12, '\0', "Rebuild",     0, BLUE,
      DBSC_TEXT,  OPT_TEXT_X, OPT_Y + 12, '\0', "Node Tree",   0, BLUE,
      DBSC_TEXT,  OPT_TEXT_X, OPT_Y + 97, '\0', "Reject Data", 0, BLUE,

      DBSC_TEXT,  OPT_TEXT_X, NODE_SPLIT, 'I', "Split Factor:",  0, YELLOW,
      DBSC_TEXT,  OPT_TEXT_X, NODE_SLOPE, 'E', "Slope Factor:",  0, YELLOW,
      DBSC_TEXT,  OPT_TEXT_X, NODE_SPEED, 'H', "Node Checking:", 0, YELLOW);

  AppendDbscList(db_yuck, NULL, 6,
      DBSC_INPUTBOX, OPT_X + 128, NODE_SPLIT - 2, 'I', (Int16*) &Config.BSP_splitfactor,
        SPLITFACTOR_MIN, SPLITFACTOR_MAX,
      DBSC_INPUTBOX, OPT_X + 128, NODE_SLOPE - 2, 'E', (Int16*) &Config.BSP_slopefactor,
        SLOPEFACTOR_MIN, SLOPEFACTOR_MAX,
      DBSC_INPUTBOX, OPT_X + 128, NODE_SPEED - 2, 'H', (Int16*) &Config.BSP_speedfactor,
        SPEEDFACTOR_MIN, SPEEDFACTOR_MAX,

      DBSC_L_CHECKBOX, T_NREJ_X,  T_NREJ_Y,  'M', &Config.RejectOption, SVAL, 0,
        "Normal",
      DBSC_L_CHECKBOX, T_PREJ_X,  T_PREJ_Y,  'P', &Config.RejectOption, SVAL, 2,
        "Peacful",
      DBSC_L_CHECKBOX, T_FREJ_X,  T_FREJ_Y,  'F', &Config.RejectOption, SVAL, 1,
        "Fake");

  AppendDbscList(db_yuck, NULL, 8,
      DBSC_BUTTON,  B_SAVE_X,    B_SAVE_Y,    'S', BUTTON_FUNCTION, "Save",
        WHITE, NULL, DB_NONE,   BuilderOptionsSave,
      DBSC_BUTTON,  B_LOAD_X,    B_LOAD_Y,    'L', BUTTON_FUNCTION, "Load",
        WHITE, NULL, DB_UPDATE, BuilderOptionsLoad,
      DBSC_BUTTON,  B_DEFAULT_X, B_DEFAULT_Y, 'D', BUTTON_FUNCTION, "Default",
        WHITE, NULL, DB_UPDATE, BuilderOptionsDefault,

      DBSC_L_CHECKBOX, T_NODES_X, T_NODES_Y, 'N', &Config.RebuildNodes, BIT, 0x01,
        "Node Tree",
      DBSC_L_CHECKBOX, T_REJ_X,   T_REJ_Y,   'R', &Config.RebuildReject,   BIT, 0x01,
        "Reject Table",
      DBSC_L_CHECKBOX, T_BLOCK_X, T_BLOCK_Y, 'B', &Config.RebuildBlockmap, BIT, 0x01,
        "Blockmap",

      DBSC_OK,      B_BUILD_X, B_BUILD_Y, 'O',
      DBSC_CANCEL,  B_QUIT_X,  B_QUIT_Y,  'C');

  if (ProcessDialogBox(db_yuck, NULL))
    {
      return(Config.RebuildNodes          |
             (Config.RebuildReject   << 1) |
             (Config.RebuildBlockmap << 2) );
    }
  else
    return(FALSE);
}


/*
   Delete builder dialogs and display build stats
*/

void ExitBuilderMenu(void)
{
  if (UseMouse)
    HideMousePointer();

  SetColor(BLACK);
  DrawScreenBox(MENU_X + SMENU_X,            MENU_Y + SMENU_Y,
                MENU_X + SMENU_X + SMENU_DX, MENU_Y + SMENU_Y + SMENU_DY);
  NodeTreeStatistics();
  Notify(-1, -1, "Finished rebuilding data", NULL);
  ClearScreen();
}

/* end of file */
