/** @file
  Implements editor interface functions.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "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 occured.
  @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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
  @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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
**/
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 occured.
  @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;
}
