/** @file
Entry and initialization module for the browser.

Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FormDisplay.h"

//
// Search table for UiDisplayMenu()
//
SCAN_CODE_TO_SCREEN_OPERATION  gScanCodeToOperation[] = {
  {
    SCAN_UP,
    UiUp,
  },
  {
    SCAN_DOWN,
    UiDown,
  },
  {
    SCAN_PAGE_UP,
    UiPageUp,
  },
  {
    SCAN_PAGE_DOWN,
    UiPageDown,
  },
  {
    SCAN_ESC,
    UiReset,
  },
  {
    SCAN_LEFT,
    UiLeft,
  },
  {
    SCAN_RIGHT,
    UiRight,
  }
};

UINTN  mScanCodeNumber = ARRAY_SIZE (gScanCodeToOperation);

SCREEN_OPERATION_T0_CONTROL_FLAG  gScreenOperationToControlFlag[] = {
  {
    UiNoOperation,
    CfUiNoOperation,
  },
  {
    UiSelect,
    CfUiSelect,
  },
  {
    UiUp,
    CfUiUp,
  },
  {
    UiDown,
    CfUiDown,
  },
  {
    UiLeft,
    CfUiLeft,
  },
  {
    UiRight,
    CfUiRight,
  },
  {
    UiReset,
    CfUiReset,
  },
  {
    UiPageUp,
    CfUiPageUp,
  },
  {
    UiPageDown,
    CfUiPageDown
  },
  {
    UiHotKey,
    CfUiHotKey
  }
};

EFI_GUID  gDisplayEngineGuid = {
  0xE38C1029, 0xE38F, 0x45b9, { 0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62 }
};

BOOLEAN                      gMisMatch;
EFI_SCREEN_DESCRIPTOR        gStatementDimensions;
BOOLEAN                      mStatementLayoutIsChanged = TRUE;
USER_INPUT                   *gUserInput;
FORM_DISPLAY_ENGINE_FORM     *gFormData;
EFI_HII_HANDLE               gHiiHandle;
UINT16                       gDirection;
LIST_ENTRY                   gMenuOption;
DISPLAY_HIGHLIGHT_MENU_INFO  gHighligthMenuInfo = { 0 };
BOOLEAN                      mIsFirstForm       = TRUE;
FORM_ENTRY_INFO              gOldFormEntry      = { 0 };

//
// Browser Global Strings
//
CHAR16  *gReconnectConfirmChanges;
CHAR16  *gReconnectFail;
CHAR16  *gReconnectRequired;
CHAR16  *gChangesOpt;
CHAR16  *gFormNotFound;
CHAR16  *gNoSubmitIf;
CHAR16  *gBrowserError;
CHAR16  *gSaveFailed;
CHAR16  *gNoSubmitIfFailed;
CHAR16  *gSaveProcess;
CHAR16  *gSaveNoSubmitProcess;
CHAR16  *gDiscardChange;
CHAR16  *gJumpToFormSet;
CHAR16  *gCheckError;
CHAR16  *gPromptForData;
CHAR16  *gPromptForPassword;
CHAR16  *gPromptForNewPassword;
CHAR16  *gConfirmPassword;
CHAR16  *gConfirmError;
CHAR16  *gPassowordInvalid;
CHAR16  *gPressEnter;
CHAR16  *gEmptyString;
CHAR16  *gMiniString;
CHAR16  *gOptionMismatch;
CHAR16  *gFormSuppress;
CHAR16  *gProtocolNotFound;
CHAR16  *gConfirmDefaultMsg;
CHAR16  *gConfirmSubmitMsg;
CHAR16  *gConfirmDiscardMsg;
CHAR16  *gConfirmResetMsg;
CHAR16  *gConfirmExitMsg;
CHAR16  *gConfirmSubmitMsg2nd;
CHAR16  *gConfirmDefaultMsg2nd;
CHAR16  *gConfirmResetMsg2nd;
CHAR16  *gConfirmExitMsg2nd;
CHAR16  *gConfirmOpt;
CHAR16  *gConfirmOptYes;
CHAR16  *gConfirmOptNo;
CHAR16  *gConfirmOptOk;
CHAR16  *gConfirmOptCancel;
CHAR16  *gYesOption;
CHAR16  *gNoOption;
CHAR16  *gOkOption;
CHAR16  *gCancelOption;
CHAR16  *gErrorPopup;
CHAR16  *gWarningPopup;
CHAR16  *gInfoPopup;
CHAR16  *gConfirmMsgConnect;
CHAR16  *gConfirmMsgEnd;
CHAR16  *gPasswordUnsupported;
CHAR16  gModalSkipColumn;
CHAR16  gPromptBlockWidth;
CHAR16  gOptionBlockWidth;
CHAR16  gHelpBlockWidth;
CHAR16  *mUnknownString;

FORM_DISPLAY_DRIVER_PRIVATE_DATA  mPrivateData = {
  FORM_DISPLAY_DRIVER_SIGNATURE,
  NULL,
  {
    FormDisplay,
    DriverClearDisplayPage,
    ConfirmDataChange
  },
  {
    EFI_HII_POPUP_PROTOCOL_REVISION,
    CreatePopup
  }
};

/**
  Get the string based on the StringId and HII Package List Handle.

  @param  Token                  The String's ID.
  @param  HiiHandle              The package list in the HII database to search for
                                 the specified string.

  @return The output string.

**/
CHAR16 *
GetToken (
  IN  EFI_STRING_ID   Token,
  IN  EFI_HII_HANDLE  HiiHandle
  )
{
  EFI_STRING  String;

  String = HiiGetString (HiiHandle, Token, NULL);
  if (String == NULL) {
    String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);
    ASSERT (String != NULL);
  }

  return (CHAR16 *)String;
}

/**
  Initialize the HII String Token to the correct values.

**/
VOID
InitializeDisplayStrings (
  VOID
  )
{
  gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle);
  mUnknownString           = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);
  gSaveFailed              = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
  gNoSubmitIfFailed        = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle);
  gReconnectFail           = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle);
  gReconnectRequired       = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle);
  gChangesOpt              = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle);
  gSaveProcess             = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle);
  gSaveNoSubmitProcess     = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle);
  gDiscardChange           = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle);
  gJumpToFormSet           = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_JUMP), gHiiHandle);
  gCheckError              = GetToken (STRING_TOKEN (DISCARD_OR_CHECK_CHECK), gHiiHandle);
  gPromptForData           = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
  gPromptForPassword       = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
  gPromptForNewPassword    = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
  gConfirmPassword         = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
  gConfirmError            = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
  gPassowordInvalid        = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
  gPressEnter              = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
  gEmptyString             = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
  gMiniString              = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
  gOptionMismatch          = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
  gFormSuppress            = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
  gProtocolNotFound        = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
  gFormNotFound            = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);
  gNoSubmitIf              = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);
  gBrowserError            = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);
  gConfirmDefaultMsg       = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle);
  gConfirmDiscardMsg       = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle);
  gConfirmSubmitMsg        = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle);
  gConfirmResetMsg         = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle);
  gConfirmExitMsg          = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle);
  gConfirmDefaultMsg2nd    = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle);
  gConfirmSubmitMsg2nd     = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle);
  gConfirmResetMsg2nd      = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle);
  gConfirmExitMsg2nd       = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle);
  gConfirmOpt              = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);
  gConfirmOptYes           = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);
  gConfirmOptNo            = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);
  gConfirmOptOk            = GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gHiiHandle);
  gConfirmOptCancel        = GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL), gHiiHandle);
  gYesOption               = GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION), gHiiHandle);
  gNoOption                = GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION), gHiiHandle);
  gOkOption                = GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION), gHiiHandle);
  gCancelOption            = GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTION), gHiiHandle);
  gErrorPopup              = GetToken (STRING_TOKEN (ERROR_POPUP_STRING), gHiiHandle);
  gWarningPopup            = GetToken (STRING_TOKEN (WARNING_POPUP_STRING), gHiiHandle);
  gInfoPopup               = GetToken (STRING_TOKEN (INFO_POPUP_STRING), gHiiHandle);
  gConfirmMsgConnect       = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);
  gConfirmMsgEnd           = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);
  gPasswordUnsupported     = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED), gHiiHandle);
}

/**
  Free up the resource allocated for all strings required
  by Setup Browser.

**/
VOID
FreeDisplayStrings (
  VOID
  )
{
  FreePool (mUnknownString);
  FreePool (gEmptyString);
  FreePool (gSaveFailed);
  FreePool (gNoSubmitIfFailed);
  FreePool (gReconnectFail);
  FreePool (gReconnectRequired);
  FreePool (gChangesOpt);
  FreePool (gReconnectConfirmChanges);
  FreePool (gSaveProcess);
  FreePool (gSaveNoSubmitProcess);
  FreePool (gDiscardChange);
  FreePool (gJumpToFormSet);
  FreePool (gCheckError);
  FreePool (gPromptForData);
  FreePool (gPromptForPassword);
  FreePool (gPromptForNewPassword);
  FreePool (gConfirmPassword);
  FreePool (gConfirmError);
  FreePool (gPassowordInvalid);
  FreePool (gPressEnter);
  FreePool (gMiniString);
  FreePool (gOptionMismatch);
  FreePool (gFormSuppress);
  FreePool (gProtocolNotFound);
  FreePool (gBrowserError);
  FreePool (gNoSubmitIf);
  FreePool (gFormNotFound);
  FreePool (gConfirmDefaultMsg);
  FreePool (gConfirmSubmitMsg);
  FreePool (gConfirmDiscardMsg);
  FreePool (gConfirmResetMsg);
  FreePool (gConfirmExitMsg);
  FreePool (gConfirmDefaultMsg2nd);
  FreePool (gConfirmSubmitMsg2nd);
  FreePool (gConfirmResetMsg2nd);
  FreePool (gConfirmExitMsg2nd);
  FreePool (gConfirmOpt);
  FreePool (gConfirmOptYes);
  FreePool (gConfirmOptNo);
  FreePool (gConfirmOptOk);
  FreePool (gConfirmOptCancel);
  FreePool (gYesOption);
  FreePool (gNoOption);
  FreePool (gOkOption);
  FreePool (gCancelOption);
  FreePool (gErrorPopup);
  FreePool (gWarningPopup);
  FreePool (gInfoPopup);
  FreePool (gConfirmMsgConnect);
  FreePool (gConfirmMsgEnd);
  FreePool (gPasswordUnsupported);
}

/**
  Get prompt string id from the opcode data buffer.

  @param  OpCode                 The input opcode buffer.

  @return The prompt string id.

**/
EFI_STRING_ID
GetPrompt (
  IN EFI_IFR_OP_HEADER  *OpCode
  )
{
  EFI_IFR_STATEMENT_HEADER  *Header;

  if (OpCode->Length <= sizeof (EFI_IFR_OP_HEADER)) {
    return 0;
  }

  Header = (EFI_IFR_STATEMENT_HEADER  *)(OpCode + 1);

  return Header->Prompt;
}

/**
  Get the supported width for a particular op-code

  @param  MenuOption             The menu option.
  @param  AdjustWidth            The width which is saved for the space.

  @return Returns the number of CHAR16 characters that is support.

**/
UINT16
GetWidth (
  IN  UI_MENU_OPTION  *MenuOption,
  OUT UINT16          *AdjustWidth
  )
{
  CHAR16                         *String;
  UINTN                          Size;
  EFI_IFR_TEXT                   *TextOp;
  UINT16                         ReturnWidth;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;

  Statement = MenuOption->ThisTag;

  //
  // For modal form, clean the entire row.
  //
  if ((gFormData->Attribute & HII_DISPLAY_MODAL) != 0) {
    if (AdjustWidth  != NULL) {
      *AdjustWidth = LEFT_SKIPPED_COLUMNS;
    }

    return (UINT16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gModalSkipColumn + LEFT_SKIPPED_COLUMNS));
  }

  Size = 0;

  //
  // See if the second text parameter is really NULL
  //
  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
    TextOp = (EFI_IFR_TEXT *)Statement->OpCode;
    if (TextOp->TextTwo != 0) {
      String = GetToken (TextOp->TextTwo, gFormData->HiiHandle);
      Size   = StrLen (String);
      FreePool (String);
    }
  }

  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
      //
      // Allow a wide display if text op-code and no secondary text op-code
      //
      ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
      )
  {
    //
    // Return the space width.
    //
    if (AdjustWidth != NULL) {
      *AdjustWidth = 2;
    }

    //
    // Keep consistent with current behavior.
    //
    ReturnWidth = (UINT16)(gPromptBlockWidth + gOptionBlockWidth - 2);
  } else {
    if (AdjustWidth != NULL) {
      *AdjustWidth = 1;
    }

    ReturnWidth =  (UINT16)(gPromptBlockWidth - 1);
  }

  //
  // For nest in statement, should the subtitle indent.
  //
  if (MenuOption->NestInStatement) {
    ReturnWidth -= SUBTITLE_INDENT;
  }

  return ReturnWidth;
}

/**
  Will copy LineWidth amount of a string in the OutputString buffer and return the
  number of CHAR16 characters that were copied into the OutputString buffer.
  The output string format is:
    Glyph Info + String info + '\0'.

  In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.

  @param  InputString            String description for this option.
  @param  LineWidth              Width of the desired string to extract in CHAR16
                                 characters
  @param  GlyphWidth             The glyph width of the begin of the char in the string.
  @param  Index                  Where in InputString to start the copy process
  @param  OutputString           Buffer to copy the string into

  @return Returns the number of CHAR16 characters that were copied into the OutputString
  buffer, include extra glyph info and '\0' info.

**/
UINT16
GetLineByWidth (
  IN      CHAR16  *InputString,
  IN      UINT16  LineWidth,
  IN OUT  UINT16  *GlyphWidth,
  IN OUT  UINTN   *Index,
  OUT     CHAR16  **OutputString
  )
{
  UINT16   StrOffset;
  UINT16   GlyphOffset;
  UINT16   OriginalGlyphWidth;
  BOOLEAN  ReturnFlag;
  UINT16   LastSpaceOffset;
  UINT16   LastGlyphWidth;

  if ((InputString == NULL) || (Index == NULL) || (OutputString == NULL)) {
    return 0;
  }

  if ((LineWidth == 0) || (*GlyphWidth == 0)) {
    return 0;
  }

  //
  // Save original glyph width.
  //
  OriginalGlyphWidth = *GlyphWidth;
  LastGlyphWidth     = OriginalGlyphWidth;
  ReturnFlag         = FALSE;
  LastSpaceOffset    = 0;

  //
  // NARROW_CHAR can not be printed in screen, so if a line only contain  the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line  in Screen.
  // To avoid displaying this  empty line in screen,  just skip  the two CHARs here.
  //
  if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
    *Index = *Index + 2;
  }

  //
  // Fast-forward the string and see if there is a carriage-return in the string
  //
  for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
    switch (InputString[*Index + StrOffset]) {
      case NARROW_CHAR:
        *GlyphWidth = 1;
        break;

      case WIDE_CHAR:
        *GlyphWidth = 2;
        break;

      case CHAR_CARRIAGE_RETURN:
      case CHAR_LINEFEED:
      case CHAR_NULL:
        ReturnFlag = TRUE;
        break;

      default:
        GlyphOffset = GlyphOffset + *GlyphWidth;

        //
        // Record the last space info in this line. Will be used in rewind.
        //
        if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
          LastSpaceOffset = StrOffset;
          LastGlyphWidth  = *GlyphWidth;
        }

        break;
    }

    if (ReturnFlag) {
      break;
    }
  }

  //
  // Rewind the string from the maximum size until we see a space to break the line
  //
  if (GlyphOffset > LineWidth) {
    //
    // Rewind the string to last space char in this line.
    //
    if (LastSpaceOffset != 0) {
      StrOffset   = LastSpaceOffset;
      *GlyphWidth = LastGlyphWidth;
    } else {
      //
      // Roll back to last char in the line width.
      //
      StrOffset--;
    }
  }

  //
  // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
  //
  if ((StrOffset == 0) && (InputString[*Index + StrOffset] == CHAR_NULL)) {
    return 0;
  }

  //
  // Need extra glyph info and '\0' info, so +2.
  //
  *OutputString = AllocateZeroPool ((StrOffset + 2) * sizeof (CHAR16));
  if (*OutputString == NULL) {
    return 0;
  }

  //
  // Save the glyph info at the begin of the string, will used by Print function.
  //
  if (OriginalGlyphWidth == 1) {
    *(*OutputString) = NARROW_CHAR;
  } else {
    *(*OutputString) = WIDE_CHAR;
  }

  CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof (CHAR16));

  if (InputString[*Index + StrOffset] == CHAR_SPACE) {
    //
    // Skip the space info at the begin of next line.
    //
    *Index = (UINT16)(*Index + StrOffset + 1);
  } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
    //
    // Skip the /n or /n/r info.
    //
    if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
      *Index = (UINT16)(*Index + StrOffset + 2);
    } else {
      *Index = (UINT16)(*Index + StrOffset + 1);
    }
  } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
    //
    // Skip the /r or /r/n info.
    //
    if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
      *Index = (UINT16)(*Index + StrOffset + 2);
    } else {
      *Index = (UINT16)(*Index + StrOffset + 1);
    }
  } else {
    *Index = (UINT16)(*Index + StrOffset);
  }

  //
  // Include extra glyph info and '\0' info, so +2.
  //
  return StrOffset + 2;
}

/**
  Add one menu option by specified description and context.

  @param  Statement              Statement of this Menu Option.
  @param  MenuItemCount          The index for this Option in the Menu.
  @param  NestIn                 Whether this statement is nest in another statement.

**/
VOID
UiAddMenuOption (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *Statement,
  IN UINT16                         *MenuItemCount,
  IN BOOLEAN                        NestIn
  )
{
  UI_MENU_OPTION  *MenuOption;
  UINTN           Index;
  UINTN           Count;
  UINT16          NumberOfLines;
  UINT16          GlyphWidth;
  UINT16          Width;
  UINTN           ArrayEntry;
  CHAR16          *OutputString;
  EFI_STRING_ID   PromptId;

  NumberOfLines = 1;
  ArrayEntry    = 0;
  GlyphWidth    = 1;
  Count         = 1;
  MenuOption    = NULL;

  PromptId = GetPrompt (Statement->OpCode);
  ASSERT (PromptId != 0);

  if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {
    Count = 3;
  }

  for (Index = 0; Index < Count; Index++) {
    MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
    ASSERT (MenuOption);

    MenuOption->Signature       = UI_MENU_OPTION_SIGNATURE;
    MenuOption->Description     = GetToken (PromptId, gFormData->HiiHandle);
    MenuOption->Handle          = gFormData->HiiHandle;
    MenuOption->ThisTag         = Statement;
    MenuOption->NestInStatement = NestIn;
    MenuOption->EntryNumber     = *MenuItemCount;

    MenuOption->Sequence = Index;

    if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {
      MenuOption->GrayOut = TRUE;
    } else {
      MenuOption->GrayOut = FALSE;
    }

    if (((Statement->Attribute & HII_DISPLAY_LOCK) != 0) || ((gFormData->Attribute & HII_DISPLAY_LOCK) != 0)) {
      MenuOption->GrayOut = TRUE;
    }

    //
    // If the form or the question has the lock attribute, deal same as grayout.
    //
    if (((gFormData->Attribute & HII_DISPLAY_LOCK) != 0) || ((Statement->Attribute & HII_DISPLAY_LOCK) != 0)) {
      MenuOption->GrayOut = TRUE;
    }

    switch (Statement->OpCode->OpCode) {
      case EFI_IFR_ORDERED_LIST_OP:
      case EFI_IFR_ONE_OF_OP:
      case EFI_IFR_NUMERIC_OP:
      case EFI_IFR_TIME_OP:
      case EFI_IFR_DATE_OP:
      case EFI_IFR_CHECKBOX_OP:
      case EFI_IFR_PASSWORD_OP:
      case EFI_IFR_STRING_OP:
        //
        // User could change the value of these items
        //
        MenuOption->IsQuestion = TRUE;
        break;
      case EFI_IFR_TEXT_OP:
        if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
          //
          // Initializing GrayOut option as TRUE for Text setup options
          // so that those options will be Gray in colour and un selectable.
          //
          MenuOption->GrayOut = TRUE;
        }

        break;
      default:
        MenuOption->IsQuestion = FALSE;
        break;
    }

    if ((Statement->Attribute & HII_DISPLAY_READONLY) != 0) {
      MenuOption->ReadOnly = TRUE;
      if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
        MenuOption->GrayOut = TRUE;
      }
    }

    if ((Index == 0) &&
        (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) &&
        (Statement->OpCode->OpCode != EFI_IFR_TIME_OP))
    {
      Width = GetWidth (MenuOption, NULL);
      for ( ; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &ArrayEntry, &OutputString) != 0x0000;) {
        //
        // If there is more string to process print on the next row and increment the Skip value
        //
        if (StrLen (&MenuOption->Description[ArrayEntry]) != 0) {
          NumberOfLines++;
        }

        FreePool (OutputString);
      }
    } else {
      //
      // Add three MenuOptions for Date/Time
      // Data format :      [01/02/2004]      [11:22:33]
      // Line number :        0  0    1         0  0  1
      //
      NumberOfLines = 0;
    }

    if (Index == 2) {
      //
      // Override LineNumber for the MenuOption in Date/Time sequence
      //
      MenuOption->Skip = 1;
    } else {
      MenuOption->Skip = NumberOfLines;
    }

    InsertTailList (&gMenuOption, &MenuOption->Link);
  }

  (*MenuItemCount)++;
}

/**
  Create the menu list base on the form data info.

**/
VOID
ConvertStatementToMenu (
  VOID
  )
{
  UINT16                         MenuItemCount;
  LIST_ENTRY                     *Link;
  LIST_ENTRY                     *NestLink;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  FORM_DISPLAY_ENGINE_STATEMENT  *NestStatement;

  MenuItemCount = 0;
  InitializeListHead (&gMenuOption);

  Link = GetFirstNode (&gFormData->StatementListHead);
  while (!IsNull (&gFormData->StatementListHead, Link)) {
    Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
    Link      = GetNextNode (&gFormData->StatementListHead, Link);

    //
    // Skip the opcode not recognized by Display core.
    //
    if (Statement->OpCode->OpCode == EFI_IFR_GUID_OP) {
      continue;
    }

    UiAddMenuOption (Statement, &MenuItemCount, FALSE);

    //
    // Check the statement nest in this host statement.
    //
    NestLink = GetFirstNode (&Statement->NestStatementList);
    while (!IsNull (&Statement->NestStatementList, NestLink)) {
      NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);
      NestLink      = GetNextNode (&Statement->NestStatementList, NestLink);

      //
      // Skip the opcode not recognized by Display core.
      //
      if (NestStatement->OpCode->OpCode == EFI_IFR_GUID_OP) {
        continue;
      }

      UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);
    }
  }
}

/**
  Count the storage space of a Unicode string.

  This function handles the Unicode string with NARROW_CHAR
  and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
  does not count in the resultant output. If a WIDE_CHAR is
  hit, then 2 Unicode character will consume an output storage
  space with size of CHAR16 till a NARROW_CHAR is hit.

  If String is NULL, then ASSERT ().

  @param String          The input string to be counted.

  @return Storage space for the input string.

**/
UINTN
GetStringWidth (
  IN CHAR16  *String
  )
{
  UINTN  Index;
  UINTN  Count;
  UINTN  IncrementValue;

  ASSERT (String != NULL);
  if (String == NULL) {
    return 0;
  }

  Index          = 0;
  Count          = 0;
  IncrementValue = 1;

  do {
    //
    // Advance to the null-terminator or to the first width directive
    //
    for ( ;
          (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
          Index++, Count = Count + IncrementValue
          )
    {
    }

    //
    // We hit the null-terminator, we now have a count
    //
    if (String[Index] == 0) {
      break;
    }

    //
    // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
    // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
    //
    if (String[Index] == NARROW_CHAR) {
      //
      // Skip to the next character
      //
      Index++;
      IncrementValue = 1;
    } else {
      //
      // Skip to the next character
      //
      Index++;
      IncrementValue = 2;
    }
  } while (String[Index] != 0);

  //
  // Increment by one to include the null-terminator in the size
  //
  Count++;

  return Count * sizeof (CHAR16);
}

/**
  Base on the input option string to update the skip value for a menu option.

  @param  MenuOption             The MenuOption to be checked.
  @param  OptionString           The input option string.

**/
VOID
UpdateSkipInfoForMenu (
  IN UI_MENU_OPTION  *MenuOption,
  IN CHAR16          *OptionString
  )
{
  UINTN   Index;
  UINT16  Width;
  UINTN   Row;
  CHAR16  *OutputString;
  UINT16  GlyphWidth;

  Width      = (UINT16)gOptionBlockWidth - 1;
  GlyphWidth = 1;
  Row        = 1;

  for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
    if (StrLen (&OptionString[Index]) != 0) {
      Row++;
    }

    FreePool (OutputString);
  }

  if ((Row > MenuOption->Skip) &&
      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
      (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP))
  {
    MenuOption->Skip = Row;
  }
}

/**
  Update display lines for a Menu Option.

  @param  MenuOption             The MenuOption to be checked.

**/
VOID
UpdateOptionSkipLines (
  IN UI_MENU_OPTION  *MenuOption
  )
{
  CHAR16  *OptionString;

  OptionString = NULL;

  ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
  if (OptionString != NULL) {
    UpdateSkipInfoForMenu (MenuOption, OptionString);

    FreePool (OptionString);
  }

  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT *)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
    OptionString = GetToken (((EFI_IFR_TEXT *)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);

    if (OptionString != NULL) {
      UpdateSkipInfoForMenu (MenuOption, OptionString);

      FreePool (OptionString);
    }
  }
}

/**
  Check whether this Menu Option could be print.

  Check Prompt string, option string or text two string not NULL.

  This is an internal function.

  @param  MenuOption             The MenuOption to be checked.

  @retval TRUE                   This Menu Option is printable.
  @retval FALSE                  This Menu Option could not be printable.

**/
BOOLEAN
PrintableMenu (
  UI_MENU_OPTION  *MenuOption
  )
{
  EFI_STATUS  Status;
  EFI_STRING  OptionString;

  OptionString = NULL;

  if (MenuOption->Description[0] != '\0') {
    return TRUE;
  }

  Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  if ((OptionString != NULL) && (OptionString[0] != '\0')) {
    FreePool (OptionString);
    return TRUE;
  }

  if ((MenuOption->ThisTag->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT *)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
    OptionString = GetToken (((EFI_IFR_TEXT *)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
    ASSERT (OptionString != NULL);
    if (OptionString[0] != '\0') {
      FreePool (OptionString);
      return TRUE;
    }
  }

  return FALSE;
}

/**
  Check whether this Menu Option could be highlighted.

  This is an internal function.

  @param  MenuOption             The MenuOption to be checked.

  @retval TRUE                   This Menu Option is selectable.
  @retval FALSE                  This Menu Option could not be selected.

**/
BOOLEAN
IsSelectable (
  UI_MENU_OPTION  *MenuOption
  )
{
  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
      MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption))
  {
    return FALSE;
  } else {
    return TRUE;
  }
}

/**
  Move to next selectable statement.

  This is an internal function.

  @param  GoUp                   The navigation direction. TRUE: up, FALSE: down.
  @param  CurrentPosition        Current position.
  @param  GapToTop               Gap position to top or bottom.
  @param  FindInForm             Whether find menu in current form or beyond.

  @return The row distance from current MenuOption to next selectable MenuOption.

  @retval -1       Reach the begin of the menu, still can't find the selectable menu.
  @retval Value    Find the selectable menu, maybe the truly selectable, maybe the
                   first menu showing beyond current form or last menu showing in
                   current form.
                   The value is the line number between the new selected menu and the
                   current select menu, not include the new selected menu.

**/
INTN
MoveToNextStatement (
  IN     BOOLEAN     GoUp,
  IN OUT LIST_ENTRY  **CurrentPosition,
  IN     UINTN       GapToTop,
  IN     BOOLEAN     FindInForm
  )
{
  INTN            Distance;
  LIST_ENTRY      *Pos;
  UI_MENU_OPTION  *NextMenuOption;
  UI_MENU_OPTION  *PreMenuOption;

  Distance = 0;
  Pos      = *CurrentPosition;

  if (Pos == &gMenuOption) {
    return -1;
  }

  PreMenuOption = MENU_OPTION_FROM_LINK (Pos);

  while (TRUE) {
    NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
    //
    // NextMenuOption->Row == 0 means this menu has not calculate
    // the NextMenuOption->Skip value yet, just calculate here.
    //
    if (NextMenuOption->Row == 0) {
      UpdateOptionSkipLines (NextMenuOption);
    }

    //
    // Check whether the menu is beyond current showing form,
    // return the first one beyond the showing form.
    //
    if ((UINTN)Distance + NextMenuOption->Skip > GapToTop) {
      if (FindInForm) {
        NextMenuOption = PreMenuOption;
      }

      break;
    }

    //
    // return the selectable menu in the showing form.
    //
    if (IsSelectable (NextMenuOption)) {
      break;
    }

    Distance += NextMenuOption->Skip;

    //
    // Arrive at begin of the menu list.
    //
    if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
      Distance = -1;
      break;
    }

    Pos           = (GoUp ? Pos->BackLink : Pos->ForwardLink);
    PreMenuOption = NextMenuOption;
  }

  *CurrentPosition = &NextMenuOption->Link;
  return Distance;
}

/**
  Process option string for date/time opcode.

  @param  MenuOption              Menu option point to date/time.
  @param  OptionString            Option string input for process.
  @param  AddOptCol               Whether need to update MenuOption->OptCol.

**/
VOID
ProcessStringForDateTime (
  UI_MENU_OPTION  *MenuOption,
  CHAR16          *OptionString,
  BOOLEAN         AddOptCol
  )
{
  UINTN                          Index;
  UINTN                          Count;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  EFI_IFR_DATE                   *Date;
  EFI_IFR_TIME                   *Time;

  ASSERT (MenuOption != NULL && OptionString != NULL);

  Statement = MenuOption->ThisTag;
  Date      = NULL;
  Time      = NULL;
  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
    Date = (EFI_IFR_DATE *)Statement->OpCode;
  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
    Time = (EFI_IFR_TIME *)Statement->OpCode;
  } else {
    // If not in a time/date opcode, exit.
    return;
  }

  //
  // If leading spaces on OptionString - remove the spaces
  //
  for (Index = 0; OptionString[Index] == L' '; Index++) {
    //
    // Base on the blockspace to get the option column info.
    //
    if (AddOptCol) {
      MenuOption->OptCol++;
    }
  }

  for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
    OptionString[Count] = OptionString[Index];
    Count++;
  }

  OptionString[Count] = CHAR_NULL;

  //
  // Enable to suppress field in the opcode base on the flag.
  //
  if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
    //
    // OptionString format is: <**:  **: ****>
    //                        |month|day|year|
    //                          4     3    5
    //
    if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
      //
      // At this point, only "<**:" in the optionstring.
      // Clean the day's ** field, after clean, the format is "<  :"
      //
      SetUnicodeMem (&OptionString[1], 2, L' ');
    } else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
      //
      // At this point, only "**:" in the optionstring.
      // Clean the month's "**" field, after clean, the format is "  :"
      //
      SetUnicodeMem (&OptionString[0], 2, L' ');
    } else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
      //
      // At this point, only "****>" in the optionstring.
      // Clean the year's "****" field, after clean, the format is "  >"
      //
      SetUnicodeMem (&OptionString[0], 4, L' ');
    }
  } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
    //
    // OptionString format is: <**:  **:    **>
    //                        |hour|minute|second|
    //                          4     3      3
    //
    if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
      //
      // At this point, only "<**:" in the optionstring.
      // Clean the hour's ** field, after clean, the format is "<  :"
      //
      SetUnicodeMem (&OptionString[1], 2, L' ');
    } else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
      //
      // At this point, only "**:" in the optionstring.
      // Clean the minute's "**" field, after clean, the format is "  :"
      //
      SetUnicodeMem (&OptionString[0], 2, L' ');
    } else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
      //
      // At this point, only "**>" in the optionstring.
      // Clean the second's "**" field, after clean, the format is "  >"
      //
      SetUnicodeMem (&OptionString[0], 2, L' ');
    }
  }
}

/**
  Adjust Data and Time position accordingly.
  Data format :      [01/02/2004]      [11:22:33]
  Line number :        0  0    1         0  0  1

  This is an internal function.

  @param  DirectionUp            the up or down direction. False is down. True is
                                 up.
  @param  CurrentPosition        Current position. On return: Point to the last
                                 Option (Year or Second) if up; Point to the first
                                 Option (Month or Hour) if down.

  @return Return line number to pad. It is possible that we stand on a zero-advance
  @return data or time opcode, so pad one line when we judge if we are going to scroll outside.

**/
UINTN
AdjustDateAndTimePosition (
  IN     BOOLEAN     DirectionUp,
  IN OUT LIST_ENTRY  **CurrentPosition
  )
{
  UINTN           Count;
  LIST_ENTRY      *NewPosition;
  UI_MENU_OPTION  *MenuOption;
  UINTN           PadLineNumber;

  PadLineNumber = 0;
  NewPosition   = *CurrentPosition;
  MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);

  if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
      (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP))
  {
    //
    // Calculate the distance from current position to the last Date/Time MenuOption
    //
    Count = 0;
    while (MenuOption->Skip == 0) {
      Count++;
      NewPosition   = NewPosition->ForwardLink;
      MenuOption    = MENU_OPTION_FROM_LINK (NewPosition);
      PadLineNumber = 1;
    }

    NewPosition = *CurrentPosition;
    if (DirectionUp) {
      //
      // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
      // to be one that back to the previous set of MenuOptions, we need to advance to the first
      // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
      // checking can be done.
      //
      while (Count++ < 2) {
        NewPosition = NewPosition->BackLink;
      }
    } else {
      //
      // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
      // to be one that progresses to the next set of MenuOptions, we need to advance to the last
      // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
      // checking can be done.
      //
      while (Count-- > 0) {
        NewPosition = NewPosition->ForwardLink;
      }
    }

    *CurrentPosition = NewPosition;
  }

  return PadLineNumber;
}

/**
  Get step info from numeric opcode.

  @param[in] OpCode     The input numeric op code.

  @return step info for this opcode.
**/
UINT64
GetFieldFromNum (
  IN  EFI_IFR_OP_HEADER  *OpCode
  )
{
  EFI_IFR_NUMERIC  *NumericOp;
  UINT64           Step;

  NumericOp = (EFI_IFR_NUMERIC *)OpCode;

  switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
    case EFI_IFR_NUMERIC_SIZE_1:
      Step = NumericOp->data.u8.Step;
      break;

    case EFI_IFR_NUMERIC_SIZE_2:
      Step = NumericOp->data.u16.Step;
      break;

    case EFI_IFR_NUMERIC_SIZE_4:
      Step = NumericOp->data.u32.Step;
      break;

    case EFI_IFR_NUMERIC_SIZE_8:
      Step = NumericOp->data.u64.Step;
      break;

    default:
      Step = 0;
      break;
  }

  return Step;
}

/**
  Find the registered HotKey based on KeyData.

  @param[in] KeyData     A pointer to a buffer that describes the keystroke
                         information for the hot key.

  @return The registered HotKey context. If no found, NULL will return.
**/
BROWSER_HOT_KEY *
GetHotKeyFromRegisterList (
  IN EFI_INPUT_KEY  *KeyData
  )
{
  LIST_ENTRY       *Link;
  BROWSER_HOT_KEY  *HotKey;

  Link = GetFirstNode (&gFormData->HotKeyListHead);
  while (!IsNull (&gFormData->HotKeyListHead, Link)) {
    HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);

    if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {
      return HotKey;
    }

    Link = GetNextNode (&gFormData->HotKeyListHead, Link);
  }

  return NULL;
}

/**
  Determine if the menu is the last menu that can be selected.

  This is an internal function.

  @param  Direction              The scroll direction. False is down. True is up.
  @param  CurrentPos             The current focus.

  @return FALSE -- the menu isn't the last menu that can be selected.
  @return TRUE  -- the menu is the last menu that can be selected.

**/
BOOLEAN
ValueIsScroll (
  IN  BOOLEAN     Direction,
  IN  LIST_ENTRY  *CurrentPos
  )
{
  LIST_ENTRY  *Temp;

  Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;

  if (Temp == &gMenuOption) {
    return TRUE;
  }

  return FALSE;
}

/**
  Wait for a given event to fire, or for an optional timeout to expire.

  @param  Event                  The event to wait for

  @retval UI_EVENT_TYPE          The type of the event which is trigged.

**/
UI_EVENT_TYPE
UiWaitForEvent (
  IN EFI_EVENT  Event
  )
{
  EFI_STATUS     Status;
  UINTN          Index;
  UINTN          EventNum;
  UINT64         Timeout;
  EFI_EVENT      TimerEvent;
  EFI_EVENT      WaitList[3];
  UI_EVENT_TYPE  EventType;

  TimerEvent = NULL;
  Timeout    = FormExitTimeout (gFormData);

  if (Timeout != 0) {
    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);

    //
    // Set the timer event
    //
    gBS->SetTimer (
           TimerEvent,
           TimerRelative,
           Timeout
           );
  }

  WaitList[0] = Event;
  EventNum    = 1;
  if (gFormData->FormRefreshEvent != NULL) {
    WaitList[EventNum] = gFormData->FormRefreshEvent;
    EventNum++;
  }

  if (Timeout != 0) {
    WaitList[EventNum] = TimerEvent;
    EventNum++;
  }

  Status = gBS->WaitForEvent (EventNum, WaitList, &Index);
  ASSERT_EFI_ERROR (Status);

  switch (Index) {
    case 0:
      EventType = UIEventKey;
      break;

    case 1:
      if (gFormData->FormRefreshEvent != NULL) {
        EventType = UIEventDriver;
      } else {
        ASSERT (Timeout != 0 && EventNum == 2);
        EventType = UIEventTimeOut;
      }

      break;

    default:
      ASSERT (Index == 2 && EventNum == 3);
      EventType = UIEventTimeOut;
      break;
  }

  if (Timeout != 0) {
    gBS->CloseEvent (TimerEvent);
  }

  return EventType;
}

/**
  Get question id info from the input opcode header.

  @param  OpCode                 The input opcode header pointer.

  @retval                        The question id for this opcode.

**/
EFI_QUESTION_ID
GetQuestionIdInfo (
  IN   EFI_IFR_OP_HEADER  *OpCode
  )
{
  EFI_IFR_QUESTION_HEADER  *QuestionHeader;

  if (OpCode->Length < sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER)) {
    return 0;
  }

  QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *)OpCode + sizeof (EFI_IFR_OP_HEADER));

  return QuestionHeader->QuestionId;
}

/**
  Find the top of screen menu base on the current menu.

  @param  CurPos                 Current input menu.
  @param  Rows                   Totol screen rows.
  @param  SkipValue              SkipValue for this new form.

  @retval TopOfScreen            Top of screen menu for the new form.

**/
LIST_ENTRY *
FindTopOfScreenMenu (
  IN  LIST_ENTRY  *CurPos,
  IN  UINTN       Rows,
  OUT UINTN       *SkipValue
  )
{
  LIST_ENTRY      *Link;
  LIST_ENTRY      *TopOfScreen;
  UI_MENU_OPTION  *PreviousMenuOption;

  Link               = CurPos;
  PreviousMenuOption = NULL;

  while (Link->BackLink != &gMenuOption) {
    Link               = Link->BackLink;
    PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
    if (PreviousMenuOption->Row == 0) {
      UpdateOptionSkipLines (PreviousMenuOption);
    }

    if (Rows <= PreviousMenuOption->Skip) {
      break;
    }

    Rows = Rows - PreviousMenuOption->Skip;
  }

  if (Link->BackLink == &gMenuOption) {
    TopOfScreen = gMenuOption.ForwardLink;
    if ((PreviousMenuOption != NULL) && (Rows < PreviousMenuOption->Skip)) {
      *SkipValue = PreviousMenuOption->Skip - Rows;
    } else {
      *SkipValue = 0;
    }
  } else {
    TopOfScreen = Link;
    if (PreviousMenuOption != NULL) {
      *SkipValue = PreviousMenuOption->Skip - Rows;
    }
  }

  return TopOfScreen;
}

/**
  Get the index info for this opcode.

  @param  OpCode      The input opcode for the statement.

  @retval  The index of this statement.

**/
UINTN
GetIndexInfoForOpcode (
  IN EFI_IFR_OP_HEADER  *OpCode
  )
{
  LIST_ENTRY      *NewPos;
  UI_MENU_OPTION  *MenuOption;
  UINTN           Index;

  NewPos = gMenuOption.ForwardLink;
  Index  = 0;

  for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink) {
    MenuOption = MENU_OPTION_FROM_LINK (NewPos);

    if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) {
      if (MenuOption->ThisTag->OpCode == OpCode) {
        return Index;
      }

      Index++;
    }
  }

  return Index;
}

/**
  Is this the saved highlight statement.

  @param  HighLightedStatement      The input highlight statement.

  @retval  TRUE   This is the highlight statement.
  @retval  FALSE  This is not the highlight statement.

**/
BOOLEAN
IsSavedHighlightStatement (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement
  )
{
  if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) &&
      (gFormData->FormId == gHighligthMenuInfo.FormId))
  {
    if (gHighligthMenuInfo.HLTQuestionId != 0) {
      return (BOOLEAN)(gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode));
    } else {
      if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {
        if ((gHighligthMenuInfo.HLTIndex == 0) || (gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode (HighLightedStatement->OpCode))) {
          return TRUE;
        } else {
          return FALSE;
        }
      }
    }
  }

  return FALSE;
}

/**
  Is this the highlight menu.

  @param  MenuOption      The input Menu option.

  @retval  TRUE   This is the highlight menu option.
  @retval  FALSE  This is not the highlight menu option.

**/
BOOLEAN
IsHighLightMenuOption (
  IN UI_MENU_OPTION  *MenuOption
  )
{
  if (gHighligthMenuInfo.HLTQuestionId != 0) {
    if (GetQuestionIdInfo (MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) {
      return (BOOLEAN)(MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);
    }
  } else {
    if (CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) {
      if ((gHighligthMenuInfo.HLTIndex == 0) || (gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode (MenuOption->ThisTag->OpCode))) {
        return (BOOLEAN)(MenuOption->Sequence == gHighligthMenuInfo.HLTSequence);
      } else {
        return FALSE;
      }
    }
  }

  return FALSE;
}

/**
  Find the highlight menu.

  If the input is NULL, base on the record highlight info in
  gHighligthMenuInfo to find the last highlight menu.

  @param  HighLightedStatement      The input highlight statement.

  @retval  The highlight menu index.

**/
LIST_ENTRY *
FindHighLightMenuOption (
  IN FORM_DISPLAY_ENGINE_STATEMENT  *HighLightedStatement
  )
{
  LIST_ENTRY      *NewPos;
  UI_MENU_OPTION  *MenuOption;

  NewPos     = gMenuOption.ForwardLink;
  MenuOption = MENU_OPTION_FROM_LINK (NewPos);

  if (HighLightedStatement != NULL) {
    while (MenuOption->ThisTag != HighLightedStatement) {
      NewPos = NewPos->ForwardLink;
      if (NewPos == &gMenuOption) {
        //
        // Not Found it, break
        //
        break;
      }

      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
    }

    //
    // Must find the highlight statement.
    //
    ASSERT (NewPos != &gMenuOption);
  } else {
    while (!IsHighLightMenuOption (MenuOption)) {
      NewPos = NewPos->ForwardLink;
      if (NewPos == &gMenuOption) {
        //
        // Not Found it, break
        //
        break;
      }

      MenuOption = MENU_OPTION_FROM_LINK (NewPos);
    }

    //
    // Highlight statement has disappear (suppressed/disableed)
    //
    if (NewPos == &gMenuOption) {
      NewPos = NULL;
    }
  }

  return NewPos;
}

/**
  Is this the Top of screen menu.

  @param  MenuOption      The input Menu option.

  @retval  TRUE   This is the Top of screen menu option.
  @retval  FALSE  This is not the Top of screen menu option.

**/
BOOLEAN
IsTopOfScreeMenuOption (
  IN UI_MENU_OPTION  *MenuOption
  )
{
  if (gHighligthMenuInfo.TOSQuestionId != 0) {
    return (BOOLEAN)(GetQuestionIdInfo (MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId);
  }

  if (CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) {
    if ((gHighligthMenuInfo.TOSIndex == 0) || (gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode (MenuOption->ThisTag->OpCode))) {
      return TRUE;
    } else {
      return FALSE;
    }
  }

  return FALSE;
}

/**
  Calculate the distance between two menus and include the skip value of StartMenu.

  @param  StartMenu             The link_entry pointer to start menu.
  @param  EndMenu               The link_entry pointer to end menu.

**/
UINTN
GetDistanceBetweenMenus (
  IN LIST_ENTRY  *StartMenu,
  IN LIST_ENTRY  *EndMenu
  )
{
  LIST_ENTRY      *Link;
  UI_MENU_OPTION  *MenuOption;
  UINTN           Distance;

  Distance = 0;

  Link = StartMenu;
  while (Link != EndMenu) {
    MenuOption = MENU_OPTION_FROM_LINK (Link);
    if (MenuOption->Row == 0) {
      UpdateOptionSkipLines (MenuOption);
    }

    Distance += MenuOption->Skip;
    Link      = Link->BackLink;
  }

  return Distance;
}

/**
  Find the top of screen menu base on the previous record menu info.

  @param  HighLightMenu      The link_entry pointer to highlight menu.

  @retval  Return the the link_entry pointer top of screen menu.

**/
LIST_ENTRY *
FindTopOfScreenMenuOption (
  IN LIST_ENTRY  *HighLightMenu
  )
{
  LIST_ENTRY      *NewPos;
  UI_MENU_OPTION  *MenuOption;
  UINTN           TopRow;
  UINTN           BottomRow;

  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;

  NewPos     = gMenuOption.ForwardLink;
  MenuOption = MENU_OPTION_FROM_LINK (NewPos);

  while (!IsTopOfScreeMenuOption (MenuOption)) {
    NewPos = NewPos->ForwardLink;
    if (NewPos == &gMenuOption) {
      //
      // Not Found it, break
      //
      break;
    }

    MenuOption = MENU_OPTION_FROM_LINK (NewPos);
  }

  //
  // Last time top of screen menu has disappeared.
  //
  if (NewPos == &gMenuOption) {
    return NULL;
  }

  //
  // Check whether highlight menu and top of screen menu can be shown within one page,
  // if can't, return NULL to re-calcaulate the top of scrren menu. Because some new menus
  // may be dynamically inserted between highlightmenu and previous top of screen menu,
  // So previous record top of screen menu is not appropriate for current display.
  //
  if (GetDistanceBetweenMenus (HighLightMenu, NewPos) + 1 > BottomRow - TopRow) {
    return NULL;
  }

  return NewPos;
}

/**
  Find the first menu which will be show at the top.

  @param  FormData               The data info for this form.
  @param  TopOfScreen            The link_entry pointer to top menu.
  @param  HighlightMenu          The menu which will be highlight.
  @param  SkipValue              The skip value for the top menu.

**/
VOID
FindTopMenu (
  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
  OUT LIST_ENTRY                **TopOfScreen,
  OUT LIST_ENTRY                **HighlightMenu,
  OUT UINTN                     *SkipValue
  )
{
  UINTN           TopRow;
  UINTN           BottomRow;
  UI_MENU_OPTION  *MenuOption;
  UINTN           TmpValue;

  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
  //
  // When option mismatch happens,there exist two cases,one is reenter the form, just like the if case below,
  // and the other is exit current form and enter last form, it can be covered by the else case.
  //
  if (gMisMatch && (gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) && (gFormData->FormId == gHighligthMenuInfo.FormId)) {
    //
    // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid),
    // base on the record highlight info to find the highlight menu.
    //

    *HighlightMenu = FindHighLightMenuOption (NULL);
    if (*HighlightMenu != NULL) {
      //
      // Update skip info for this highlight menu.
      //
      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
      UpdateOptionSkipLines (MenuOption);

      //
      // Found the last time highlight menu.
      //
      *TopOfScreen = FindTopOfScreenMenuOption (*HighlightMenu);
      if (*TopOfScreen != NULL) {
        //
        // Found the last time selectable top of screen menu.
        //
        AdjustDateAndTimePosition (TRUE, TopOfScreen);
        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);
        UpdateOptionSkipLines (MenuOption);

        *SkipValue = gHighligthMenuInfo.SkipValue;
      } else {
        //
        // Not found last time top of screen menu, so base on current highlight menu
        // to find the new top of screen menu.
        // Make the current highlight menu at the bottom of the form to calculate the
        // top of screen menu.
        //
        if (MenuOption->Skip >= BottomRow - TopRow) {
          *TopOfScreen = *HighlightMenu;
          TmpValue     = 0;
        } else {
          *TopOfScreen = FindTopOfScreenMenu (*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
        }

        *SkipValue = TmpValue;
      }
    } else {
      //
      // Last time highlight menu has disappear, find the first highlightable menu as the default one.
      //
      *HighlightMenu = gMenuOption.ForwardLink;
      if (!IsListEmpty (&gMenuOption)) {
        MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
      }

      *TopOfScreen = gMenuOption.ForwardLink;
      *SkipValue   = 0;
    }
  } else if (FormData->HighLightedStatement != NULL) {
    if (IsSavedHighlightStatement (FormData->HighLightedStatement)) {
      //
      // Input highlight menu is same as last time highlight menu.
      // Base on last time highlight menu to set the top of screen menu and highlight menu.
      //
      *HighlightMenu = FindHighLightMenuOption (NULL);
      ASSERT (*HighlightMenu != NULL);

      //
      // Update skip info for this highlight menu.
      //
      MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu);
      UpdateOptionSkipLines (MenuOption);

      *TopOfScreen = FindTopOfScreenMenuOption (*HighlightMenu);
      if (*TopOfScreen == NULL) {
        //
        // Not found last time top of screen menu, so base on current highlight menu
        // to find the new top of screen menu.
        // Make the current highlight menu at the bottom of the form to calculate the
        // top of screen menu.
        //
        if (MenuOption->Skip >= BottomRow - TopRow) {
          *TopOfScreen = *HighlightMenu;
          TmpValue     = 0;
        } else {
          *TopOfScreen = FindTopOfScreenMenu (*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
        }

        *SkipValue = TmpValue;
      } else {
        AdjustDateAndTimePosition (TRUE, TopOfScreen);
        MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen);
        UpdateOptionSkipLines (MenuOption);

        *SkipValue = gHighligthMenuInfo.SkipValue;
      }

      AdjustDateAndTimePosition (TRUE, TopOfScreen);
    } else {
      //
      // Input highlight menu is not save as last time highlight menu.
      //
      *HighlightMenu = FindHighLightMenuOption (FormData->HighLightedStatement);
      MenuOption     = MENU_OPTION_FROM_LINK (*HighlightMenu);
      UpdateOptionSkipLines (MenuOption);

      //
      // Make the current highlight menu at the bottom of the form to calculate the
      // top of screen menu.
      //
      if (MenuOption->Skip >= BottomRow - TopRow) {
        *TopOfScreen = *HighlightMenu;
        TmpValue     = 0;
      } else {
        *TopOfScreen = FindTopOfScreenMenu (*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue);
      }

      *SkipValue = TmpValue;
    }

    AdjustDateAndTimePosition (TRUE, TopOfScreen);
  } else {
    //
    // If not has input highlight statement, just return the first one in this form.
    //
    *TopOfScreen   = gMenuOption.ForwardLink;
    *HighlightMenu = gMenuOption.ForwardLink;
    if (!IsListEmpty (&gMenuOption)) {
      MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE);
    }

    *SkipValue = 0;
  }

  gMisMatch = FALSE;

  //
  // First enter to show the menu, update highlight info.
  //
  UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue);
}

/**
  Record the highlight menu and top of screen menu info.

  @param  Highlight               The menu option which is highlight.
  @param  TopOfScreen             The menu option which is at the top of the form.
  @param  SkipValue               The skip line info for the top of screen menu.

**/
VOID
UpdateHighlightMenuInfo (
  IN  LIST_ENTRY  *Highlight,
  IN  LIST_ENTRY  *TopOfScreen,
  IN  UINTN       SkipValue
  )
{
  UI_MENU_OPTION                 *MenuOption;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;

  gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle;
  gHighligthMenuInfo.FormId    = gFormData->FormId;
  gHighligthMenuInfo.SkipValue = (UINT16)SkipValue;

  if (!IsListEmpty (&gMenuOption)) {
    MenuOption = MENU_OPTION_FROM_LINK (Highlight);
    Statement  = MenuOption->ThisTag;

    gUserInput->SelectedStatement = Statement;

    gHighligthMenuInfo.HLTSequence   = MenuOption->Sequence;
    gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo (Statement->OpCode);
    if (gHighligthMenuInfo.HLTQuestionId == 0) {
      //
      // if question id == 0, save the opcode buffer..
      //
      if (gHighligthMenuInfo.HLTOpCode != NULL) {
        FreePool (gHighligthMenuInfo.HLTOpCode);
      }

      gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);
      ASSERT (gHighligthMenuInfo.HLTOpCode != NULL);

      gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode (Statement->OpCode);
    }

    MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
    Statement  = MenuOption->ThisTag;

    gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo (Statement->OpCode);
    if (gHighligthMenuInfo.TOSQuestionId == 0) {
      //
      // if question id == 0, save the opcode buffer..
      //
      if (gHighligthMenuInfo.TOSOpCode != NULL) {
        FreePool (gHighligthMenuInfo.TOSOpCode);
      }

      gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode);
      ASSERT (gHighligthMenuInfo.TOSOpCode != NULL);

      gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode (Statement->OpCode);
    }
  } else {
    gUserInput->SelectedStatement = NULL;

    gHighligthMenuInfo.HLTSequence   = 0;
    gHighligthMenuInfo.HLTQuestionId = 0;
    if (gHighligthMenuInfo.HLTOpCode != NULL) {
      FreePool (gHighligthMenuInfo.HLTOpCode);
    }

    gHighligthMenuInfo.HLTOpCode = NULL;
    gHighligthMenuInfo.HLTIndex  = 0;

    gHighligthMenuInfo.TOSQuestionId = 0;
    if (gHighligthMenuInfo.TOSOpCode != NULL) {
      FreePool (gHighligthMenuInfo.TOSOpCode);
    }

    gHighligthMenuInfo.TOSOpCode = NULL;
    gHighligthMenuInfo.TOSIndex  = 0;
  }
}

/**
  Update attribute for this menu.

  @param  MenuOption               The menu option which this attribute used to.
  @param  Highlight                Whether this menu will be highlight.

**/
VOID
SetDisplayAttribute (
  IN UI_MENU_OPTION  *MenuOption,
  IN BOOLEAN         Highlight
  )
{
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;

  Statement = MenuOption->ThisTag;

  if (Highlight) {
    gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
    return;
  }

  if (MenuOption->GrayOut) {
    gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
  } else {
    if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
      gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
    } else {
      gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
    }
  }
}

/**
  Print string for this menu option.

  @param  MenuOption               The menu option which this attribute used to.
  @param  Col                      The column that this string will be print at.
  @param  Row                      The row that this string will be print at.
  @param  String                   The string which need to print.
  @param  Width                    The width need to print, if string is less than the
                                   width, the block space will be used.
  @param  Highlight                Whether this menu will be highlight.

**/
VOID
DisplayMenuString (
  IN UI_MENU_OPTION  *MenuOption,
  IN UINTN           Col,
  IN UINTN           Row,
  IN CHAR16          *String,
  IN UINTN           Width,
  IN BOOLEAN         Highlight
  )
{
  UINTN  Length;

  //
  // Print string with normal color.
  //
  if (!Highlight) {
    PrintStringAtWithWidth (Col, Row, String, Width);
    return;
  }

  //
  // Print the highlight menu string.
  // First print the highlight string.
  //
  SetDisplayAttribute (MenuOption, TRUE);
  PrintStringAt (Col, Row, String);

  //
  // Second, clean the empty after the string.
  //
  SetDisplayAttribute (MenuOption, FALSE);
  Length = GetStringWidth (String) / 2 - 1;
  PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length);
}

/**
  Check whether this menu can has option string.

  @param  MenuOption               The menu option which this attribute used to.

  @retval TRUE                     This menu option can have option string.
  @retval FALSE                    This menu option can't have option string.

**/
BOOLEAN
HasOptionString (
  IN UI_MENU_OPTION  *MenuOption
  )
{
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  CHAR16                         *String;
  UINTN                          Size;
  EFI_IFR_TEXT                   *TextOp;

  Size      = 0;
  Statement = MenuOption->ThisTag;

  //
  // See if the second text parameter is really NULL
  //
  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
    TextOp = (EFI_IFR_TEXT *)Statement->OpCode;
    if (TextOp->TextTwo != 0) {
      String = GetToken (TextOp->TextTwo, gFormData->HiiHandle);
      Size   = StrLen (String);
      FreePool (String);
    }
  }

  if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
      (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
      //
      // Allow a wide display if text op-code and no secondary text op-code
      //
      ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
      )
  {
    return FALSE;
  }

  return TRUE;
}

/**
  Double confirm with user about the action.

  @param  Action               The user input action.

  @retval TRUE                 User confirm with the input or not need user confirm.
  @retval FALSE                User want ignore this input.

**/
BOOLEAN
FxConfirmPopup (
  IN UINT32  Action
  )
{
  EFI_INPUT_KEY  Key;
  CHAR16         *CfmStr;
  UINTN          CfmStrLen;
  UINT32         CheckFlags;
  BOOLEAN        RetVal;
  UINTN          CatLen;
  UINTN          MaxLen;

  CfmStrLen = 0;
  CatLen    = StrLen (gConfirmMsgConnect);

  //
  // Below action need extra popup dialog to confirm.
  //
  CheckFlags = BROWSER_ACTION_DISCARD |
               BROWSER_ACTION_DEFAULT |
               BROWSER_ACTION_SUBMIT |
               BROWSER_ACTION_RESET |
               BROWSER_ACTION_EXIT;

  //
  // Not need to confirm with user, just return TRUE.
  //
  if ((Action & CheckFlags) == 0) {
    return TRUE;
  }

  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
    CfmStrLen += StrLen (gConfirmDiscardMsg);
  }

  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
    if (CfmStrLen != 0) {
      CfmStrLen += CatLen;
    }

    CfmStrLen += StrLen (gConfirmDefaultMsg);
  }

  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {
    if (CfmStrLen != 0) {
      CfmStrLen += CatLen;
    }

    CfmStrLen += StrLen (gConfirmSubmitMsg);
  }

  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {
    if (CfmStrLen != 0) {
      CfmStrLen += CatLen;
    }

    CfmStrLen += StrLen (gConfirmResetMsg);
  }

  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {
    if (CfmStrLen != 0) {
      CfmStrLen += CatLen;
    }

    CfmStrLen += StrLen (gConfirmExitMsg);
  }

  //
  // Allocate buffer to save the string.
  // String + "?" + "\0"
  //
  MaxLen = CfmStrLen + 1 + 1;
  CfmStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));
  ASSERT (CfmStr != NULL);

  if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
    StrCpyS (CfmStr, MaxLen, gConfirmDiscardMsg);
  }

  if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
    if (CfmStr[0] != 0) {
      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
      StrCatS (CfmStr, MaxLen, gConfirmDefaultMsg2nd);
    } else {
      StrCpyS (CfmStr, MaxLen, gConfirmDefaultMsg);
    }
  }

  if ((Action & BROWSER_ACTION_SUBMIT)  == BROWSER_ACTION_SUBMIT) {
    if (CfmStr[0] != 0) {
      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
      StrCatS (CfmStr, MaxLen, gConfirmSubmitMsg2nd);
    } else {
      StrCpyS (CfmStr, MaxLen, gConfirmSubmitMsg);
    }
  }

  if ((Action & BROWSER_ACTION_RESET)  == BROWSER_ACTION_RESET) {
    if (CfmStr[0] != 0) {
      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
      StrCatS (CfmStr, MaxLen, gConfirmResetMsg2nd);
    } else {
      StrCpyS (CfmStr, MaxLen, gConfirmResetMsg);
    }
  }

  if ((Action & BROWSER_ACTION_EXIT)  == BROWSER_ACTION_EXIT) {
    if (CfmStr[0] != 0) {
      StrCatS (CfmStr, MaxLen, gConfirmMsgConnect);
      StrCatS (CfmStr, MaxLen, gConfirmExitMsg2nd);
    } else {
      StrCpyS (CfmStr, MaxLen, gConfirmExitMsg);
    }
  }

  StrCatS (CfmStr, MaxLen, gConfirmMsgEnd);

  do {
    CreateDialog (&Key, gEmptyString, CfmStr, gConfirmOpt, gEmptyString, NULL);
  } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) &&
           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)) &&
           (Key.ScanCode != SCAN_ESC));

  if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) {
    RetVal = TRUE;
  } else {
    RetVal = FALSE;
  }

  FreePool (CfmStr);

  return RetVal;
}

/**
  Print string for this menu option.

  @param  MenuOption               The menu option which this attribute used to.
  @param  SkipWidth                The skip width between the left to the start of the prompt.
  @param  BeginCol                 The begin column for one menu.
  @param  SkipLine                 The skip line for this menu.
  @param  BottomRow                The bottom row for this form.
  @param  Highlight                Whether this menu will be highlight.
  @param  UpdateCol                Whether need to update the column info for Date/Time.

  @retval EFI_SUCCESS              Process the user selection success.

**/
EFI_STATUS
DisplayOneMenu (
  IN UI_MENU_OPTION  *MenuOption,
  IN UINTN           SkipWidth,
  IN UINTN           BeginCol,
  IN UINTN           SkipLine,
  IN UINTN           BottomRow,
  IN BOOLEAN         Highlight,
  IN BOOLEAN         UpdateCol
  )
{
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  UINTN                          Index;
  UINT16                         Width;
  UINT16                         PromptWidth;
  CHAR16                         *StringPtr;
  CHAR16                         *OptionString;
  CHAR16                         *OutputString;
  UINT16                         GlyphWidth;
  UINTN                          Temp;
  UINTN                          Temp2;
  UINTN                          Temp3;
  EFI_STATUS                     Status;
  UINTN                          Row;
  BOOLEAN                        IsProcessingFirstRow;
  UINTN                          Col;
  UINTN                          PromptLineNum;
  UINTN                          OptionLineNum;
  CHAR16                         AdjustValue;
  UINTN                          MaxRow;

  Statement            = MenuOption->ThisTag;
  Temp                 = SkipLine;
  Temp2                = SkipLine;
  Temp3                = SkipLine;
  AdjustValue          = 0;
  PromptLineNum        = 0;
  OptionLineNum        = 0;
  MaxRow               = 0;
  IsProcessingFirstRow = TRUE;

  //
  // Set default color.
  //
  SetDisplayAttribute (MenuOption, FALSE);

  //
  // 1. Paint the option string.
  //
  Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (OptionString != NULL) {
    if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {
      //
      // Adjust option string for date/time opcode.
      //
      ProcessStringForDateTime (MenuOption, OptionString, UpdateCol);
    }

    Width         = (UINT16)gOptionBlockWidth - 1;
    Row           = MenuOption->Row;
    GlyphWidth    = 1;
    OptionLineNum = 0;

    for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
      if (((Temp2 == 0)) && (Row <= BottomRow)) {
        if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {
          //
          // For date/time question, it has three menu options for this qustion.
          // The first/second menu options with the skip value is 0. the last one
          // with skip value is 1.
          //
          if (MenuOption->Skip != 0) {
            //
            // For date/ time, print the last past (year for date and second for time)
            // - 7 means skip [##/##/ for date and [##:##: for time.
            //
            DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1 - 7, Highlight);
          } else {
            //
            // For date/ time, print the first and second past (year for date and second for time)
            // The OutputString has a NARROW_CHAR or WIDE_CHAR at the begin of the string,
            // so need to - 1 to remove it, otherwise, it will clean 1 extr char follow it.
            DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString) - 1, Highlight);
          }
        } else {
          DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
        }

        OptionLineNum++;
      }

      //
      // If there is more string to process print on the next row and increment the Skip value
      //
      if (StrLen (&OptionString[Index]) != 0) {
        if (Temp2 == 0) {
          Row++;
          //
          // Since the Number of lines for this menu entry may or may not be reflected accurately
          // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
          // some testing to ensure we are keeping this in-sync.
          //
          // If the difference in rows is greater than or equal to the skip value, increase the skip value
          //
          if ((Row - MenuOption->Row) >= MenuOption->Skip) {
            MenuOption->Skip++;
          }
        }
      }

      FreePool (OutputString);
      if (Temp2 != 0) {
        Temp2--;
      }
    }

    Highlight = FALSE;

    FreePool (OptionString);
  }

  //
  // 2. Paint the description.
  //
  PromptWidth   = GetWidth (MenuOption, &AdjustValue);
  Row           = MenuOption->Row;
  GlyphWidth    = 1;
  PromptLineNum = 0;

  if ((MenuOption->Description == NULL) || (MenuOption->Description[0] == '\0')) {
    PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth);
    PromptLineNum++;
  } else {
    for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
      if ((Temp == 0) && (Row <= BottomRow)) {
        //
        // 1.Clean the start LEFT_SKIPPED_COLUMNS
        //
        PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);

        if ((Statement->OpCode->OpCode == EFI_IFR_REF_OP) && (MenuOption->Col >= 2) && IsProcessingFirstRow) {
          //
          // Print Arrow for Goto button.
          //
          PrintCharAt (
            MenuOption->Col - 2,
            Row,
            GEOMETRICSHAPE_RIGHT_TRIANGLE
            );
          IsProcessingFirstRow = FALSE;
        }

        DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);
        PromptLineNum++;
      }

      //
      // If there is more string to process print on the next row and increment the Skip value
      //
      if (StrLen (&MenuOption->Description[Index]) != 0) {
        if (Temp == 0) {
          Row++;
        }
      }

      FreePool (OutputString);
      if (Temp != 0) {
        Temp--;
      }
    }

    Highlight = FALSE;
  }

  //
  // 3. If this is a text op with secondary text information
  //
  if ((Statement->OpCode->OpCode  == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT *)Statement->OpCode)->TextTwo != 0)) {
    StringPtr = GetToken (((EFI_IFR_TEXT *)Statement->OpCode)->TextTwo, gFormData->HiiHandle);

    Width         = (UINT16)gOptionBlockWidth - 1;
    Row           = MenuOption->Row;
    GlyphWidth    = 1;
    OptionLineNum = 0;

    for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
      if ((Temp3 == 0) && (Row <= BottomRow)) {
        DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight);
        OptionLineNum++;
      }

      //
      // If there is more string to process print on the next row and increment the Skip value
      //
      if (StrLen (&StringPtr[Index]) != 0) {
        if (Temp3 == 0) {
          Row++;
          //
          // If the rows for text two is greater than or equal to the skip value, increase the skip value
          //
          if ((Row - MenuOption->Row) >= MenuOption->Skip) {
            MenuOption->Skip++;
          }
        }
      }

      FreePool (OutputString);
      if (Temp3 != 0) {
        Temp3--;
      }
    }

    FreePool (StringPtr);
  }

  //
  // 4.Line number for Option string and prompt string are not equal.
  //  Clean the column whose line number is less.
  //
  if (HasOptionString (MenuOption) && (OptionLineNum != PromptLineNum)) {
    Col    =  OptionLineNum < PromptLineNum ? MenuOption->OptCol : BeginCol;
    Row    = (OptionLineNum < PromptLineNum ? OptionLineNum : PromptLineNum) + MenuOption->Row;
    Width  = (UINT16)(OptionLineNum < PromptLineNum ? gOptionBlockWidth : PromptWidth + AdjustValue + SkipWidth);
    MaxRow = (OptionLineNum < PromptLineNum ? PromptLineNum : OptionLineNum) + MenuOption->Row - 1;

    while (Row <= MaxRow) {
      DisplayMenuString (MenuOption, Col, Row++, L"", Width, FALSE);
    }
  }

  return EFI_SUCCESS;
}

/**
  Display menu and wait for user to select one menu option, then return it.
  If AutoBoot is enabled, then if user doesn't select any option,
  after period of time, it will automatically return the first menu option.

  @param  FormData               The current form data info.

  @retval EFI_SUCCESS            Process the user selection success.
  @retval EFI_NOT_FOUND          Process option string for orderedlist/Oneof fail.

**/
EFI_STATUS
UiDisplayMenu (
  IN  FORM_DISPLAY_ENGINE_FORM  *FormData
  )
{
  UINTN                          SkipValue;
  INTN                           Difference;
  UINTN                          DistanceValue;
  UINTN                          Row;
  UINTN                          Col;
  UINTN                          Temp;
  UINTN                          Temp2;
  UINTN                          TopRow;
  UINTN                          BottomRow;
  UINTN                          Index;
  CHAR16                         *StringPtr;
  CHAR16                         *StringRightPtr;
  CHAR16                         *StringErrorPtr;
  CHAR16                         *OptionString;
  CHAR16                         *HelpString;
  CHAR16                         *HelpHeaderString;
  CHAR16                         *HelpBottomString;
  BOOLEAN                        NewLine;
  BOOLEAN                        Repaint;
  BOOLEAN                        UpArrow;
  BOOLEAN                        DownArrow;
  EFI_STATUS                     Status;
  EFI_INPUT_KEY                  Key;
  LIST_ENTRY                     *Link;
  LIST_ENTRY                     *NewPos;
  LIST_ENTRY                     *TopOfScreen;
  LIST_ENTRY                     *SavedListEntry;
  UI_MENU_OPTION                 *MenuOption;
  UI_MENU_OPTION                 *NextMenuOption;
  UI_MENU_OPTION                 *SavedMenuOption;
  UI_CONTROL_FLAG                ControlFlag;
  UI_SCREEN_OPERATION            ScreenOperation;
  FORM_DISPLAY_ENGINE_STATEMENT  *Statement;
  BROWSER_HOT_KEY                *HotKey;
  UINTN                          HelpPageIndex;
  UINTN                          HelpPageCount;
  UINTN                          RowCount;
  UINTN                          HelpLine;
  UINTN                          HelpHeaderLine;
  UINTN                          HelpBottomLine;
  BOOLEAN                        MultiHelpPage;
  UINT16                         EachLineWidth;
  UINT16                         HeaderLineWidth;
  UINT16                         BottomLineWidth;
  EFI_STRING_ID                  HelpInfo;
  UI_EVENT_TYPE                  EventType;
  BOOLEAN                        SkipHighLight;
  EFI_HII_VALUE                  *StatementValue;

  EventType        = UIEventNone;
  Status           = EFI_SUCCESS;
  HelpString       = NULL;
  HelpHeaderString = NULL;
  HelpBottomString = NULL;
  OptionString     = NULL;
  ScreenOperation  = UiNoOperation;
  NewLine          = TRUE;
  HelpPageCount    = 0;
  HelpLine         = 0;
  RowCount         = 0;
  HelpBottomLine   = 0;
  HelpHeaderLine   = 0;
  HelpPageIndex    = 0;
  MultiHelpPage    = FALSE;
  EachLineWidth    = 0;
  HeaderLineWidth  = 0;
  BottomLineWidth  = 0;
  UpArrow          = FALSE;
  DownArrow        = FALSE;
  SkipValue        = 0;
  SkipHighLight    = FALSE;

  NextMenuOption   = NULL;
  SavedMenuOption  = NULL;
  HotKey           = NULL;
  Repaint          = TRUE;
  MenuOption       = NULL;
  gModalSkipColumn = (CHAR16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;

  ZeroMem (&Key, sizeof (EFI_INPUT_KEY));

  TopRow    = gStatementDimensions.TopRow    + SCROLL_ARROW_HEIGHT;
  BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;

  Row = TopRow;
  if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gModalSkipColumn;
  } else {
    Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS;
  }

  FindTopMenu (FormData, &TopOfScreen, &NewPos, &SkipValue);
  if (!IsListEmpty (&gMenuOption)) {
    NextMenuOption                = MENU_OPTION_FROM_LINK (NewPos);
    gUserInput->SelectedStatement = NextMenuOption->ThisTag;
  }

  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

  ControlFlag = CfInitialization;
  while (TRUE) {
    switch (ControlFlag) {
      case CfInitialization:
        if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||
            (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid)))
        {
          //
          // Clear Statement range if different formset is painted.
          //
          ClearLines (
            gStatementDimensions.LeftColumn,
            gStatementDimensions.RightColumn,
            TopRow - SCROLL_ARROW_HEIGHT,
            BottomRow + SCROLL_ARROW_HEIGHT,
            GetFieldTextColor ()
            );
        }

        ControlFlag = CfRepaint;
        break;

      case CfRepaint:
        ControlFlag = CfRefreshHighLight;

        if (Repaint) {
          //
          // Display menu
          //
          DownArrow = FALSE;
          UpArrow   = FALSE;
          Row       = TopRow;

          gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());

          //
          // 1. Check whether need to print the arrow up.
          //
          if (!ValueIsScroll (TRUE, TopOfScreen)) {
            UpArrow = TRUE;
          }

          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
            PrintStringAtWithWidth (gStatementDimensions.LeftColumn + gModalSkipColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
          } else {
            PrintStringAtWithWidth (gStatementDimensions.LeftColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
          }

          if (UpArrow) {
            gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
            PrintCharAt (
              gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
              TopRow - SCROLL_ARROW_HEIGHT,
              ARROW_UP
              );
            gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
          }

          //
          // 2.Paint the menu.
          //
          for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
            MenuOption      = MENU_OPTION_FROM_LINK (Link);
            MenuOption->Row = Row;
            MenuOption->Col = Col;
            if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
              MenuOption->OptCol = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth + gModalSkipColumn;
            } else {
              MenuOption->OptCol = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth;
            }

            if (MenuOption->NestInStatement) {
              MenuOption->Col += SUBTITLE_INDENT;
            }

            //
            // Save the highlight menu, will be used in CfRefreshHighLight case.
            //
            if (Link == NewPos) {
              SavedMenuOption = MenuOption;
              SkipHighLight   = TRUE;
            }

            if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
              Status = DisplayOneMenu (
                         MenuOption,
                         MenuOption->Col - gStatementDimensions.LeftColumn,
                         gStatementDimensions.LeftColumn + gModalSkipColumn,
                         Link == TopOfScreen ? SkipValue : 0,
                         BottomRow,
                         (BOOLEAN)((Link == NewPos) && IsSelectable (MenuOption)),
                         TRUE
                         );
            } else {
              Status = DisplayOneMenu (
                         MenuOption,
                         MenuOption->Col - gStatementDimensions.LeftColumn,
                         gStatementDimensions.LeftColumn,
                         Link == TopOfScreen ? SkipValue : 0,
                         BottomRow,
                         (BOOLEAN)((Link == NewPos) && IsSelectable (MenuOption)),
                         TRUE
                         );
            }

            if (EFI_ERROR (Status)) {
              if (gMisMatch) {
                return EFI_SUCCESS;
              } else {
                return Status;
              }
            }

            //
            // 3. Update the row info which will be used by next menu.
            //
            if (Link == TopOfScreen) {
              Row += MenuOption->Skip - SkipValue;
            } else {
              Row += MenuOption->Skip;
            }

            if (Row > BottomRow) {
              if (!ValueIsScroll (FALSE, Link)) {
                DownArrow = TRUE;
              }

              Row = BottomRow + 1;
              break;
            }
          }

          //
          // 3. Menus in this form may not cover all form, clean the remain field.
          //
          while (Row <= BottomRow) {
            if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
              PrintStringAtWithWidth (gStatementDimensions.LeftColumn + gModalSkipColumn, Row++, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn);
            } else {
              PrintStringAtWithWidth (gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gHelpBlockWidth - gStatementDimensions.LeftColumn);
            }
          }

          //
          // 4. Print the down arrow row.
          //
          if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
            PrintStringAtWithWidth (gStatementDimensions.LeftColumn + gModalSkipColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 *  +gModalSkipColumn);
          } else {
            PrintStringAtWithWidth (gStatementDimensions.LeftColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn);
          }

          if (DownArrow) {
            gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
            PrintCharAt (
              gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
              BottomRow + SCROLL_ARROW_HEIGHT,
              ARROW_DOWN
              );
            gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
          }

          MenuOption = NULL;
        }

        break;

      case CfRefreshHighLight:

        //
        // MenuOption: Last menu option that need to remove highlight
        //             MenuOption is set to NULL in Repaint
        // NewPos:     Current menu option that need to highlight
        //
        ControlFlag = CfUpdateHelpString;

        ASSERT (NewPos != NULL);
        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);

        if (SkipHighLight) {
          SkipHighLight = FALSE;
          MenuOption    = SavedMenuOption;
          if (SavedMenuOption != NULL) {
            RefreshKeyHelp (gFormData, SavedMenuOption->ThisTag, FALSE);
          }

          break;
        }

        if (IsListEmpty (&gMenuOption)) {
          //
          // No menu option, just update the hotkey filed.
          //
          RefreshKeyHelp (gFormData, NULL, FALSE);
          break;
        }

        if ((MenuOption != NULL) && (TopOfScreen == &MenuOption->Link)) {
          Temp = SkipValue;
        } else {
          Temp = 0;
        }

        if (NewPos == TopOfScreen) {
          Temp2 = SkipValue;
        } else {
          Temp2 = 0;
        }

        if ((MenuOption == NULL) || (NewPos != &MenuOption->Link)) {
          if (MenuOption != NULL) {
            //
            // Remove the old highlight menu.
            //
            Status = DisplayOneMenu (
                       MenuOption,
                       MenuOption->Col - gStatementDimensions.LeftColumn,
                       gStatementDimensions.LeftColumn,
                       Temp,
                       BottomRow,
                       FALSE,
                       FALSE
                       );
          }

          //
          // This is the current selected statement
          //
          MenuOption = MENU_OPTION_FROM_LINK (NewPos);
          RefreshKeyHelp (gFormData, MenuOption->ThisTag, FALSE);

          if (!IsSelectable (MenuOption)) {
            break;
          }

          Status = DisplayOneMenu (
                     MenuOption,
                     MenuOption->Col - gStatementDimensions.LeftColumn,
                     gStatementDimensions.LeftColumn,
                     Temp2,
                     BottomRow,
                     TRUE,
                     FALSE
                     );
        }

        break;

      case CfUpdateHelpString:
        ControlFlag = CfPrepareToReadKey;
        if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
          break;
        }

        //
        // NewLine means only update highlight menu (remove old highlight and highlight
        // the new one), not need to full repaint the form.
        //
        if (Repaint || NewLine) {
          if (IsListEmpty (&gMenuOption)) {
            //
            // Don't print anything if no menu option.
            //
            StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
          } else {
            //
            // Don't print anything if it is a NULL help token
            //
            if (MenuOption == NULL) {
              ASSERT (MenuOption != NULL);
              break;
            }

            HelpInfo       = ((EFI_IFR_STATEMENT_HEADER *)((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
            Statement      = MenuOption->ThisTag;
            StatementValue = &Statement->CurrentValue;
            if ((HelpInfo == 0) || !IsSelectable (MenuOption)) {
              if (((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) && (StatementValue->Value.date.Month == 0xff)) || ((Statement->OpCode->OpCode == EFI_IFR_TIME_OP) && (StatementValue->Value.time.Hour == 0xff))) {
                StringPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);
              } else {
                StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
              }
            } else {
              if (((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) && (StatementValue->Value.date.Month == 0xff)) || ((Statement->OpCode->OpCode == EFI_IFR_TIME_OP) && (StatementValue->Value.time.Hour == 0xff))) {
                StringRightPtr = GetToken (HelpInfo, gFormData->HiiHandle);
                StringErrorPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle);
                StringPtr      = AllocateZeroPool ((StrLen (StringRightPtr) + StrLen (StringErrorPtr)+ 1) * sizeof (CHAR16));
                StrCpyS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringRightPtr);
                StrCatS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringErrorPtr);
                FreePool (StringRightPtr);
                FreePool (StringErrorPtr);
              } else {
                StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
              }
            }
          }

          RowCount      = BottomRow - TopRow + 1;
          HelpPageIndex = 0;
          //
          // 1.Calculate how many line the help string need to print.
          //
          if (HelpString != NULL) {
            FreePool (HelpString);
            HelpString = NULL;
          }

          HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
          FreePool (StringPtr);

          if (HelpLine > RowCount) {
            MultiHelpPage = TRUE;
            StringPtr     = GetToken (STRING_TOKEN (ADJUST_HELP_PAGE_UP), gHiiHandle);
            if (HelpHeaderString != NULL) {
              FreePool (HelpHeaderString);
              HelpHeaderString = NULL;
            }

            HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, 0);
            FreePool (StringPtr);
            StringPtr = GetToken (STRING_TOKEN (ADJUST_HELP_PAGE_DOWN), gHiiHandle);
            if (HelpBottomString != NULL) {
              FreePool (HelpBottomString);
              HelpBottomString = NULL;
            }

            HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, 0);
            FreePool (StringPtr);
            //
            // Calculate the help page count.
            //
            if (HelpLine > 2 * RowCount - 2) {
              HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
              if ((HelpLine - RowCount + 1) % (RowCount - 2) != 0) {
                HelpPageCount += 1;
              }
            } else {
              HelpPageCount = 2;
            }
          } else {
            MultiHelpPage = FALSE;
          }
        }

        //
        // Check whether need to show the 'More(U/u)' at the begin.
        // Base on current direct info, here shows aligned to the right side of the column.
        // If the direction is multi line and aligned to right side may have problem, so
        // add ASSERT code here.
        //
        if (HelpPageIndex > 0) {
          gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
          for (Index = 0; Index < HelpHeaderLine; Index++) {
            ASSERT (HelpHeaderLine == 1);
            ASSERT (GetStringWidth (HelpHeaderString) / 2 < ((UINT32)gHelpBlockWidth - 1));
            PrintStringAtWithWidth (
              gStatementDimensions.RightColumn - gHelpBlockWidth,
              Index + TopRow,
              gEmptyString,
              gHelpBlockWidth
              );
            PrintStringAt (
              gStatementDimensions.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
              Index + TopRow,
              &HelpHeaderString[Index * HeaderLineWidth]
              );
          }
        }

        gST->ConOut->SetAttribute (gST->ConOut, GetHelpTextColor ());
        //
        // Print the help string info.
        //
        if (!MultiHelpPage) {
          for (Index = 0; Index < HelpLine; Index++) {
            PrintStringAtWithWidth (
              gStatementDimensions.RightColumn - gHelpBlockWidth,
              Index + TopRow,
              &HelpString[Index * EachLineWidth],
              gHelpBlockWidth
              );
          }

          for ( ; Index < RowCount; Index++) {
            PrintStringAtWithWidth (
              gStatementDimensions.RightColumn - gHelpBlockWidth,
              Index + TopRow,
              gEmptyString,
              gHelpBlockWidth
              );
          }

          gST->ConOut->SetCursorPosition (gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
        } else {
          if (HelpPageIndex == 0) {
            for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
              PrintStringAtWithWidth (
                gStatementDimensions.RightColumn - gHelpBlockWidth,
                Index + TopRow,
                &HelpString[Index * EachLineWidth],
                gHelpBlockWidth
                );
            }
          } else {
            for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
                 (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++)
            {
              PrintStringAtWithWidth (
                gStatementDimensions.RightColumn - gHelpBlockWidth,
                Index + TopRow + HelpHeaderLine,
                &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth],
                gHelpBlockWidth
                );
            }

            if (HelpPageIndex == HelpPageCount - 1) {
              for ( ; Index < RowCount - HelpHeaderLine; Index++) {
                PrintStringAtWithWidth (
                  gStatementDimensions.RightColumn - gHelpBlockWidth,
                  Index + TopRow + HelpHeaderLine,
                  gEmptyString,
                  gHelpBlockWidth
                  );
              }

              gST->ConOut->SetCursorPosition (gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
            }
          }
        }

        //
        // Check whether need to print the 'More(D/d)' at the bottom.
        // Base on current direct info, here shows aligned to the right side of the column.
        // If the direction is multi line and aligned to right side may have problem, so
        // add ASSERT code here.
        //
        if ((HelpPageIndex < HelpPageCount - 1) && MultiHelpPage) {
          gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
          for (Index = 0; Index < HelpBottomLine; Index++) {
            ASSERT (HelpBottomLine == 1);
            ASSERT (GetStringWidth (HelpBottomString) / 2 < ((UINT32)gHelpBlockWidth - 1));
            PrintStringAtWithWidth (
              gStatementDimensions.RightColumn - gHelpBlockWidth,
              BottomRow + Index - HelpBottomLine + 1,
              gEmptyString,
              gHelpBlockWidth
              );
            PrintStringAt (
              gStatementDimensions.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
              BottomRow + Index - HelpBottomLine + 1,
              &HelpBottomString[Index * BottomLineWidth]
              );
          }
        }

        //
        // Reset this flag every time we finish using it.
        //
        Repaint = FALSE;
        NewLine = FALSE;
        break;

      case CfPrepareToReadKey:
        ControlFlag     = CfReadKey;
        ScreenOperation = UiNoOperation;
        break;

      case CfReadKey:
        ControlFlag = CfScreenOperation;

        //
        // Wait for user's selection
        //
        while (TRUE) {
          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
          if (!EFI_ERROR (Status)) {
            EventType = UIEventKey;
            break;
          }

          //
          // If we encounter error, continue to read another key in.
          //
          if (Status != EFI_NOT_READY) {
            continue;
          }

          EventType = UiWaitForEvent (gST->ConIn->WaitForKey);
          if (EventType == UIEventKey) {
            gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
          }

          break;
        }

        if (EventType == UIEventDriver) {
          gMisMatch          = TRUE;
          gUserInput->Action = BROWSER_ACTION_NONE;
          ControlFlag        = CfExit;
          break;
        }

        if (EventType == UIEventTimeOut) {
          gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
          ControlFlag        = CfExit;
          break;
        }

        switch (Key.UnicodeChar) {
          case CHAR_CARRIAGE_RETURN:
            if ((MenuOption == NULL) || MenuOption->GrayOut || MenuOption->ReadOnly) {
              ControlFlag = CfReadKey;
              break;
            }

            ScreenOperation = UiSelect;
            gDirection      = 0;
            break;

          //
          // We will push the adjustment of these numeric values directly to the input handler
          //  NOTE: we won't handle manual input numeric
          //
          case '+':
          case '-':
            //
            // If the screen has no menu items, and the user didn't select UiReset
            // ignore the selection and go back to reading keys.
            //
            if (MenuOption == NULL ) {
              ASSERT (MenuOption != NULL);
              break;
            }

            if (IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
              ControlFlag = CfReadKey;
              break;
            }

            Statement = MenuOption->ThisTag;
            if (  (Statement->OpCode->OpCode == EFI_IFR_DATE_OP)
               || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)
               || ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (GetFieldFromNum (Statement->OpCode) != 0))
                  )
            {
              if (Key.UnicodeChar == '+') {
                gDirection = SCAN_RIGHT;
              } else {
                gDirection = SCAN_LEFT;
              }

              Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
              if (OptionString != NULL) {
                FreePool (OptionString);
              }

              if (EFI_ERROR (Status)) {
                //
                // Repaint to clear possible error prompt pop-up
                //
                Repaint = TRUE;
                NewLine = TRUE;
              } else {
                ControlFlag = CfExit;
              }
            }

            break;

          case '^':
            ScreenOperation = UiUp;
            break;

          case 'V':
          case 'v':
            ScreenOperation = UiDown;
            break;

          case ' ':
            if (IsListEmpty (&gMenuOption)) {
              ControlFlag = CfReadKey;
              break;
            }

            if (MenuOption == NULL) {
              ASSERT (MenuOption != NULL);
              break;
            }

            if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP) && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
              ScreenOperation = UiSelect;
            }

            break;

          case 'D':
          case 'd':
            if (!MultiHelpPage) {
              ControlFlag = CfReadKey;
              break;
            }

            ControlFlag   = CfUpdateHelpString;
            HelpPageIndex = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
            break;

          case 'U':
          case 'u':
            if (!MultiHelpPage) {
              ControlFlag = CfReadKey;
              break;
            }

            ControlFlag   = CfUpdateHelpString;
            HelpPageIndex = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
            break;

          case CHAR_NULL:
            for (Index = 0; Index < mScanCodeNumber; Index++) {
              if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
                ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
                break;
              }
            }

            if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && ((Key.ScanCode == SCAN_ESC) || (Index == mScanCodeNumber))) {
              //
              // ModalForm has no ESC key and Hot Key.
              //
              ControlFlag = CfReadKey;
            } else if (Index == mScanCodeNumber) {
              //
              // Check whether Key matches the registered hot key.
              //
              HotKey = NULL;
              HotKey = GetHotKeyFromRegisterList (&Key);
              if (HotKey != NULL) {
                ScreenOperation = UiHotKey;
              }
            }

            break;
        }

        break;

      case CfScreenOperation:
        if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {
          //
          // If the screen has no menu items, and the user didn't select UiReset or UiHotKey
          // ignore the selection and go back to reading keys.
          //
          if (IsListEmpty (&gMenuOption)) {
            ControlFlag = CfReadKey;
            break;
          }
        }

        for (Index = 0;
             Index < ARRAY_SIZE (gScreenOperationToControlFlag);
             Index++
             )
        {
          if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
            ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
            break;
          }
        }

        break;

      case CfUiSelect:
        ControlFlag = CfRepaint;
        if (MenuOption == NULL ) {
          ASSERT (MenuOption != NULL);
          break;
        }

        Statement = MenuOption->ThisTag;
        if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
          break;
        }

        switch (Statement->OpCode->OpCode) {
          case EFI_IFR_REF_OP:
          case EFI_IFR_ACTION_OP:
          case EFI_IFR_RESET_BUTTON_OP:
            ControlFlag = CfExit;
            break;

          default:
            //
            // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
            //
            RefreshKeyHelp (gFormData, Statement, TRUE);
            Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);

            if (OptionString != NULL) {
              FreePool (OptionString);
            }

            if (EFI_ERROR (Status)) {
              Repaint = TRUE;
              NewLine = TRUE;
              RefreshKeyHelp (gFormData, Statement, FALSE);
              break;
            } else {
              ControlFlag = CfExit;
              break;
            }
        }

        break;

      case CfUiReset:
        //
        // We come here when someone press ESC
        // If the policy is not exit front page when user press ESC, process here.
        //
        if (!FormExitPolicy ()) {
          Repaint     = TRUE;
          NewLine     = TRUE;
          ControlFlag = CfRepaint;
          break;
        }

        gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
        ControlFlag        = CfExit;
        break;

      case CfUiHotKey:
        ControlFlag = CfRepaint;
        if (HotKey == NULL ) {
          ASSERT (HotKey != NULL);
          break;
        }

        if (FxConfirmPopup (HotKey->Action)) {
          gUserInput->Action = HotKey->Action;
          if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
            gUserInput->DefaultId = HotKey->DefaultId;
          }

          ControlFlag = CfExit;
        } else {
          Repaint     = TRUE;
          NewLine     = TRUE;
          ControlFlag = CfRepaint;
        }

        break;

      case CfUiLeft:
        ControlFlag = CfRepaint;
        if (MenuOption == NULL) {
          ASSERT (MenuOption != NULL);
          break;
        }

        if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
          if (MenuOption->Sequence != 0) {
            //
            // In the middle or tail of the Date/Time op-code set, go left.
            //
            ASSERT (NewPos != NULL);
            NewPos = NewPos->BackLink;
          }
        }

        break;

      case CfUiRight:
        ControlFlag = CfRepaint;
        if (MenuOption == NULL) {
          ASSERT (MenuOption != NULL);
          break;
        }

        if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
          if (MenuOption->Sequence != 2) {
            //
            // In the middle or tail of the Date/Time op-code set, go left.
            //
            ASSERT (NewPos != NULL);
            NewPos = NewPos->ForwardLink;
          }
        }

        break;

      case CfUiUp:
        ControlFlag = CfRepaint;
        NewLine     = TRUE;

        SavedListEntry = NewPos;
        ASSERT (NewPos != NULL);

        MenuOption = MENU_OPTION_FROM_LINK (NewPos);
        ASSERT (MenuOption != NULL);

        //
        // Adjust Date/Time position before we advance forward.
        //
        AdjustDateAndTimePosition (TRUE, &NewPos);

        NewPos = NewPos->BackLink;
        //
        // Find next selectable menu or the first menu beyond current form.
        //
        Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE);
        if (Difference < 0) {
          //
          // We hit the begining MenuOption that can be focused
          // so we simply scroll to the top.
          //
          Repaint = TRUE;
          if ((TopOfScreen != gMenuOption.ForwardLink) || (SkipValue != 0)) {
            TopOfScreen = gMenuOption.ForwardLink;
            NewPos      = SavedListEntry;
            SkipValue   = 0;
          } else {
            //
            // Scroll up to the last page when we have arrived at top page.
            //
            TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);
            NewPos      = gMenuOption.BackLink;
            MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);
          }
        } else {
          NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);

          if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {
            //
            // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
            //
            TopOfScreen = NewPos;
            Repaint     = TRUE;
            SkipValue   = 0;
          }

          //
          // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
          //
          // BottomRow - TopRow + 1 means the total rows current forms supported.
          // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
          // and new top menu. New top menu will all shows in next form, but last highlight menu
          // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
          // last highlight menu.
          //
          if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&
              (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1))
          {
            NewPos = SavedListEntry;
          }
        }

        UpdateStatusBar (INPUT_ERROR, FALSE);

        //
        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
        //
        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
        AdjustDateAndTimePosition (TRUE, &NewPos);

        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);
        break;

      case CfUiPageUp:
        //
        // SkipValue means lines is skipped when show the top menu option.
        //
        ControlFlag = CfRepaint;
        NewLine     = TRUE;
        Repaint     = TRUE;

        Link = TopOfScreen;
        //
        // First minus the menu of the top screen, it's value is SkipValue.
        //
        if (SkipValue >= BottomRow - TopRow + 1) {
          //
          // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
          // form of options to be show, so just update the SkipValue to show the next
          // parts of options.
          //
          SkipValue -= BottomRow - TopRow + 1;
          NewPos     = TopOfScreen;
          break;
        } else {
          Index = (BottomRow + 1) - SkipValue - TopRow;
        }

        TopOfScreen = FindTopOfScreenMenu (TopOfScreen, Index, &SkipValue);
        NewPos      = TopOfScreen;
        MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE);

        UpdateStatusBar (INPUT_ERROR, FALSE);

        //
        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
        // Don't do this when we are already in the first page.
        //
        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
        AdjustDateAndTimePosition (TRUE, &NewPos);

        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);
        break;

      case CfUiPageDown:
        //
        // SkipValue means lines is skipped when show the top menu option.
        //
        ControlFlag = CfRepaint;
        NewLine     = TRUE;
        Repaint     = TRUE;

        Link           = TopOfScreen;
        NextMenuOption = MENU_OPTION_FROM_LINK (Link);
        Index          = TopRow + NextMenuOption->Skip - SkipValue;
        //
        // Count to the menu option which will show at the top of the next form.
        //
        while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
          Link           = Link->ForwardLink;
          NextMenuOption = MENU_OPTION_FROM_LINK (Link);
          Index          = Index + NextMenuOption->Skip;
        }

        if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
          //
          // Highlight on the last menu which can be highlight.
          //
          Repaint = FALSE;
          MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);
        } else {
          //
          // Calculate the skip line for top of screen menu.
          //
          if (Link == TopOfScreen) {
            //
            // The top of screen menu option occupies the entire form.
            //
            SkipValue += BottomRow - TopRow + 1;
          } else {
            SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
          }

          TopOfScreen = Link;
          MenuOption  = NULL;
          //
          // Move to the Next selectable menu.
          //
          MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);
        }

        //
        // Save the menu as the next highlight menu.
        //
        NewPos = Link;

        UpdateStatusBar (INPUT_ERROR, FALSE);

        //
        // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
        // Don't do this when we are already in the last page.
        //
        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
        AdjustDateAndTimePosition (TRUE, &NewPos);

        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);
        break;

      case CfUiDown:
        //
        // SkipValue means lines is skipped when show the top menu option.
        // NewPos  points to the menu which is highlighted now.
        //
        ControlFlag = CfRepaint;
        NewLine     = TRUE;

        if (NewPos == TopOfScreen) {
          Temp2 = SkipValue;
        } else {
          Temp2 = 0;
        }

        SavedListEntry = NewPos;
        //
        // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
        // to be one that progresses to the next set of op-codes, we need to advance to the last
        // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
        // checking can be done.  The only other logic we need to introduce is that if a Date/Time
        // op-code is the last entry in the menu, we need to rewind back to the first op-code of
        // the Date/Time op-code.
        //
        AdjustDateAndTimePosition (FALSE, &NewPos);

        MenuOption = MENU_OPTION_FROM_LINK (NewPos);
        NewPos     = NewPos->ForwardLink;
        //
        // Find the next selectable menu.
        //
        if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) {
          if ((gMenuOption.ForwardLink == NewPos) || (&gMenuOption == NewPos)) {
            Difference = -1;
          } else {
            Difference = 0;
          }
        } else {
          Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE);
        }

        if (Difference < 0) {
          //
          // Scroll to the first page.
          //
          if ((TopOfScreen != gMenuOption.ForwardLink) || (SkipValue != 0)) {
            TopOfScreen = gMenuOption.ForwardLink;
            Repaint     = TRUE;
            MenuOption  = NULL;
          } else {
            MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
          }

          NewPos = gMenuOption.ForwardLink;
          MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE);

          SkipValue = 0;
          //
          // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
          //
          AdjustDateAndTimePosition (TRUE, &TopOfScreen);
          AdjustDateAndTimePosition (TRUE, &NewPos);

          UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);
          break;
        }

        //
        // Get next selected menu info.
        //
        AdjustDateAndTimePosition (FALSE, &NewPos);
        NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
        if (NextMenuOption->Row == 0) {
          UpdateOptionSkipLines (NextMenuOption);
        }

        //
        // Calculate new highlight menu end row.
        //
        Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1;
        if (Temp > BottomRow) {
          //
          // Get the top screen menu info.
          //
          AdjustDateAndTimePosition (FALSE, &TopOfScreen);
          SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);

          //
          // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.
          // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.
          //
          if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
            //
            // Skip the top op-code
            //
            TopOfScreen   = TopOfScreen->ForwardLink;
            DistanceValue = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);

            SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);

            //
            // If we have a remainder, skip that many more op-codes until we drain the remainder
            // Special case is the selected highlight menu has more than one form of menus.
            //
            while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) {
              //
              // Since the Difference is greater than or equal to this op-code's skip value, skip it
              //
              DistanceValue   = DistanceValue - (INTN)SavedMenuOption->Skip;
              TopOfScreen     = TopOfScreen->ForwardLink;
              SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
            }

            //
            // Since we will act on this op-code in the next routine, and increment the
            // SkipValue, set the skips to one less than what is required.
            //
            if (TopOfScreen != NewPos) {
              SkipValue = DistanceValue;
            } else {
              SkipValue = 0;
            }
          } else {
            //
            // Since we will act on this op-code in the next routine, and increment the
            // SkipValue, set the skips to one less than what is required.
            //
            SkipValue += Temp - BottomRow;
          }

          Repaint = TRUE;
        } else if (!IsSelectable (NextMenuOption)) {
          //
          // Continue to go down until scroll to next page or the selectable option is found.
          //
          ScreenOperation = UiDown;
          ControlFlag     = CfScreenOperation;
          break;
        }

        MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);

        //
        // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
        //
        // BottomRow - TopRow + 1 means the total rows current forms supported.
        // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu
        // and new top menu. New top menu will all shows in next form, but last highlight menu
        // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the
        // last highlight menu.
        //
        if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) &&
            (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1))
        {
          NewPos = SavedListEntry;
        }

        UpdateStatusBar (INPUT_ERROR, FALSE);

        //
        // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
        //
        AdjustDateAndTimePosition (TRUE, &TopOfScreen);
        AdjustDateAndTimePosition (TRUE, &NewPos);

        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);
        break;

      case CfUiNoOperation:
        ControlFlag = CfRepaint;
        break;

      case CfExit:
        gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
        if (HelpString != NULL) {
          FreePool (HelpString);
        }

        if (HelpHeaderString != NULL) {
          FreePool (HelpHeaderString);
        }

        if (HelpBottomString != NULL) {
          FreePool (HelpBottomString);
        }

        return EFI_SUCCESS;

      default:
        break;
    }
  }
}

/**
  Free the UI Menu Option structure data.

  @param   MenuOptionList         Point to the menu option list which need to be free.

**/
VOID
FreeMenuOptionData (
  LIST_ENTRY  *MenuOptionList
  )
{
  LIST_ENTRY      *Link;
  UI_MENU_OPTION  *Option;

  //
  // Free menu option list
  //
  while (!IsListEmpty (MenuOptionList)) {
    Link   = GetFirstNode (MenuOptionList);
    Option = MENU_OPTION_FROM_LINK (Link);
    if (Option->Description != NULL) {
      FreePool (Option->Description);
    }

    RemoveEntryList (&Option->Link);
    FreePool (Option);
  }
}

/**

  Base on the browser status info to show an pop up message.

**/
VOID
BrowserStatusProcess (
  VOID
  )
{
  CHAR16              *ErrorInfo;
  EFI_INPUT_KEY       Key;
  EFI_EVENT           WaitList[2];
  EFI_EVENT           RefreshIntervalEvent;
  EFI_EVENT           TimeOutEvent;
  UINT8               TimeOut;
  EFI_STATUS          Status;
  UINTN               Index;
  WARNING_IF_CONTEXT  EventContext;
  EFI_IFR_OP_HEADER   *OpCodeBuf;
  EFI_STRING_ID       StringToken;
  CHAR16              DiscardChange;
  CHAR16              JumpToFormSet;
  CHAR16              *PrintString;

  if (gFormData->BrowserStatus == BROWSER_SUCCESS) {
    return;
  }

  StringToken          = 0;
  TimeOutEvent         = NULL;
  RefreshIntervalEvent = NULL;
  OpCodeBuf            = NULL;
  if (gFormData->HighLightedStatement == NULL) {
    // Ensure there is a highlighted statement, otherwise exit
    return;
  }

  OpCodeBuf = gFormData->HighLightedStatement->OpCode;

  if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) {
    ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP);

    TimeOut     = ((EFI_IFR_WARNING_IF *)OpCodeBuf)->TimeOut;
    StringToken = ((EFI_IFR_WARNING_IF *)OpCodeBuf)->Warning;
  } else {
    TimeOut = 0;
    if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) &&
        ((OpCodeBuf != NULL) && (OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)))
    {
      StringToken = ((EFI_IFR_NO_SUBMIT_IF *)OpCodeBuf)->Error;
    } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) &&
               ((OpCodeBuf != NULL) && (OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)))
    {
      StringToken = ((EFI_IFR_INCONSISTENT_IF *)OpCodeBuf)->Error;
    }
  }

  if (StringToken != 0) {
    ErrorInfo = GetToken (StringToken, gFormData->HiiHandle);
  } else if (gFormData->ErrorString != NULL) {
    //
    // Only used to compatible with old setup browser.
    // Not use this field in new browser core.
    //
    ErrorInfo = gFormData->ErrorString;
  } else {
    switch (gFormData->BrowserStatus) {
      case BROWSER_SUBMIT_FAIL:
        ErrorInfo = gSaveFailed;
        break;

      case BROWSER_FORM_NOT_FOUND:
        ErrorInfo = gFormNotFound;
        break;

      case BROWSER_FORM_SUPPRESS:
        ErrorInfo = gFormSuppress;
        break;

      case BROWSER_PROTOCOL_NOT_FOUND:
        ErrorInfo = gProtocolNotFound;
        break;

      case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:
        ErrorInfo = gNoSubmitIfFailed;
        break;

      case BROWSER_RECONNECT_FAIL:
        ErrorInfo = gReconnectFail;
        break;

      case BROWSER_RECONNECT_SAVE_CHANGES:
        ErrorInfo = gReconnectConfirmChanges;
        break;

      case BROWSER_RECONNECT_REQUIRED:
        ErrorInfo = gReconnectRequired;
        break;

      default:
        ErrorInfo = gBrowserError;
        break;
    }
  }

  switch (gFormData->BrowserStatus) {
    case BROWSER_SUBMIT_FAIL:
    case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF:
    case BROWSER_RECONNECT_SAVE_CHANGES:
      ASSERT (gUserInput != NULL);
      if (gFormData->BrowserStatus == (BROWSER_SUBMIT_FAIL)) {
        PrintString   = gSaveProcess;
        JumpToFormSet = gJumpToFormSet[0];
        DiscardChange = gDiscardChange[0];
      } else if (gFormData->BrowserStatus == (BROWSER_RECONNECT_SAVE_CHANGES)) {
        PrintString   = gChangesOpt;
        JumpToFormSet = gConfirmOptYes[0];
        DiscardChange = gConfirmOptNo[0];
      } else {
        PrintString   = gSaveNoSubmitProcess;
        JumpToFormSet = gCheckError[0];
        DiscardChange = gDiscardChange[0];
      }

      do {
        CreateDialog (&Key, gEmptyString, ErrorInfo, PrintString, gEmptyString, NULL);
      } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (DiscardChange | UPPER_LOWER_CASE_OFFSET)) &&
               ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (JumpToFormSet | UPPER_LOWER_CASE_OFFSET)));

      if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (DiscardChange | UPPER_LOWER_CASE_OFFSET)) {
        gUserInput->Action = BROWSER_ACTION_DISCARD;
      } else {
        gUserInput->Action = BROWSER_ACTION_GOTO;
      }

      break;

    default:
      if (TimeOut == 0) {
        do {
          CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
      } else {
        Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent);
        ASSERT_EFI_ERROR (Status);

        EventContext.SyncEvent = TimeOutEvent;
        EventContext.TimeOut   = &TimeOut;
        EventContext.ErrorInfo = ErrorInfo;

        Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent);
        ASSERT_EFI_ERROR (Status);

        //
        // Show the dialog first to avoid long time not reaction.
        //
        gBS->SignalEvent (RefreshIntervalEvent);

        Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND);
        ASSERT_EFI_ERROR (Status);

        while (TRUE) {
          Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
          if (!EFI_ERROR (Status) && (Key.UnicodeChar == CHAR_CARRIAGE_RETURN)) {
            break;
          }

          if (Status != EFI_NOT_READY) {
            continue;
          }

          WaitList[0] = TimeOutEvent;
          WaitList[1] = gST->ConIn->WaitForKey;

          Status = gBS->WaitForEvent (2, WaitList, &Index);
          ASSERT_EFI_ERROR (Status);

          if (Index == 0) {
            //
            // Timeout occur, close the hoot time out event.
            //
            break;
          }
        }

        gBS->CloseEvent (TimeOutEvent);
        gBS->CloseEvent (RefreshIntervalEvent);
      }

      break;
  }

  if (StringToken != 0) {
    FreePool (ErrorInfo);
  }
}

/**
  Display one form, and return user input.

  @param FormData                Form Data to be shown.
  @param UserInputData           User input data.

  @retval EFI_SUCCESS            1.Form Data is shown, and user input is got.
                                 2.Error info has show and return.
  @retval EFI_INVALID_PARAMETER  The input screen dimension is not valid
  @retval EFI_NOT_FOUND          New form data has some error.
**/
EFI_STATUS
EFIAPI
FormDisplay (
  IN  FORM_DISPLAY_ENGINE_FORM  *FormData,
  OUT USER_INPUT                *UserInputData
  )
{
  EFI_STATUS  Status;

  ASSERT (FormData != NULL);
  if (FormData == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  gUserInput = UserInputData;
  gFormData  = FormData;

  //
  // Process the status info first.
  //
  BrowserStatusProcess ();
  if (gFormData->BrowserStatus != BROWSER_SUCCESS) {
    //
    // gFormData->BrowserStatus != BROWSER_SUCCESS, means only need to print the error info, return here.
    //
    return EFI_SUCCESS;
  }

  Status = DisplayPageFrame (FormData, &gStatementDimensions);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Global Widths should be initialized before any MenuOption creation
  // or the GetWidth() used in UiAddMenuOption() will return incorrect value.
  //
  //
  //  Left                                              right
  //   |<-.->|<-.........->|<- .........->|<-...........->|
  //     Skip    Prompt         Option         Help
  //
  gOptionBlockWidth = (CHAR16)((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3) + 1;
  gHelpBlockWidth   = (CHAR16)(gOptionBlockWidth - 1 - LEFT_SKIPPED_COLUMNS);
  gPromptBlockWidth = (CHAR16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gOptionBlockWidth - 1) - 1);

  ConvertStatementToMenu ();

  //
  // Check whether layout is changed.
  //
  if (  mIsFirstForm
     || (gOldFormEntry.HiiHandle != FormData->HiiHandle)
     || (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))
     || (gOldFormEntry.FormId != FormData->FormId))
  {
    mStatementLayoutIsChanged = TRUE;
  } else {
    mStatementLayoutIsChanged = FALSE;
  }

  Status = UiDisplayMenu (FormData);

  //
  // Backup last form info.
  //
  mIsFirstForm            = FALSE;
  gOldFormEntry.HiiHandle = FormData->HiiHandle;
  CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);
  gOldFormEntry.FormId = FormData->FormId;

  //
  // Free the Ui menu option list.
  //
  FreeMenuOptionData (&gMenuOption);

  return Status;
}

/**
  Clear Screen to the initial state.
**/
VOID
EFIAPI
DriverClearDisplayPage (
  VOID
  )
{
  ClearDisplayPage ();
  mIsFirstForm = TRUE;
}

/**
  Set Buffer to Value for Size bytes.

  @param  Buffer                 Memory to set.
  @param  Size                   Number of bytes to set
  @param  Value                  Value of the set operation.

**/
VOID
SetUnicodeMem (
  IN VOID    *Buffer,
  IN UINTN   Size,
  IN CHAR16  Value
  )
{
  CHAR16  *Ptr;

  Ptr = Buffer;
  while ((Size--)  != 0) {
    *(Ptr++) = Value;
  }
}

/**
  Initialize Setup Browser driver.

  @param ImageHandle     The image handle.
  @param SystemTable     The system table.

  @retval EFI_SUCCESS    The Setup Browser module is initialized correctly..
  @return Other value if failed to initialize the Setup Browser module.

**/
EFI_STATUS
EFIAPI
InitializeDisplayEngine (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                              Status;
  EFI_INPUT_KEY                           HotKey;
  EFI_STRING                              NewString;
  EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL  *FormBrowserEx2;

  //
  // Publish our HII data
  //
  gHiiHandle = HiiAddPackages (
                 &gDisplayEngineGuid,
                 ImageHandle,
                 DisplayEngineStrings,
                 NULL
                 );
  ASSERT (gHiiHandle != NULL);

  //
  // Install Form Display protocol
  //
  Status = gBS->InstallProtocolInterface (
                  &mPrivateData.Handle,
                  &gEdkiiFormDisplayEngineProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mPrivateData.FromDisplayProt
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Install HII Popup Protocol.
  //
  Status = gBS->InstallProtocolInterface (
                  &mPrivateData.Handle,
                  &gEfiHiiPopupProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mPrivateData.HiiPopup
                  );
  ASSERT_EFI_ERROR (Status);

  InitializeDisplayStrings ();

  ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
  ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));

  //
  // Use BrowserEx2 protocol to register HotKey.
  //
  Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **)&FormBrowserEx2);
  if (!EFI_ERROR (Status)) {
    //
    // Register the default HotKey F9 and F10 again.
    //
    HotKey.UnicodeChar = CHAR_NULL;
    HotKey.ScanCode    = SCAN_F10;
    NewString          = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
    ASSERT (NewString != NULL);
    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
    FreePool (NewString);

    HotKey.ScanCode = SCAN_F9;
    NewString       = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
    ASSERT (NewString != NULL);
    FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
    FreePool (NewString);
  }

  return EFI_SUCCESS;
}

/**
  This is the default unload handle for display core drivers.

  @param[in]  ImageHandle       The drivers' driver image.

  @retval EFI_SUCCESS           The image is unloaded.
  @retval Others                Failed to unload the image.

**/
EFI_STATUS
EFIAPI
UnloadDisplayEngine (
  IN EFI_HANDLE  ImageHandle
  )
{
  HiiRemovePackages (gHiiHandle);

  FreeDisplayStrings ();

  if (gHighligthMenuInfo.HLTOpCode != NULL) {
    FreePool (gHighligthMenuInfo.HLTOpCode);
  }

  if (gHighligthMenuInfo.TOSOpCode != NULL) {
    FreePool (gHighligthMenuInfo.TOSOpCode);
  }

  return EFI_SUCCESS;
}
