/** @file
  Implements inputbar interface functions.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "EditInputBar.h"
#include "UefiShellDebug1CommandsLib.h"

CHAR16                             *mPrompt;       // Input bar mPrompt string.
CHAR16                             *mReturnString; // The returned string.
UINTN                              StringSize;     // Size of mReturnString space size.
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *mTextInEx;

/**
  Initialize the input bar.

  @param[in] TextInEx  Pointer to SimpleTextInEx instance in System Table.
**/
VOID
InputBarInit (
  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *TextInEx
  )
{
  mPrompt       = NULL;
  mReturnString = NULL;
  StringSize    = 0;
  mTextInEx     = TextInEx;
}

/**
  Cleanup function for input bar.
**/
VOID
InputBarCleanup (
  VOID
  )
{
  //
  // free input bar's prompt and input string
  //
  SHELL_FREE_NON_NULL (mPrompt);
  SHELL_FREE_NON_NULL (mReturnString);
  mPrompt       = NULL;
  mReturnString = NULL;
}

/**
  Display the prompt.
  Do the requesting of input.

  @param[in]  LastColumn   The last printable column.
  @param[in]  LastRow      The last printable row.
**/
VOID
InputBarPrintInput (
  IN UINTN  LastColumn,
  IN UINTN  LastRow
  )
{
  UINTN   Limit;
  UINTN   Size;
  CHAR16  *Buffer;
  UINTN   Index;
  UINTN   mPromptLen;

  mPromptLen = StrLen (mPrompt);
  Limit      = LastColumn - mPromptLen - 1;
  Size       = StrLen (mReturnString);

  //
  // check whether the mPrompt length and input length will
  // exceed limit
  //
  if (Size <= Limit) {
    Buffer = mReturnString;
  } else {
    Buffer = mReturnString + Size - Limit;
  }

  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

  ShellPrintEx (((INT32)mPromptLen), ((INT32)LastRow) - 1, L"%s", Buffer);
  Size = StrLen (Buffer);

  //
  // print " " after mPrompt
  //
  for (Index = Size; Index < Limit; Index++) {
    ShellPrintEx ((INT32)(mPromptLen + Size), ((INT32)LastRow) - 1, L" ");
  }

  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
  gST->ConOut->SetCursorPosition (gST->ConOut, Size + mPromptLen, LastRow - 1);
}

typedef struct {
  UINT32    Foreground : 4;
  UINT32    Background : 3;
} INPUT_BAR_COLOR_ATTRIBUTES;

typedef union {
  INPUT_BAR_COLOR_ATTRIBUTES    Colors;
  UINTN                         Data;
} INPUT_BAR_COLOR_UNION;

/**
  The refresh function for InputBar, it will wait for user input

  @param[in] LastRow            The last printable row.
  @param[in] LastColumn         The last printable column.

  @retval EFI_SUCCESS           The operation was successful.
**/
EFI_STATUS
InputBarRefresh (
  UINTN  LastRow,
  UINTN  LastColumn
  )
{
  INPUT_BAR_COLOR_UNION  Orig;
  INPUT_BAR_COLOR_UNION  New;
  EFI_KEY_DATA           KeyData;
  UINTN                  Size;
  EFI_STATUS             Status;
  BOOLEAN                NoDisplay;
  UINTN                  EventIndex;
  UINTN                  CursorRow;
  UINTN                  CursorCol;

  //
  // variable initialization
  //
  Size   = 0;
  Status = EFI_SUCCESS;

  //
  // back up the old screen attributes
  //
  CursorCol             = gST->ConOut->Mode->CursorColumn;
  CursorRow             = gST->ConOut->Mode->CursorRow;
  Orig.Data             = gST->ConOut->Mode->Attribute;
  New.Data              = 0;
  New.Colors.Foreground = Orig.Colors.Background & 0xF;
  New.Colors.Background = Orig.Colors.Foreground & 0x7;

  gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);

  //
  // clear input bar
  //
  EditorClearLine (LastRow, LastColumn, LastRow);

  gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1);
  ShellPrintHiiDefaultEx (STRING_TOKEN (STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt);

  //
  // this is a selection mPrompt, cursor will stay in edit area
  // actually this is for search , search/replace
  //
  if (StrStr (mPrompt, L"Yes/No")) {
    NoDisplay = TRUE;
    gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
    gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
  } else {
    NoDisplay = FALSE;
  }

  //
  // wait for user input
  //
  for ( ; ;) {
    Status = gBS->WaitForEvent (1, &mTextInEx->WaitForKeyEx, &EventIndex);
    if (EFI_ERROR (Status) || (EventIndex != 0)) {
      continue;
    }

    Status = mTextInEx->ReadKeyStrokeEx (mTextInEx, &KeyData);
    if (EFI_ERROR (Status)) {
      continue;
    }

    if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
        (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID))
    {
      //
      // Shift key pressed.
      //
      continue;
    }

    //
    // pressed ESC
    //
    if (KeyData.Key.ScanCode == SCAN_ESC) {
      Size   = 0;
      Status = EFI_NOT_READY;
      break;
    }

    //
    // return pressed
    //
    if ((KeyData.Key.UnicodeChar == CHAR_LINEFEED) || (KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
      break;
    } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) {
      //
      // backspace
      //
      if (Size > 0) {
        Size--;
        mReturnString[Size] = CHAR_NULL;
        if (!NoDisplay) {
          InputBarPrintInput (LastColumn, LastRow);
        }
      }
    } else if ((KeyData.Key.UnicodeChar <= 127) && (KeyData.Key.UnicodeChar >= 32)) {
      //
      // VALID ASCII char pressed
      //
      mReturnString[Size] = KeyData.Key.UnicodeChar;

      //
      // should be less than specified length
      //
      if (Size >= StringSize) {
        continue;
      }

      Size++;

      mReturnString[Size] = CHAR_NULL;

      if (!NoDisplay) {
        InputBarPrintInput (LastColumn, LastRow);
      } else {
        //
        // if just choose yes/no
        //
        break;
      }
    }
  }

  mReturnString[Size] = CHAR_NULL;

  //
  // restore screen attributes
  //
  gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow);
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);

  return Status;
}

/**
  SetPrompt and wait for input.

  @param[in] Str                The prompt string.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
InputBarSetPrompt (
  IN CONST CHAR16  *Str
  )
{
  //
  // FREE the old mPrompt string
  //
  SHELL_FREE_NON_NULL (mPrompt);

  mPrompt = CatSPrint (NULL, L"%s ", Str);
  if (mPrompt == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Set the size of the string in characters.

  @param[in] Size               The max number of characters to accept.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
InputBarSetStringSize (
  UINTN  Size
  )
{
  //
  // free the old ReturnStirng
  //
  SHELL_FREE_NON_NULL (mReturnString);

  StringSize    = Size;
  mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof (mReturnString[0]));
  if (mReturnString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Function to retrieve the input from the user.

  @retval NULL                  No input has been received.
  @return The string that was input.
**/
CONST CHAR16 *
InputBarGetString (
  VOID
  )
{
  return (mReturnString);
}
