/** @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>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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                  *TestOp;
  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) {
    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
    if (TestOp->TextTwo != 0) {
      String = GetToken (TestOp->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                    *TestOp;

  Size = 0;
  Statement = MenuOption->ThisTag;

  //
  // See if the second text parameter is really NULL
  //
  if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
    TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
    if (TestOp->TextTwo != 0) {
      String = GetToken (TestOp->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;

      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 (NewPos != NULL && (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);

    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);
  }

  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;
}
