/** @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;
  }

  //
  // 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;
    *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 opton which is highlight.
  @param  TopOfScreen             The menu opton 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 attribut for this menu.

  @param  MenuOption               The menu opton which this attribut 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 opton which this attribut 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);
  Length = PrintStringAt (Col, Row, String);

  //
  // Second, clean the empty after the string.
  //
  SetDisplayAttribute (MenuOption, FALSE);
  PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length);
}

/**
  Check whether this menu can has option string.

  @param  MenuOption               The menu opton which this attribut 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 opton which this attribut 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_SUCESSS              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_SUCESSS            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 hilight
        //             MenuOption is set to NULL in Repaint
        // NewPos:     Current menu option that need to hilight
        //
        ControlFlag = CfUpdateHelpString;

        ASSERT (NewPos != NULL);
        UpdateHighlightMenuInfo (NewPos, TopOfScreen, SkipValue);

        if (SkipHighLight) {
          SkipHighLight = FALSE;
          MenuOption    = SavedMenuOption;
          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 highlith
        // the new one), not need to full repain the form.
        //
        if (Repaint || NewLine) {
          if (IsListEmpty (&gMenuOption)) {
            //
            // Don't print anything if no mwnu option.
            //
            StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
          } else {
            //
            // Don't print anything if it is a NULL help token
            //
            ASSERT (MenuOption != NULL);
            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.
            //
            ASSERT (MenuOption != NULL);
            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;
            }

            ASSERT (MenuOption != NULL);
            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;

        ASSERT (MenuOption != NULL);
        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;

        ASSERT (HotKey != NULL);

        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;
        ASSERT (MenuOption != NULL);
        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;
        ASSERT (MenuOption != NULL);
        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) {
    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;
}
