/** @file
Entry and initialization module for the browser.

Copyright (c) 2007 - 2017, 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            *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
  }
};


/**
  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);
  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 (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;
}

/**
  Find the Top of screen 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 *
FindTopOfScreenMenuOption (
 VOID
 )
{
  LIST_ENTRY                      *NewPos;
  UI_MENU_OPTION                  *MenuOption;

  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) {
    NewPos = 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();
      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();
      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);

  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;
}
