//-------------------------------------------------------------------
//
//  This code is copyright 2001 by G5 Software.
//  Any unauthorized usage, either in part or in whole of this code
//  is strictly prohibited. Violators WILL be prosecuted to the
//  maximum extent allowed by law.
//
//-------------------------------------------------------------------
//
//  This script provides menu functionality
//  that is used in both Game menu and Mission menu

//
//  Base Menu
//

class CBaseMenu extends CStrings
{
  // Menu initialization variables
  // (variables read by menu component)

  string strSkinFile   = "Common/Menu.skin";
  color  MenuTextNormalColor = color(0.7, 0.7, 0.7);
  color  MenuTextHiliteColor = color(1.0, 0.0, 0.0);
  string HiliteSoundScript = "CHiliteSound";
  string SelectSoundScript = "CSelectSound";

  // video mode filter settings
  int    MinAcceptedVideoModeWidth  = 640;
  int    MinAcceptedVideoModeHeight = 480;
  int    MinAcceptedVideoModeDepth  = 16;

  //
  //  standard buttons
  //

  float fStdButtonWidth        = 0.125;
  float fStdButtonHeight       = 0.0412;

  float fScrollButtonWidth     = 0.031;
  float fScrollButtonHeight    = 0.042;

  int   nBackButtonNormMat     = 48;
  int   nBackButtonHiMat       = 49;

  int   nAcceptButtonNormMat   = 50;
  int   nAcceptButtonHiMat     = 51;

  int   nStartButtonNormMat    = 58;
  int   nStartButtonHiMat      = 59;

  int   nSettingsButtonNormMat = 54;
  int   nSettingsButtonHiMat   = 55;

  int   nCreditsButtonNormMat  = 52;
  int   nCreditsButtonHiMat    = 53;

  int   nQuitButtonNormMat     = 56;
  int   nQuitButtonHiMat       = 57;

  int   nDownButtonNormMat     = 60;
  int   nDownButtonHiMat       = 61;

  int   nUpButtonNormMat       = 62;
  int   nUpButtonHiMat         = 63;

  // combo box helper method

  float BaseMenu_CreateCenteredComboBox(string _title, string _id, float _y, array _list, float _width)
  {
    _y =
      CenterText(_title, _y, _id + "_TEXT", color(1.0, 1.0, 1.0));

    float fSpacing    = 0.02;
    float fArrowWidth = 0.05;

    float LeftArrowX = (1.0 - _width) / 2 - fSpacing - fArrowWidth;
    float RightArrowX = (1.0 - _width) / 2 + _width + fSpacing;

    //
    //  left arrow
    //

    CreateBitmapButton(
      _id + "_LEFT_ARROW",
      7,
      8,
      LeftArrowX,
      _y,
      fArrowWidth,
      fButtonHeight);

    //
    //  combo box
    //

    CreateComboBox(
      _list,
      _id + "_COMBO_BOX",
      (1.0 - _width) / 2,
      _y,
      _width,
      fButtonHeight
    );

    //
    //  right arrow
    //

    CreateBitmapButton(
      _id + "_RIGHT_ARROW",
      9,
      10,
      RightArrowX,
      _y,
      fArrowWidth,
      fButtonHeight);

    return _y + fButtonHeight;
  }

  //
  //  Slider
  //

  float BaseMenu_CreateCenteredSlider(
     string _name,
     string _sid,
     float  _y,
     float  _width
    )
  {
    color  SliderColor        = color(1.0, 1.0, 1.0);
    float  SliderX            = (1.0 - _width) / 2.0;
    float  SliderCursorWidth  = 0.05;
    float  SliderCursorHeight = 0.05 / 0.75;
    float  SliderCursorMargin = SliderCursorWidth / 6.0;

    float y =
      CenterText(_name, _y + fVertSpacing, "ID_SLIDER_TEXT", color(1.0, 1.0, 1.0));

    CreateSliderBack(
      _sid + "_SLIDER_BACK",  // control id
      SliderColor,           // color
      SliderX,               // x
      y,                     // y
      _width,                // width
      fButtonHeight          // height
    );

    CreateSliderCursor(
      _sid + "_SLIDER_CURSOR",      // control id
      14,                           // normal material
      15,                           // highlighted material
      SliderX - SliderCursorMargin,                  // x
      y + (fButtonHeight - SliderCursorHeight) / 2 + 0.003,  // y
      SliderCursorWidth,            // width
      SliderCursorHeight,           // height
      SliderX + _width + SliderCursorMargin - SliderCursorWidth
    );

    return y + fButtonHeight + fVertSpacing;
  }


  // attributes

  int    MenuWidth   = 10;
  int    MenuSpacing = 5;

  float fButtonWidth  = 0.4;
  float fButtonHeight = 0.07;
  float fVertSpacing  = 0.01;

  float fPrevButtonWidth = 0.15;
  float fNextButtonWidth = 0.15;

  // methods

  void CBaseMenu()
  {
  }

  //
  //  Should be called by subclasses on move of menu button
  //

  void BaseMenu_MenuButtonMoved(string _id)
  {
    if ("ID_GAMMA_CORRECTION_SLIDER_CURSOR" == _id)
    {
      float value = SendCommandToControl("ID_GAMMA_CORRECTION_SLIDER_CURSOR", "GET_VALUE");
      SetGammaCorrection(value);
    }
  }

  //
  //  Should be called by subclasses on user click on menu button
  //

  void BaseMenu_MenuButtonClicked(string _id)
  {
    if ("ID_MISSION_STATUS_OK" == _id)
    {
      GoToRootMenu();

      // after debriefing -- go to select mission screen
      if (!m_bInGame)
        GoToSubMenu("GameMenu_InitMissionsMenu");

      Core_SendEventTo(SOID_MissionController, "OnHideMissionStatus");
    }
    else
    if ("ID_MISSION_HELP_SCREEN_OK" == _id)
    {
      GoToRootMenu();
      Core_SendEventTo(SOID_MissionController, "OnHideMissionHelpScreen");
    }
    else
    if ("ID_CONTROLS_OK" == _id)
    {
      SaveControls("controls.settings");
      GoToPrevMenu();
    }
    else
    if ("ID_DEFAULT_CONTROLS_OK" == _id)
    {
      LoadControls("def_controls.settings");
      GoToPrevMenu();
    }
    else
    if ("ID_DEFAULT_WASD_CONTROLS_OK" == _id)
    {
      LoadControls("def_wasd_controls.settings");
      GoToPrevMenu();
    }
    else
    if ("ID_VIDEO_SETTINGS_OK" == _id)
    {
      // apply video mode settings
      int device = SendCommandToControl("ID_VIDEO_CARD_COMBO_BOX", "GET_SELECTION");

      // apply video mode settings
      int mode = SendCommandToControl("ID_VIDEO_MODE_COMBO_BOX", "GET_SELECTION");

      SetVideoMode(device, mode);

      // apply forest detail settings
      float value = SendCommandToControl("ID_FOREST_DETAIL_SLIDER_CURSOR", "GET_VALUE");
      SetForestDetail(value);

      // apply terrain detail settings
      float value = SendCommandToControl("ID_TERRAIN_DETAIL_SLIDER_CURSOR", "GET_VALUE");
      SetTerrainDetail(value);

      GoToPrevMenu();
    }
    else
    if ("ID_MOUSE_SENSITIVITY_SLIDER_CURSOR" == _id)
    {
      float value = SendCommandToControl("ID_MOUSE_SENSITIVITY_SLIDER_CURSOR", "GET_VALUE");
      SetMouseSensitivity(value);
      SaveControls("controls.settings");
    }
    else
    if ("ID_SOUND_VOLUME_SLIDER_CURSOR" == _id)
    {
      float value = SendCommandToControl("ID_SOUND_VOLUME_SLIDER_CURSOR", "GET_VALUE");
      SetSoundFxVolume(value);
      SaveSoundSettings();
    }
    else
    if ("ID_MUSIC_VOLUME_SLIDER_CURSOR" == _id)
    {
      float value = SendCommandToControl("ID_MUSIC_VOLUME_SLIDER_CURSOR", "GET_VALUE");
      SetMusicVolume(value);
      SaveSoundSettings();
    }

    if (Core_IsStringEndsWith(_id, "_LEFT_ARROW"))
    {
      // left combo box arrow

      string combo_id =
        Core_GetStringPartPreceding(_id, "_LEFT_ARROW") + "_COMBO_BOX";

      SendCommandToControl(combo_id, "PREV");
    }

    if (Core_IsStringEndsWith(_id, "_RIGHT_ARROW"))
    {
      // right combo box arrow

      string combo_id =
        Core_GetStringPartPreceding(_id, "_RIGHT_ARROW") + "_COMBO_BOX";

      SendCommandToControl(combo_id, "NEXT");
    }

    if (Core_IsStringStartsWith(_id, "ID_INPUT_DEVICE_"))
    {
      // input device switched
      int device = SendCommandToControl("ID_INPUT_DEVICE_COMBO_BOX", "GET_SELECTION");
      SetInputDevice(device);
      SaveControls("controls.settings");
    }

    if (Core_IsStringStartsWith(_id, "ID_DIFFICULTY_LEVEL_"))
    {
      // difficulty level switched
      int level = SendCommandToControl("ID_DIFFICULTY_LEVEL_COMBO_BOX", "GET_SELECTION");
      SetDifficultyLevel(level);
    }

    if (Core_IsStringStartsWith(_id, "ID_VIDEO_CARD_"))
    {
      // video card switched - refresh video mode list
      int device = SendCommandToControl("ID_VIDEO_CARD_COMBO_BOX", "GET_SELECTION");

      // replace array of modes in mode combo box
      SendCommandToControl(
        "ID_VIDEO_MODE_COMBO_BOX",
        "SET_LIST",
        GetVideoModesList(device)
      );

      // try to find the equal mode in this list
      SendCommandToControl(
        "ID_VIDEO_MODE_COMBO_BOX",
        "SET_SELECTION " + GetCurrentVideoModeIndex(device)
      );
    }

    if (Core_IsStringStartsWith(_id, "ID_TARGET_WINDOW_"))
    {
      int enabled = SendCommandToControl("ID_TARGET_WINDOW_COMBO_BOX", "GET_SELECTION");
      Core_CallFunction("Helicopter",
                        "EnableTargetScreen",
                        enabled != 0);
    }
  }

  //
  //  Submenus construction
  //

  //
  //  Settings menu
  //

  void BaseMenu_InitSettingsBackground()
  {
    CreateBitmapControl(
      "Resources/Menu_Settings.tex",
      "ID_BITMAP",
      0.0,
      0.0,
      1.0,
      1.0
    );
  }

  void BaseMenu_InitSettingsMenu()
  {
    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.2;

    BaseMenu_InitSettingsBackground();

    //
    //  Game settings button
    //

    if (GetMenuType() == "GameMenu")
    {
      CreateSubMenu(
          str_GameSettingsButton,
          "ID_GAME_SETTINGS",
          fButtonX,
          fButtonY,
          fButtonWidth,
          fButtonHeight,
          "BaseMenu_InitGameSettingsMenu");
      fButtonY = fButtonY + fButtonHeight + fVertSpacing;
    }

    // video settings -- for game menu only

    //
    //  Video settings button
    //

    CreateSubMenu(
        str_VideoSettingsButton,
        "ID_VIDEO_SETTINGS",
        fButtonX,
        fButtonY,
        fButtonWidth,
        fButtonHeight,
        "BaseMenu_InitVideoSettingsMenu");
    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Audio settings button
    //

    CreateSubMenu(
      str_AudioSettingsButton,
      "ID_AUDIO_SETTINGS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitAudioSettingsMenu");

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Controls button
    //

    CreateSubMenu(
      str_ControlsButton,
      "ID_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitControlsMenu");

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Back button
    //

    CreateTextButton(
      str_BackButton,
      "ID_BACK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight);

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  Game settings menu
  //

  void BaseMenu_InitGameSettingsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.2;

    fButtonY =
      BaseMenu_CreateCenteredComboBox(
        str_DifficultyLevel,
        "ID_DIFFICULTY_LEVEL",
        fButtonY,
          array(
            str_Easy,
            str_Medium,
            str_Hard,
            str_Nightmare
          ),
        0.5
        );

    // display current difficulty level in combo box
    SendCommandToControl(
      "ID_DIFFICULTY_LEVEL_COMBO_BOX",
      "SET_SELECTION " + GetDifficultyLevel()
    );

    //
    //  BACK button
    //

    CreateTextButton(
        str_BackButton,
        "ID_BACK",
        fButtonX,
        fButtonY,
        fButtonWidth,
        fButtonHeight);

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  Video settings menu
  //

  void BaseMenu_InitVideoSettingsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.2;

    //
    //  for mission menu disable background to let player see
    //  how gamma correction affects game picture
    //

    if (GetMenuType() == "MissionMenu")
    {
      DisableBackgroundForThisMenu();
    }

    //
    //  video modes and forest detail for game menu only
    //

    if (GetMenuType() == "GameMenu")
    {
      fButtonY =
        BaseMenu_CreateCenteredComboBox(
          str_SelectVideoDevice,
          "ID_VIDEO_CARD",
          fButtonY,
          GetVideoDevicesList(),
          0.5
        );

      // display current device in video device combo box
      SendCommandToControl(
        "ID_VIDEO_CARD_COMBO_BOX",
        "SET_SELECTION " + GetCurrentVideoDeviceIndex()
      );

      fButtonY = fButtonY + fVertSpacing;

      fButtonY =
        BaseMenu_CreateCenteredComboBox(
          str_SelectVideoMode,
          "ID_VIDEO_MODE",
          fButtonY,
          GetVideoModesList(GetCurrentVideoDeviceIndex()),
          0.5
        );

      // display current video mode in video mode combo box
      SendCommandToControl(
        "ID_VIDEO_MODE_COMBO_BOX",
        "SET_SELECTION " + GetCurrentVideoModeIndex(GetCurrentVideoDeviceIndex())
      );

      fButtonY = fButtonY + fVertSpacing;
    }

    //
    //  Gamma correction slider
    //

    if (IsGammaCorrectionAvailable())
    {

      fButtonY =
        BaseMenu_CreateCenteredSlider(
          str_GammaCorrectionTitle,
          "ID_GAMMA_CORRECTION",
          fButtonY,
          0.5
        );

      SendCommandToControl(
        "ID_GAMMA_CORRECTION_SLIDER_CURSOR",
        "SET_VALUE " + GetGammaCorrection()
      );

      fButtonY = fButtonY + fVertSpacing;
    }

    if (GetMenuType() == "MissionMenu")
    {
      //
      //  Target window combo box
      //

      fButtonY =
        BaseMenu_CreateCenteredComboBox(
          str_TargetWindowTitle,
          "ID_TARGET_WINDOW",
          fButtonY,
          array(str_Off, str_On),
          0.5
        );

      bool bEnabled = Core_CallFunction("Helicopter",
                                        "IsTargetScreenEnabled");

      int init_value = 0;
      if (bEnabled) init_value = 1;

      // display current device in video device combo box
      SendCommandToControl(
        "ID_TARGET_WINDOW_COMBO_BOX",
        "SET_SELECTION " + init_value
      );

      fButtonY = fButtonY + fVertSpacing;
    }

    if (GetMenuType() == "GameMenu")
    {
      //
      //  Forest detail slider
      //

      fButtonY =
        BaseMenu_CreateCenteredSlider(
          str_ForestDetailTitle,
          "ID_FOREST_DETAIL",
          fButtonY,
          0.5
        );

      SendCommandToControl(
        "ID_FOREST_DETAIL_SLIDER_CURSOR",
        "SET_VALUE " + GetForestDetail()
      );

      fButtonY = fButtonY + fVertSpacing;

      //
      //  Terrain detail slider
      //

      fButtonY =
        BaseMenu_CreateCenteredSlider(
          str_TerrainDetailTitle,
          "ID_TERRAIN_DETAIL",
          fButtonY,
          0.5
        );

      SendCommandToControl(
        "ID_TERRAIN_DETAIL_SLIDER_CURSOR",
        "SET_VALUE " + GetTerrainDetail()
      );

      fButtonY = fButtonY + fVertSpacing;
    }

    if (GetMenuType() == "MissionMenu")
    {
      //
      //  BACK button
      //

      CreateTextButton(
          str_BackButton,
          "ID_BACK",
          fButtonX,
          fButtonY,
          fButtonWidth,
          fButtonHeight);
    }
    else
    {
      //
      //  OK button
      //

      CreateTextButton(
          str_OkButton,
          "ID_VIDEO_SETTINGS_OK",
          fButtonX,
          fButtonY,
          fButtonWidth,
          fButtonHeight);

      fButtonY = fButtonY + fButtonHeight + fVertSpacing;

      //
      //  CANCEL button
      //

      CreateTextButton(
          str_CancelButton,
          "ID_BACK",
          fButtonX,
          fButtonY,
          fButtonWidth,
          fButtonHeight);

      fButtonY = fButtonY + fButtonHeight + fVertSpacing;
    }
  }

  //
  //  Audio settings menu
  //

  void BaseMenu_InitAudioSettingsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.2;

    //
    //  Sound fx volume
    //

    fButtonY =
      BaseMenu_CreateCenteredSlider(
        str_SoundVolumeTitle,
        "ID_SOUND_VOLUME",
        fButtonY,
        0.5
      );

    SendCommandToControl(
      "ID_SOUND_VOLUME_SLIDER_CURSOR",
      "SET_VALUE " + GetSoundFxVolume()
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  Music volume
    //

    fButtonY =
      BaseMenu_CreateCenteredSlider(
        str_MusicVolumeTitle,
        "ID_MUSIC_VOLUME",
        fButtonY,
        0.5
      );

    SendCommandToControl(
      "ID_MUSIC_VOLUME_SLIDER_CURSOR",
      "SET_VALUE " + GetMusicVolume()
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  Back button
    //

    CreateTextButton(
        str_BackButton,
        "ID_BACK",
        fButtonX,
        fButtonY,
        fButtonWidth,
        fButtonHeight);

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  Controls menu
  //

  void BaseMenu_InitControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.2;

    array devices;

    if (IsJoystickAvailable())
      devices =
        array(
          str_Mouse,
          str_Joystick
        );
    else
      devices =
        array(
          str_Mouse
        );

    fButtonY =
      BaseMenu_CreateCenteredComboBox(
        str_SelectInputDevice,
        "ID_INPUT_DEVICE",
        fButtonY,
        devices,
        0.5
      );

    fButtonY = fButtonY + fVertSpacing;

    // display currently selected device in combo box
    SendCommandToControl(
      "ID_INPUT_DEVICE_COMBO_BOX",
      "SET_SELECTION " + GetInputDevice()
    );

    //
    //  Movement controls button
    //

    CreateSubMenu(
      str_MovementButton,
      "ID_MOVEMENT_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitMovementControlsMenu"
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Fire controls button
    //

    CreateSubMenu(
      str_FireButton,
      "ID_FIRE_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitFireControlsMenu"
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Other controls button
    //

    CreateSubMenu(
      str_OtherButton,
      "ID_OTHER_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitOtherControlsMenu"
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Default arrow controls button
    //

    CreateSubMenu(
      str_SetDefaultButton,
      "ID_DEFAULT_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitDefaultControlsMenu"
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    CreateSubMenu(
      str_SetWASDDefaultButton,
      "ID_DEFAULT_WASD_CONTROLS",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight,
      "BaseMenu_InitDefaultWASDControlsMenu"
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  Mouse sensitivity slider
    //

    fButtonY =
      BaseMenu_CreateCenteredSlider(
        str_MouseSensitivityTitle,
        "ID_MOUSE_SENSITIVITY",
        fButtonY,
        0.5
      );

    SendCommandToControl(
      "ID_MOUSE_SENSITIVITY_SLIDER_CURSOR",
      "SET_VALUE " + GetMouseSensitivity()
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  Back button
    //

    CreateTextButton(
      str_BackButton,
      "ID_BACK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );
  }

  void BaseMenu_InitDefaultControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float y =
      CenterText(str_APPLY_DEFAULT_SETTINGS, 0.3, "ID_TITLE_TEXT", color(1.0, 1.0, 1.0));

    float fButtonY = y + fVertSpacing * 2;
    float fButtonX = (1.0 - fButtonWidth) / 2;

    //
    //  YES button
    //

    CreateTextButton(
      str_YesButton,
      "ID_DEFAULT_CONTROLS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  NO button
    //

    CreateTextButton(
      str_NoButton,
      "ID_BACK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );
  }

  void BaseMenu_InitDefaultWASDControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float y =
      CenterText(str_APPLY_DEFAULT_SETTINGS, 0.3, "ID_TITLE_TEXT", color(1.0, 1.0, 1.0));

    float fButtonY = y + fVertSpacing * 2;
    float fButtonX = (1.0 - fButtonWidth) / 2;

    //
    //  YES button
    //

    CreateTextButton(
      str_YesButton,
      "ID_DEFAULT_WASD_CONTROLS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;

    //
    //  NO button
    //

    CreateTextButton(
      str_NoButton,
      "ID_BACK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );
  }

  //
  //  Key binding helper methods
  //

  string GetCommandName(
      int _Command
    )
  {
    if (CTLCMD_FORWARD == _Command)             return str_FORWARD;
    if (CTLCMD_BACKWARD == _Command)            return str_BACKWARD;
    if (CTLCMD_LEFT == _Command)                return str_LEFT;
    if (CTLCMD_RIGHT == _Command)               return str_RIGHT;
    if (CTLCMD_UP == _Command)                  return str_UP;
    if (CTLCMD_DOWN == _Command)                return str_DOWN;
    if (CTLCMD_FIRE == _Command)                return str_FIRE;
    if (CTLCMD_LAUNCH == _Command)              return str_LAUNCH;
    if (CTLCMD_INCSPEED == _Command)            return str_INCSPEED;
    if (CTLCMD_DECSPEED == _Command)            return str_DECSPEED;
    if (CTLCMD_MAXSPEED == _Command)            return str_MAXSPEED;
    if (CTLCMD_STOP == _Command)                return str_STOP;
    if (CTLCMD_NEXT_TARGET == _Command)         return str_NEXT_TARGET;
    if (CTLCMD_NEAREST_TARGET == _Command)      return str_NEAREST_TARGET;
    if (CTLCMD_NEXT_NAVPOINT == _Command)       return str_NEXT_NAVPOINT;
    if (CTLCMD_VIKHR_LAUNCHER == _Command)      return str_VIKHR_LAUNCHER;
    if (CTLCMD_S8_LAUNCHER == _Command)         return str_S8_LAUNCHER;
    if (CTLCMD_CLEAR_SCREEN == _Command)        return str_CLEAR_SCREEN;
    if (CTLCMD_SHOW_MISSION_STATUS == _Command) return str_SHOW_MISSION_STATUS;
    if (CTLCMD_SHOW_TARGET == _Command)         return str_SHOW_TARGET;
    if (CTLCMD_MAP_ZOOM_IN == _Command)         return str_MAP_ZOOM_IN;
    if (CTLCMD_MAP_ZOOM_OUT == _Command)        return str_MAP_ZOOM_OUT;
    if (CTLCMD_NEXT_CAMERA_VIEW == _Command)    return str_NEXT_CAMERA_VIEW;
    if (CTLCMD_DEFAULT_CAMERA_VIEW == _Command) return str_DEFAULT_CAMERA_VIEW;
    if (CTLCMD_TOGGLE_FULLSCREEN_TARGET == _Command)
     return str_TOGGLE_FULLSCREEN_TARGET;
    if (CTLCMD_TOGGLE_COCKPIT_COLOR == _Command)
     return str_TOGGLE_COCKPIT_COLOR;

    return "UNKNWOWN";
  }

  float BaseMenu_CreateBindingControl(float _y, int _cmd, string _id_text, string _id_ctl)
  {
    float fSpacing   = 0.05;
    float fTextWidth = 0.5;
    color fTextColor = color(1.0, 1.0, 1.0);

    string text = GetCommandName(_cmd);

    CreateTextControl(
      text,
      _id_text,
            fSpacing,
            _y + (fButtonHeight - GetTextHeight(text))/2,
            fTextWidth,
            fButtonHeight,
      color(1.0, 1.0, 1.0)
          );

    CreateKeyButton(
      _id_ctl,
      _cmd,
      fSpacing + fTextWidth + fSpacing,
      _y,
      fButtonWidth,
      fButtonHeight
    );

    return _y + fButtonHeight + fVertSpacing;
  }

  //
  //  Movement controls screen
  //

  void BaseMenu_InitMovementControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.05;

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_FORWARD,
      "CTLCMD_FORWARD_TEXT",
      "CTLCMD_FORWARD_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_BACKWARD,
      "CTLCMD_BACKWARD_TEXT",
      "CTLCMD_BACKWARD_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_LEFT,
      "CTLCMD_LEFT_TEXT",
      "CTLCMD_LEFT_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_RIGHT,
      "CTLCMD_RIGHT_TEXT",
      "CTLCMD_RIGHT_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_UP,
      "CTLCMD_UP_TEXT",
      "CTLCMD_UP_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_DOWN,
      "CTLCMD_DOWN_TEXT",
      "CTLCMD_DOWN_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_INCSPEED,
      "CTLCMD_INCSPEED_TEXT",
      "CTLCMD_INCSPEED_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_DECSPEED,
      "CTLCMD_DECSPEED_TEXT",
      "CTLCMD_DECSPEED_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_MAXSPEED,
      "CTLCMD_MAXSPEED_TEXT",
      "CTLCMD_MAXSPEED_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_STOP,
      "CTLCMD_STOP_TEXT",
      "CTLCMD_STOP_CTRL"
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  OK button
    //

    CreateTextButton(
      str_OkButton,
      "ID_CONTROLS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  Fire controls screen
  //

  void BaseMenu_InitFireControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.05;

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_FIRE,
      "CTLCMD_FIRE_TEXT",
      "CTLCMD_FIRE_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_LAUNCH,
      "CTLCMD_LAUNCH_TEXT",
      "CTLCMD_LAUNCH_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_NEXT_TARGET,
      "CTLCMD_NEXT_TARGET_TEXT",
      "CTLCMD_NEXT_TARGET_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_NEAREST_TARGET,
      "CTLCMD_NEAREST_TARGET_TEXT",
      "CTLCMD_NEAREST_TARGET_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_VIKHR_LAUNCHER,
      "CTLCMD_VIKHR_LAUNCHER_TEXT",
      "CTLCMD_VIKHR_LAUNCHER_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_S8_LAUNCHER,
      "CTLCMD_S8_LAUNCHER_TEXT",
      "CTLCMD_S8_LAUNCHER_CTRL"
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  OK button
    //

    CreateTextButton(
      str_OkButton,
      "ID_CONTROLS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  Other controls screen
  //

  void BaseMenu_InitOtherControlsMenu()
  {
    BaseMenu_InitSettingsBackground();

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 0.05;

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_NEXT_NAVPOINT,
      "CTLCMD_NEXT_NAVPOINT_TEXT",
      "CTLCMD_NEXT_NAVPOINT_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_CLEAR_SCREEN,
      "CTLCMD_CLEAR_SCREEN_TEXT",
      "CTLCMD_CLEAR_SCREEN_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_SHOW_TARGET,
      "CTLCMD_SHOW_TARGET_TEXT",
      "CTLCMD_SHOW_TARGET_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_MAP_ZOOM_IN,
      "CTLCMD_MAP_ZOOM_IN_TEXT",
      "CTLCMD_MAP_ZOOM_IN_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_MAP_ZOOM_OUT,
      "CTLCMD_MAP_ZOOM_OUT_TEXT",
      "CTLCMD_MAP_ZOOM_OUT_CTRL"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_NEXT_CAMERA_VIEW,
      "CTLCMD_NEXT_CAMERA_VIEW",
      "CTLCMD_NEXT_CAMERA_VIEW"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_DEFAULT_CAMERA_VIEW,
      "CTLCMD_DEFAULT_CAMERA_VIEW",
      "CTLCMD_DEFAULT_CAMERA_VIEW"
    );

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_TOGGLE_FULLSCREEN_TARGET,
      "CTLCMD_TOGGLE_FULLSCREEN_TARGET",
      "CTLCMD_TOGGLE_FULLSCREEN_TARGET"
    );

    fButtonY = fButtonY + fVertSpacing;

    fButtonY =
    BaseMenu_CreateBindingControl(
      fButtonY,
      CTLCMD_TOGGLE_COCKPIT_COLOR,
      "CTLCMD_TOGGLE_COCKPIT_COLOR",
      "CTLCMD_TOGGLE_COCKPIT_COLOR"
    );

    fButtonY = fButtonY + fVertSpacing;

    //
    //  Back button
    //

    CreateTextButton(
      str_OkButton,
      "ID_CONTROLS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight
    );

    fButtonY = fButtonY + fButtonHeight + fVertSpacing;
  }

  //
  //  service methods
  //

  //
  //  creates a text control with the given text in one line
  //  centered on the screen, returns the bottom y coord of the
  //  control
  //

  float CenterText(string _text, float _y, string _id2)
  {
    return CenterText(_text, _y, _id2, color(1.0, 1.0, 1.0, 1.0));
  }

  float CenterText(string _text, float _y, string _id1, color _color)
  {
    float  fWidth  = GetTextWidth(_text);
    float  fHeight = GetTextHeight(_text);

    CreateTextControl(
      _text,
      _id1,
      (1.0 - fWidth) / 2,
      _y,
      fWidth,
      fHeight,
      _color
    );

    return _y + fHeight;
  }

  float CenterTextMultiLine(
          string _text,
          float  _y,
          string _id,
          color  _color,
          int    _lines)
  {
    float  fWidth  = GetTextWidth(_text);
    float  fHeight = GetTextHeight(_text) * _lines;

    CreateTextControl(
      _text,
      _id,
      (1.0 - fWidth) / 2,
      _y,
      fWidth,
      fHeight,
      _color
    );

    return _y + fHeight;
  }

  //
  //  Mission status screen
  //

  array  m_MissionObjectives;
  array  m_MissionObjectivesStatuses;
  array  m_BonusMissionObjectives;
  array  m_BonusMissionObjectivesStatuses;
  string m_MissionStatistics;
  bool   m_bInGame;
  bool   m_bMissionComplete;

  void BaseMenu_SetMissionStatus(
          array  _objectives,
          array  _statuses,
          array  _bonus_objectives,
          array  _bonus_statuses,
          string _statistics,
          bool   _in_game,
          bool   _mission_complete)
  {
    m_MissionObjectives              = _objectives;
    m_MissionObjectivesStatuses      = _statuses;
    m_BonusMissionObjectives         = _bonus_objectives;
    m_BonusMissionObjectivesStatuses = _bonus_statuses;
    m_MissionStatistics              = _statistics;
    m_bInGame                        = _in_game;
    m_bMissionComplete               = _mission_complete;

    if (!_in_game)
    {
      // replace 'In progress' statuses with 'Failed'
      for (int i = 0; i < m_MissionObjectivesStatuses.size(); i = i + 1)
        if (m_MissionObjectivesStatuses[i] == str_ObjectiveInProgress)
          m_MissionObjectivesStatuses[i] = str_ObjectiveFailed;

      for (int i = 0; i < m_BonusMissionObjectivesStatuses.size(); i = i + 1)
        if (m_BonusMissionObjectivesStatuses[i] == str_ObjectiveInProgress)
          m_BonusMissionObjectivesStatuses[i] = str_ObjectiveFailed;
    }
  }

  bool   m_bFinishMissionEnabled = false;

  void BaseMenu_EnableFinishMission()
  {
    m_bFinishMissionEnabled = true;
  }

  void BaseMenu_ShowMissionStatus()
  {
    //
    //  Background
    //

    if (!m_bInGame)
    {
      string strBackground;

      if (m_bMissionComplete)
        strBackground = "Resources/Menu_Mission_Complete.tex";
      else
        strBackground = "Resources/Menu_Mission_Failed.tex";

      CreateBitmapControl(
        strBackground,
        "ID_BITMAP",
        0.0,
        0.0,
        1.0,
        1.0
      );
    }

    color ScreenTitleColor  = color(1.0, 1.0, 1.0);
    color TitleColor        = color(0.7, 0.7, 0.7);
    color TextColor         = color(0.88, 0.43, 0.32);
    color StatusColor       = color(0.0, 0.7, 0.0);
    color FailedStatusColor = color(1.0, 0.0, 0.0);
    color InProgressColor   = color(0.7, 0.7, 0.0);

    float fSectionSpacing   = 0.05;
    float fObjectiveSpacing = 0.02;

    //
    //  Title
    //

    string strTitle;
    if (m_bInGame)
      strTitle = str_MissionStatusTitle;
    else
      strTitle = "";

    float fObjectivesY =
      CenterText(strTitle, 0.1, "ID_TITLE_TEXT", ScreenTitleColor);

    fObjectivesY = fObjectivesY + fSectionSpacing;

    //
    //  "Objectives"
    //

    fObjectivesY =
      CenterText(str_ObjectivesTitle, fObjectivesY, "ID_OBJECTIVES_TEXT", TitleColor);

    fObjectivesY = fObjectivesY + fObjectiveSpacing;

    //
    //  Objectives description
    //

    float fObjectiveHeight  = 0.05;
    float fObjectiveWidth   = 0.7 - fObjectiveSpacing * 2;
    float fStatusWidth      = 0.3 - fObjectiveSpacing * 2;

    for (int i = 0; i < m_MissionObjectives.size(); i = i + 1)
    {
      CreateTextControl(
        m_MissionObjectives[i],
        "ID_OBJECTIVE_DESCRIPTION" + i,
        fObjectiveSpacing,
        fObjectivesY + i * (fObjectiveHeight + fObjectiveSpacing),
        fObjectiveWidth,
        fObjectiveHeight,
        TextColor
      );
    }

    //
    //  Objectives' satuses
    //

    for (int i = 0; i < m_MissionObjectivesStatuses.size(); i = i + 1)
    {
      color status_color = StatusColor;
      if (m_MissionObjectivesStatuses[i] == str_ObjectiveFailed)
        status_color = FailedStatusColor;
      if (m_MissionObjectivesStatuses[i] == str_ObjectiveInProgress)
        status_color = InProgressColor;

      CreateTextControl(
        m_MissionObjectivesStatuses[i],
        "ID_OBJECTIVE_STATUS" + i,
        fObjectiveWidth + fObjectiveSpacing * 2,
        fObjectivesY + i * (fObjectiveHeight + fObjectiveSpacing),
        fStatusWidth,
        fObjectiveHeight,
        status_color
      );
    }

    //
    //  Bonus objectives description
    //

    float fBonusY;

    fBonusY =
      fObjectivesY + fSectionSpacing +
        + m_MissionObjectivesStatuses.size()
          * (fObjectiveHeight + fObjectiveSpacing);

    if (m_BonusMissionObjectives.size() > 0)
    {

      //
      //  "Bonus Objectives"
      //

      fBonusY =
        CenterText(str_BonusObjectivesTitle, fBonusY, "ID_BONUS_OBJECTIVES_TEXT", TitleColor);

      fBonusY = fBonusY + fObjectiveSpacing;

      for (int i = 0; i < m_BonusMissionObjectives.size(); i = i + 1)
      {
        CreateTextControl(
          m_BonusMissionObjectives[i],
          "ID_BONUS_OBJECTIVE_DESCRIPTION" + i,
          fObjectiveSpacing,
          fBonusY + i * (fObjectiveHeight + fObjectiveSpacing),
          fObjectiveWidth,
          fObjectiveHeight,
          TextColor
        );
      }

      //
      //  Bonus objectives statuses
      //

      for (int i = 0; i < m_BonusMissionObjectivesStatuses.size(); i = i + 1)
      {
        color status_color = StatusColor;
        if (m_BonusMissionObjectivesStatuses[i] == str_ObjectiveFailed)
          status_color = FailedStatusColor;
        if (m_BonusMissionObjectivesStatuses[i] == str_ObjectiveInProgress)
          status_color = InProgressColor;

        CreateTextControl(
          m_BonusMissionObjectivesStatuses[i],
          "ID_BONUS_OBJECTIVE_STATUS" + i,
          fObjectiveWidth + fObjectiveSpacing * 2,
          fBonusY + i * (fObjectiveHeight + fObjectiveSpacing),
          fStatusWidth,
          fObjectiveHeight,
          status_color
        );
      }
    }

    if (m_MissionStatistics != "")
    {

      //
      //  "Mission information"
      //

      float fInfoY =
        fBonusY + fSectionSpacing +
          + m_BonusMissionObjectivesStatuses.size()
            * (fObjectiveHeight + fObjectiveSpacing);

      fInfoY =
        CenterText(str_MissionInfoTitle, fInfoY, "ID_MISSION_INFO_TEXT", TitleColor);

      fInfoY = fInfoY + fObjectiveSpacing;

      //
      //  Text control with statistics
      //

      CenterTextMultiLine(
        m_MissionStatistics,
        fInfoY,
        "ID_MISSION_STATISTICS",
        TextColor,
        2
      );
    }

    //
    //  OK button
    //

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fSpacing      = 0.05;
    float fButtonX      = (1.0 - fButtonWidth * 2 - fSpacing) / 2;
    float fButtonY      = 1.0 - fButtonHeight - 0.05;

    string OkButtonTitle;

    if (!m_bInGame)
      OkButtonTitle = str_ExitDebriefing;
    else
      OkButtonTitle = str_Continue;

    CreateTextButton(
      OkButtonTitle,
      "ID_MISSION_STATUS_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight);

    fButtonX = fButtonX + fButtonWidth + fSpacing;

    if (!m_bInGame)
    {
      CreateTextButton(
        str_RestartMissionButton,
        "ID_RESTART_MISSION",
        fButtonX,
        fButtonY,
        fButtonWidth,
        fButtonHeight);

      fButtonY = fButtonY + fButtonHeight + fVertSpacing;
    }
    else
    {
      CreateTextButton(
        str_FinishMission,
        "ID_FINISH_MISSION",
        fButtonX,
        fButtonY,
        fButtonWidth,
        fButtonHeight,
        m_bFinishMissionEnabled);

      fButtonY = fButtonY + fButtonHeight + fVertSpacing;
    }
  }

  //
  //  HelpScreen
  //

  void BaseMenu_ShowMissionHelpScreen()
  {
    color TitleColor       = color(0.7, 0.7, 0.7, 1.0);
    color TextColor        = color(0.0, 0.7, 0.7, 1.0);

    //
    //  Title
    //

    float fSpacing = 0.05;

    float fY =
      CenterText(str_HelpTitle, fSpacing, "ID_TITLE_TEXT", TitleColor);

    float fTextHeight = fY - fSpacing;

    float fHelpTextY = fY + fSpacing;
    float fHelpTextX = fSpacing;
    float fHelpTextWidth = 1.0 - fSpacing * 2;
    float fHelpTextHeight = 1.0 - fSpacing * 4 - fButtonHeight - fTextHeight;

    CreateTextControl(
      LoadTextFromFile("Resources/Help.txt"),
      "ID_HELP_TEXT",
      fHelpTextX,
      fHelpTextY,
      fHelpTextWidth,
      fHelpTextHeight,
      TextColor
    );

    //
    //  OK button
    //

    CreateMenuButtonGroup(MenuWidth, MenuSpacing);

    float fButtonX      = (1.0 - fButtonWidth) / 2;
    float fButtonY      = 1.0 - fButtonHeight - fSpacing;

    CreateTextButton(
      str_OkButton,
      "ID_MISSION_HELP_SCREEN_OK",
      fButtonX,
      fButtonY,
      fButtonWidth,
      fButtonHeight);
  }

};
