/** @file
  Implements editor interface functions.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TextEditor.h"
#include "EditStatusBar.h"
#include "EditInputBar.h"
#include "EditMenuBar.h"

//
// the first time editor launch
//
BOOLEAN  EditorFirst;

//
// it's time editor should exit
//
BOOLEAN  EditorExit;

BOOLEAN  EditorMouseAction;

extern EFI_EDITOR_FILE_BUFFER  FileBuffer;

extern BOOLEAN  FileBufferNeedRefresh;

extern BOOLEAN  FileBufferOnlyLineNeedRefresh;

extern BOOLEAN  FileBufferMouseNeedRefresh;

extern EFI_EDITOR_FILE_BUFFER  FileBufferBackupVar;

EFI_EDITOR_GLOBAL_EDITOR  MainEditor;

/**
  Load a file from disk to editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
MainCommandOpenFile (
  VOID
  );

/**
  Switch a file from ASCII to UNICODE or vise-versa.

  @retval EFI_SUCCESS           The switch was ok or a warning was presented.
**/
EFI_STATUS
MainCommandSwitchFileType (
  VOID
  );

/**
  move cursor to specified lines

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
MainCommandGotoLine (
  VOID
  );

/**
  Save current file to disk, you can save to current file name or
  save to another file name.

  @retval EFI_SUCCESS           The file was saved correctly.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR          A file access error occurred.
**/
EFI_STATUS
MainCommandSaveFile (
  VOID
  );

/**
  Show help information for the editor.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
MainCommandDisplayHelp (
  VOID
  );

/**
  exit editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandExit (
  VOID
  );

/**
  search string in file buffer

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandSearch (
  VOID
  );

/**
  search string in file buffer, and replace it with another str

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandSearchReplace (
  VOID
  );

/**
  cut current line to clipboard

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandCutLine (
  VOID
  );

/**
  paste line to file buffer.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandPasteLine (
  VOID
  );

/**
  Help info that will be displayed.
**/
EFI_STRING_ID  MainMenuHelpInfo[] = {
  STRING_TOKEN (STR_EDIT_HELP_TITLE),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_LIST_TITLE),
  STRING_TOKEN (STR_EDIT_HELP_DIV),
  STRING_TOKEN (STR_EDIT_HELP_GO_TO_LINE),
  STRING_TOKEN (STR_EDIT_HELP_SAVE_FILE),
  STRING_TOKEN (STR_EDIT_HELP_EXIT),
  STRING_TOKEN (STR_EDIT_HELP_SEARCH),
  STRING_TOKEN (STR_EDIT_HELP_SEARCH_REPLACE),
  STRING_TOKEN (STR_EDIT_HELP_CUT_LINE),
  STRING_TOKEN (STR_EDIT_HELP_PASTE_LINE),
  STRING_TOKEN (STR_EDIT_HELP_OPEN_FILE),
  STRING_TOKEN (STR_EDIT_HELP_FILE_TYPE),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_EXIT_HELP),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_BLANK),
  STRING_TOKEN (STR_EDIT_HELP_DIV),
  0
};

MENU_ITEM_FUNCTION  MainControlBasedMenuFunctions[] = {
  NULL,
  NULL,                      /* Ctrl - A */
  NULL,                      /* Ctrl - B */
  NULL,                      /* Ctrl - C */
  NULL,                      /* Ctrl - D */
  MainCommandDisplayHelp,    /* Ctrl - E */
  MainCommandSearch,         /* Ctrl - F */
  MainCommandGotoLine,       /* Ctrl - G */
  NULL,                      /* Ctrl - H */
  NULL,                      /* Ctrl - I */
  NULL,                      /* Ctrl - J */
  MainCommandCutLine,        /* Ctrl - K */
  NULL,                      /* Ctrl - L */
  NULL,                      /* Ctrl - M */
  NULL,                      /* Ctrl - N */
  MainCommandOpenFile,       /* Ctrl - O */
  NULL,                      /* Ctrl - P */
  MainCommandExit,           /* Ctrl - Q */
  MainCommandSearchReplace,  /* Ctrl - R */
  MainCommandSaveFile,       /* Ctrl - S */
  MainCommandSwitchFileType, /* Ctrl - T */
  MainCommandPasteLine,      /* Ctrl - U */
  NULL,                      /* Ctrl - V */
  NULL,                      /* Ctrl - W */
  NULL,                      /* Ctrl - X */
  NULL,                      /* Ctrl - Y */
  NULL,                      /* Ctrl - Z */
};

EDITOR_MENU_ITEM  MainMenuItems[] = {
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_GO_TO_LINE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F1),
    MainCommandGotoLine
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_SAVE_FILE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F2),
    MainCommandSaveFile
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_EXIT),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F3),
    MainCommandExit
  },

  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_SEARCH),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F4),
    MainCommandSearch
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_SEARCH_REPLACE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F5),
    MainCommandSearchReplace
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_CUT_LINE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F6),
    MainCommandCutLine
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_PASTE_LINE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F7),
    MainCommandPasteLine
  },

  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_OPEN_FILE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F8),
    MainCommandOpenFile
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_FILE_TYPE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F9),
    MainCommandSwitchFileType
  },
  {
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_FILE_TYPE),
    STRING_TOKEN (STR_EDIT_LIBMENUBAR_F11),
    MainCommandSwitchFileType
  },

  {
    0,
    0,
    NULL
  }
};

/**
  Load a file from disk to editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
MainCommandOpenFile (
  VOID
  )
{
  BOOLEAN     Done;
  EFI_STATUS  Status;

  //
  //  This command will open a file from current working directory.
  //   Read-only file can also be opened. But it can not be modified.
  // Below is the scenario of Open File command:
  // 1.IF currently opened file has not been modIFied, directly go to step .
  //   IF currently opened file has been modified,
  //     an Input Bar will be prompted as :
  //       "File Modified. Save ( Yes/No/Cancel) ?"
  //           IF user press 'y' or 'Y', currently opened file will be saved.
  //           IF user press 'n' or 'N', currently opened file will
  //              not be saved.
  //           IF user press 'c' or 'C' or ESC, Open File command ends and
  //              currently opened file is still opened.
  //
  // 2.  An Input Bar will be prompted as :  "File Name to Open: "
  //       IF user press ESC, Open File command ends and
  //          currently opened file is still opened.
  //       Any other inputs with a Return will
  //          cause currently opened file close.
  //
  // 3.  IF user input file name is an existing file , this file will be read
  //        and opened.
  //    IF user input file name is a new file, this file will be created
  //        and opened. This file's type ( UNICODE or ASCII ) is the same
  //        with the old file.
  // if current file is modified, so you need to choose
  // whether to save it first.
  //
  if (MainEditor.FileBuffer->FileModified) {
    Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // the answer is just one character
    //
    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // loop for user's answer
    // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
    //
    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
      StatusBarSetRefresh ();

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString ()[0]) {
        case L'y':
        case L'Y':
          //
          // want to save this file first
          //
          Status = FileBufferSave (MainEditor.FileBuffer->FileName);
          if (EFI_ERROR (Status)) {
            return Status;
          }

          MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
          FileBufferRestorePosition ();
          Done = TRUE;
          break;

        case L'n':
        case L'N':
          //
          // the file won't be saved
          //
          Done = TRUE;
          break;

        case L'c':
        case L'C':
          return EFI_SUCCESS;
      }
    }
  }

  //
  // TO get the open file name
  //
  Status = InputBarSetPrompt (L"File Name to Open: ");
  if (EFI_ERROR (Status)) {
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
    return Status;
  }

  Status = InputBarSetStringSize (100);
  if (EFI_ERROR (Status)) {
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
    StatusBarSetRefresh ();

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {
      return EFI_SUCCESS;
    }

    //
    // The input string length should > 0
    //
    if (StrLen (InputBarGetString ()) > 0) {
      //
      // CHECK if filename is valid
      //
      if (!IsValidFileName (InputBarGetString ())) {
        FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
        StatusBarSetStatusString (L"Invalid File Name");
        return EFI_SUCCESS;
      }

      break;
    }
  }

  //
  // read from disk
  //
  Status = FileBufferRead (InputBarGetString (), FALSE);

  if (EFI_ERROR (Status)) {
    FileBufferRead (MainEditor.FileBuffer->FileName, TRUE);
    return EFI_LOAD_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Switch a file from ASCII to UNICODE or vise-versa.

  @retval EFI_SUCCESS           The switch was ok or a warning was presented.
**/
EFI_STATUS
MainCommandSwitchFileType (
  VOID
  )
{
  //
  // Below is the scenario of File Type command:
  // After File Type is executed, file type will be changed to another type
  // if file is read-only, can not be modified
  //
  if (MainEditor.FileBuffer->ReadOnly) {
    StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
    return EFI_SUCCESS;
  }

  if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
    MainEditor.FileBuffer->FileType = FileTypeAscii;
  } else {
    MainEditor.FileBuffer->FileType = FileTypeUnicode;
  }

  MainEditor.FileBuffer->FileModified = TRUE;

  return EFI_SUCCESS;
}

/**
  cut current line to clipboard

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandCutLine (
  VOID
  )
{
  EFI_STATUS       Status;
  EFI_EDITOR_LINE  *Line;

  //
  // This command will cut current line ( where cursor is on ) to clip board.
  //      And cursor will move to the beginning of next line.
  // Below is the scenario of Cut Line command:
  // 1.  IF cursor is on valid line, current line will be cut to clip board.
  //     IF cursor is not on valid line, an Status String will be prompted :
  //        "Nothing to Cut".
  //
  Line   = NULL;
  Status = FileBufferCutLine (&Line);
  if (Status == EFI_NOT_FOUND) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  MainEditor.CutLine = Line;

  return EFI_SUCCESS;
}

/**
  paste line to file buffer.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandPasteLine (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Below is the scenario of Paste Line command:
  // 1.  IF nothing is on clipboard, a Status String will be prompted :
  //        "No Line to Paste" and Paste Line command ends.
  //     IF something is on clipboard, insert it above current line.
  // nothing on clipboard
  //
  if (MainEditor.CutLine == NULL) {
    StatusBarSetStatusString (L"No Line to Paste");
    return EFI_SUCCESS;
  }

  Status = FileBufferPasteLine ();

  return Status;
}

/**
  search string in file buffer

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandSearch (
  VOID
  )
{
  EFI_STATUS  Status;
  CHAR16      *Buffer;
  BOOLEAN     Done;
  UINTN       Offset;

  //
  // Below is the scenario of Search command:
  // 1.  An Input Bar will be prompted : "Enter Search String:".
  //       IF user press ESC, Search command ends.
  //       IF user just press Enter, Search command ends.
  //       IF user inputs the search string,  do Step 2.
  //
  // 2.  IF input search string is found, cursor will move to the first
  //        occurrence and do Step 3.
  //     IF input search string is not found, a Status String
  //        "Search String Not Found" will be prompted and Search command ends.
  //
  // 3.  An Input Bar will be prompted: "Find Next (Yes/No/Cancel ) ?".
  //      IF user press ESC, Search command ends.
  //       IF user press 'y' or 'Y', do Step 2.
  //       IF user press 'n' or 'N', Search command ends.
  //       IF user press 'c' or 'C', Search command ends.
  //
  Status = InputBarSetPrompt (L"Enter Search String: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (40);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
  StatusBarSetRefresh ();

  //
  // ESC
  //
  if (Status == EFI_NOT_READY) {
    return EFI_SUCCESS;
  }

  //
  // just enter pressed
  //
  if (StrLen (InputBarGetString ()) == 0) {
    return EFI_SUCCESS;
  }

  Buffer = CatSPrint (NULL, L"%s", InputBarGetString ());
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // the first time , search from current position
  //
  Offset = 0;
  do {
    //
    // since search may be continued to search multiple times
    // so we need to backup editor each time
    //
    MainEditorBackup ();

    Status = FileBufferSearch (Buffer, Offset);

    if (Status == EFI_NOT_FOUND) {
      break;
    }

    //
    // Find next
    //
    Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");
    if (EFI_ERROR (Status)) {
      FreePool (Buffer);
      return Status;
    }

    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      FreePool (Buffer);
      return Status;
    }

    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
      StatusBarSetRefresh ();

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        FreePool (Buffer);
        return EFI_SUCCESS;
      }

      switch (InputBarGetString ()[0]) {
        case L'y':
        case L'Y':
          Done = TRUE;
          break;

        case L'n':
        case L'N':
          FreePool (Buffer);
          return EFI_SUCCESS;
      }

      //
      // end of which
      //
    }

    //
    // end of while !Done
    // for search second, third time, search from current position + strlen
    //
    Offset = StrLen (Buffer);
  } while (1);

  //
  // end of do
  //
  FreePool (Buffer);
  StatusBarSetStatusString (L"Search String Not Found");

  return EFI_SUCCESS;
}

/**
  Search string in file buffer, and replace it with another str.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandSearchReplace (
  VOID
  )
{
  EFI_STATUS  Status;
  CHAR16      *Search;
  CHAR16      *Replace;
  BOOLEAN     Done;
  BOOLEAN     First;
  BOOLEAN     ReplaceOption;
  UINTN       SearchLen;
  UINTN       ReplaceLen;
  BOOLEAN     ReplaceAll;

  ReplaceOption = FALSE;

  //
  // Below is the scenario of Search/Replace command:
  // 1.  An Input Bar is prompted : "Enter Search String:".
  //       IF user press ESC, Search/Replace command ends.
  //       IF user just press Enter, Search/Replace command ends.
  //       IF user inputs the search string S, do Step 2.
  //
  // 2.  An Input Bar is prompted: "Replace With:".
  //       IF user press ESC, Search/Replace command ends.
  //      IF user inputs the replace string R, do Step 3.
  //
  // 3.  IF input search string is not found, an Status String
  //        "Search String Not Found" will be prompted
  //        and Search/Replace command ends
  //     IF input search string is found, do Step 4.
  //
  // 4.  An Input Bar will be prompted: "Replace ( Yes/No/All/Cancel )?"
  //       IF user press 'y' or 'Y', S will be replaced with R and do Step 5
  //       IF user press 'n' or 'N', S will not be replaced and do Step 5.
  //       IF user press 'a' or 'A', all the S from file current position on
  //          will be replaced with R and Search/Replace command ends.
  //       IF user press 'c' or 'C' or ESC, Search/Replace command ends.
  //
  // 5.  An Input Bar will be prompted: "Find Next (Yes/No/Cancel) ?".
  //       IF user press ESC, Search/Replace command ends.
  //       IF user press 'y' or 'Y', do Step 3.
  //       IF user press 'n' or 'N', Search/Replace command ends.
  //       IF user press 'c' or 'C', Search/Replace command ends.
  // input search string
  //
  Status = InputBarSetPrompt (L"Enter Search String: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (40);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
  StatusBarSetRefresh ();

  //
  // ESC
  //
  if (Status == EFI_NOT_READY) {
    return EFI_SUCCESS;
  }

  //
  // if just pressed enter
  //
  if (StrLen (InputBarGetString ()) == 0) {
    return EFI_SUCCESS;
  }

  Search = CatSPrint (NULL, L"%s", InputBarGetString ());
  if (Search == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  SearchLen = StrLen (Search);

  //
  // input replace string
  //
  Status = InputBarSetPrompt (L"Replace With: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (40);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
  StatusBarSetRefresh ();

  //
  // ESC
  //
  if (Status == EFI_NOT_READY) {
    return EFI_SUCCESS;
  }

  Replace = CatSPrint (NULL, L"%s", InputBarGetString ());
  if (Replace == NULL) {
    FreePool (Search);
    return EFI_OUT_OF_RESOURCES;
  }

  ReplaceLen = StrLen (Replace);

  First      = TRUE;
  ReplaceAll = FALSE;
  do {
    //
    // since search may be continued to search multiple times
    // so we need to backup editor each time
    //
    MainEditorBackup ();

    if (First) {
      Status = FileBufferSearch (Search, 0);
    } else {
      //
      // if just replace, so skip this replace string
      // if replace string is an empty string, so skip to next character
      //
      if (ReplaceOption) {
        Status = FileBufferSearch (Search, (ReplaceLen == 0) ? 1 : ReplaceLen);
      } else {
        Status = FileBufferSearch (Search, SearchLen);
      }
    }

    if (Status == EFI_NOT_FOUND) {
      break;
    }

    //
    // replace or not?
    //
    Status = InputBarSetPrompt (L"Replace (Yes/No/All/Cancel) ?");

    if (EFI_ERROR (Status)) {
      FreePool (Search);
      FreePool (Replace);
      return Status;
    }

    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      FreePool (Search);
      FreePool (Replace);
      return Status;
    }

    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
      StatusBarSetRefresh ();

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        FreePool (Search);
        FreePool (Replace);
        return EFI_SUCCESS;
      }

      switch (InputBarGetString ()[0]) {
        case L'y':
        case L'Y':
          Done          = TRUE;
          ReplaceOption = TRUE;
          break;

        case L'n':
        case L'N':
          Done          = TRUE;
          ReplaceOption = FALSE;
          break;

        case L'a':
        case L'A':
          Done          = TRUE;
          ReplaceOption = TRUE;
          ReplaceAll    = TRUE;
          break;

        case L'c':
        case L'C':
          FreePool (Search);
          FreePool (Replace);
          return EFI_SUCCESS;
      }

      //
      // end of which
      //
    }

    //
    // end of while !Done
    // Decide to Replace
    //
    if (ReplaceOption) {
      //
      // file is read-only
      //
      if (MainEditor.FileBuffer->ReadOnly) {
        StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
        return EFI_SUCCESS;
      }

      //
      // replace all
      //
      if (ReplaceAll) {
        Status = FileBufferReplaceAll (Search, Replace, 0);
        FreePool (Search);
        FreePool (Replace);
        return Status;
      }

      //
      // replace
      //
      Status = FileBufferReplace (Replace, SearchLen);
      if (EFI_ERROR (Status)) {
        FreePool (Search);
        FreePool (Replace);
        return Status;
      }
    }

    //
    // Find next
    //
    Status = InputBarSetPrompt (L"Find Next (Yes/No) ?");
    if (EFI_ERROR (Status)) {
      FreePool (Search);
      FreePool (Replace);
      return Status;
    }

    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      FreePool (Search);
      FreePool (Replace);
      return Status;
    }

    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
      StatusBarSetRefresh ();

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        FreePool (Search);
        FreePool (Replace);
        return EFI_SUCCESS;
      }

      switch (InputBarGetString ()[0]) {
        case L'y':
        case L'Y':
          Done = TRUE;
          break;

        case L'n':
        case L'N':
          FreePool (Search);
          FreePool (Replace);
          return EFI_SUCCESS;
      }

      //
      // end of which
      //
    }

    //
    // end of while !Done
    //
    First = FALSE;
  } while (1);

  //
  // end of do
  //
  FreePool (Search);
  FreePool (Replace);

  StatusBarSetStatusString (L"Search String Not Found");

  return EFI_SUCCESS;
}

/**
  exit editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainCommandExit (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Below is the scenario of Exit command:
  // 1.  IF currently opened file is not modified, exit the editor and
  //        Exit command ends.
  //     IF currently opened file is modified, do Step 2
  //
  // 2.  An Input Bar will be prompted:
  //        "File modified. Save ( Yes/No/Cancel )?"
  //       IF user press 'y' or 'Y', currently opened file will be saved
  //          and Editor exits
  //       IF user press 'n' or 'N', currently opened file will not be saved
  //          and Editor exits.
  //       IF user press 'c' or 'C' or ESC, Exit command ends.
  // if file has been modified, so will prompt user whether to save the changes
  //
  if (MainEditor.FileBuffer->FileModified) {
    Status = InputBarSetPrompt (L"File modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    while (1) {
      Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
      StatusBarSetRefresh ();

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString ()[0]) {
        case L'y':
        case L'Y':
          //
          // write file back to disk
          //
          Status = FileBufferSave (MainEditor.FileBuffer->FileName);
          if (!EFI_ERROR (Status)) {
            EditorExit = TRUE;
          }

          return Status;

        case L'n':
        case L'N':
          EditorExit = TRUE;
          return EFI_SUCCESS;

        case L'c':
        case L'C':
          return EFI_SUCCESS;
      }
    }
  }

  EditorExit = TRUE;
  return EFI_SUCCESS;
}

/**
  move cursor to specified lines

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
MainCommandGotoLine (
  VOID
  )
{
  EFI_STATUS  Status;
  UINTN       Row;

  //
  // Below is the scenario of Go To Line command:
  // 1.  An Input Bar will be prompted : "Go To Line:".
  //       IF user press ESC, Go To Line command ends.
  //       IF user just press Enter, cursor remains unchanged.
  //       IF user inputs line number, do Step 2.
  //
  // 2.  IF input line number is valid, move cursor to the beginning
  //        of specified line and Go To Line command ends.
  //    IF input line number is invalid, a Status String will be prompted:
  //        "No Such Line" and Go To Line command ends.
  //
  Status = InputBarSetPrompt (L"Go To Line: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // line number's digit <= 6
  //
  Status = InputBarSetStringSize (6);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
  StatusBarSetRefresh ();

  //
  // press ESC
  //
  if (Status == EFI_NOT_READY) {
    return EFI_SUCCESS;
  }

  //
  // if JUST press enter
  //
  if (StrLen (InputBarGetString ()) == 0) {
    return EFI_SUCCESS;
  }

  Row = ShellStrToUintn (InputBarGetString ());

  //
  // invalid line number
  //
  if ((Row > MainEditor.FileBuffer->NumLines) || (Row <= 0)) {
    StatusBarSetStatusString (L"No Such Line");
    return EFI_SUCCESS;
  }

  //
  // move cursor to that line's start
  //
  FileBufferMovePosition (Row, 1);

  return EFI_SUCCESS;
}

/**
  Save current file to disk, you can save to current file name or
  save to another file name.

  @retval EFI_SUCCESS           The file was saved correctly.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR          A file access error occurred.
**/
EFI_STATUS
MainCommandSaveFile (
  VOID
  )
{
  EFI_STATUS         Status;
  CHAR16             *FileName;
  BOOLEAN            OldFile;
  CHAR16             *Str;
  SHELL_FILE_HANDLE  FileHandle;
  EFI_FILE_INFO      *Info;

  //
  // This command will save currently opened file to disk.
  // You can choose save to another file name or just save to
  //    current file name.
  // Below is the scenario of Save File command:
  //    ( Suppose the old file name is A )
  // 1.  An Input Bar will be prompted:    "File To Save: [ old file name]"
  //     IF user press ESC, Save File command ends .
  //     IF user press Enter, input file name will be A.
  //     IF user inputs a new file name B,  input file name will be B.
  //
  // 2.  IF input file name is A, go to do Step 3.
  //     IF input file name is B, go to do Step 4.
  //
  // 3.  IF A is read only, Status Bar will show "Access Denied" and
  //       Save File commands ends.
  //     IF A is not read only, save file buffer to disk and remove modified
  //       flag in Title Bar , then Save File command ends.
  //
  // 4.  IF B does not exist, create this file and save file buffer to it.
  //       Go to do Step 7.
  //     IF B exits, do Step 5.
  //
  // 5.An Input Bar will be prompted:
  //      "File Exists. Overwrite ( Yes/No/Cancel )?"
  //       IF user press 'y' or 'Y', do Step 6.
  //       IF user press 'n' or 'N', Save File commands ends.
  //       IF user press 'c' or 'C' or ESC, Save File commands ends.
  //
  // 6. IF B is a read-only file, Status Bar will show "Access Denied" and
  //       Save File commands ends.
  //    IF B can be read and write, save file buffer to B.
  //
  // 7.  Update File Name field in Title Bar to B and remove the modified
  //       flag in Title Bar.
  //
  Str = CatSPrint (NULL, L"File to Save: [%s]", MainEditor.FileBuffer->FileName);
  if (Str == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (StrLen (Str) >= 50) {
    //
    // replace the long file name with "..."
    //
    Str[46] = L'.';
    Str[47] = L'.';
    Str[48] = L'.';
    Str[49] = L']';
    Str[50] = CHAR_NULL;
  }

  Status = InputBarSetPrompt (Str);
  FreePool (Str);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (100);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // get new file name
  //
  Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
  StatusBarSetRefresh ();

  //
  // if user pressed ESC
  //
  if (Status == EFI_NOT_READY) {
    return EFI_SUCCESS;
  }

  //
  // if just enter pressed, so think save to current file name
  //
  if (StrLen (InputBarGetString ()) == 0) {
    FileName = CatSPrint (NULL, L"%s", MainEditor.FileBuffer->FileName);
  } else {
    FileName = CatSPrint (NULL, L"%s", InputBarGetString ());
  }

  if (FileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!IsValidFileName (FileName)) {
    StatusBarSetStatusString (L"Invalid File Name");
    FreePool (FileName);
    return EFI_SUCCESS;
  }

  OldFile = FALSE;

  //
  // save to the old file
  //
  if (StringNoCaseCompare (&FileName, &MainEditor.FileBuffer->FileName) == 0) {
    OldFile = TRUE;
  }

  if (OldFile) {
    //
    // if the file is read only, so can not write back to it.
    //
    if (MainEditor.FileBuffer->ReadOnly == TRUE) {
      StatusBarSetStatusString (L"Access Denied");
      FreePool (FileName);
      return EFI_SUCCESS;
    }
  } else {
    //
    // if the file exists
    //
    if (ShellFileExists (FileName) != EFI_NOT_FOUND) {
      //
      // check for read only
      //
      Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
      if (EFI_ERROR (Status)) {
        StatusBarSetStatusString (L"Open Failed");
        FreePool (FileName);
        return EFI_SUCCESS;
      }

      Info = ShellGetFileInfo (FileHandle);
      if (Info == NULL) {
        StatusBarSetStatusString (L"Access Denied");
        FreePool (FileName);
        return (EFI_SUCCESS);
      }

      if (Info->Attribute & EFI_FILE_READ_ONLY) {
        StatusBarSetStatusString (L"Access Denied - Read Only");
        FreePool (Info);
        FreePool (FileName);
        return (EFI_SUCCESS);
      }

      FreePool (Info);

      //
      // ask user whether to overwrite this file
      //
      Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");
      if (EFI_ERROR (Status)) {
        SHELL_FREE_NON_NULL (FileName);
        return Status;
      }

      Status = InputBarSetStringSize (1);
      if (EFI_ERROR (Status)) {
        SHELL_FREE_NON_NULL (FileName);
        return Status;
      }

      while (TRUE) {
        Status = InputBarRefresh (MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column);
        StatusBarSetRefresh ();

        //
        // ESC pressed
        //
        if (Status == EFI_NOT_READY) {
          SHELL_FREE_NON_NULL (FileName);
          return EFI_SUCCESS;
        }

        switch (InputBarGetString ()[0]) {
          case L'y':
          case L'Y':
            break;

          case L'n':
          case L'N':
          case L'c':
          case L'C':
            SHELL_FREE_NON_NULL (FileName);
            return EFI_SUCCESS;
        } // end switch
      } // while (!done)
    } // file does exist
  } // if old file name same

  //
  // save file to disk with specified name
  //
  FileBufferSetModified ();
  Status = FileBufferSave (FileName);
  SHELL_FREE_NON_NULL (FileName);

  return Status;
}

/**
  Show help information for the editor.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
MainCommandDisplayHelp (
  VOID
  )
{
  INT32         CurrentLine;
  CHAR16        *InfoString;
  EFI_KEY_DATA  KeyData;
  EFI_STATUS    Status;
  UINTN         EventIndex;

  //
  // print helpInfo
  //
  for (CurrentLine = 0; 0 != MainMenuHelpInfo[CurrentLine]; CurrentLine++) {
    InfoString = HiiGetString (gShellDebug1HiiHandle, MainMenuHelpInfo[CurrentLine], NULL);
    if (InfoString != NULL) {
      ShellPrintEx (0, CurrentLine+1, L"%E%s%N", InfoString);
    }
  }

  //
  // scan for ctrl+w
  //
  while (TRUE) {
    Status = gBS->WaitForEvent (1, &MainEditor.TextInputEx->WaitForKeyEx, &EventIndex);
    if (EFI_ERROR (Status) || (EventIndex != 0)) {
      continue;
    }

    Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);
    if (EFI_ERROR (Status)) {
      continue;
    }

    if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) ||
        (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID))
    {
      //
      // For consoles that don't support/report shift state,
      // CTRL+W is translated to L'W' - L'A' + 1.
      //
      if (KeyData.Key.UnicodeChar == L'W' - L'A' + 1) {
        break;
      }
    } else if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) &&
               ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) &&
               ((KeyData.KeyState.KeyShiftState & ~(EFI_SHIFT_STATE_VALID | EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) == 0))
    {
      //
      // For consoles that supports/reports shift state,
      // make sure that only CONTROL shift key is pressed.
      //
      if ((KeyData.Key.UnicodeChar == 'w') || (KeyData.Key.UnicodeChar == 'W')) {
        break;
      }
    }
  }

  //
  // update screen with file buffer's info
  //
  FileBufferRestorePosition ();
  FileBufferNeedRefresh         = TRUE;
  FileBufferOnlyLineNeedRefresh = FALSE;
  FileBufferRefresh ();

  return EFI_SUCCESS;
}

EFI_EDITOR_COLOR_ATTRIBUTES  OriginalColors;
INTN                         OriginalMode;

//
// basic initialization for MainEditor
//
EFI_EDITOR_GLOBAL_EDITOR  MainEditorConst = {
  &FileBuffer,
  {
    { 0,      0}
  },
  {
    0,
    0
  },
  NULL,
  NULL,
  FALSE,
  NULL
};

/**
  The initialization function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainEditorInit (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  *HandleBuffer;
  UINTN       HandleCount;
  UINTN       Index;

  //
  // basic initialization
  //
  CopyMem (&MainEditor, &MainEditorConst, sizeof (MainEditor));

  //
  // set screen attributes
  //
  MainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;

  MainEditor.ColorAttributes.Colors.Background = (UINT8)(gST->ConOut->Mode->Attribute >> 4);
  OriginalColors                               = MainEditor.ColorAttributes.Colors;

  OriginalMode = gST->ConOut->Mode->Mode;

  //
  // query screen size
  //
  gST->ConOut->QueryMode (
                 gST->ConOut,
                 gST->ConOut->Mode->Mode,
                 &(MainEditor.ScreenSize.Column),
                 &(MainEditor.ScreenSize.Row)
                 );

  //
  // Find TextInEx in System Table ConsoleInHandle
  // Per UEFI Spec, TextInEx is required for a console capable platform.
  //
  Status = gBS->HandleProtocol (
                  gST->ConsoleInHandle,
                  &gEfiSimpleTextInputExProtocolGuid,
                  (VOID **)&MainEditor.TextInputEx
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Find mouse in System Table ConsoleInHandle
  //
  Status = gBS->HandleProtocol (
                  gST->ConsoleInHandle,
                  &gEfiSimplePointerProtocolGuid,
                  (VOID **)&MainEditor.MouseInterface
                  );
  if (EFI_ERROR (Status)) {
    //
    // If there is no Simple Pointer Protocol on System Table
    //
    HandleBuffer              = NULL;
    MainEditor.MouseInterface = NULL;
    Status                    = gBS->LocateHandleBuffer (
                                       ByProtocol,
                                       &gEfiSimplePointerProtocolGuid,
                                       NULL,
                                       &HandleCount,
                                       &HandleBuffer
                                       );
    if (!EFI_ERROR (Status) && (HandleCount > 0)) {
      //
      // Try to find the first available mouse device
      //
      for (Index = 0; Index < HandleCount; Index++) {
        Status = gBS->HandleProtocol (
                        HandleBuffer[Index],
                        &gEfiSimplePointerProtocolGuid,
                        (VOID **)&MainEditor.MouseInterface
                        );
        if (!EFI_ERROR (Status)) {
          break;
        }
      }
    }

    if (HandleBuffer != NULL) {
      FreePool (HandleBuffer);
    }
  }

  if (!EFI_ERROR (Status) && (MainEditor.MouseInterface != NULL)) {
    MainEditor.MouseAccumulatorX = 0;
    MainEditor.MouseAccumulatorY = 0;
    MainEditor.MouseSupported    = TRUE;
  }

  //
  // below will call the five components' init function
  //
  Status = MainTitleBarInit (L"UEFI EDIT");
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EDIT_LIBEDITOR_TITLEBAR), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = ControlHotKeyInit (MainControlBasedMenuFunctions);
  Status = MenuBarInit (MainMenuItems);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EDIT_LIBEDITOR_MAINMENU), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = StatusBarInit ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EDIT_LIBEDITOR_STATUSBAR), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  InputBarInit (MainEditor.TextInputEx);

  Status = FileBufferInit ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EDIT_LIBEDITOR_FILEBUFFER), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  //
  // clear whole screen and enable cursor
  //
  gST->ConOut->ClearScreen (gST->ConOut);
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  //
  // initialize EditorFirst and EditorExit
  //
  EditorFirst       = TRUE;
  EditorExit        = FALSE;
  EditorMouseAction = FALSE;

  return EFI_SUCCESS;
}

/**
  The cleanup function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
**/
EFI_STATUS
MainEditorCleanup (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // call the five components' cleanup function
  // if error, do not exit
  // just print some warning
  //
  MainTitleBarCleanup ();
  StatusBarCleanup ();
  InputBarCleanup ();
  MenuBarCleanup ();

  Status = FileBufferCleanup ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_EDIT_LIBEDITOR_FILEBUFFER_CLEANUP), gShellDebug1HiiHandle);
  }

  //
  // restore old mode
  //
  if (OriginalMode != gST->ConOut->Mode->Mode) {
    gST->ConOut->SetMode (gST->ConOut, OriginalMode);
  }

  //
  // restore old screen color
  //
  gST->ConOut->SetAttribute (
                 gST->ConOut,
                 EFI_TEXT_ATTR (OriginalColors.Foreground, OriginalColors.Background)
                 );

  gST->ConOut->ClearScreen (gST->ConOut);

  return EFI_SUCCESS;
}

/**
  Refresh the main editor component.
**/
VOID
MainEditorRefresh (
  VOID
  )
{
  //
  // The Stall value is from experience. NOT from spec.  avoids 'flicker'
  //
  gBS->Stall (50);

  //
  // call the components refresh function
  //
  if (  EditorFirst
     || (StrCmp (FileBufferBackupVar.FileName, FileBuffer.FileName) != 0)
     || (FileBufferBackupVar.FileType != FileBuffer.FileType)
     || (FileBufferBackupVar.FileModified != FileBuffer.FileModified)
     || (FileBufferBackupVar.ReadOnly != FileBuffer.ReadOnly))
  {
    MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
    FileBufferRestorePosition ();
  }

  if (  EditorFirst
     || (FileBufferBackupVar.FilePosition.Row != FileBuffer.FilePosition.Row)
     || (FileBufferBackupVar.FilePosition.Column != FileBuffer.FilePosition.Column)
     || (FileBufferBackupVar.ModeInsert != FileBuffer.ModeInsert)
     || StatusBarGetRefresh ())
  {
    StatusBarRefresh (EditorFirst, MainEditor.ScreenSize.Row, MainEditor.ScreenSize.Column, MainEditor.FileBuffer->FilePosition.Row, MainEditor.FileBuffer->FilePosition.Column, MainEditor.FileBuffer->ModeInsert);
    FileBufferRestorePosition ();
  }

  if (EditorFirst) {
    FileBufferRestorePosition ();
  }

  FileBufferRefresh ();

  //
  // EditorFirst is now set to FALSE
  //
  EditorFirst = FALSE;
}

/**
  Get's the resultant location of the cursor based on the relative movement of the Mouse.

  @param[in] GuidX    The relative mouse movement.

  @return The X location of the mouse.
**/
INT32
GetTextX (
  IN INT32  GuidX
  )
{
  INT32  Gap;

  MainEditor.MouseAccumulatorX += GuidX;
  Gap                           = (MainEditor.MouseAccumulatorX * (INT32)MainEditor.ScreenSize.Column) / (INT32)(50 * (INT32)MainEditor.MouseInterface->Mode->ResolutionX);
  MainEditor.MouseAccumulatorX  = (MainEditor.MouseAccumulatorX * (INT32)MainEditor.ScreenSize.Column) % (INT32)(50 * (INT32)MainEditor.MouseInterface->Mode->ResolutionX);
  MainEditor.MouseAccumulatorX  = MainEditor.MouseAccumulatorX / (INT32)MainEditor.ScreenSize.Column;
  return Gap;
}

/**
  Get's the resultant location of the cursor based on the relative movement of the Mouse.

  @param[in] GuidY    The relative mouse movement.

  @return The Y location of the mouse.
**/
INT32
GetTextY (
  IN INT32  GuidY
  )
{
  INT32  Gap;

  MainEditor.MouseAccumulatorY += GuidY;
  Gap                           = (MainEditor.MouseAccumulatorY * (INT32)MainEditor.ScreenSize.Row) / (INT32)(50 * (INT32)MainEditor.MouseInterface->Mode->ResolutionY);
  MainEditor.MouseAccumulatorY  = (MainEditor.MouseAccumulatorY * (INT32)MainEditor.ScreenSize.Row) % (INT32)(50 * (INT32)MainEditor.MouseInterface->Mode->ResolutionY);
  MainEditor.MouseAccumulatorY  = MainEditor.MouseAccumulatorY / (INT32)MainEditor.ScreenSize.Row;

  return Gap;
}

/**
  Support mouse movement.  Move the cursor.

  @param[in] MouseState     The current mouse state.

  @retval EFI_SUCCESS       The operation was successful.
  @retval EFI_NOT_FOUND     There was no mouse support found.
**/
EFI_STATUS
MainEditorHandleMouseInput (
  IN EFI_SIMPLE_POINTER_STATE  MouseState
  )
{
  INT32  TextX;
  INT32  TextY;
  UINTN  FRow;
  UINTN  FCol;

  LIST_ENTRY       *Link;
  EFI_EDITOR_LINE  *Line;

  UINTN    Index;
  BOOLEAN  Action;

  //
  // mouse action means:
  //    mouse movement
  //    mouse left button
  //
  Action = FALSE;

  //
  // have mouse movement
  //
  if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
    //
    // handle
    //
    TextX = GetTextX (MouseState.RelativeMovementX);
    TextY = GetTextY (MouseState.RelativeMovementY);

    FileBufferAdjustMousePosition (TextX, TextY);

    Action = TRUE;
  }

  //
  // if left button pushed down
  //
  if (MouseState.LeftButton) {
    FCol = MainEditor.FileBuffer->MousePosition.Column - 1 + 1;

    FRow = MainEditor.FileBuffer->FilePosition.Row +
           MainEditor.FileBuffer->MousePosition.Row -
           MainEditor.FileBuffer->DisplayPosition.Row;

    //
    // beyond the file line length
    //
    if (MainEditor.FileBuffer->NumLines < FRow) {
      FRow = MainEditor.FileBuffer->NumLines;
    }

    Link = MainEditor.FileBuffer->ListHead->ForwardLink;
    for (Index = 0; Index < FRow - 1; Index++) {
      Link = Link->ForwardLink;
    }

    Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

    //
    // beyond the line's column length
    //
    if (FCol > Line->Size + 1) {
      FCol = Line->Size + 1;
    }

    FileBufferMovePosition (FRow, FCol);

    MainEditor.FileBuffer->MousePosition.Row = MainEditor.FileBuffer->DisplayPosition.Row;

    MainEditor.FileBuffer->MousePosition.Column = MainEditor.FileBuffer->DisplayPosition.Column;

    Action = TRUE;
  }

  //
  // mouse has action
  //
  if (Action) {
    return EFI_SUCCESS;
  }

  //
  // no mouse action
  //
  return EFI_NOT_FOUND;
}

/**
  Handle user key input. This routes to other functions for the actions.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occurred.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
MainEditorKeyInput (
  VOID
  )
{
  EFI_KEY_DATA              KeyData;
  EFI_STATUS                Status;
  EFI_SIMPLE_POINTER_STATE  MouseState;
  BOOLEAN                   NoShiftState;

  do {
    Status            = EFI_SUCCESS;
    EditorMouseAction = FALSE;

    //
    // backup some key elements, so that can aVOID some refresh work
    //
    MainEditorBackup ();

    //
    // change priority of checking mouse/keyboard activity dynamically
    // so prevent starvation of keyboard.
    // if last time, mouse moves then this time check keyboard
    //
    if (MainEditor.MouseSupported) {
      Status = MainEditor.MouseInterface->GetState (
                                            MainEditor.MouseInterface,
                                            &MouseState
                                            );
      if (!EFI_ERROR (Status)) {
        Status = MainEditorHandleMouseInput (MouseState);

        if (!EFI_ERROR (Status)) {
          EditorMouseAction          = TRUE;
          FileBufferMouseNeedRefresh = TRUE;
        } else if (Status == EFI_LOAD_ERROR) {
          StatusBarSetStatusString (L"Invalid Mouse Movement ");
        }
      }
    }

    //
    // CheckEvent() returns Success when non-partial key is pressed.
    //
    Status = gBS->CheckEvent (MainEditor.TextInputEx->WaitForKeyEx);
    if (!EFI_ERROR (Status)) {
      Status = MainEditor.TextInputEx->ReadKeyStrokeEx (MainEditor.TextInputEx, &KeyData);
      if (!EFI_ERROR (Status)) {
        //
        // dispatch to different components' key handling function
        // so not everywhere has to set this variable
        //
        FileBufferMouseNeedRefresh = TRUE;
        //
        // clear previous status string
        //
        StatusBarSetRefresh ();
        //
        // NoShiftState: TRUE when no shift key is pressed.
        //
        NoShiftState = ((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) == 0) || (KeyData.KeyState.KeyShiftState == EFI_SHIFT_STATE_VALID);
        //
        // dispatch to different components' key handling function
        //
        if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey (&KeyData)) {
          Status = EFI_SUCCESS;
        } else if (NoShiftState && ((KeyData.Key.ScanCode == SCAN_NULL) || ((KeyData.Key.ScanCode >= SCAN_UP) && (KeyData.Key.ScanCode <= SCAN_PAGE_DOWN)))) {
          Status = FileBufferHandleInput (&KeyData.Key);
        } else if (NoShiftState && (KeyData.Key.ScanCode >= SCAN_F1) && (KeyData.Key.ScanCode <= SCAN_F12)) {
          Status = MenuBarDispatchFunctionKey (&KeyData.Key);
        } else {
          StatusBarSetStatusString (L"Unknown Command");
          FileBufferMouseNeedRefresh = FALSE;
        }

        if ((Status != EFI_SUCCESS) && (Status != EFI_OUT_OF_RESOURCES)) {
          //
          // not already has some error status
          //
          if ((StatusBarGetString () != NULL) && (StrCmp (L"", StatusBarGetString ()) == 0)) {
            StatusBarSetStatusString (L"Disk Error. Try Again");
          }
        }
      }
    }

    //
    // after handling, refresh editor
    //
    MainEditorRefresh ();
  } while (Status != EFI_OUT_OF_RESOURCES && !EditorExit);

  return Status;
}

/**
  Set clipboard

  @param[in] Line   A pointer to the line to be set to clipboard

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
**/
EFI_STATUS
MainEditorSetCutLine (
  EFI_EDITOR_LINE  *Line
  )
{
  if (Line == NULL) {
    return EFI_SUCCESS;
  }

  if (MainEditor.CutLine != NULL) {
    //
    // free the old clipboard
    //
    LineFree (MainEditor.CutLine);
  }

  //
  // duplicate the line to clipboard
  //
  MainEditor.CutLine = LineDup (Line);
  if (MainEditor.CutLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Backup function for MainEditor

  @retval EFI_SUCCESS The operation was successful.
**/
EFI_STATUS
MainEditorBackup (
  VOID
  )
{
  FileBufferBackup ();

  return EFI_SUCCESS;
}
