/** @file
Implementation for handling user input from the User Interfaces.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
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 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);
}
