/** @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;

  Index         = 0;
  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;
  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;
    OrderList   = (EFI_IFR_ORDERED_LIST *)Question->OpCode;
  } else {
    OrderList = NULL;
  }

  //
  // Calculate Option count
  //
  PopUpMenuLines = 0;
  if (OrderList != NULL) {
    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 ((OrderList == NULL) && (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 (OrderList != NULL) {
          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--;
            if (CurrentOption == NULL) {
              ASSERT (CurrentOption != NULL);
              break;
            }

            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 (OrderList != NULL) {
          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++;

            if (CurrentOption == NULL) {
              ASSERT (CurrentOption != NULL);
              break;
            }

            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 (OrderList != NULL) {
              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 (OrderList != NULL) {
          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 {
          if (CurrentOption == NULL) {
            ASSERT (CurrentOption != NULL);
          } else {
            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);
}
