/** @file
  Implements editor interface functions.

  Copyright (c) 2005 - 2012, 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".
  //
  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_INPUT_KEY   Key;
  
  //
  // 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
  //
  do {
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
  } while(SCAN_CONTROL_W != Key.UnicodeChar); 

  //
  // 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,
  FALSE,
  NULL
};

/**
  The initialization function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
EFIAPI
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 mouse in System Table ConsoleInHandle
  //
  Status = gBS->HandleProtocol (
                gST->ConIn,
                &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 ();

  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
EFIAPI
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
EFIAPI
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 ();
    FileBufferRefresh ();
  }
  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 ();
    FileBufferRefresh ();
  }

  if (EditorFirst) {
    FileBufferRestorePosition ();
  }

  //
  // 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
EFIAPI
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
EFIAPI
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
EFIAPI
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
EFIAPI
MainEditorKeyInput (
  VOID
  )
{
  EFI_INPUT_KEY             Key;
  EFI_STATUS                Status;
  EFI_SIMPLE_POINTER_STATE  MouseState;

  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 ");
        }
      }
    }

    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    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();

      //
      // dispatch to different components' key handling function
      //
      if (EFI_NOT_FOUND != MenuBarDispatchControlHotKey(&Key)) {
        Status = EFI_SUCCESS;
      } else if ((Key.ScanCode == SCAN_NULL) || ((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
        Status = FileBufferHandleInput (&Key);
      } else if ((Key.ScanCode >= SCAN_F1) && (Key.ScanCode <= SCAN_F12)) {
        Status = MenuBarDispatchFunctionKey (&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
EFIAPI
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
EFIAPI
MainEditorBackup (
  VOID
  )
{
  FileBufferBackup ();
  
  return EFI_SUCCESS;
}
