/**@file
   Implementation for handling user input from the User Interface

Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Setup.h"
#include "Ui.h"
#include "Colors.h"

EFI_STATUS
ReadString(
  IN  UI_MENU_OPTION              *MenuOption,
  OUT CHAR16                      *StringPtr
  )
{
  EFI_STATUS    Status;
  EFI_INPUT_KEY Key;
  CHAR16        NullCharacter;
  UINTN         ScreenSize;
  EFI_TAG       *Tag;
  CHAR16        Space[2];
  CHAR16        KeyPad[2];
  BOOLEAN       SelectionComplete;
  CHAR16        *TempString;
  CHAR16        *BufferedString;
  UINTN         Index;
  UINTN         Count;
  UINTN         Start;
  UINTN         Top;
  CHAR16        *PromptForDataString;
  UINTN         DimensionsWidth;
  UINTN         DimensionsHeight;
  BOOLEAN       CursorVisible;

  DimensionsWidth     = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
  DimensionsHeight    = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

  PromptForDataString = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);

  NullCharacter       = CHAR_NULL;
  ScreenSize          = GetStringWidth (PromptForDataString) / 2;
  Tag                 = MenuOption->ThisTag;
  Space[0]            = L' ';
  Space[1]            = CHAR_NULL;
  SelectionComplete   = FALSE;

  TempString          = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);
  ASSERT (TempString);

  if (ScreenSize < (Tag->Maximum / (UINTN) 2)) {
    ScreenSize = Tag->Maximum / 2;
  }

  if ((ScreenSize + 2) > DimensionsWidth) {
    ScreenSize = DimensionsWidth - 2;
  }

  BufferedString = AllocateZeroPool (ScreenSize * 2);
  ASSERT (BufferedString);

  Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;
  Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;

  //
  // Display prompt for string
  //
  CreatePopUp (ScreenSize, 4, &NullCharacter, PromptForDataString, Space, &NullCharacter);

  FreePool (PromptForDataString);

  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));

  CursorVisible = gST->ConOut->Mode->CursorVisible;
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  do {
    Status = WaitForKeyStroke (&Key);

    gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
    switch (Key.UnicodeChar) {
    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_LEFT:
        break;

      case SCAN_RIGHT:
        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;

      default:
        break;
      }

      break;

    case CHAR_CARRIAGE_RETURN:
      if (GetStringWidth (StringPtr) >= MenuOption->ThisTag->Minimum) {
        SelectionComplete = TRUE;
        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 {
        ScreenSize = GetStringWidth (gMiniString) / 2;
        CreatePopUp (ScreenSize, 4, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);
        //
        // 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 {
          Status = WaitForKeyStroke (&Key);
        } 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;
      }

      break;

    case CHAR_BACKSPACE:
      if (StringPtr[0] != CHAR_NULL) {
        for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {
          TempString[Index] = StringPtr[Index];
        }
        //
        // Effectively truncate string by 1 character
        //
        TempString[Index - 1] = CHAR_NULL;
        StrCpy (StringPtr, TempString);
      }

    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)) {
        StrnCpy (StringPtr, &Key.UnicodeChar, 1);
        StrnCpy (TempString, &Key.UnicodeChar, 1);
      } else if ((GetStringWidth (StringPtr) < MenuOption->ThisTag->Maximum) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
        KeyPad[0] = Key.UnicodeChar;
        KeyPad[1] = CHAR_NULL;
        StrCat (StringPtr, KeyPad);
        StrCat (TempString, KeyPad);
      }
      //
      // 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;
      }

      for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
        BufferedString[Count] = StringPtr[Index];
      }

      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 + GetStringWidth (StringPtr) / 2, Top + 3);
  } while (!SelectionComplete);
  gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
  gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
  return Status;
}

EFI_STATUS
ReadPassword (
  IN  UI_MENU_OPTION              *MenuOption,
  IN  BOOLEAN                     PromptForPassword,
  IN  EFI_TAG                     *Tag,
  IN  EFI_IFR_DATA_ARRAY          *PageData,
  IN  BOOLEAN                     SecondEntry,
  IN  EFI_FILE_FORM_TAGS          *FileFormTags,
  OUT CHAR16                      *StringPtr
  )
{
  EFI_STATUS                  Status;
  UINTN                       ScreenSize;
  CHAR16                      NullCharacter;
  CHAR16                      Space[2];
  EFI_INPUT_KEY               Key;
  CHAR16                      KeyPad[2];
  UINTN                       Index;
  UINTN                       Start;
  UINTN                       Top;
  CHAR16                      *TempString;
  CHAR16                      *TempString2;
  BOOLEAN                     Confirmation;
  BOOLEAN                     ConfirmationComplete;
  EFI_HII_CALLBACK_PACKET     *Packet;
  EFI_FORM_CALLBACK_PROTOCOL  *FormCallback;
  EFI_VARIABLE_DEFINITION     *VariableDefinition;
  UINTN                       DimensionsWidth;
  UINTN                       DimensionsHeight;
  EFI_IFR_DATA_ENTRY          *DataEntry;
  UINTN                       WidthOfString;

  DimensionsWidth       = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
  DimensionsHeight      = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;

  VariableDefinition    = NULL;
  NullCharacter         = CHAR_NULL;
  Space[0]              = L' ';
  Space[1]              = CHAR_NULL;
  Confirmation          = FALSE;
  ConfirmationComplete  = FALSE;
  Status                = EFI_SUCCESS;
  FormCallback          = NULL;
  Packet                = NULL;

  //
  // Remember that dynamic pages in an environment where all pages are not
  // dynamic require us to call back to the user to give them an opportunity
  // to register fresh information in the HII database so that we can extract it.
  //
  Status = gBS->HandleProtocol (
                  (VOID *) (UINTN) MenuOption->Tags[0].CallbackHandle,
                  &gEfiFormCallbackProtocolGuid,
                  (VOID **) &FormCallback
                  );

  TempString  = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);
  TempString2 = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2);

  ASSERT (TempString);
  ASSERT (TempString2);

  if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {
    //
    // Password requires a callback to determine if a password exists
    //
    DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);
    DataEntry->OpCode  = EFI_IFR_PASSWORD_OP;
    DataEntry->Length  = 3;

    ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

    //
    // The user is about to be prompted with a password field, Data = 0 (Return Status determines the type of prompt)
    //
    DataEntry->Data  = (VOID *) (UINTN) (UINT8) (0 + SecondEntry * 2);
    PageData->NvRamMap    = VariableDefinition->NvRamMap;

    if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
      Status = FormCallback->Callback (
                              FormCallback,
                              Tag->Key,
                              PageData,
                              &Packet
                              );
    }
    //
    // If error on return, continue with the reading of a typed in password to verify user knows password
    // If no error, there is no password set, so prompt for new password
    // if the previous callback was to verify the user knew password, and user typed it correctly - should return no error
    //
    if (!EFI_ERROR (Status)) {
      PromptForPassword = FALSE;

      //
      // Simulate this as the second entry into this routine for an interactive behavior
      //
      SecondEntry = TRUE;
    } else if (Status == EFI_NOT_READY) {
Error:
      if (Packet != NULL) {
        //
        // Upon error, we will likely receive a string to print out
        // Display error popup
        //
        WidthOfString = GetStringWidth (Packet->String);
        ScreenSize = MAX(WidthOfString, GetStringWidth (gPressEnter)) / 2;
        CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter);
        FreePool (Packet);

        do {
          Status = WaitForKeyStroke (&Key);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
      }

      Status = EFI_NOT_READY;
      goto Done;
    }
  }

  do {
    //
    // Display PopUp Screen
    //
    ScreenSize = GetStringWidth (gPromptForNewPassword) / 2;
    if (GetStringWidth (gConfirmPassword) / 2 > ScreenSize) {
      ScreenSize = GetStringWidth (gConfirmPassword) / 2;
    }

    Start = (DimensionsWidth - ScreenSize - 4) / 2 + gScreenDimensions.LeftColumn + 2;
    Top   = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;

    if (!Confirmation) {
      if (PromptForPassword) {
        CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForPassword, Space, &NullCharacter);
      } else {
        CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForNewPassword, Space, &NullCharacter);
      }
    } else {
      CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmPassword, Space, &NullCharacter);
      StringPtr[0] = CHAR_NULL;
    }

    do {
      Status = WaitForKeyStroke (&Key);

      switch (Key.UnicodeChar) {
      case CHAR_NULL:
        if (Key.ScanCode == SCAN_ESC) {
          return EFI_NOT_READY;
        }

        ConfirmationComplete = FALSE;
        break;

      case CHAR_CARRIAGE_RETURN:
        if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) {
          //
          // User just typed a string in
          //
          DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);
          DataEntry->OpCode = EFI_IFR_PASSWORD_OP;

          //
          // If the user just typed in a password, Data = 1
          // If the user just typed in a password to confirm the previous password, Data = 2
          //
          if (!Confirmation) {
            DataEntry->Length  = 3;
            DataEntry->Data    = (VOID *) (UINTN) (UINT8) (1 + SecondEntry * 2);

            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
              Status = FormCallback->Callback (
                                      FormCallback,
                                      Tag->Key,
                                      PageData,
                                      &Packet
                                      );
            }

            DataEntry->Length  = sizeof (EFI_IFR_DATA_ENTRY);
            DataEntry->Data    = (VOID *) TempString;
          } else {
            DataEntry->Length  = 3;
            DataEntry->Data    = (VOID *) (UINTN) (UINT8) (2 + SecondEntry * 2);

            if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
              Status = FormCallback->Callback (
                                      FormCallback,
                                      Tag->Key,
                                      PageData,
                                      &Packet
                                      );
            }

            DataEntry->Length  = sizeof (EFI_IFR_DATA_ENTRY);
            DataEntry->Data    = (VOID *) TempString2;
          }

          if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
            Status = FormCallback->Callback (
                                    FormCallback,
                                    Tag->Key,
                                    PageData,
                                    &Packet
                                    );
          }
          //
          // If this was the confirmation round of callbacks
          // and an error comes back, display an error
          //
          if (Confirmation) {
            if (EFI_ERROR (Status)) {
              if (Packet->String == NULL) {
                WidthOfString = GetStringWidth (gConfirmError);
                ScreenSize = MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2;
                CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);
              } else {
                WidthOfString = GetStringWidth (Packet->String);
                ScreenSize = MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2;
                CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter);
                FreePool (Packet);
              }

              StringPtr[0] = CHAR_NULL;
              do {
                Status = WaitForKeyStroke (&Key);

                if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
                  Status = EFI_NOT_READY;
                  goto Done;
                }
              } while (1);
            } else {
                Status = EFI_NOT_READY;
                goto Done;
            }
          } else {
            //
            // User typed a string in and it wasn't valid somehow from the callback
            // For instance, callback may have said that some invalid characters were contained in the string
            //
            if (Status == EFI_NOT_READY) {
              goto Error;
            }

            if (PromptForPassword && EFI_ERROR (Status)) {
              Status = EFI_DEVICE_ERROR;
              goto Done;
            }
          }
        }

        if (Confirmation) {
          //
          // Compare tempstring and tempstring2, if the same, return with StringPtr success
          // Otherwise, kick and error box, and return an error
          //
          if (StrCmp (TempString, TempString2) == 0) {
            Status = EFI_SUCCESS;
            goto Done;
          } else {
            WidthOfString = GetStringWidth (gConfirmError);
            ScreenSize = MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2;
            CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter);
            StringPtr[0] = CHAR_NULL;
            do {
              Status = WaitForKeyStroke (&Key);
              if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
                Status = EFI_DEVICE_ERROR;
                goto Done;
              }
            } while (1);
          }
        }

        if (PromptForPassword) {
          //
          // I was asked for a password, return it back in StringPtr
          //
          Status = EFI_SUCCESS;
          goto Done;
        } else {
          //
          // If the two passwords were not the same kick an error popup
          //
          Confirmation          = TRUE;
          ConfirmationComplete  = TRUE;
          break;
        }

      case CHAR_BACKSPACE:
        if (StringPtr[0] != CHAR_NULL) {
          if (!Confirmation) {
            for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {
              TempString[Index] = StringPtr[Index];
            }
            //
            // Effectively truncate string by 1 character
            //
            TempString[Index - 1] = CHAR_NULL;
            StrCpy (StringPtr, TempString);
          } else {
            for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) {
              TempString2[Index] = StringPtr[Index];
            }
            //
            // Effectively truncate string by 1 character
            //
            TempString2[Index - 1] = CHAR_NULL;
            StrCpy (StringPtr, TempString2);
          }

          ConfirmationComplete = FALSE;
        } else {
          ConfirmationComplete = FALSE;
        }

      //
      // Must be a character we are interested in!
      //
      default:
        if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
          if (!Confirmation) {
            StrnCpy (StringPtr, &Key.UnicodeChar, 1);
            StrnCpy (TempString, &Key.UnicodeChar, 1);
          } else {
            StrnCpy (StringPtr, &Key.UnicodeChar, 1);
            StrnCpy (TempString2, &Key.UnicodeChar, 1);
            ConfirmationComplete = FALSE;
          }
        } else if ((GetStringWidth (StringPtr) / 2 <= (UINTN) (MenuOption->ThisTag->Maximum - 1) / 2) &&
                 (Key.UnicodeChar != CHAR_BACKSPACE)
                ) {
          KeyPad[0] = Key.UnicodeChar;
          KeyPad[1] = CHAR_NULL;
          if (!Confirmation) {
            StrCat (StringPtr, KeyPad);
            StrCat (TempString, KeyPad);
          } else {
            StrCat (StringPtr, KeyPad);
            StrCat (TempString2, KeyPad);
          }
        }

        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
        for (Index = 1; Index < ScreenSize; Index++) {
          PrintCharAt (Start + Index, Top + 3, L' ');
        }

        gST->ConOut->SetCursorPosition (
                      gST->ConOut,
                      (DimensionsWidth - GetStringWidth (StringPtr) / 2) / 2 + gScreenDimensions.LeftColumn,
                      Top + 3
                      );
        for (Index = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++) {
          PrintChar (L'*');
        }

        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        break;
      }
      //
      // end switch
      //
    } while (!ConfirmationComplete);

  } while (1);

Done:
  FreePool (TempString);
  FreePool (TempString2);
  return Status;
}

VOID
EncodePassword (
  IN  CHAR16                      *Password,
  IN  UINT8                       MaxSize
  )
{
  UINTN   Index;
  UINTN   Loop;
  CHAR16  *Buffer;
  CHAR16  *Key;

  Key     = (CHAR16 *) L"MAR10648567";
  Buffer  = AllocateZeroPool (MaxSize);

  ASSERT (Buffer);

  for (Index = 0; Key[Index] != 0; Index++) {
    for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {
      Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);
    }
  }

  CopyMem (Password, Buffer, MaxSize);

  FreePool (Buffer);
  return ;
}

EFI_STATUS
GetNumericInput (
  IN  UI_MENU_OPTION              *MenuOption,
  IN  EFI_FILE_FORM_TAGS          *FileFormTagsHead,
  IN  BOOLEAN                     ManualInput,
  IN  EFI_TAG                     *Tag,
  IN  UINTN                       NumericType,
  OUT UINT16                      *Value
  )
/*++

Routine Description:

  This routine reads a numeric value from the user input.

Arguments:

  MenuOption       -  Pointer to the current input menu.

  FileFormTagsHead -  Pointer to the root of formset.

  ManualInput      -  If the input is manual or not.

  Tag              -  Pointer to all the attributes and values associated with a tag.

  Value            -  Pointer to the numeric value that is going to be read.

Returns:

  EFI_SUCCESS       - If numerical input is read successfully
  EFI_DEVICE_ERROR  - If operation fails

--*/
{
  EFI_INPUT_KEY           Key;
  BOOLEAN                 SelectionComplete;
  UINTN                   Column;
  UINTN                   Row;
  CHAR16                  FormattedNumber[6];
  UINTN                   PreviousNumber[6];
  INTN                    Number;
  UINTN                   Count;
  UINT16                  BackupValue;
  STRING_REF              PopUp;
  CHAR16                  NullCharacter;
  CHAR16                  *StringPtr;
  EFI_FILE_FORM_TAGS      *FileFormTags;
  EFI_VARIABLE_DEFINITION *VariableDefinition;
  UINTN                   Loop;

  NullCharacter     = CHAR_NULL;
  StringPtr         = NULL;
  Column            = MenuOption->OptCol;
  Row               = MenuOption->Row;
  Number            = 0;
  PreviousNumber[0] = 0;
  Count             = 0;
  SelectionComplete = FALSE;
  BackupValue       = Tag->Value;
  FileFormTags      = FileFormTagsHead;

  if (ManualInput) {
    PrintAt (Column, Row, (CHAR16 *) L"[     ]");
    Column++;
    if (Tag->Operand != EFI_IFR_TIME_OP) {
      *Value = BackupValue;
    }
  }
  //
  // 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 ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
        Key.UnicodeChar = CHAR_NULL;
        if (Key.UnicodeChar == '+') {
          Key.ScanCode = SCAN_RIGHT;
        } else {
          Key.ScanCode = SCAN_LEFT;
        }

        goto TheKey2;
      }
      break;

    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_LEFT:
      case SCAN_RIGHT:
        if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
          //
          // 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 (!ManualInput) {
          Tag->Value = *Value;
          if (Key.ScanCode == SCAN_LEFT) {
            Number = *Value - Tag->Step;
            if (Number < Tag->Minimum) {
              Number = Tag->Minimum;
            }
          } else if (Key.ScanCode == SCAN_RIGHT) {
            Number = *Value + Tag->Step;
            if (Number > Tag->Maximum) {
              Number = Tag->Maximum;
            }
          }

          Tag->Value  = (UINT16) Number;
          *Value      = (UINT16) Number;
          UnicodeValueToString (
            FormattedNumber,
            FALSE,
            (UINTN) Number,
            (sizeof (FormattedNumber) / sizeof (FormattedNumber[0]))
            );
          Number = (UINT16) GetStringWidth (FormattedNumber);

          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
          if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) {
            for (Loop = 0; Loop < (UINTN) ((Number >= 8) ? 4 : 2); Loop++) {
              PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" ");
            }
          } else {
            for (Loop = 0; Loop < gOptionBlockWidth; Loop++) {
              PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" ");
            }
          }

          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);

          if ((MenuOption->Col + gPromptBlockWidth + 1) == MenuOption->OptCol) {
            PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
            Column = MenuOption->OptCol + 1;
          }
          //
          // If Number looks like "3", convert it to "03/"
          //
          if (Number == 4 && (NumericType == DATE_NUMERIC)) {
            FormattedNumber[3]  = FormattedNumber[1];
            FormattedNumber[2]  = DATE_SEPARATOR;
            FormattedNumber[1]  = FormattedNumber[0];
            FormattedNumber[0]  = L'0';
            Number              = 8;
          }
          //
          // If Number looks like "13", convert it to "13/"
          //
          if (Number == 6 && (NumericType == DATE_NUMERIC)) {
            FormattedNumber[3]  = FormattedNumber[2];
            FormattedNumber[2]  = DATE_SEPARATOR;
            Number              = 8;
          }

          if (Number == 4 &&
              (NumericType == TIME_NUMERIC) &&
              (MenuOption->Col + gPromptBlockWidth + 8) != MenuOption->OptCol
              ) {
            FormattedNumber[3]  = FormattedNumber[1];
            FormattedNumber[2]  = TIME_SEPARATOR;
            FormattedNumber[1]  = FormattedNumber[0];
            FormattedNumber[0]  = L'0';
            Number              = 8;
          }

          if (Number == 4 &&
              (NumericType == TIME_NUMERIC) &&
              (MenuOption->Col + gPromptBlockWidth + 8) == MenuOption->OptCol
              ) {
            FormattedNumber[3]  = FormattedNumber[1];
            FormattedNumber[2]  = RIGHT_NUMERIC_DELIMITER;
            FormattedNumber[1]  = FormattedNumber[0];
            FormattedNumber[0]  = L'0';
            Number              = 8;
          }

          PrintStringAt (Column, Row, FormattedNumber);
          if (Number == 10 && (NumericType == DATE_NUMERIC)) {
            PrintChar (RIGHT_NUMERIC_DELIMITER);
          }

          if (NumericType == REGULAR_NUMERIC) {
            PrintChar (RIGHT_NUMERIC_DELIMITER);
          }
        }
        break;

      case SCAN_UP:
      case SCAN_DOWN:
        goto EnterCarriageReturn;

      case SCAN_ESC:
        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

EnterCarriageReturn:

    case CHAR_CARRIAGE_RETURN:
      //
      // Check to see if the Value is something reasonable against consistency limitations.
      // If not, let's kick the error specified.
      //
      //
      // This gives us visibility to the FileFormTags->NvRamMap to check things
      // ActiveIfr is a global maintained by the menuing code to ensure that we
      // are pointing to the correct formset's file data.
      //
      for (Count = 0; Count < gActiveIfr; Count++) {
        FileFormTags = FileFormTags->NextFile;
      }

      ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);

      CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth);

      //
      // Data associated with a NULL device (in the fake NV storage)
      //
      if (Tag->StorageWidth == (UINT16) 0) {
        CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2);
      }
      //
      // If a late check is required save off the information.  This is used when consistency checks
      // are required, but certain values might be bound by an impossible consistency check such as
      // if two questions are bound by consistency checks and each only has two possible choices, there
      // would be no way for a user to switch the values.  Thus we require late checking.
      //
      if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {
        CopyMem (&Tag->OldValue, &BackupValue, Tag->StorageWidth);
      } else {
        //
        // In theory, passing the value and the Id are sufficient to determine what needs
        // to be done.  The Id is the key to look for the entry needed in the Inconsistency
        // database.  That will yields operand and ID data - and since the ID's correspond
        // to the NV storage, we can determine the values for other IDs there.
        //
        if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {
          if (PopUp == 0x0000) {
            SelectionComplete = TRUE;
            break;
          }

          StringPtr = GetToken (PopUp, MenuOption->Handle);

          CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);

          do {
            WaitForKeyStroke (&Key);

            switch (Key.UnicodeChar) {

            case CHAR_CARRIAGE_RETURN:
              SelectionComplete = TRUE;
              FreePool (StringPtr);
              break;

            default:
              break;
            }
          } while (!SelectionComplete);

          Tag->Value  = BackupValue;
          *Value      = BackupValue;

          CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth);

          //
          // Data associated with a NULL device (in the fake NV storage)
          //
          if (Tag->StorageWidth == (UINT16) 0) {
            CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2);
          }

          return EFI_DEVICE_ERROR;
        }
      }

      return EFI_SUCCESS;
      break;

    case CHAR_BACKSPACE:
      if (ManualInput) {
        if (Count == 0) {
          break;
        }
        //
        // Remove a character
        //
        Number  = PreviousNumber[Count - 1];
        *Value  = (UINT16) Number;
        UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE);
        Count--;
        Column--;
        PrintAt (Column, Row, (CHAR16 *) L" ");
      }
      break;

    default:
      if (ManualInput) {
        if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {
          UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE);
          break;
        }
        //
        // If Count 0-4 is complete, there is no way more is valid
        //
        if (Count > 4) {
          break;
        }
        //
        // Someone typed something valid!
        //
        if (Count != 0) {
          Number = Number * 10 + (Key.UnicodeChar - L'0');
        } else {
          Number = Key.UnicodeChar - L'0';
        }

        if (Number > Tag->Maximum) {
          UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE);
          Number = PreviousNumber[Count];
          break;
        } else {
          UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE);
        }

        Count++;

        PreviousNumber[Count] = Number;
        *Value                = (UINT16) Number;
        Tag->Value            = (UINT16) Number;

        PrintCharAt (Column, Row, Key.UnicodeChar);
        Column++;
      }
      break;
    }
  } while (!SelectionComplete);
  return EFI_SUCCESS;
}
//
// Notice that this is at least needed for the ordered list manipulation.
// Left/Right doesn't make sense for this op-code
//
EFI_STATUS
GetSelectionInputPopUp (
  IN  UI_MENU_OPTION              *MenuOption,
  IN  EFI_TAG                     *Tag,
  IN  UINTN                       ValueCount,
  OUT UINT16                      *Value,
  OUT UINT16                      *KeyValue
  )
{
  EFI_INPUT_KEY Key;
  UINTN         Index;
  UINTN         TempIndex;
  CHAR16        *StringPtr;
  CHAR16        *TempStringPtr;
  UINT16        Token;
  UINTN         Index2;
  UINTN         TopOptionIndex;
  UINTN         HighlightPosition;
  UINTN         Start;
  UINTN         End;
  UINTN         Top;
  UINTN         Bottom;
  UINT16        TempValue;
  UINTN         Count;
  UINTN         PopUpMenuLines;
  UINTN         MenuLinesInView;
  UINTN         PopUpWidth;
  CHAR16        Character;
  BOOLEAN       FirstOptionFoundFlag;
  INT32         SavedAttribute;
  EFI_TAG       TagBackup;
  UINT8         *ValueArray;
  UINT8         *ValueArrayBackup;
  UINT8         ValueBackup;
  BOOLEAN       Initialized;
  BOOLEAN       KeyInitialized;
  BOOLEAN       ShowDownArrow;
  BOOLEAN       ShowUpArrow;
  UINTN         DimensionsWidth;

  DimensionsWidth   = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;

  TempValue         = 0;
  TempIndex         = 0;
  ValueArray        = (UINT8 *) Value;
  ValueArrayBackup  = NULL;
  Initialized       = FALSE;
  KeyInitialized    = FALSE;
  ShowDownArrow     = FALSE;
  ShowUpArrow       = FALSE;

  if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {
    ValueArrayBackup = AllocateZeroPool (Tag->StorageWidth);
    ASSERT (ValueArrayBackup != NULL);
    CopyMem (ValueArrayBackup, ValueArray, ValueCount);
    TempValue = *(UINT8 *) (ValueArray);
    if (ValueArray[0] != 0x00) {
      Initialized = TRUE;
    }

    for (Index = 0; ValueArray[Index] != 0x00; Index++)
      ;
    ValueCount = Index;
  } else {
    TempValue = *Value;
  }

  Count                 = 0;
  PopUpWidth            = 0;

  FirstOptionFoundFlag  = FALSE;

  StringPtr             = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);
  ASSERT (StringPtr);

  //
  // Initialization for "One of" pop-up menu
  //
  //
  // Get the number of one of options present and its size
  //
  for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; Index++) {
    if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP &&
        !MenuOption->Tags[Index].Suppress) {
      if (!FirstOptionFoundFlag) {
        FirstOptionFoundFlag  = TRUE;
      }

      Count++;
      Token = MenuOption->Tags[Index].Text;

      //
      // If this is an ordered list that is initialized
      //
      if (Initialized) {
        for (ValueBackup = (UINT8) MenuOption->TagIndex;
             MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_OP;
             ValueBackup++
            ) {
          if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) {
            StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle);
            break;
          }
        }
      } else {
        StringPtr = GetToken (Token, MenuOption->Handle);
      }

      if (StrLen (StringPtr) > PopUpWidth) {
        PopUpWidth = StrLen (StringPtr);
      }

      FreePool (StringPtr);
    }
  }
  //
  // Perform popup menu initialization.
  //
  PopUpMenuLines  = Count;
  PopUpWidth      = PopUpWidth + POPUP_PAD_SPACE_COUNT;

  SavedAttribute  = gST->ConOut->Mode->Attribute;
  gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);

  if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
    PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
  }

  Start           = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;
  End             = Start + PopUpWidth + POPUP_FRAME_WIDTH;
  Top             = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
  Bottom          = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT;

  MenuLinesInView = Bottom - Top - 1;
  if (MenuLinesInView >= PopUpMenuLines) {
    Top     = Top + (MenuLinesInView - PopUpMenuLines) / 2;
    Bottom  = Top + PopUpMenuLines + 1;
  } else {
    TempValue     = MenuOption->Tags[MenuOption->TagIndex + 1].Value;
    ShowDownArrow = TRUE;
  }

  TopOptionIndex    = 1;
  HighlightPosition = 0;
  do {
    if (Initialized) {
      for (Index = MenuOption->TagIndex, Index2 = 0; Index2 < ValueCount; Index++, Index2++) {
        //
        // Set the value for the item we are looking for
        //
        Count = ValueArrayBackup[Index2];

        //
        // If we hit the end of the Array, we are complete
        //
        if (Count == 0) {
          break;
        }

        if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
          for (ValueBackup = (UINT8) MenuOption->TagIndex;
               MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP;
               ValueBackup++
              ) {
            //
            // We just found what we are looking for
            //
            if (MenuOption->Tags[ValueBackup].Value == Count) {
              //
              // As long as the two indexes aren't the same, we have
              // two different op-codes we need to swap internally
              //
              if (Index != ValueBackup) {
                //
                // Backup destination tag, then copy source to destination, then copy backup to source location
                //
                CopyMem (&TagBackup, &MenuOption->Tags[Index], sizeof (EFI_TAG));
                CopyMem (&MenuOption->Tags[Index], &MenuOption->Tags[ValueBackup], sizeof (EFI_TAG));
                CopyMem (&MenuOption->Tags[ValueBackup], &TagBackup, sizeof (EFI_TAG));
              } else {
                //
                // If the indexes are the same, then the op-code is where he belongs
                //
              }
            }
          }
        } else {
          //
          // Since this wasn't an option op-code (likely the ordered list op-code) decerement Index2
          //
          Index2--;
        }
      }
    }
    //
    // Clear that portion of the screen
    //
    ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);

    //
    // Draw "One of" pop-up menu
    //
    Character = (CHAR16) BOXDRAW_DOWN_RIGHT;
    PrintCharAt (Start, Top, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = (CHAR16) GEOMETRICSHAPE_UP_TRIANGLE;
      } else {
        Character = (CHAR16) BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = (CHAR16) BOXDRAW_DOWN_LEFT;
    PrintChar (Character);
    Character = (CHAR16) BOXDRAW_VERTICAL;
    for (Index = Top + 1; Index < Bottom; Index++) {
      PrintCharAt (Start, Index, Character);
      PrintCharAt (End - 1, Index, Character);
    }
    //
    // Display the One of options
    //
    Index2 = Top + 1;
    for (Index = MenuOption->TagIndex + TopOptionIndex;
         (MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP) && (Index2 < Bottom);
         Index++
        ) {
      if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
        Token = MenuOption->Tags[Index].Text;
        if (Initialized) {
          for (ValueBackup = (UINT8) MenuOption->TagIndex;
               MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP;
               ValueBackup++
              ) {
            if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) {
              StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle);
              break;
            }
          }
        } else {
          ValueBackup = (UINT8) Index;
          StringPtr   = GetToken (Token, MenuOption->Handle);
        }
        //
        // 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;
          StrCat (StringPtr, (CHAR16 *) L"...");
        }
        //
        // Code to display the text should go here. Follwed by the [*]
        //
        if (MenuOption->Tags[ValueBackup].Suppress == TRUE) {
          //
          // Don't show the one, so decrease the Index2 for balance
          //
          Index2--;
        } else if (MenuOption->Tags[ValueBackup].GrayOut == TRUE) {
          //
          // Gray Out the one
          //
          gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | POPUP_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
        } else if (MenuOption->Tags[ValueBackup].Value == TempValue) {
          //
          // Highlight the selected one
          //
          gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
          HighlightPosition = Index2;
        } else {
          gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
          PrintStringAt (Start + 2, Index2, StringPtr);
        }

        FreePool (StringPtr);
        Index2 = Index2 + 1;
      }
    }

    Character = (CHAR16) BOXDRAW_UP_RIGHT;
    PrintCharAt (Start, Bottom, Character);
    for (Index = Start; Index + 2 < End; Index++) {
      if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
        Character = (CHAR16) GEOMETRICSHAPE_DOWN_TRIANGLE;
      } else {
        Character = (CHAR16) BOXDRAW_HORIZONTAL;
      }

      PrintChar (Character);
    }

    Character = (CHAR16) BOXDRAW_UP_LEFT;
    PrintChar (Character);
    //
    // Get User selection and change TempValue if necessary
    //
    //
    // Stop: One of pop-up menu
    //
    Key.UnicodeChar = CHAR_NULL;
    if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
      Key.ScanCode  = gDirection;
      gDirection    = 0;
      goto TheKey;
    }

    if (!KeyInitialized) {
      if (MenuOption->ThisTag->Operand == EFI_IFR_ONE_OF_OP) {
        *KeyValue = MenuOption->Tags[MenuOption->TagIndex + 1].Key;
      } else {
        *KeyValue = MenuOption->ThisTag->Key;
      }

      KeyInitialized = TRUE;
    }

    WaitForKeyStroke (&Key);

TheKey:
    switch (Key.UnicodeChar) {
    case '+':
    case '-':
      //
      // If an ordered list op-code, we will allow for a popup of +/- keys
      // to create an ordered list of items
      //
      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {
        if (Key.UnicodeChar == '+') {
          if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {
            //
            // Highlight reaches the top of the popup window, scroll one menu item.
            //
            TopOptionIndex--;
            ShowDownArrow = TRUE;
          }

          if (TopOptionIndex == 1) {
            ShowUpArrow = FALSE;
          }
        } else {
          if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {
            //
            // Highlight reaches the bottom of the popup window, scroll one menu item.
            //
            TopOptionIndex++;
            ShowUpArrow = TRUE;
          }

          if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {
            ShowDownArrow = FALSE;
          }
        }

        for (Index = MenuOption->TagIndex + TopOptionIndex;
             MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;
             Index++
            ) {
          if (MenuOption->Tags[Index].Operand == EFI_IFR_ORDERED_LIST_OP) {
            continue;
          }

          if (Key.UnicodeChar == '+') {
            TempIndex = Index - 1;
          } else {
            TempIndex = Index + 1;
          }
          //
          // Is this the current tag we are on?
          //
          if (MenuOption->Tags[Index].Value == TempValue) {
            //
            // Is this prior tag a valid choice?  If not, bail out
            //
            if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
              //
              // Copy the destination tag to the local variable
              //
              CopyMem (&TagBackup, &MenuOption->Tags[TempIndex], sizeof (EFI_TAG));
              //
              // Copy the current tag to the tag location before us
              //
              CopyMem (&MenuOption->Tags[TempIndex], &MenuOption->Tags[Index], sizeof (EFI_TAG));
              //
              // Copy the backed up tag to the current location
              //
              CopyMem (&MenuOption->Tags[Index], &TagBackup, sizeof (EFI_TAG));

              //
              // Adjust the array of values
              //
              for (Index = 0; Index < ValueCount; Index++) {
                if (ValueArrayBackup[Index] == (UINT8) TempValue) {
                  if (Key.UnicodeChar == '+') {
                    if (Index == 0) {
                      //
                      // It is the top of the array already
                      //
                      break;
                    }

                    TempIndex = Index - 1;
                  } else {
                    if ((Index + 1) == ValueCount) {
                      //
                      // It is the bottom of the array already
                      //
                      break;
                    }

                    TempIndex = Index + 1;
                  }

                  ValueBackup                 = ValueArrayBackup[TempIndex];
                  ValueArrayBackup[TempIndex] = ValueArrayBackup[Index];
                  ValueArrayBackup[Index]     = ValueBackup;
                  Initialized                 = TRUE;
                  break;
                }
              }
              break;
            } else {
              break;
            }
          }
        }
      }
      break;

    case CHAR_NULL:
      switch (Key.ScanCode) {
      case SCAN_UP:
      case SCAN_DOWN:
        if (Key.ScanCode == SCAN_UP) {
          if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) {
            //
            // Highlight reaches the top of the popup window, scroll one menu item.
            //
            TopOptionIndex--;
            ShowDownArrow = TRUE;
          }

          if (TopOptionIndex == 1) {
            ShowUpArrow = FALSE;
          }
        } else {
          if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) {
            //
            // Highlight reaches the bottom of the popup window, scroll one menu item.
            //
            TopOptionIndex++;
            ShowUpArrow = TRUE;
          }

          if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) {
            ShowDownArrow = FALSE;
          }
        }

        for (Index = MenuOption->TagIndex + TopOptionIndex;
             MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP;
             Index++
            ) {
          if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
            if (Initialized) {
              for (Index = 0; (ValueArrayBackup[Index] != TempValue) && (Index < ValueCount); Index++)
                ;

              //
              // Did we hit the end of the array?  Either get the first TempValue or the next one
              //
              if (Key.ScanCode == SCAN_UP) {
                if (Index == 0) {
                  TempValue = ValueArrayBackup[0];
                } else {
                  TempValue = ValueArrayBackup[Index - 1];
                }
              } else {
                if ((Index + 1) == ValueCount) {
                  TempValue = ValueArrayBackup[Index];
                } else {
                  TempValue = ValueArrayBackup[Index + 1];
                }
              }
              break;
            } else {
              if (Key.ScanCode == SCAN_UP) {
                TempIndex = Index - 1;

                //
                // Keep going until meets meaningful tag.
                //
                while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP  &&
                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP        &&
                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)
                       ||
                       (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP  &&
                         (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {
                  TempIndex--;
                }
              } else {
                TempIndex = Index + 1;

                //
                // Keep going until meets meaningful tag.
                //
                while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP  &&
                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP        &&
                         MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP)
                       ||
                       (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP  &&
                         (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) {
                  TempIndex++;
                }
              }
              //
              // The option value is the same as what is stored in NV store.  This is where we take action
              //
              if (MenuOption->Tags[Index].Value == TempValue) {
                //
                // Only if the previous op-code is an option can we select it, otherwise we are at the left-most option
                //
                if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) {
                  TempValue = MenuOption->Tags[TempIndex].Value;
                  *KeyValue = MenuOption->Tags[TempIndex].Key;
                } else {
                  TempValue = MenuOption->Tags[Index].Value;
                  *KeyValue = MenuOption->Tags[Index].Key;
                }
                break;
              }
            }
          }
        }
        break;

      case SCAN_ESC:
        gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
        if (ValueArrayBackup != NULL) {
          FreePool (ValueArrayBackup);
        }

        return EFI_DEVICE_ERROR;

      default:
        break;
      }

      break;

    case CHAR_CARRIAGE_RETURN:
      //
      // return the current selection
      //
      if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) {
        CopyMem (ValueArray, ValueArrayBackup, ValueCount);
        FreePool (ValueArrayBackup);
      } else {
        *Value = TempValue;
      }

      goto Done;

    default:
      break;
    }
  } while (1);

Done:
  gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
  return EFI_SUCCESS;
}

EFI_STATUS
WaitForKeyStroke (
  OUT  EFI_INPUT_KEY           *Key
  )
{
  EFI_STATUS  Status;

  do {
    UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
  } while (EFI_ERROR(Status));

  return Status;
}
