/** @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);
    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;
}
