/** @file
Implementation for handling user input from the User Interfaces.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FormDisplay.h"

/**
  Get maximum and minimum info from this opcode.

  @param  OpCode            Pointer to the current input opcode.
  @param  Minimum           The minimum size info for this opcode.
  @param  Maximum           The maximum size info for this opcode.

**/
VOID
GetFieldFromOp (
  IN   EFI_IFR_OP_HEADER  *OpCode,
  OUT  UINTN              *Minimum,
  OUT  UINTN              *Maximum
  )
{
  EFI_IFR_STRING    *StringOp;
  EFI_IFR_PASSWORD  *PasswordOp;

  if (OpCode->OpCode == EFI_IFR_STRING_OP) {
    StringOp = (EFI_IFR_STRING *)OpCode;
    *Minimum = StringOp->MinSize;
    *Maximum = StringOp->MaxSize;
  } else if (OpCode->OpCode == EFI_IFR_PASSWORD_OP) {
    PasswordOp = (EFI_IFR_PASSWORD *)OpCode;
    *Minimum   = PasswordOp->MinSize;
    *Maximum   = PasswordOp->MaxSize;
  } else {
    *Minimum = 0;
    *Maximum = 0;
  }
}

/**
  Get string or password input from user.

  @param  MenuOption        Pointer to the current input menu.
  @param  Prompt            The prompt string shown on popup window.
  @param  StringPtr         Old user input and destination for use input string.

  @retval EFI_SUCCESS       If string input is read successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
ReadString (
  IN     UI_MENU_OPTION  *MenuOption,
  IN     CHAR16          *Prompt,
  IN OUT CHAR16          *StringPtr
  )
{
  EFI_STATUS                     Status;
  EFI_INPUT_KEY                  Key;
  CHAR16                         NullCharacter;
  UINTN                          ScreenSize;
  CHAR16                         Space[2];
  CHAR16                         KeyPad[2];
  CHAR16                         *TempString;
  CHAR16                         *BufferedString;
  UINTN                          Index;
  UINTN                          Index2;
  UINTN                          Count;
  UINTN                          Start;
  UINTN                          Top;
  UINTN                          DimensionsWidth;
  UINTN                          DimensionsHeight;
  UINTN                          CurrentCursor;
  BOOLEAN                        CursorVisible;
  UINTN                          Minimum;
  UINTN                          Maximum;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  BOOLEAN                        IsPassword;
  UINTN                          MaxLen;

  DimensionsWidth  = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
  DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;

  NullCharacter = CHAR_NULL;
  ScreenSize    = GetStringWidth (Prompt) / sizeof (CHAR16);
  Space[0]      = L' ';
  Space[1]      = CHAR_NULL;

  Question = MenuOption->ThisTag;
  GetFieldFromOp (Question->OpCode, &Minimum, &Maximum);

  if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) {
    IsPassword = TRUE;
  } else {
    IsPassword = FALSE;
  }

  MaxLen     = Maximum + 1;
  TempString = AllocateZeroPool (MaxLen * sizeof (CHAR16));
  ASSERT (TempString);

  if (ScreenSize < (Maximum + 1)) {
    ScreenSize = Maximum + 1;
  }

  if ((ScreenSize + 2) > DimensionsWidth) {
    ScreenSize = DimensionsWidth - 2;
  }

  BufferedString = AllocateZeroPool (ScreenSize * 2);
  ASSERT (BufferedString);

  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1;
  Top   = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1;

  //
  // Display prompt for string
  //
  // CreateDialog (NULL, "", Prompt, Space, "", NULL);
  CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);
  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

  CursorVisible = gST->ConOut->Mode->CursorVisible;
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  CurrentCursor = GetStringWidth (StringPtr) / 2 - 1;
  if (CurrentCursor != 0) {
    //
    // Show the string which has beed saved before.
    //
    SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');
    PrintStringAt (Start + 1, Top + 3, BufferedString);

    if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {
      Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;
    } else {
      Index = 0;
    }

    if (IsPassword) {
      gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);
    }

    for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
      BufferedString[Count] = StringPtr[Index];

      if (IsPassword) {
        PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');
      }
    }

    if (!IsPassword) {
      PrintStringAt (Start + 1, Top + 3, BufferedString);
    }

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
    gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);
  }

  do {
    Status = WaitForKeyStroke (&Key);
    ASSERT_EFI_ERROR (Status);

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
    switch (Key.UnicodeChar) {
      case CHAR_NULL:
        switch (Key.ScanCode) {
          case SCAN_LEFT:
            if (CurrentCursor > 0) {
              CurrentCursor--;
            }

            break;

          case SCAN_RIGHT:
            if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) {
              CurrentCursor++;
            }

            break;

          case SCAN_ESC:
            FreePool (TempString);
            FreePool (BufferedString);
            gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
            gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
            return EFI_DEVICE_ERROR;

          case SCAN_DELETE:
            for (Index = CurrentCursor; StringPtr[Index] != CHAR_NULL; Index++) {
              StringPtr[Index] = StringPtr[Index + 1];
              PrintCharAt (Start + Index + 1, Top + 3, IsPassword && StringPtr[Index] != CHAR_NULL ? L'*' : StringPtr[Index]);
            }

            break;

          default:
            break;
        }

        break;

      case CHAR_CARRIAGE_RETURN:
        if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) {
          FreePool (TempString);
          FreePool (BufferedString);
          gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
          gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
          return EFI_SUCCESS;
        } else {
          //
          // Simply create a popup to tell the user that they had typed in too few characters.
          // To save code space, we can then treat this as an error and return back to the menu.
          //
          do {
            CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL);
          } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

          FreePool (TempString);
          FreePool (BufferedString);
          gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
          gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
          return EFI_DEVICE_ERROR;
        }

      case CHAR_BACKSPACE:
        if ((StringPtr[0] != CHAR_NULL) && (CurrentCursor != 0)) {
          if (CurrentCursor > 1) {
            CopyMem (TempString, StringPtr, (CurrentCursor - 1) * sizeof (CHAR16));
          }

          Count = GetStringWidth (StringPtr) / 2 - 1;
          if (Count >= CurrentCursor) {
            for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) {
              TempString[Index] = StringPtr[Index2];
            }

            TempString[Index] = CHAR_NULL;
          }

          //
          // Effectively truncate string by 1 character
          //
          StrCpyS (StringPtr, MaxLen, TempString);
          CurrentCursor--;
        }

      default:
        //
        // If it is the beginning of the string, don't worry about checking maximum limits
        //
        if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
          StrnCpyS (StringPtr, MaxLen, &Key.UnicodeChar, 1);
          CurrentCursor++;
        } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
          KeyPad[0] = Key.UnicodeChar;
          KeyPad[1] = CHAR_NULL;
          Count     = GetStringWidth (StringPtr) / 2 - 1;
          if (CurrentCursor < Count) {
            CopyMem (TempString, StringPtr, CurrentCursor * sizeof (CHAR16));

            TempString[Index] = CHAR_NULL;
            StrCatS (TempString, MaxLen, KeyPad);
            StrCatS (TempString, MaxLen, StringPtr + CurrentCursor);
            StrCpyS (StringPtr, MaxLen, TempString);
          } else {
            StrCatS (StringPtr, MaxLen, KeyPad);
          }

          CurrentCursor++;
        }

        //
        // If the width of the input string is now larger than the screen, we nee to
        // adjust the index to start printing portions of the string
        //
        SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');
        PrintStringAt (Start + 1, Top + 3, BufferedString);

        if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {
          Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;
        } else {
          Index = 0;
        }

        if (IsPassword) {
          gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);
        }

        for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
          BufferedString[Count] = StringPtr[Index];

          if (IsPassword) {
            PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');
          }
        }

        if (!IsPassword) {
          PrintStringAt (Start + 1, Top + 3, BufferedString);
        }

        break;
    }

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
    gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3);
  } while (TRUE);
}

/**
  Adjust the value to the correct one. Rules follow the sample:
  like:  Year change:  2012.02.29 -> 2013.02.29 -> 2013.02.01
         Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28

  @param  QuestionValue     Pointer to current question.
  @param  Sequence          The sequence of the field in the question.
**/
VOID
AdjustQuestionValue (
  IN  EFI_HII_VALUE  *QuestionValue,
  IN  UINT8          Sequence
  )
{
  UINT8   Month;
  UINT16  Year;
  UINT8   Maximum;
  UINT8   Minimum;

  Month   = QuestionValue->Value.date.Month;
  Year    = QuestionValue->Value.date.Year;
  Minimum = 1;

  switch (Month) {
    case 2:
      if (((Year % 4) == 0) && (((Year % 100) != 0) || ((Year % 400) == 0))) {
        Maximum = 29;
      } else {
        Maximum = 28;
      }

      break;
    case 4:
    case 6:
    case 9:
    case 11:
      Maximum = 30;
      break;
    default:
      Maximum = 31;
      break;
  }

  //
  // Change the month area.
  //
  if (Sequence == 0) {
    if (QuestionValue->Value.date.Day > Maximum) {
      QuestionValue->Value.date.Day = Maximum;
    }
  }

  //
  // Change the Year area.
  //
  if (Sequence == 2) {
    if (QuestionValue->Value.date.Day > Maximum) {
      QuestionValue->Value.date.Day = Minimum;
    }
  }
}

/**
  Get field info from numeric opcode.

  @param  OpCode            Pointer to the current input opcode.
  @param  IntInput          Whether question shows with EFI_IFR_DISPLAY_INT_DEC type.
  @param  QuestionValue     Input question value, with EFI_HII_VALUE type.
  @param  Value             Return question value, always return UINT64 type.
  @param  Minimum           The minimum size info for this opcode.
  @param  Maximum           The maximum size info for this opcode.
  @param  Step              The step size info for this opcode.
  @param  StorageWidth      The storage width info for this opcode.

**/
VOID
GetValueFromNum (
  IN  EFI_IFR_OP_HEADER  *OpCode,
  IN  BOOLEAN            IntInput,
  IN  EFI_HII_VALUE      *QuestionValue,
  OUT UINT64             *Value,
  OUT UINT64             *Minimum,
  OUT UINT64             *Maximum,
  OUT UINT64             *Step,
  OUT UINT16             *StorageWidth
  )
{
  EFI_IFR_NUMERIC  *NumericOp;

  NumericOp = (EFI_IFR_NUMERIC *)OpCode;

  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
    case EFI_IFR_NUMERIC_SIZE_1:
      if (IntInput) {
        *Minimum = (INT64)(INT8)NumericOp->data.u8.MinValue;
        *Maximum = (INT64)(INT8)NumericOp->data.u8.MaxValue;
        *Value   = (INT64)(INT8)QuestionValue->Value.u8;
      } else {
        *Minimum = NumericOp->data.u8.MinValue;
        *Maximum = NumericOp->data.u8.MaxValue;
        *Value   = QuestionValue->Value.u8;
      }

      *Step         = NumericOp->data.u8.Step;
      *StorageWidth = (UINT16)sizeof (UINT8);
      break;

    case EFI_IFR_NUMERIC_SIZE_2:
      if (IntInput) {
        *Minimum = (INT64)(INT16)NumericOp->data.u16.MinValue;
        *Maximum = (INT64)(INT16)NumericOp->data.u16.MaxValue;
        *Value   = (INT64)(INT16)QuestionValue->Value.u16;
      } else {
        *Minimum = NumericOp->data.u16.MinValue;
        *Maximum = NumericOp->data.u16.MaxValue;
        *Value   = QuestionValue->Value.u16;
      }

      *Step         = NumericOp->data.u16.Step;
      *StorageWidth = (UINT16)sizeof (UINT16);
      break;

    case EFI_IFR_NUMERIC_SIZE_4:
      if (IntInput) {
        *Minimum = (INT64)(INT32)NumericOp->data.u32.MinValue;
        *Maximum = (INT64)(INT32)NumericOp->data.u32.MaxValue;
        *Value   = (INT64)(INT32)QuestionValue->Value.u32;
      } else {
        *Minimum = NumericOp->data.u32.MinValue;
        *Maximum = NumericOp->data.u32.MaxValue;
        *Value   = QuestionValue->Value.u32;
      }

      *Step         = NumericOp->data.u32.Step;
      *StorageWidth = (UINT16)sizeof (UINT32);
      break;

    case EFI_IFR_NUMERIC_SIZE_8:
      if (IntInput) {
        *Minimum = (INT64)NumericOp->data.u64.MinValue;
        *Maximum = (INT64)NumericOp->data.u64.MaxValue;
        *Value   = (INT64)QuestionValue->Value.u64;
      } else {
        *Minimum = NumericOp->data.u64.MinValue;
        *Maximum = NumericOp->data.u64.MaxValue;
        *Value   = QuestionValue->Value.u64;
      }

      *Step         = NumericOp->data.u64.Step;
      *StorageWidth = (UINT16)sizeof (UINT64);
      break;

    default:
      break;
  }

  if (*Maximum == 0) {
    *Maximum = (UINT64)-1;
  }
}

/**
  This routine reads a numeric value from the user input.

  @param  MenuOption        Pointer to the current input menu.

  @retval EFI_SUCCESS       If numerical input is read successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
GetNumericInput (
  IN  UI_MENU_OPTION  *MenuOption
  )
{
  UINTN                          Column;
  UINTN                          Row;
  CHAR16                         InputText[MAX_NUMERIC_INPUT_WIDTH];
  CHAR16                         FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1];
  UINT64                         PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3];
  UINTN                          Count;
  UINTN                          Loop;
  BOOLEAN                        ManualInput;
  BOOLEAN                        HexInput;
  BOOLEAN                        IntInput;
  BOOLEAN                        Negative;
  BOOLEAN                        ValidateFail;
  BOOLEAN                        DateOrTime;
  UINTN                          InputWidth;
  UINT64                         EditValue;
  UINT64                         Step;
  UINT64                         Minimum;
  UINT64                         Maximum;
  UINTN                          EraseLen;
  UINT8                          Digital;
  EFI_INPUT_KEY                  Key;
  EFI_HII_VALUE                  *QuestionValue;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  EFI_IFR_NUMERIC                *NumericOp;
  UINT16                         StorageWidth;

  Column            = MenuOption->OptCol;
  Row               = MenuOption->Row;
  PreviousNumber[0] = 0;
  Count             = 0;
  InputWidth        = 0;
  Digital           = 0;
  StorageWidth      = 0;
  Minimum           = 0;
  Maximum           = 0;
  NumericOp         = NULL;
  IntInput          = FALSE;
  HexInput          = FALSE;
  Negative          = FALSE;
  ValidateFail      = FALSE;

  Question      = MenuOption->ThisTag;
  QuestionValue = &Question->CurrentValue;
  ZeroMem (InputText, MAX_NUMERIC_INPUT_WIDTH * sizeof (CHAR16));

  //
  // Only two case, user can enter to this function: Enter and +/- case.
  // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT
  //
  ManualInput = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);

  if ((Question->OpCode->OpCode == EFI_IFR_DATE_OP) || (Question->OpCode->OpCode == EFI_IFR_TIME_OP)) {
    DateOrTime = TRUE;
  } else {
    DateOrTime = FALSE;
  }

  //
  // Prepare Value to be edit
  //
  EraseLen  = 0;
  EditValue = 0;
  if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
    Step    = 1;
    Minimum = 1;

    switch (MenuOption->Sequence) {
      case 0:
        Maximum   = 12;
        EraseLen  = 4;
        EditValue = QuestionValue->Value.date.Month;
        break;

      case 1:
        switch (QuestionValue->Value.date.Month) {
          case 2:
            if (((QuestionValue->Value.date.Year % 4) == 0) &&
                (((QuestionValue->Value.date.Year % 100) != 0) ||
                 ((QuestionValue->Value.date.Year % 400) == 0)))
            {
              Maximum = 29;
            } else {
              Maximum = 28;
            }

            break;
          case 4:
          case 6:
          case 9:
          case 11:
            Maximum = 30;
            break;
          default:
            Maximum = 31;
            break;
        }

        EraseLen  = 3;
        EditValue = QuestionValue->Value.date.Day;
        break;

      case 2:
        Maximum   = 0xffff;
        EraseLen  = 5;
        EditValue = QuestionValue->Value.date.Year;
        break;

      default:
        break;
    }
  } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
    Step    = 1;
    Minimum = 0;

    switch (MenuOption->Sequence) {
      case 0:
        Maximum   = 23;
        EraseLen  = 4;
        EditValue = QuestionValue->Value.time.Hour;
        break;

      case 1:
        Maximum   = 59;
        EraseLen  = 3;
        EditValue = QuestionValue->Value.time.Minute;
        break;

      case 2:
        Maximum   = 59;
        EraseLen  = 3;
        EditValue = QuestionValue->Value.time.Second;
        break;

      default:
        break;
    }
  } else {
    ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP);
    NumericOp = (EFI_IFR_NUMERIC *)Question->OpCode;
    GetValueFromNum (Question->OpCode, (NumericOp->Flags & EFI_IFR_DISPLAY) == 0, QuestionValue, &EditValue, &Minimum, &Maximum, &Step, &StorageWidth);
    EraseLen = gOptionBlockWidth;
  }

  if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL)) {
    if ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX) {
      HexInput = TRUE;
    } else if ((NumericOp->Flags & EFI_IFR_DISPLAY) == 0) {
      //
      // Display with EFI_IFR_DISPLAY_INT_DEC type. Support negative number.
      //
      IntInput = TRUE;
    }
  }

  //
  // Enter from "Enter" input, clear the old word showing.
  //
  if (ManualInput) {
    if (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {
      if (HexInput) {
        InputWidth = StorageWidth * 2;
      } else {
        switch (StorageWidth) {
          case 1:
            InputWidth = 3;
            break;

          case 2:
            InputWidth = 5;
            break;

          case 4:
            InputWidth = 10;
            break;

          case 8:
            InputWidth = 20;
            break;

          default:
            InputWidth = 0;
            break;
        }

        if (IntInput) {
          //
          // Support an extra '-' for negative number.
          //
          InputWidth += 1;
        }
      }

      InputText[0] = LEFT_NUMERIC_DELIMITER;
      SetUnicodeMem (InputText + 1, InputWidth, L' ');
      ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH);
      InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
      InputText[InputWidth + 2] = L'\0';

      PrintStringAt (Column, Row, InputText);
      Column++;
    }

    if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
      if (MenuOption->Sequence == 2) {
        InputWidth = 4;
      } else {
        InputWidth = 2;
      }

      if (MenuOption->Sequence == 0) {
        InputText[0] = LEFT_NUMERIC_DELIMITER;
        SetUnicodeMem (InputText + 1, InputWidth, L' ');
        InputText[InputWidth + 1] = DATE_SEPARATOR;
        InputText[InputWidth + 2] = L'\0';
      } else if (MenuOption->Sequence == 1) {
        SetUnicodeMem (InputText, InputWidth, L' ');
        InputText[InputWidth]     = DATE_SEPARATOR;
        InputText[InputWidth + 1] = L'\0';
      } else {
        SetUnicodeMem (InputText, InputWidth, L' ');
        InputText[InputWidth]     = RIGHT_NUMERIC_DELIMITER;
        InputText[InputWidth + 1] = L'\0';
      }

      PrintStringAt (Column, Row, InputText);
      if (MenuOption->Sequence == 0) {
        Column++;
      }
    }

    if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
      InputWidth = 2;

      if (MenuOption->Sequence == 0) {
        InputText[0] = LEFT_NUMERIC_DELIMITER;
        SetUnicodeMem (InputText + 1, InputWidth, L' ');
        InputText[InputWidth + 1] = TIME_SEPARATOR;
        InputText[InputWidth + 2] = L'\0';
      } else if (MenuOption->Sequence == 1) {
        SetUnicodeMem (InputText, InputWidth, L' ');
        InputText[InputWidth]     = TIME_SEPARATOR;
        InputText[InputWidth + 1] = L'\0';
      } else {
        SetUnicodeMem (InputText, InputWidth, L' ');
        InputText[InputWidth]     = RIGHT_NUMERIC_DELIMITER;
        InputText[InputWidth + 1] = L'\0';
      }

      PrintStringAt (Column, Row, InputText);
      if (MenuOption->Sequence == 0) {
        Column++;
      }
    }
  }

  //
  // First time we enter this handler, we need to check to see if
  // we were passed an increment or decrement directive
  //
  do {
    Key.UnicodeChar = CHAR_NULL;
    if (gDirection != 0) {
      Key.ScanCode = gDirection;
      gDirection   = 0;
      goto TheKey2;
    }

    WaitForKeyStroke (&Key);

TheKey2:
    switch (Key.UnicodeChar) {
      case '+':
      case '-':
        if (ManualInput && IntInput) {
          //
          // In Manual input mode, check whether input the negative flag.
          //
          if (Key.UnicodeChar == '-') {
            if (Negative) {
              break;
            }

            Negative = TRUE;
            PrintCharAt (Column++, Row, Key.UnicodeChar);
          }
        } else {
          if (Key.UnicodeChar == '+') {
            Key.ScanCode = SCAN_RIGHT;
          } else {
            Key.ScanCode = SCAN_LEFT;
          }

          Key.UnicodeChar = CHAR_NULL;
          goto TheKey2;
        }

        break;

      case CHAR_NULL:
        switch (Key.ScanCode) {
          case SCAN_LEFT:
          case SCAN_RIGHT:
            if (DateOrTime && !ManualInput) {
              //
              // By setting this value, we will return back to the caller.
              // We need to do this since an auto-refresh will destroy the adjustment
              // based on what the real-time-clock is showing.  So we always commit
              // upon changing the value.
              //
              gDirection = SCAN_DOWN;
            }

            if ((Step != 0) && !ManualInput) {
              if (Key.ScanCode == SCAN_LEFT) {
                if (IntInput) {
                  if ((INT64)EditValue >= (INT64)Minimum + (INT64)Step) {
                    EditValue = EditValue - Step;
                  } else if ((INT64)EditValue > (INT64)Minimum) {
                    EditValue = Minimum;
                  } else {
                    EditValue = Maximum;
                  }
                } else {
                  if (EditValue >= Minimum + Step) {
                    EditValue = EditValue - Step;
                  } else if (EditValue > Minimum) {
                    EditValue = Minimum;
                  } else {
                    EditValue = Maximum;
                  }
                }
              } else if (Key.ScanCode == SCAN_RIGHT) {
                if (IntInput) {
                  if ((INT64)EditValue + (INT64)Step <= (INT64)Maximum) {
                    EditValue = EditValue + Step;
                  } else if ((INT64)EditValue < (INT64)Maximum) {
                    EditValue = Maximum;
                  } else {
                    EditValue = Minimum;
                  }
                } else {
                  if (EditValue + Step <= Maximum) {
                    EditValue = EditValue + Step;
                  } else if (EditValue < Maximum) {
                    EditValue = Maximum;
                  } else {
                    EditValue = Minimum;
                  }
                }
              }

              ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
              if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
                if (MenuOption->Sequence == 2) {
                  //
                  // Year
                  //
                  UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16)EditValue);
                } else {
                  //
                  // Month/Day
                  //
                  UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8)EditValue);
                }

                if (MenuOption->Sequence == 0) {
                  ASSERT (EraseLen >= 2);
                  FormattedNumber[EraseLen - 2] = DATE_SEPARATOR;
                } else if (MenuOption->Sequence == 1) {
                  ASSERT (EraseLen >= 1);
                  FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;
                }
              } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
                UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8)EditValue);

                if (MenuOption->Sequence == 0) {
                  ASSERT (EraseLen >= 2);
                  FormattedNumber[EraseLen - 2] = TIME_SEPARATOR;
                } else if (MenuOption->Sequence == 1) {
                  ASSERT (EraseLen >= 1);
                  FormattedNumber[EraseLen - 1] = TIME_SEPARATOR;
                }
              } else {
                QuestionValue->Value.u64 = EditValue;
                PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
              }

              gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
              for (Loop = 0; Loop < EraseLen; Loop++) {
                PrintStringAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
              }

              gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());

              if (MenuOption->Sequence == 0) {
                PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
                Column = MenuOption->OptCol + 1;
              }

              PrintStringAt (Column, Row, FormattedNumber);

              if (!DateOrTime || (MenuOption->Sequence == 2)) {
                PrintCharAt ((UINTN)-1, (UINTN)-1, RIGHT_NUMERIC_DELIMITER);
              }
            }

            goto EnterCarriageReturn;

          case SCAN_UP:
          case SCAN_DOWN:
            goto EnterCarriageReturn;

          case SCAN_ESC:
            return EFI_DEVICE_ERROR;

          default:
            break;
        }

        break;

EnterCarriageReturn:

      case CHAR_CARRIAGE_RETURN:
        //
        // Validate input value with Minimum value.
        //
        ValidateFail = FALSE;
        if (IntInput) {
          //
          // After user input Enter, need to check whether the input value.
          // If input a negative value, should compare with maximum value.
          // else compare with the minimum value.
          //
          if (Negative) {
            ValidateFail = (INT64)EditValue > (INT64)Maximum ? TRUE : FALSE;
          } else {
            ValidateFail = (INT64)EditValue < (INT64)Minimum ? TRUE : FALSE;
          }

          if (ValidateFail) {
            UpdateStatusBar (INPUT_ERROR, TRUE);
            break;
          }
        } else if (EditValue < Minimum) {
          UpdateStatusBar (INPUT_ERROR, TRUE);
          break;
        }

        UpdateStatusBar (INPUT_ERROR, FALSE);
        CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof (EFI_HII_VALUE));
        QuestionValue = &gUserInput->InputValue;
        //
        // Store Edit value back to Question
        //
        if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
          switch (MenuOption->Sequence) {
            case 0:
              QuestionValue->Value.date.Month = (UINT8)EditValue;
              break;

            case 1:
              QuestionValue->Value.date.Day = (UINT8)EditValue;
              break;

            case 2:
              QuestionValue->Value.date.Year = (UINT16)EditValue;
              break;

            default:
              break;
          }
        } else if (Question->OpCode->OpCode  == EFI_IFR_TIME_OP) {
          switch (MenuOption->Sequence) {
            case 0:
              QuestionValue->Value.time.Hour = (UINT8)EditValue;
              break;

            case 1:
              QuestionValue->Value.time.Minute = (UINT8)EditValue;
              break;

            case 2:
              QuestionValue->Value.time.Second = (UINT8)EditValue;
              break;

            default:
              break;
          }
        } else {
          //
          // Numeric
          //
          QuestionValue->Value.u64 = EditValue;
        }

        //
        // Adjust the value to the correct one.
        // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01
        //              2013.03.29 -> 2013.02.29 -> 2013.02.28
        //
        if ((Question->OpCode->OpCode  == EFI_IFR_DATE_OP) &&
            ((MenuOption->Sequence == 0) || (MenuOption->Sequence == 2)))
        {
          AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence);
        }

        return EFI_SUCCESS;

      case CHAR_BACKSPACE:
        if (ManualInput) {
          if (Count == 0) {
            if (Negative) {
              Negative = FALSE;
              Column--;
              PrintStringAt (Column, Row, L" ");
            }

            break;
          }

          //
          // Remove a character
          //
          EditValue = PreviousNumber[Count - 1];
          UpdateStatusBar (INPUT_ERROR, FALSE);
          Count--;
          Column--;
          PrintStringAt (Column, Row, L" ");
        }

        break;

      default:
        if (ManualInput) {
          if (HexInput) {
            if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) {
              Digital = (UINT8)(Key.UnicodeChar - L'0');
            } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) {
              Digital = (UINT8)(Key.UnicodeChar - L'A' + 0x0A);
            } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {
              Digital = (UINT8)(Key.UnicodeChar - L'a' + 0x0A);
            } else {
              UpdateStatusBar (INPUT_ERROR, TRUE);
              break;
            }
          } else {
            if ((Key.UnicodeChar > L'9') || (Key.UnicodeChar < L'0')) {
              UpdateStatusBar (INPUT_ERROR, TRUE);
              break;
            }
          }

          //
          // If Count exceed input width, there is no way more is valid
          //
          if (Count >= InputWidth) {
            break;
          }

          //
          // Someone typed something valid!
          //
          if (Count != 0) {
            if (HexInput) {
              EditValue = LShiftU64 (EditValue, 4) + Digital;
            } else if (IntInput && Negative) {
              //
              // Save the negative number.
              //
              EditValue = ~(MultU64x32 (~(EditValue - 1), 10) + (Key.UnicodeChar - L'0')) + 1;
            } else {
              EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');
            }
          } else {
            if (HexInput) {
              EditValue = Digital;
            } else if (IntInput && Negative) {
              //
              // Save the negative number.
              //
              EditValue = ~(Key.UnicodeChar - L'0') + 1;
            } else {
              EditValue = Key.UnicodeChar - L'0';
            }
          }

          if (IntInput) {
            ValidateFail = FALSE;
            //
            // When user input a new value, should check the current value.
            // If user input a negative value, should compare it with minimum
            // value, else compare it with maximum value.
            //
            if (Negative) {
              ValidateFail = (INT64)EditValue < (INT64)Minimum ? TRUE : FALSE;
            } else {
              ValidateFail = (INT64)EditValue > (INT64)Maximum ? TRUE : FALSE;
            }

            if (ValidateFail) {
              UpdateStatusBar (INPUT_ERROR, TRUE);
              ASSERT (Count < ARRAY_SIZE (PreviousNumber));
              EditValue = PreviousNumber[Count];
              break;
            }
          } else {
            if (EditValue > Maximum) {
              UpdateStatusBar (INPUT_ERROR, TRUE);
              ASSERT (Count < ARRAY_SIZE (PreviousNumber));
              EditValue = PreviousNumber[Count];
              break;
            }
          }

          UpdateStatusBar (INPUT_ERROR, FALSE);

          Count++;
          ASSERT (Count < (ARRAY_SIZE (PreviousNumber)));
          PreviousNumber[Count] = EditValue;

          gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
          PrintCharAt (Column, Row, Key.UnicodeChar);
          Column++;
        }

        break;
    }
  } while (TRUE);
}

/**
  Adjust option order base on the question value.

  @param  Question           Pointer to current question.
  @param  PopUpMenuLines     The line number of the pop up menu.

  @retval EFI_SUCCESS       If Option input is processed successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
AdjustOptionOrder (
  IN  FORM_DISPLAY_ENGINE_STATEMENT  *Question,
  OUT UINTN                          *PopUpMenuLines
  )
{
  UINTN                    Index;
  EFI_IFR_ORDERED_LIST     *OrderList;
  UINT8                    *ValueArray;
  UINT8                    ValueType;
  LIST_ENTRY               *Link;
  DISPLAY_QUESTION_OPTION  *OneOfOption;
  EFI_HII_VALUE            *HiiValueArray;

  Link        = GetFirstNode (&Question->OptionListHead);
  OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
  ValueArray  = Question->CurrentValue.Buffer;
  ValueType   =  OneOfOption->OptionOpCode->Type;
  OrderList   = (EFI_IFR_ORDERED_LIST *)Question->OpCode;

  for (Index = 0; Index < OrderList->MaxContainers; Index++) {
    if (GetArrayData (ValueArray, ValueType, Index) == 0) {
      break;
    }
  }

  *PopUpMenuLines = Index;

  //
  // Prepare HiiValue array
  //
  HiiValueArray = AllocateZeroPool (*PopUpMenuLines * sizeof (EFI_HII_VALUE));
  ASSERT (HiiValueArray != NULL);

  for (Index = 0; Index < *PopUpMenuLines; Index++) {
    HiiValueArray[Index].Type      = ValueType;
    HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
  }

  for (Index = 0; Index < *PopUpMenuLines; Index++) {
    OneOfOption = ValueToOption (Question, &HiiValueArray[*PopUpMenuLines - Index - 1]);
    if (OneOfOption == NULL) {
      return EFI_NOT_FOUND;
    }

    RemoveEntryList (&OneOfOption->Link);

    //
    // Insert to head.
    //
    InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);
  }

  FreePool (HiiValueArray);

  return EFI_SUCCESS;
}

/**
  Base on the type to compare the value.

  @param  Value1                The first value need to compare.
  @param  Value2                The second value need to compare.
  @param  Type                  The value type for above two values.

  @retval TRUE                  The two value are same.
  @retval FALSE                 The two value are different.

**/
BOOLEAN
IsValuesEqual (
  IN EFI_IFR_TYPE_VALUE  *Value1,
  IN EFI_IFR_TYPE_VALUE  *Value2,
  IN UINT8               Type
  )
{
  switch (Type) {
    case EFI_IFR_TYPE_BOOLEAN:
    case EFI_IFR_TYPE_NUM_SIZE_8:
      return (BOOLEAN)(Value1->u8 == Value2->u8);

    case EFI_IFR_TYPE_NUM_SIZE_16:
      return (BOOLEAN)(Value1->u16 == Value2->u16);

    case EFI_IFR_TYPE_NUM_SIZE_32:
      return (BOOLEAN)(Value1->u32 == Value2->u32);

    case EFI_IFR_TYPE_NUM_SIZE_64:
      return (BOOLEAN)(Value1->u64 == Value2->u64);

    default:
      ASSERT (FALSE);
      return FALSE;
  }
}

/**
  Base on the type to set the value.

  @param  Dest                  The dest value.
  @param  Source                The source value.
  @param  Type                  The value type for above two values.

**/
VOID
SetValuesByType (
  OUT EFI_IFR_TYPE_VALUE  *Dest,
  IN  EFI_IFR_TYPE_VALUE  *Source,
  IN  UINT8               Type
  )
{
  switch (Type) {
    case EFI_IFR_TYPE_BOOLEAN:
      Dest->b = Source->b;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_8:
      Dest->u8 = Source->u8;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_16:
      Dest->u16 = Source->u16;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_32:
      Dest->u32 = Source->u32;
      break;

    case EFI_IFR_TYPE_NUM_SIZE_64:
      Dest->u64 = Source->u64;
      break;

    default:
      ASSERT (FALSE);
      break;
  }
}

/**
  Get selection for OneOf and OrderedList (Left/Right will be ignored).

  @param  MenuOption        Pointer to the current input menu.

  @retval EFI_SUCCESS       If Option input is processed successfully
  @retval EFI_DEVICE_ERROR  If operation fails

**/
EFI_STATUS
GetSelectionInputPopUp (
  IN  UI_MENU_OPTION  *MenuOption
  )
{
  EFI_INPUT_KEY                  Key;
  UINTN                          Index;
  CHAR16                         *StringPtr;
  CHAR16                         *TempStringPtr;
  UINTN                          Index2;
  UINTN                          TopOptionIndex;
  UINTN                          HighlightOptionIndex;
  UINTN                          Start;
  UINTN                          End;
  UINTN                          Top;
  UINTN                          Bottom;
  UINTN                          PopUpMenuLines;
  UINTN                          MenuLinesInView;
  UINTN                          PopUpWidth;
  CHAR16                         Character;
  INT32                          SavedAttribute;
  BOOLEAN                        ShowDownArrow;
  BOOLEAN                        ShowUpArrow;
  UINTN                          DimensionsWidth;
  LIST_ENTRY                     *Link;
  BOOLEAN                        OrderedList;
  UINT8                          *ValueArray;
  UINT8                          *ReturnValue;
  UINT8                          ValueType;
  EFI_HII_VALUE                  HiiValue;
  DISPLAY_QUESTION_OPTION        *OneOfOption;
  DISPLAY_QUESTION_OPTION        *CurrentOption;
  FORM_DISPLAY_ENGINE_STATEMENT  *Question;
  INTN                           Result;
  EFI_IFR_ORDERED_LIST           *OrderList;

  DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;

  ValueArray    = NULL;
  ValueType     = 0;
  CurrentOption = NULL;
  ShowDownArrow = FALSE;
  ShowUpArrow   = FALSE;

  ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE));

  Question = MenuOption->ThisTag;
  if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {
    Link        = GetFirstNode (&Question->OptionListHead);
    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
    ValueArray  = Question->CurrentValue.Buffer;
    ValueType   =  OneOfOption->OptionOpCode->Type;
    OrderedList = TRUE;
    OrderList   = (EFI_IFR_ORDERED_LIST *)Question->OpCode;
  } else {
    OrderedList = FALSE;
    OrderList   = NULL;
  }

  //
  // Calculate Option count
  //
  PopUpMenuLines = 0;
  if (OrderedList) {
    AdjustOptionOrder (Question, &PopUpMenuLines);
  } else {
    Link = GetFirstNode (&Question->OptionListHead);
    while (!IsNull (&Question->OptionListHead, Link)) {
      OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
      PopUpMenuLines++;
      Link = GetNextNode (&Question->OptionListHead, Link);
    }
  }

  //
  // Get the number of one of options present and its size
  //
  PopUpWidth           = 0;
  HighlightOptionIndex = 0;
  Link                 = GetFirstNode (&Question->OptionListHead);
  for (Index = 0; Index < PopUpMenuLines; Index++) {
    OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);

    StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
    if (StrLen (StringPtr) > PopUpWidth) {
      PopUpWidth = StrLen (StringPtr);
    }

    FreePool (StringPtr);
    HiiValue.Type = OneOfOption->OptionOpCode->Type;
    SetValuesByType (&HiiValue.Value, &OneOfOption->OptionOpCode->Value, HiiValue.Type);
    if (!OrderedList && (CompareHiiValue (&Question->CurrentValue, &HiiValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
      //
      // Find current selected Option for OneOf
      //
      HighlightOptionIndex = Index;
    }

    Link = GetNextNode (&Question->OptionListHead, Link);
  }

  //
  // Perform popup menu initialization.
  //
  PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;

  SavedAttribute = gST->ConOut->Mode->Attribute;
  gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());

  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
  }

  Start  = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn;
  End    = Start + PopUpWidth + POPUP_FRAME_WIDTH;
  Top    = gStatementDimensions.TopRow;
  Bottom = gStatementDimensions.BottomRow - 1;

  MenuLinesInView = Bottom - Top - 1;
  if (MenuLinesInView >= PopUpMenuLines) {
    Top    = Top + (MenuLinesInView - PopUpMenuLines) / 2;
    Bottom = Top + PopUpMenuLines + 1;
  } else {
    ShowDownArrow = TRUE;
  }

  if (HighlightOptionIndex > (MenuLinesInView - 1)) {
    TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;
  } else {
    TopOptionIndex = 0;
  }

  do {
    //
    // Clear that portion of the screen
    //
    ClearLines (Start, End, Top, Bottom, GetPopupColor ());

    //
    // Draw "One of" pop-up menu
    //
    Character = BOXDRAW_DOWN_RIGHT;
    PrintCharAt (Start, Top, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_UP_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
    }

    Character = BOXDRAW_DOWN_LEFT;
    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
    Character = BOXDRAW_VERTICAL;
    for (Index = Top + 1; Index < Bottom; Index++) {
      PrintCharAt (Start, Index, Character);
      PrintCharAt (End - 1, Index, Character);
    }

    //
    // Move to top Option
    //
    Link = GetFirstNode (&Question->OptionListHead);
    for (Index = 0; Index < TopOptionIndex; Index++) {
      Link = GetNextNode (&Question->OptionListHead, Link);
    }

    //
    // Display the One of options
    //
    Index2 = Top + 1;
    for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {
      OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
      Link        = GetNextNode (&Question->OptionListHead, Link);

      StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
      ASSERT (StringPtr != NULL);
      //
      // If the string occupies multiple lines, truncate it to fit in one line,
      // and append a "..." for indication.
      //
      if (StrLen (StringPtr) > (PopUpWidth - 1)) {
        TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));
        ASSERT (TempStringPtr != NULL);
        CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));
        FreePool (StringPtr);
        StringPtr = TempStringPtr;
        StrCatS (StringPtr, PopUpWidth - 1, L"...");
      }

      if (Index == HighlightOptionIndex) {
        //
        // Highlight the selected one
        //
        CurrentOption = OneOfOption;

        gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ());
        PrintStringAt (Start + 2, Index2, StringPtr);
        gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
      } else {
        gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
        PrintStringAt (Start + 2, Index2, StringPtr);
      }

      Index2++;
      FreePool (StringPtr);
    }

    Character = BOXDRAW_UP_RIGHT;
    PrintCharAt (Start, Bottom, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = GEOMETRICSHAPE_DOWN_TRIANGLE;
      } else {
        Character = BOXDRAW_HORIZONTAL;
      }

      PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
    }

    Character = BOXDRAW_UP_LEFT;
    PrintCharAt ((UINTN)-1, (UINTN)-1, Character);

    //
    // Get User selection
    //
    Key.UnicodeChar = CHAR_NULL;
    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
      Key.ScanCode = gDirection;
      gDirection   = 0;
      goto TheKey;
    }

    WaitForKeyStroke (&Key);

TheKey:
    switch (Key.UnicodeChar) {
      case '+':
        if (OrderedList) {
          if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
            //
            // Highlight reaches the top of the popup window, scroll one menu item.
            //
            TopOptionIndex--;
            ShowDownArrow = TRUE;
          }

          if (TopOptionIndex == 0) {
            ShowUpArrow = FALSE;
          }

          if (HighlightOptionIndex > 0) {
            HighlightOptionIndex--;

            ASSERT (CurrentOption != NULL);
            SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);
          }
        }

        break;

      case '-':
        //
        // If an ordered list op-code, we will allow for a popup of +/- keys
        // to create an ordered list of items
        //
        if (OrderedList) {
          if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
              (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1)))
          {
            //
            // Highlight reaches the bottom of the popup window, scroll one menu item.
            //
            TopOptionIndex++;
            ShowUpArrow = TRUE;
          }

          if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
            ShowDownArrow = FALSE;
          }

          if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
            HighlightOptionIndex++;

            ASSERT (CurrentOption != NULL);
            SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);
          }
        }

        break;

      case '^':
        if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
          //
          // Highlight reaches the top of the popup window, scroll one menu item.
          //
          TopOptionIndex--;
          ShowDownArrow = TRUE;
        }

        if (TopOptionIndex == 0) {
          ShowUpArrow = FALSE;
        }

        if (HighlightOptionIndex > 0) {
          HighlightOptionIndex--;
        }

        break;

      case 'V':
      case 'v':
        if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
            (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1)))
        {
          //
          // Highlight reaches the bottom of the popup window, scroll one menu item.
          //
          TopOptionIndex++;
          ShowUpArrow = TRUE;
        }

        if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
          ShowDownArrow = FALSE;
        }

        if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
          HighlightOptionIndex++;
        }

        break;

      case CHAR_NULL:
        switch (Key.ScanCode) {
          case SCAN_UP:
          case SCAN_DOWN:
            if (Key.ScanCode == SCAN_UP) {
              if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
                //
                // Highlight reaches the top of the popup window, scroll one menu item.
                //
                TopOptionIndex--;
                ShowDownArrow = TRUE;
              }

              if (TopOptionIndex == 0) {
                ShowUpArrow = FALSE;
              }

              if (HighlightOptionIndex > 0) {
                HighlightOptionIndex--;
              }
            } else {
              if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
                  (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1)))
              {
                //
                // Highlight reaches the bottom of the popup window, scroll one menu item.
                //
                TopOptionIndex++;
                ShowUpArrow = TRUE;
              }

              if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
                ShowDownArrow = FALSE;
              }

              if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
                HighlightOptionIndex++;
              }
            }

            break;

          case SCAN_ESC:
            gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

            //
            // Restore link list order for orderedlist
            //
            if (OrderedList) {
              HiiValue.Type      = ValueType;
              HiiValue.Value.u64 = 0;
              for (Index = 0; Index < OrderList->MaxContainers; Index++) {
                HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
                if (HiiValue.Value.u64 == 0) {
                  break;
                }

                OneOfOption = ValueToOption (Question, &HiiValue);
                if (OneOfOption == NULL) {
                  return EFI_NOT_FOUND;
                }

                RemoveEntryList (&OneOfOption->Link);
                InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
              }
            }

            return EFI_DEVICE_ERROR;

          default:
            break;
        }

        break;

      case CHAR_CARRIAGE_RETURN:
        //
        // return the current selection
        //
        if (OrderedList) {
          ReturnValue = AllocateZeroPool (Question->CurrentValue.BufferLen);
          ASSERT (ReturnValue != NULL);
          Index = 0;
          Link  = GetFirstNode (&Question->OptionListHead);
          while (!IsNull (&Question->OptionListHead, Link)) {
            OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
            Link        = GetNextNode (&Question->OptionListHead, Link);

            SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64);

            Index++;
            if (Index > OrderList->MaxContainers) {
              break;
            }
          }

          if (CompareMem (ReturnValue, ValueArray, Question->CurrentValue.BufferLen) == 0) {
            FreePool (ReturnValue);
            return EFI_DEVICE_ERROR;
          } else {
            gUserInput->InputValue.Buffer    = ReturnValue;
            gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
          }
        } else {
          ASSERT (CurrentOption != NULL);
          gUserInput->InputValue.Type = CurrentOption->OptionOpCode->Type;
          if (IsValuesEqual (&Question->CurrentValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type)) {
            return EFI_DEVICE_ERROR;
          } else {
            SetValuesByType (&gUserInput->InputValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type);
          }
        }

        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);

        return EFI_SUCCESS;

      default:
        break;
    }
  } while (TRUE);
}
