/** @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)) {
          for (Index = 0; Index < CurrentCursor - 1; Index++) {
            TempString[Index] = StringPtr[Index];
          }

          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) {
            for (Index = 0; Index < CurrentCursor; Index++) {
              TempString[Index] = StringPtr[Index];
            }

            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);
}
