/** @file
  implements menubar interface functions.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "EditMenuBar.h"
#include "UefiShellDebug1CommandsLib.h"
#include "EditStatusBar.h"

EDITOR_MENU_ITEM   *MenuItems;
MENU_ITEM_FUNCTION *ControlBasedMenuFunctions;
UINTN                 NumItems;

/**
  Cleanup function for a menu bar.  frees all allocated memory.
**/
VOID
MenuBarCleanup (
  VOID
  )
{
  SHELL_FREE_NON_NULL(MenuItems);
}

/**
  Initialize the menu bar with the specified items.

  @param[in] Items              The items to display and their functions.

  @retval EFI_SUCCESS           The initialization was correct.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
MenuBarInit (
  IN CONST EDITOR_MENU_ITEM  *Items
  )
{
  CONST EDITOR_MENU_ITEM  *ItemsWalker;

  for (NumItems = 0, ItemsWalker = Items ; ItemsWalker != NULL && ItemsWalker->Function != NULL ; ItemsWalker++,NumItems++);
  
  MenuItems = AllocateZeroPool((NumItems+1) * sizeof(EDITOR_MENU_ITEM));
  if (MenuItems == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  CopyMem(MenuItems, Items, (NumItems+1) * sizeof(EDITOR_MENU_ITEM));
  return EFI_SUCCESS;
}

/**
  Initialize the control hot-key with the specified items.

  @param[in] Items              The hot-key functions.

  @retval EFI_SUCCESS           The initialization was correct.
**/
EFI_STATUS
ControlHotKeyInit (
  IN MENU_ITEM_FUNCTION  *Items
  )
{
  ControlBasedMenuFunctions = Items;
  return EFI_SUCCESS; 
}
/**
  Refresh function for the menu bar.

  @param[in] LastRow            The last printable row.
  @param[in] LastCol            The last printable column.

  @retval EFI_SUCCESS           The refresh was successful.
**/
EFI_STATUS
MenuBarRefresh (
  IN CONST UINTN LastRow,
  IN CONST UINTN LastCol
  )
{
  EDITOR_MENU_ITEM  *Item;
  UINTN                 Col;
  UINTN                 Row;
  UINTN                 Width;
  CHAR16                *NameString;
  CHAR16                *FunctionKeyString;

  //
  // variable initialization
  //
  Col = 1;
  Row = (LastRow - 2);

  //
  // clear menu bar rows
  //
  EditorClearLine (LastRow - 2, LastCol, LastRow);
  EditorClearLine (LastRow - 1, LastCol, LastRow);
  EditorClearLine (LastRow    , LastCol, LastRow);


  //
  // print out the menu items
  //
  for (Item = MenuItems; Item != NULL && Item->Function != NULL; Item++) {


    NameString = HiiGetString(gShellDebug1HiiHandle, Item->NameToken, NULL);


    Width             = MAX ((StrLen (NameString) + 6), 20);
    if (((Col + Width) > LastCol)) {
      Row++;
      Col = 1;
    }

    FunctionKeyString = HiiGetString(gShellDebug1HiiHandle, Item->FunctionKeyToken, NULL);

    ShellPrintEx ((INT32)(Col) - 1, (INT32)(Row) - 1, L"%E%s%N  %H%s%N  ", FunctionKeyString, NameString);

    FreePool (NameString);
    FreePool (FunctionKeyString);
    Col += Width;
  }

  return EFI_SUCCESS;
}

/**
  Function to dispatch the correct function based on a function key (F1...)

  @param[in] Key                The pressed key.

  @retval EFI_NOT_FOUND         The key was not a valid function key 
                                (an error was sent to the status bar).
  @return The return value from the called dispatch function.
**/
EFI_STATUS
MenuBarDispatchFunctionKey (
  IN CONST EFI_INPUT_KEY   *Key
  )
{
  UINTN                 Index;

  Index     = Key->ScanCode - SCAN_F1;

  //
  // check whether in range
  //
  if (Index > (NumItems - 1)) {
    StatusBarSetStatusString (L"Unknown Command");
    return EFI_SUCCESS;
  }

  return (MenuItems[Index].Function ());
}

/**
  Function to dispatch the correct function based on a control-based key (ctrl+o...)

  @param[in] KeyData                The pressed key.

  @retval EFI_NOT_FOUND         The key was not a valid control-based key 
                                (an error was sent to the status bar).
  @return EFI_SUCCESS.
**/
EFI_STATUS
MenuBarDispatchControlHotKey (
  IN CONST EFI_KEY_DATA   *KeyData
  )
{
  UINT16                  ControlIndex;

  //
  // Set to invalid value first.
  //
  ControlIndex = MAX_UINT16;

  if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) ||
      (KeyData->KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID)) {
    //
    // For consoles that don't support/report shift state,
    // Ctrl+A is translated to 1 (UnicodeChar).
    //
    ControlIndex = KeyData->Key.UnicodeChar;
  } else if (((KeyData->KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
             ((KeyData->KeyState.KeyShiftState & (EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) != 0) &&
             ((KeyData->KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_RIGHT_CONTROL_PRESSED | EFI_LEFT_CONTROL_PRESSED)) == 0)) {
    //
    // For consoles that supports/reports shift state,
    // make sure only CONTROL is pressed.
    //
    if ((KeyData->Key.UnicodeChar >= L'A') && (KeyData->Key.UnicodeChar <= L'Z')) {
      ControlIndex = KeyData->Key.UnicodeChar - L'A' + 1;
    } else if ((KeyData->Key.UnicodeChar >= L'a') && (KeyData->Key.UnicodeChar <= L'z')) {
      ControlIndex = KeyData->Key.UnicodeChar - L'a' + 1;
    }
  }
  if ((SCAN_CONTROL_Z < ControlIndex)
    ||(NULL == ControlBasedMenuFunctions[ControlIndex]))
  {
      return EFI_NOT_FOUND;
  }

  ControlBasedMenuFunctions[ControlIndex]();
  return EFI_SUCCESS;
}


