/** @file
Entry and initialization module for the browser.

Copyright (c) 2007 - 2015, 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 = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);

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 (((UINTN) (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;
  CHAR16           *String;
  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);

  String = GetToken (PromptId, gFormData->HiiHandle);
  ASSERT (String != NULL);

  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 = String;
    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 (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
        //
        // If there is more string to process print on the next row and increment the Skip value
        //
        if (StrLen (&String[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;
  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 defalut 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 < (UINTN) (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 < (UINTN) (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 < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
           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;
    }
  }
}

/**

  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;

  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;
}
