/** @file
  Implements filebuffer interface functions.

  Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "TextEditor.h"
#include <Guid/FileSystemInfo.h>
#include <Library/FileHandleLib.h>

EFI_EDITOR_FILE_BUFFER  FileBuffer;
EFI_EDITOR_FILE_BUFFER  FileBufferBackupVar;

//
// for basic initialization of FileBuffer
//
EFI_EDITOR_FILE_BUFFER  FileBufferConst = {
  NULL,
  FileTypeUnicode,
  NULL,
  NULL,
  0,
  {
    0,
    0
  },
  {
    0,
    0
  },
  {
    0,
    0
  },
  {
    0,
    0
  },
  FALSE,
  TRUE,
  FALSE,
  NULL
};

//
// the whole edit area needs to be refreshed
//
BOOLEAN          FileBufferNeedRefresh;

//
// only the current line in edit area needs to be refresh
//
BOOLEAN                 FileBufferOnlyLineNeedRefresh;

BOOLEAN                 FileBufferMouseNeedRefresh;

extern BOOLEAN          EditorMouseAction;

/**
  Initialization function for FileBuffer.

  @param EFI_SUCCESS            The initialization was successful.
  @param EFI_LOAD_ERROR         A default name could not be created.
  @param EFI_OUT_OF_RESOURCES   A memory allocation failed.
**/
EFI_STATUS
FileBufferInit (
  VOID
  )
{
  //
  // basically initialize the FileBuffer
  //
  CopyMem (&FileBuffer         , &FileBufferConst, sizeof (EFI_EDITOR_FILE_BUFFER));
  CopyMem (&FileBufferBackupVar, &FileBufferConst, sizeof (EFI_EDITOR_FILE_BUFFER));

  //
  // set default FileName
  //
  FileBuffer.FileName = EditGetDefaultFileName (L"txt");
  if (FileBuffer.FileName == NULL) {
    return EFI_LOAD_ERROR;
  }

  FileBuffer.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY));
  if (FileBuffer.ListHead == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (FileBuffer.ListHead);

  FileBuffer.DisplayPosition.Row    = 2;
  FileBuffer.DisplayPosition.Column = 1;
  FileBuffer.LowVisibleRange.Row    = 2;
  FileBuffer.LowVisibleRange.Column = 1;

  FileBufferNeedRefresh             = FALSE;
  FileBufferMouseNeedRefresh        = FALSE;
  FileBufferOnlyLineNeedRefresh     = FALSE;

  return EFI_SUCCESS;
}

/**
  Backup function for FileBuffer.  Only backup the following items:
      Mouse/Cursor position
      File Name, Type, ReadOnly, Modified
      Insert Mode

  This is for making the file buffer refresh as few as possible.

  @retval EFI_SUCCESS           The backup operation was successful.
**/
EFI_STATUS
FileBufferBackup (
  VOID
  )
{
  FileBufferBackupVar.MousePosition = FileBuffer.MousePosition;

  SHELL_FREE_NON_NULL (FileBufferBackupVar.FileName);
  FileBufferBackupVar.FileName        = NULL;
  FileBufferBackupVar.FileName        = StrnCatGrow (&FileBufferBackupVar.FileName, NULL, FileBuffer.FileName, 0);

  FileBufferBackupVar.ModeInsert      = FileBuffer.ModeInsert;
  FileBufferBackupVar.FileType        = FileBuffer.FileType;

  FileBufferBackupVar.FilePosition    = FileBuffer.FilePosition;
  FileBufferBackupVar.LowVisibleRange = FileBuffer.LowVisibleRange;

  FileBufferBackupVar.FileModified    = FileBuffer.FileModified;
  FileBufferBackupVar.ReadOnly        = FileBuffer.ReadOnly;

  return EFI_SUCCESS;
}

/**
  Advance to the next Count lines

  @param[in] Count              The line number to advance by.
  @param[in] CurrentLine        The pointer to the current line structure.
  @param[in] LineList           The pointer to the linked list of lines.

  @retval NULL                  There was an error.
  @return  The line structure after the advance.
**/
EFI_EDITOR_LINE *
InternalEditorMiscLineAdvance (
  IN CONST UINTN            Count,
  IN CONST EFI_EDITOR_LINE  *CurrentLine,
  IN CONST LIST_ENTRY       *LineList
  )

{
  UINTN                 Index;
  CONST EFI_EDITOR_LINE *Line;

  if (CurrentLine == NULL || LineList == NULL) {
    return NULL;
  }

  for (Line = CurrentLine, Index = 0; Index < Count; Index++) {
    //
    // if already last line
    //
    if (Line->Link.ForwardLink == LineList) {
      return NULL;
    }

    Line = CR (Line->Link.ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
  }

  return ((EFI_EDITOR_LINE *)Line);
}

/**
  Retreat to the previous Count lines.

  @param[in] Count              The line number to retreat by.
  @param[in] CurrentLine        The pointer to the current line structure.
  @param[in] LineList           The pointer to the linked list of lines.

  @retval NULL                  There was an error.
  @return  The line structure after the retreat.
**/
EFI_EDITOR_LINE *
InternalEditorMiscLineRetreat (
  IN CONST UINTN            Count,
  IN CONST EFI_EDITOR_LINE  *CurrentLine,
  IN CONST LIST_ENTRY       *LineList
  )

{
  UINTN                 Index;
  CONST EFI_EDITOR_LINE *Line;

  if (CurrentLine == NULL || LineList == NULL) {
    return NULL;
  }

  for (Line = CurrentLine, Index = 0; Index < Count; Index++) {
    //
    // already the first line
    //
    if (Line->Link.BackLink == LineList) {
      return NULL;
    }

    Line = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
  }

  return ((EFI_EDITOR_LINE *)Line);
}

/**
  Advance/Retreat lines

  @param[in] Count  line number to advance/retreat
                       >0 : advance
                       <0 : retreat

  @retval NULL An error occurred.
  @return The line after advance/retreat.
**/
EFI_EDITOR_LINE *
MoveLine (
  IN CONST INTN Count
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           AbsCount;

  //
  // if < 0, then retreat
  // if > 0, the advance
  //
  if (Count <= 0) {
    AbsCount  = (UINTN)ABS(Count);
    Line      = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
  } else {
    Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
  }

  return Line;
}

/**
  Function to update the 'screen' to display the mouse position.

  @retval EFI_SUCCESS           The backup operation was successful.
**/
EFI_STATUS
FileBufferRestoreMousePosition (
  VOID
  )
{
  EFI_EDITOR_COLOR_UNION  Orig;
  EFI_EDITOR_COLOR_UNION  New;
  UINTN                   FRow;
  UINTN                   FColumn;
  BOOLEAN                 HasCharacter;
  EFI_EDITOR_LINE         *CurrentLine;
  EFI_EDITOR_LINE         *Line;
  CHAR16                  Value;

  //
  // variable initialization
  //
  Line = NULL;

  if (MainEditor.MouseSupported) {

    if (FileBufferMouseNeedRefresh) {

      FileBufferMouseNeedRefresh = FALSE;

      //
      // if mouse position not moved and only mouse action
      // so do not need to refresh mouse position
      //
      if ((FileBuffer.MousePosition.Row == FileBufferBackupVar.MousePosition.Row &&
          FileBuffer.MousePosition.Column == FileBufferBackupVar.MousePosition.Column)
          && EditorMouseAction) {
        return EFI_SUCCESS;
      }
      //
      // backup the old screen attributes
      //
      Orig                  = MainEditor.ColorAttributes;
      New.Data              = 0;
      New.Colors.Foreground = Orig.Colors.Background & 0xF;
      New.Colors.Background = Orig.Colors.Foreground & 0x7;

      //
      // clear the old mouse position
      //
      FRow          = FileBuffer.LowVisibleRange.Row + FileBufferBackupVar.MousePosition.Row - 2;

      FColumn       = FileBuffer.LowVisibleRange.Column + FileBufferBackupVar.MousePosition.Column - 1;

      HasCharacter  = TRUE;
      if (FRow > FileBuffer.NumLines) {
        HasCharacter = FALSE;
      } else {
        CurrentLine = FileBuffer.CurrentLine;
        Line        = MoveLine (FRow - FileBuffer.FilePosition.Row);

        if (Line == NULL || FColumn > Line->Size) {
          HasCharacter = FALSE;
        }

        FileBuffer.CurrentLine = CurrentLine;
      }

      ShellPrintEx (
        (INT32)FileBufferBackupVar.MousePosition.Column - 1,
        (INT32)FileBufferBackupVar.MousePosition.Row - 1,
        L" "
        );

      if (HasCharacter) {
        Value = (Line->Buffer[FColumn - 1]);
        ShellPrintEx (
          (INT32)FileBufferBackupVar.MousePosition.Column - 1,
          (INT32)FileBufferBackupVar.MousePosition.Row - 1,
          L"%c",
          Value
          );
      }
      //
      // set the new mouse position
      //
      gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);

      //
      // clear the old mouse position
      //
      FRow          = FileBuffer.LowVisibleRange.Row + FileBuffer.MousePosition.Row - 2;
      FColumn       = FileBuffer.LowVisibleRange.Column + FileBuffer.MousePosition.Column - 1;

      HasCharacter  = TRUE;
      if (FRow > FileBuffer.NumLines) {
        HasCharacter = FALSE;
      } else {
        CurrentLine = FileBuffer.CurrentLine;
        Line        = MoveLine (FRow - FileBuffer.FilePosition.Row);

        if (Line == NULL || FColumn > Line->Size) {
          HasCharacter = FALSE;
        }

        FileBuffer.CurrentLine = CurrentLine;
      }

      ShellPrintEx (
        (INT32)FileBuffer.MousePosition.Column - 1,
        (INT32)FileBuffer.MousePosition.Row - 1,
        L" "
        );

      if (HasCharacter) {
        Value = Line->Buffer[FColumn - 1];
        ShellPrintEx (
          (INT32)FileBuffer.MousePosition.Column - 1,
          (INT32)FileBuffer.MousePosition.Row - 1,
          L"%c",
          Value
          );
      }
      //
      // end of HasCharacter
      //
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
    }
    //
    // end of MouseNeedRefresh
    //
  }
  //
  // end of MouseSupported
  //
  return EFI_SUCCESS;
}

/**
  Free all the lines in FileBuffer
   Fields affected:
     Lines
     CurrentLine
     NumLines
     ListHead

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferFreeLines (
  VOID
  )
{
  LIST_ENTRY  *Link;
  EFI_EDITOR_LINE *Line;

  //
  // free all the lines
  //
  if (FileBuffer.Lines != NULL) {

    Line  = FileBuffer.Lines;
    Link  = &(Line->Link);
    do {
      Line  = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
      Link  = Link->ForwardLink;

      //
      // free line's buffer and line itself
      //
      LineFree (Line);
    } while (Link != FileBuffer.ListHead);
  }
  //
  // clean the line list related structure
  //
  FileBuffer.Lines            = NULL;
  FileBuffer.CurrentLine      = NULL;
  FileBuffer.NumLines         = 0;

  FileBuffer.ListHead->ForwardLink  = FileBuffer.ListHead;
  FileBuffer.ListHead->BackLink  = FileBuffer.ListHead;

  return EFI_SUCCESS;
}

/**
  Cleanup function for FileBuffer.

  @retval EFI_SUCCESS   The cleanup was successful.
**/
EFI_STATUS
FileBufferCleanup (
  VOID
  )
{
  EFI_STATUS  Status;

  SHELL_FREE_NON_NULL (FileBuffer.FileName);

  //
  // free all the lines
  //
  Status = FileBufferFreeLines ();

  SHELL_FREE_NON_NULL (FileBuffer.ListHead);
  FileBuffer.ListHead = NULL;

  SHELL_FREE_NON_NULL (FileBufferBackupVar.FileName);
  return Status;

}

/**
  Print a line specified by Line on a row specified by Row of the screen.

  @param[in] Line               The line to print.
  @param[in] Row                The row on the screen to print onto (begin from 1).

  @retval EFI_SUCCESS           The printing was successful.
**/
EFI_STATUS
FileBufferPrintLine (
  IN CONST EFI_EDITOR_LINE  *Line,
  IN CONST UINTN            Row
  )
{

  CHAR16  *Buffer;
  UINTN   Limit;
  CHAR16  *PrintLine;
  CHAR16  *PrintLine2;
  UINTN   BufLen;

  //
  // print start from correct character
  //
  Buffer  = Line->Buffer + FileBuffer.LowVisibleRange.Column - 1;

  Limit   = Line->Size - FileBuffer.LowVisibleRange.Column + 1;
  if (Limit > Line->Size) {
    Limit = 0;
  }

  BufLen = (MainEditor.ScreenSize.Column + 1) * sizeof (CHAR16);
  PrintLine = AllocatePool (BufLen);
  if (PrintLine != NULL) {
    StrnCpyS (PrintLine, BufLen/sizeof(CHAR16), Buffer, MIN(Limit, MainEditor.ScreenSize.Column));
    for (Limit = StrLen (PrintLine); Limit < MainEditor.ScreenSize.Column; Limit++) {
      PrintLine[Limit] = L' ';
    }

    PrintLine[MainEditor.ScreenSize.Column] = CHAR_NULL;

    PrintLine2 = AllocatePool (BufLen * 2);
    if (PrintLine2 != NULL) {
      ShellCopySearchAndReplace(PrintLine, PrintLine2, BufLen * 2, L"%", L"^%", FALSE, FALSE);

      ShellPrintEx (
        0,
        (INT32)Row - 1,
        L"%s",
        PrintLine2
        );
      FreePool (PrintLine2);
    }
    FreePool (PrintLine);
  }

  return EFI_SUCCESS;
}

/**
  Set the cursor position according to FileBuffer.DisplayPosition.

  @retval EFI_SUCCESS           The operation was successful.
**/
EFI_STATUS
FileBufferRestorePosition (
  VOID
  )
{
  //
  // set cursor position
  //
  return (gST->ConOut->SetCursorPosition (
        gST->ConOut,
        FileBuffer.DisplayPosition.Column - 1,
        FileBuffer.DisplayPosition.Row - 1
        ));
}

/**
  Refresh the screen with whats in the buffer.

  @retval EFI_SUCCESS     The refresh was successful.
  @retval EFI_LOAD_ERROR  There was an error finding what to write.
**/
EFI_STATUS
FileBufferRefresh (
  VOID
  )
{
  LIST_ENTRY  *Link;
  EFI_EDITOR_LINE *Line;
  UINTN           Row;

  //
  // if it's the first time after editor launch, so should refresh
  //
  if (!EditorFirst) {
    //
    // no definite required refresh
    // and file position displayed on screen has not been changed
    //
    if (!FileBufferNeedRefresh &&
        !FileBufferOnlyLineNeedRefresh &&
        FileBufferBackupVar.LowVisibleRange.Row == FileBuffer.LowVisibleRange.Row &&
        FileBufferBackupVar.LowVisibleRange.Column == FileBuffer.LowVisibleRange.Column
        ) {

      FileBufferRestoreMousePosition ();
      FileBufferRestorePosition ();

      return EFI_SUCCESS;
    }
  }

  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

  //
  // only need to refresh current line
  //
  if (FileBufferOnlyLineNeedRefresh &&
      FileBufferBackupVar.LowVisibleRange.Row == FileBuffer.LowVisibleRange.Row &&
      FileBufferBackupVar.LowVisibleRange.Column == FileBuffer.LowVisibleRange.Column
      ) {

    EditorClearLine (FileBuffer.DisplayPosition.Row, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row);
    FileBufferPrintLine (
      FileBuffer.CurrentLine,
      FileBuffer.DisplayPosition.Row
      );
  } else {
    //
    // the whole edit area need refresh
    //

    //
    // no line
    //
    if (FileBuffer.Lines == NULL) {
      FileBufferRestoreMousePosition ();
      FileBufferRestorePosition ();
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);

      return EFI_SUCCESS;
    }
    //
    // get the first line that will be displayed
    //
    Line = MoveLine (FileBuffer.LowVisibleRange.Row - FileBuffer.FilePosition.Row);
    if (Line == NULL) {
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);

      return EFI_LOAD_ERROR;
    }

    Link  = &(Line->Link);
    Row   = 2;
    do {
      Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

      //
      // print line at row
      //
      FileBufferPrintLine (Line, Row);

      Link = Link->ForwardLink;
      Row++;
    } while (Link != FileBuffer.ListHead && Row <= (MainEditor.ScreenSize.Row - 1));
    //
    // while not file end and not screen full
    //
    while (Row <= (MainEditor.ScreenSize.Row - 1)) {
      EditorClearLine (Row, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row);
      Row++;
    }
  }

  FileBufferRestoreMousePosition ();
  FileBufferRestorePosition ();

  FileBufferNeedRefresh         = FALSE;
  FileBufferOnlyLineNeedRefresh = FALSE;

  gST->ConOut->EnableCursor (gST->ConOut, TRUE);
  return EFI_SUCCESS;
}

/**
  Create a new line and append it to the line list.
    Fields affected:
      NumLines
      Lines

  @retval NULL    The create line failed.
  @return         The line created.
**/
EFI_EDITOR_LINE *
FileBufferCreateLine (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;

  //
  // allocate a line structure
  //
  Line = AllocateZeroPool (sizeof (EFI_EDITOR_LINE));
  if (Line == NULL) {
    return NULL;
  }
  //
  // initialize the structure
  //
  Line->Signature = LINE_LIST_SIGNATURE;
  Line->Size      = 0;
  Line->TotalSize = 0;
  Line->Type      = NewLineTypeDefault;

  //
  // initial buffer of the line is "\0"
  //
  ASSERT(CHAR_NULL == CHAR_NULL);
  Line->Buffer = CatSPrint (NULL, L"\0");
  if (Line->Buffer == NULL) {
    return NULL;
  }

  FileBuffer.NumLines++;

  //
  // insert the line into line list
  //
  InsertTailList (FileBuffer.ListHead, &Line->Link);

  if (FileBuffer.Lines == NULL) {
    FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
  }

  return Line;
}

/**
  Set FileName field in FileBuffer.

  @param Str                    The file name to set.

  @retval EFI_SUCCESS           The filename was successfully set.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_INVALID_PARAMETER Str is not a valid filename.
**/
EFI_STATUS
FileBufferSetFileName (
  IN CONST CHAR16 *Str
  )
{
  //
  // Verify the parameters
  //
  if (!IsValidFileName(Str)) {
    return (EFI_INVALID_PARAMETER);
  }
  //
  // free the old file name
  //
  SHELL_FREE_NON_NULL (FileBuffer.FileName);

  //
  // Allocate and set the new name
  //
  FileBuffer.FileName = CatSPrint (NULL, L"%s", Str);
  if (FileBuffer.FileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}
/**
  Free the existing file lines and reset the modified flag.

  @retval EFI_SUCCESS           The operation was successful.
**/
EFI_STATUS
FileBufferFree (
  VOID
  )
{
  //
  // free all the lines
  //
  FileBufferFreeLines ();
  FileBuffer.FileModified = FALSE;

  return EFI_SUCCESS;
}


/**
  Read a file from disk into the FileBuffer.

  @param[in] FileName           The filename to read.
  @param[in] Recover            TRUE if is for recover mode, no information printouts.

  @retval EFI_SUCCESS            The load was successful.
  @retval EFI_LOAD_ERROR         The load failed.
  @retval EFI_OUT_OF_RESOURCES   A memory allocation failed.
  @retval EFI_INVALID_PARAMETER  FileName is a directory.
**/
EFI_STATUS
FileBufferRead (
  IN CONST CHAR16  *FileName,
  IN CONST BOOLEAN Recover
  )
{
  EFI_EDITOR_LINE                 *Line;
  EE_NEWLINE_TYPE                 Type;
  UINTN                           LoopVar1;
  UINTN                           LoopVar2;
  UINTN                           LineSize;
  VOID                            *Buffer;
  CHAR16                          *UnicodeBuffer;
  UINT8                           *AsciiBuffer;
  UINTN                           FileSize;
  SHELL_FILE_HANDLE               FileHandle;
  BOOLEAN                         CreateFile;
  EFI_STATUS                      Status;
  UINTN                           LineSizeBackup;
  EFI_FILE_INFO                   *Info;

  Line          = NULL;
  LoopVar1      = 0;
  FileSize      = 0;
  UnicodeBuffer = NULL;
  Type          = NewLineTypeDefault;
  FileHandle    = NULL;
  CreateFile    = FALSE;

  //
  // in this function, when you return error ( except EFI_OUT_OF_RESOURCES )
  // you should set status string via StatusBarSetStatusString(L"blah")
  // since this function maybe called before the editorhandleinput loop
  // so any error will cause editor return
  // so if you want to print the error status
  // you should set the status string
  //

  //
  // try to open the file
  //
  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);

  if (!EFI_ERROR(Status)) {
    CreateFile = FALSE;
    if (FileHandle == NULL) {
      StatusBarSetStatusString (L"Disk Error");
      return EFI_LOAD_ERROR;
    }

    Info = ShellGetFileInfo(FileHandle);

    if (Info->Attribute & EFI_FILE_DIRECTORY) {
      StatusBarSetStatusString (L"Directory Can Not Be Edited");
      FreePool (Info);
      return EFI_INVALID_PARAMETER;
    }

    if (Info->Attribute & EFI_FILE_READ_ONLY) {
      FileBuffer.ReadOnly = TRUE;
    } else {
      FileBuffer.ReadOnly = FALSE;
    }
    //
    // get file size
    //
    FileSize = (UINTN) Info->FileSize;

    FreePool (Info);
  } else if (Status == EFI_NOT_FOUND) {
    //
    // file not exists.  add create and try again
    //
    Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, 0);
    if (EFI_ERROR (Status)) {
      if (Status == EFI_WRITE_PROTECTED ||
          Status == EFI_ACCESS_DENIED ||
          Status == EFI_NO_MEDIA ||
          Status == EFI_MEDIA_CHANGED
          ) {
        StatusBarSetStatusString (L"Access Denied");
      } else if (Status == EFI_DEVICE_ERROR || Status == EFI_VOLUME_CORRUPTED || Status == EFI_VOLUME_FULL) {
        StatusBarSetStatusString (L"Disk Error");
      } else {
        StatusBarSetStatusString (L"Invalid File Name or Current-working-directory");
      }

      return Status;
    } else {
      //
      // it worked.  now delete it and move on with the name (now validated)
      //
      Status = ShellDeleteFile (&FileHandle);
      if (Status == EFI_WARN_DELETE_FAILURE) {
        Status = EFI_ACCESS_DENIED;
      }
      FileHandle = NULL;
      if (EFI_ERROR (Status)) {
        StatusBarSetStatusString (L"Access Denied");
        return Status;
      }
    }
    //
    // file doesn't exist, so set CreateFile to TRUE
    //
    CreateFile          = TRUE;
    FileBuffer.ReadOnly = FALSE;

    //
    // all the check ends
    // so now begin to set file name, free lines
    //
    if (StrCmp (FileName, FileBuffer.FileName) != 0) {
      FileBufferSetFileName (FileName);
    }
    //
    // free the old lines
    //
    FileBufferFree ();

  }
  //
  // the file exists
  //
  if (!CreateFile) {
    //
    // allocate buffer to read file
    //
    Buffer = AllocateZeroPool (FileSize);
    if (Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // read file into Buffer
    //
    Status = ShellReadFile (FileHandle, &FileSize, Buffer);
    ShellCloseFile(&FileHandle);
    FileHandle = NULL;
    if (EFI_ERROR (Status)) {
      StatusBarSetStatusString (L"Read File Failed");
      SHELL_FREE_NON_NULL (Buffer);
      return EFI_LOAD_ERROR;
    }
    //
    // nothing in this file
    //
    if (FileSize == 0) {
      SHELL_FREE_NON_NULL (Buffer);
      //
      // since has no head, so only can be an ASCII file
      //
      FileBuffer.FileType = FileTypeAscii;

      goto Done;
    }

    AsciiBuffer = Buffer;

    if (FileSize < 2) {
      //
      // size < Unicode file header, so only can be ASCII file
      //
      FileBuffer.FileType = FileTypeAscii;
    } else {
      //
      // Unicode file
      //
      if (*(UINT16 *) Buffer == EFI_UNICODE_BYTE_ORDER_MARK) {
        //
        // Unicode file's size should be even
        //
        if ((FileSize % 2) != 0) {
          StatusBarSetStatusString (L"File Format Wrong");
          SHELL_FREE_NON_NULL (Buffer);
          return EFI_LOAD_ERROR;
        }

        FileSize /= 2;

        FileBuffer.FileType = FileTypeUnicode;
        UnicodeBuffer       = Buffer;

        //
        // pass this 0xff and 0xfe
        //
        UnicodeBuffer++;
        FileSize--;
      } else {
        FileBuffer.FileType = FileTypeAscii;
      }
      //
      // end of AsciiBuffer ==
      //
    }
    //
    // end of FileSize < 2
    // all the check ends
    // so now begin to set file name, free lines
    //
    if (StrCmp (FileName, FileBuffer.FileName) != 0) {
      FileBufferSetFileName (FileName);
    }

    //
    // free the old lines
    //
    FileBufferFree ();

    //
    // parse file content line by line
    //
    for (LoopVar1 = 0; LoopVar1 < FileSize; LoopVar1++) {
      Type = NewLineTypeUnknown;

      for (LineSize = LoopVar1; LineSize < FileSize; LineSize++) {
        if (FileBuffer.FileType == FileTypeAscii) {
          if (AsciiBuffer[LineSize] == CHAR_CARRIAGE_RETURN) {
            Type = NewLineTypeCarriageReturn;

            //
            // has LF following
            //
            if (LineSize < FileSize - 1) {
              if (AsciiBuffer[LineSize + 1] == CHAR_LINEFEED) {
                Type = NewLineTypeCarriageReturnLineFeed;
              }
            }

            break;
          } else if (AsciiBuffer[LineSize] == CHAR_LINEFEED) {
            Type = NewLineTypeLineFeed;

            //
            // has CR following
            //
            if (LineSize < FileSize - 1) {
              if (AsciiBuffer[LineSize + 1] == CHAR_CARRIAGE_RETURN) {
                Type = NewLineTypeLineFeedCarriageReturn;
              }
            }

            break;
          }
        } else {
          if (UnicodeBuffer[LineSize] == CHAR_CARRIAGE_RETURN) {
            Type = NewLineTypeCarriageReturn;

            //
            // has LF following
            //
            if (LineSize < FileSize - 1) {
              if (UnicodeBuffer[LineSize + 1] == CHAR_LINEFEED) {
                Type = NewLineTypeCarriageReturnLineFeed;
              }
            }

            break;
          } else if (UnicodeBuffer[LineSize] == CHAR_LINEFEED) {
            Type = NewLineTypeLineFeed;

            //
            // has CR following
            //
            if (LineSize < FileSize - 1) {
              if (UnicodeBuffer[LineSize + 1] == CHAR_CARRIAGE_RETURN) {
                Type = NewLineTypeLineFeedCarriageReturn;
              }
            }

            break;
          }
        }
        //
        // endif == ASCII
        //
      }
      //
      // end of for LineSize
      //
      // if the type is wrong, then exit
      //
      if (Type == NewLineTypeUnknown) {
        //
        // Now if Type is NewLineTypeUnknown, it should be file end
        //
        Type = NewLineTypeDefault;
      }

      LineSizeBackup = LineSize;

      //
      // create a new line
      //
      Line = FileBufferCreateLine ();
      if (Line == NULL) {
        SHELL_FREE_NON_NULL (Buffer);
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // calculate file length
      //
      LineSize -= LoopVar1;

      //
      // Unicode and one CHAR_NULL
      //
      SHELL_FREE_NON_NULL (Line->Buffer);
      Line->Buffer = AllocateZeroPool (LineSize * 2 + 2);

      if (Line->Buffer == NULL) {
        RemoveEntryList (&Line->Link);
        return EFI_OUT_OF_RESOURCES;
      }
      //
      // copy this line to Line->Buffer
      //
      for (LoopVar2 = 0; LoopVar2 < LineSize; LoopVar2++) {
        if (FileBuffer.FileType == FileTypeAscii) {
          Line->Buffer[LoopVar2] = (CHAR16) AsciiBuffer[LoopVar1];
        } else {
          Line->Buffer[LoopVar2] = UnicodeBuffer[LoopVar1];
        }

        LoopVar1++;
      }
      //
      // LoopVar1 now points to where CHAR_CARRIAGE_RETURN or CHAR_LINEFEED;
      //
      Line->Buffer[LineSize]  = 0;

      Line->Size              = LineSize;
      Line->TotalSize         = LineSize;
      Line->Type              = Type;

      if (Type == NewLineTypeCarriageReturnLineFeed || Type == NewLineTypeLineFeedCarriageReturn) {
        LoopVar1++;
      }

      //
      // last character is a return, SO create a new line
      //
      if (((Type == NewLineTypeCarriageReturnLineFeed || Type == NewLineTypeLineFeedCarriageReturn) && LineSizeBackup == FileSize - 2) ||
          ((Type == NewLineTypeLineFeed || Type == NewLineTypeCarriageReturn) && LineSizeBackup == FileSize - 1)
          ) {
        Line = FileBufferCreateLine ();
        if (Line == NULL) {
          SHELL_FREE_NON_NULL (Buffer);
          return EFI_OUT_OF_RESOURCES;
        }
      }
      //
      // end of if
      //
    }
    //
    // end of LoopVar1
    //
    SHELL_FREE_NON_NULL (Buffer);

  }
  //
  // end of if CreateFile
  //
Done:

  FileBuffer.DisplayPosition.Row    = 2;
  FileBuffer.DisplayPosition.Column = 1;
  FileBuffer.LowVisibleRange.Row    = 1;
  FileBuffer.LowVisibleRange.Column = 1;
  FileBuffer.FilePosition.Row       = 1;
  FileBuffer.FilePosition.Column    = 1;
  FileBuffer.MousePosition.Row      = 2;
  FileBuffer.MousePosition.Column   = 1;

  if (!Recover) {
    UnicodeBuffer = CatSPrint (NULL, L"%d Lines Read", FileBuffer.NumLines);
    if (UnicodeBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    StatusBarSetStatusString (UnicodeBuffer);
    FreePool (UnicodeBuffer);
  }
/*
    //
    // check whether we have fs?: in filename
    //
    LoopVar1             = 0;
    FSMappingPtr  = NULL;
    while (FileName[LoopVar1] != 0) {
      if (FileName[LoopVar1] == L':') {
        FSMappingPtr = &FileName[LoopVar1];
        break;
      }

      LoopVar1++;
    }

    if (FSMappingPtr == NULL) {
      CurDir = ShellGetCurrentDir (NULL);
    } else {
      LoopVar1 = 0;
      LoopVar2 = 0;
      while (FileName[LoopVar1] != 0) {
        if (FileName[LoopVar1] == L':') {
          break;
        }

        FSMapping[LoopVar2++] = FileName[LoopVar1];

        LoopVar1++;
      }

      FSMapping[LoopVar2]  = 0;
      CurDir        = ShellGetCurrentDir (FSMapping);
    }

    if (CurDir != NULL) {
      for (LoopVar1 = 0; LoopVar1 < StrLen (CurDir) && CurDir[LoopVar1] != ':'; LoopVar1++);

      CurDir[LoopVar1]   = 0;
      DevicePath  = (EFI_DEVICE_PATH_PROTOCOL *) ShellGetMap (CurDir);
      FreePool (CurDir);
    } else {
      return EFI_LOAD_ERROR;
    }

    Status = LibDevicePathToInterface (
              &gEfiSimpleFileSystemProtocolGuid,
              DevicePath,
              (VOID **) &Vol
              );
    if (EFI_ERROR (Status)) {
      return EFI_LOAD_ERROR;
    }

    Status = Vol->OpenVolume (Vol, &RootFs);
    if (EFI_ERROR (Status)) {
      return EFI_LOAD_ERROR;
    }
    //
    // Get volume information of file system
    //
    Size        = SIZE_OF_EFI_FILE_SYSTEM_INFO + 100;
    VolumeInfo  = (EFI_FILE_SYSTEM_INFO *) AllocateZeroPool (Size);
    Status      = RootFs->GetInfo (RootFs, &gEfiFileSystemInfoGuid, &Size, VolumeInfo);
    if (EFI_ERROR (Status)) {
      RootFs->Close (RootFs);
      return EFI_LOAD_ERROR;
    }

    if (VolumeInfo->ReadOnly) {
      StatusBarSetStatusString (L"WARNING: Volume Read Only");
    }

    FreePool (VolumeInfo);
    RootFs->Close (RootFs);
  }
//
*/
  //
  // has line
  //
  if (FileBuffer.Lines != 0) {
    FileBuffer.CurrentLine = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
  } else {
    //
    // create a dummy line
    //
    Line = FileBufferCreateLine ();
    if (Line == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    FileBuffer.CurrentLine = Line;
  }

  FileBuffer.FileModified       = FALSE;
  FileBufferNeedRefresh         = TRUE;
  FileBufferOnlyLineNeedRefresh = FALSE;
  FileBufferMouseNeedRefresh    = TRUE;


  return EFI_SUCCESS;
}

/**
  According to FileBuffer.NewLineType & FileBuffer.FileType,
  get the return buffer and size.

  @param[in] Type               The type of line.
  @param[out] Buffer            The buffer to fill.
  @param[out] Size              The amount of the buffer used on return.
**/
VOID
GetNewLine (
  IN CONST EE_NEWLINE_TYPE Type,
  OUT CHAR8           *Buffer,
  OUT UINT8           *Size
  )
{
  UINT8 NewLineSize;

  //
  // give new line buffer,
  // and will judge unicode or ascii
  //
  NewLineSize = 0;

  //
  // not legal new line type
  //
  if (Type != NewLineTypeLineFeed && Type != NewLineTypeCarriageReturn && Type != NewLineTypeCarriageReturnLineFeed && Type != NewLineTypeLineFeedCarriageReturn) {
    *Size = 0;
    return ;
  }
  //
  // use_cr: give 0x0d
  //
  if (Type == NewLineTypeCarriageReturn) {
    if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
      Buffer[0]   = 0x0d;
      Buffer[1]   = 0;
      NewLineSize = 2;
    } else {
      Buffer[0]   = 0x0d;
      NewLineSize = 1;
    }

    *Size = NewLineSize;
    return ;
  }
  //
  // use_lf: give 0x0a
  //
  if (Type == NewLineTypeLineFeed) {
    if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
      Buffer[0]   = 0x0a;
      Buffer[1]   = 0;
      NewLineSize = 2;
    } else {
      Buffer[0]   = 0x0a;
      NewLineSize = 1;
    }

    *Size = NewLineSize;
    return ;
  }
  //
  // use_crlf: give 0x0d 0x0a
  //
  if (Type == NewLineTypeCarriageReturnLineFeed) {
    if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
      Buffer[0]   = 0x0d;
      Buffer[1]   = 0;
      Buffer[2]   = 0x0a;
      Buffer[3]   = 0;

      NewLineSize = 4;
    } else {
      Buffer[0]   = 0x0d;
      Buffer[1]   = 0x0a;
      NewLineSize = 2;
    }

    *Size = NewLineSize;
    return ;
  }
  //
  // use_lfcr: give 0x0a 0x0d
  //
  if (Type == NewLineTypeLineFeedCarriageReturn) {
    if (MainEditor.FileBuffer->FileType == FileTypeUnicode) {
      Buffer[0]   = 0x0a;
      Buffer[1]   = 0;
      Buffer[2]   = 0x0d;
      Buffer[3]   = 0;

      NewLineSize = 4;
    } else {
      Buffer[0]   = 0x0a;
      Buffer[1]   = 0x0d;
      NewLineSize = 2;
    }

    *Size = NewLineSize;
    return ;
  }

}

/**
  Change a Unicode string to an ASCII string.

  @param[in] UStr     The Unicode string.
  @param[in] Length   The maximum size of AStr.
  @param[out] AStr    ASCII string to pass out.

  @return The actuall length.
**/
UINTN
UnicodeToAscii (
  IN CONST CHAR16   *UStr,
  IN CONST UINTN    Length,
  OUT CHAR8         *AStr
  )
{
  UINTN Index;

  //
  // just buffer copy, not character copy
  //
  for (Index = 0; Index < Length; Index++) {
    *AStr++ = (CHAR8) *UStr++;
  }

  return Index;
}

/**
  Save lines in FileBuffer to disk

  @param[in] FileName           The file name for writing.

  @retval EFI_SUCCESS           Data was written.
  @retval EFI_LOAD_ERROR
  @retval EFI_OUT_OF_RESOURCES  There were not enough resources to write the file.
**/
EFI_STATUS
FileBufferSave (
  IN CONST CHAR16 *FileName
  )
{
  SHELL_FILE_HANDLE FileHandle;
  LIST_ENTRY        *Link;
  EFI_EDITOR_LINE   *Line;
  CHAR16            *Str;

  EFI_STATUS        Status;
  UINTN             Length;
  UINTN             NumLines;
  CHAR8             NewLineBuffer[4];
  UINT8             NewLineSize;

  EFI_FILE_INFO     *Info;

  UINT64            Attribute;

  EE_NEWLINE_TYPE   Type;

  UINTN             TotalSize;
  //
  // 2M
  //
  CHAR8             *Cache;
  UINTN             LeftSize;
  UINTN             Size;
  CHAR8             *Ptr;

  Length    = 0;
  //
  // 2M
  //
  TotalSize = 0x200000;

  Attribute = 0;



  //
  // if is the old file
  //
  if (FileBuffer.FileName != NULL && StrCmp (FileName, FileBuffer.FileName) == 0) {
    //
    // file has not been modified
    //
    if (!FileBuffer.FileModified) {
      return EFI_SUCCESS;
    }

    //
    // if file is read-only, set error
    //
    if (FileBuffer.ReadOnly) {
      StatusBarSetStatusString (L"Read Only File Can Not Be Saved");
      return EFI_SUCCESS;
    }
  }

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0);

  if (!EFI_ERROR (Status)) {
    Info = ShellGetFileInfo(FileHandle);

    if (Info != NULL && Info->Attribute & EFI_FILE_DIRECTORY) {
      StatusBarSetStatusString (L"Directory Can Not Be Saved");
      ShellCloseFile (&FileHandle);
      FreePool(Info);
      return EFI_LOAD_ERROR;
    }

    if (Info != NULL) {
      Attribute = Info->Attribute & ~EFI_FILE_READ_ONLY;
      FreePool(Info);
    }

    //
    // if file exits, so delete it
    //
    Status = ShellDeleteFile (&FileHandle);
    if (EFI_ERROR (Status) || Status == EFI_WARN_DELETE_FAILURE) {
      StatusBarSetStatusString (L"Write File Failed");
      return EFI_LOAD_ERROR;
    }
 }

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_CREATE, Attribute);

  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Create File Failed");
    return EFI_LOAD_ERROR;
  }

  //
  // if file is Unicode file, write Unicode header to it.
  //
  if (FileBuffer.FileType == FileTypeUnicode) {
    Length  = 2;
    Status  = ShellWriteFile (FileHandle, &Length, (VOID*)&gUnicodeFileTag);
    if (EFI_ERROR (Status)) {
      ShellDeleteFile (&FileHandle);
      return EFI_LOAD_ERROR;
    }
  }

  Cache = AllocateZeroPool (TotalSize);
  if (Cache == NULL) {
    ShellDeleteFile (&FileHandle);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // write all the lines back to disk
  //
  NumLines  = 0;
  Type      = NewLineTypeCarriageReturnLineFeed;

  Ptr       = Cache;
  LeftSize  = TotalSize;

  for (Link = FileBuffer.ListHead->ForwardLink; Link != FileBuffer.ListHead; Link = Link->ForwardLink) {
    Line = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

    if (Line->Type != NewLineTypeDefault) {
      Type = Line->Type;
    }
    //
    // newline character is at most 4 bytes ( two Unicode characters )
    //
    Length = 4;
    if (Line->Buffer != NULL && Line->Size != 0) {
      if (FileBuffer.FileType == FileTypeAscii) {
        Length += Line->Size;
      } else {
        Length += (Line->Size * 2);
      }
      //
      // end if FileTypeAscii
      //
    }

    //
    // no cache room left, so write cache to disk
    //
    if (LeftSize < Length) {
      Size    = TotalSize - LeftSize;
      Status  = ShellWriteFile (FileHandle, &Size, Cache);
      if (EFI_ERROR (Status)) {
        ShellDeleteFile (&FileHandle);
        FreePool (Cache);
        return EFI_LOAD_ERROR;
      }
      Ptr       = Cache;
      LeftSize  = TotalSize;
    }

    if (Line->Buffer != NULL && Line->Size != 0) {
      if (FileBuffer.FileType == FileTypeAscii) {
        UnicodeToAscii (Line->Buffer, Line->Size, Ptr);
        Length = Line->Size;
      } else {
        Length = (Line->Size * 2);
        CopyMem (Ptr, (CHAR8 *) Line->Buffer, Length);
      }
      //
      // end if FileTypeAscii
      //
      Ptr += Length;
      LeftSize -= Length;

    }
    //
    // end of if Line -> Buffer != NULL && Line -> Size != 0
    //
    // if not the last line , write return buffer to disk
    //
    if (Link->ForwardLink != FileBuffer.ListHead) {
      GetNewLine (Type, NewLineBuffer, &NewLineSize);
      CopyMem (Ptr, (CHAR8 *) NewLineBuffer, NewLineSize);

      Ptr += NewLineSize;
      LeftSize -= NewLineSize;
    }

    NumLines++;
  }

  if (TotalSize != LeftSize) {
    Size    = TotalSize - LeftSize;
    Status  = ShellWriteFile (FileHandle, &Size, Cache);
    if (EFI_ERROR (Status)) {
      ShellDeleteFile (&FileHandle);
      FreePool (Cache);
      return EFI_LOAD_ERROR;
    }
  }

  FreePool (Cache);

  ShellCloseFile(&FileHandle);

  FileBuffer.FileModified = FALSE;

  //
  // set status string
  //
  Str = CatSPrint (NULL, L"%d Lines Written", NumLines);
  if (Str == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  StatusBarSetStatusString (Str);
  SHELL_FREE_NON_NULL (Str);

  //
  // now everything is ready , you can set the new file name to filebuffer
  //
  if (FileName != NULL && FileBuffer.FileName != NULL && StrCmp (FileName, FileBuffer.FileName) != 0) {
    //
    // not the same
    //
    FileBufferSetFileName (FileName);
    if (FileBuffer.FileName == NULL) {
      ShellDeleteFile (&FileHandle);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  FileBuffer.ReadOnly = FALSE;
  return EFI_SUCCESS;
}

/**
  Scroll cursor to left 1 character position.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferScrollLeft (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;

  Line  = FileBuffer.CurrentLine;

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // if already at start of this line, so move to the end of previous line
  //
  if (FCol <= 1) {
    //
    // has previous line
    //
    if (Line->Link.BackLink != FileBuffer.ListHead) {
      FRow--;
      Line  = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
      FCol  = Line->Size + 1;
    } else {
      return EFI_SUCCESS;
    }
  } else {
    //
    // if not at start of this line, just move to previous column
    //
    FCol--;
  }

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Delete a char in line

  @param[in, out] Line   The line to delete in.
  @param[in] Pos         Position to delete the char at ( start from 0 ).
**/
VOID
LineDeleteAt (
  IN  OUT EFI_EDITOR_LINE       *Line,
  IN      UINTN                 Pos
  )
{
  UINTN Index;

  //
  // move the latter characters front
  //
  for (Index = Pos - 1; Index < Line->Size; Index++) {
    Line->Buffer[Index] = Line->Buffer[Index + 1];
  }

  Line->Size--;
}

/**
  Concatenate Src into Dest.

  @param[in, out] Dest   Destination string
  @param[in] Src         Src String.
**/
VOID
LineCat (
  IN  OUT EFI_EDITOR_LINE *Dest,
  IN      EFI_EDITOR_LINE *Src
  )
{
  CHAR16  *Str;
  UINTN   Size;

  Size                = Dest->Size;

  Dest->Buffer[Size]  = 0;

  //
  // concatenate the two strings
  //
  Str = CatSPrint (NULL, L"%s%s", Dest->Buffer, Src->Buffer);
  if (Str == NULL) {
    Dest->Buffer = NULL;
    return ;
  }

  Dest->Size      = Size + Src->Size;
  Dest->TotalSize = Dest->Size;

  FreePool (Dest->Buffer);
  FreePool (Src->Buffer);

  //
  // put str to dest->buffer
  //
  Dest->Buffer = Str;
}

/**
  Delete the previous character.

  @retval EFI_SUCCESS           The delete was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
FileBufferDoBackspace (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  EFI_EDITOR_LINE *End;
  LIST_ENTRY  *Link;
  UINTN           FileColumn;

  FileColumn  = FileBuffer.FilePosition.Column;

  Line        = FileBuffer.CurrentLine;

  //
  // the first column
  //
  if (FileColumn == 1) {
    //
    // the first row
    //
    if (FileBuffer.FilePosition.Row == 1) {
      return EFI_SUCCESS;
    }

    FileBufferScrollLeft ();

    Line  = FileBuffer.CurrentLine;
    Link  = Line->Link.ForwardLink;
    End   = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

    //
    // concatenate this line with previous line
    //
    LineCat (Line, End);
    if (Line->Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // remove End from line list
    //
    RemoveEntryList (&End->Link);
    FreePool (End);

    FileBuffer.NumLines--;

    FileBufferNeedRefresh         = TRUE;
    FileBufferOnlyLineNeedRefresh = FALSE;

  } else {
    //
    // just delete the previous character
    //
    LineDeleteAt (Line, FileColumn - 1);
    FileBufferScrollLeft ();
    FileBufferOnlyLineNeedRefresh = TRUE;
  }

  if (!FileBuffer.FileModified) {
    FileBuffer.FileModified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Add a return into line at current position.

  @retval EFI_SUCCESS           The insetrion of the character was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
FileBufferDoReturn (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  EFI_EDITOR_LINE *NewLine;
  UINTN           FileColumn;
  UINTN           Index;
  CHAR16          *Buffer;
  UINTN           Row;
  UINTN           Col;

  FileBufferNeedRefresh         = TRUE;
  FileBufferOnlyLineNeedRefresh = FALSE;

  Line                          = FileBuffer.CurrentLine;

  FileColumn                    = FileBuffer.FilePosition.Column;

  NewLine                       = AllocateZeroPool (sizeof (EFI_EDITOR_LINE));
  if (NewLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewLine->Signature  = LINE_LIST_SIGNATURE;
  NewLine->Size       = Line->Size - FileColumn + 1;
  NewLine->TotalSize  = NewLine->Size;
  NewLine->Buffer     = CatSPrint (NULL, L"\0");
  if (NewLine->Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NewLine->Type = NewLineTypeDefault;

  if (NewLine->Size > 0) {
    //
    // UNICODE + CHAR_NULL
    //
    Buffer = AllocateZeroPool (2 * (NewLine->Size + 1));
    if (Buffer == NULL) {
      FreePool (NewLine->Buffer);
      FreePool (NewLine);
      return EFI_OUT_OF_RESOURCES;
    }

    FreePool (NewLine->Buffer);

    NewLine->Buffer = Buffer;

    for (Index = 0; Index < NewLine->Size; Index++) {
      NewLine->Buffer[Index] = Line->Buffer[Index + FileColumn - 1];
    }

    NewLine->Buffer[NewLine->Size]  = CHAR_NULL;

    Line->Buffer[FileColumn - 1]    = CHAR_NULL;
    Line->Size                      = FileColumn - 1;
  }
  //
  // increase NumLines
  //
  FileBuffer.NumLines++;

  //
  // insert it into the correct position of line list
  //
  NewLine->Link.BackLink     = &(Line->Link);
  NewLine->Link.ForwardLink     = Line->Link.ForwardLink;
  Line->Link.ForwardLink->BackLink = &(NewLine->Link);
  Line->Link.ForwardLink        = &(NewLine->Link);

  //
  // move cursor to the start of next line
  //
  Row = FileBuffer.FilePosition.Row + 1;
  Col = 1;

  FileBufferMovePosition (Row, Col);

  //
  // set file is modified
  //
  if (!FileBuffer.FileModified) {
    FileBuffer.FileModified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Delete current character from current line.  This is the effect caused
  by the 'del' key.

  @retval EFI_SUCCESS
**/
EFI_STATUS
FileBufferDoDelete (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  EFI_EDITOR_LINE *Next;
  LIST_ENTRY  *Link;
  UINTN           FileColumn;

  Line        = FileBuffer.CurrentLine;
  FileColumn  = FileBuffer.FilePosition.Column;

  //
  // the last column
  //
  if (FileColumn >= Line->Size + 1) {
    //
    // the last line
    //
    if (Line->Link.ForwardLink == FileBuffer.ListHead) {
      return EFI_SUCCESS;
    }
    //
    // since last character,
    // so will add the next line to this line
    //
    Link  = Line->Link.ForwardLink;
    Next  = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
    LineCat (Line, Next);
    if (Line->Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    RemoveEntryList (&Next->Link);
    FreePool (Next);

    FileBuffer.NumLines--;

    FileBufferNeedRefresh         = TRUE;
    FileBufferOnlyLineNeedRefresh = FALSE;

  } else {
    //
    // just delete current character
    //
    LineDeleteAt (Line, FileColumn);
    FileBufferOnlyLineNeedRefresh = TRUE;
  }

  if (!FileBuffer.FileModified) {
    FileBuffer.FileModified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Scroll cursor to right 1 character.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferScrollRight (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;

  Line = FileBuffer.CurrentLine;
  if (Line->Buffer == NULL) {
    return EFI_SUCCESS;
  }

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // if already at end of this line, scroll it to the start of next line
  //
  if (FCol > Line->Size) {
    //
    // has next line
    //
    if (Line->Link.ForwardLink != FileBuffer.ListHead) {
      FRow++;
      FCol = 1;
    } else {
      return EFI_SUCCESS;
    }
  } else {
    //
    // if not at end of this line, just move to next column
    //
    FCol++;
  }

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Insert a char into line


  @param[in] Line     The line to insert into.
  @param[in] Char     The char to insert.
  @param[in] Pos      The position to insert the char at ( start from 0 ).
  @param[in] StrSize  The current string size ( include CHAR_NULL ),unit is Unicode character.

  @return The new string size ( include CHAR_NULL ) ( unit is Unicode character ).
**/
UINTN
LineStrInsert (
  IN      EFI_EDITOR_LINE  *Line,
  IN      CHAR16           Char,
  IN      UINTN            Pos,
  IN      UINTN            StrSize
  )
{
  UINTN   Index;
  CHAR16  *TempStringPtr;
  CHAR16  *Str;

  Index = (StrSize) * 2;

  Str   = Line->Buffer;

  //
  // do not have free space
  //
  if (Line->TotalSize <= Line->Size) {
    Str = ReallocatePool (Index, Index + 16, Str);
    if (Str == NULL) {
      return 0;
    }

    Line->TotalSize += 8;
  }
  //
  // move the later part of the string one character right
  //
  TempStringPtr = Str;
  for (Index = StrSize; Index > Pos; Index--) {
    TempStringPtr[Index] = TempStringPtr[Index - 1];
  }
  //
  // insert char into it.
  //
  TempStringPtr[Index]      = Char;

  Line->Buffer  = Str;
  Line->Size++;

  return StrSize + 1;
}

/**
  Add a character to the current line.

  @param[in] Char               The Character to input.

  @retval EFI_SUCCESS           The input was succesful.
**/
EFI_STATUS
FileBufferAddChar (
  IN  CHAR16  Char
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FilePos;

  Line = FileBuffer.CurrentLine;

  //
  // only needs to refresh current line
  //
  FileBufferOnlyLineNeedRefresh = TRUE;

  //
  // when is insert mode, or cursor is at end of this line,
  // so insert this character
  // or replace the character.
  //
  FilePos = FileBuffer.FilePosition.Column - 1;
  if (FileBuffer.ModeInsert || FilePos + 1 > Line->Size) {
    LineStrInsert (Line, Char, FilePos, Line->Size + 1);
  } else {
    Line->Buffer[FilePos] = Char;
  }
  //
  // move cursor to right
  //
  FileBufferScrollRight ();

  if (!FileBuffer.FileModified) {
    FileBuffer.FileModified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Handles inputs from characters (ASCII key + Backspace + return)

  @param[in] Char               The input character.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_LOAD_ERROR        There was an error.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
FileBufferDoCharInput (
  IN CONST CHAR16 Char
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  switch (Char) {
  case CHAR_NULL:
    break;

  case CHAR_BACKSPACE:
    Status = FileBufferDoBackspace ();
    break;

  case CHAR_TAB:
    //
    // Tabs are ignored
    //
    break;

  case CHAR_LINEFEED:
  case CHAR_CARRIAGE_RETURN:
    Status = FileBufferDoReturn ();
    break;

  default:
    //
    // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
    //
    if (Char > 127 || Char < 32) {
      Status = StatusBarSetStatusString (L"Unknown Command");
    } else {
      Status = FileBufferAddChar (Char);
    }

    break;

  }

  return Status;
}

/**
  Scroll cursor to the next line.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferScrollDown (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;

  Line = FileBuffer.CurrentLine;
  if (Line->Buffer == NULL) {
    return EFI_SUCCESS;
  }

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // has next line
  //
  if (Line->Link.ForwardLink != FileBuffer.ListHead) {
    FRow++;
    Line = CR (Line->Link.ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

    //
    // if the next line is not that long, so move to end of next line
    //
    if (FCol > Line->Size) {
      FCol = Line->Size + 1;
    }

  } else {
    return EFI_SUCCESS;
  }

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Scroll the cursor to previous line.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferScrollUp (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;

  Line  = FileBuffer.CurrentLine;

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // has previous line
  //
  if (Line->Link.BackLink != FileBuffer.ListHead) {
    FRow--;
    Line = CR (Line->Link.BackLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

    //
    // if previous line is not that long, so move to the end of previous line
    //
    if (FCol > Line->Size) {
      FCol = Line->Size + 1;
    }

  } else {
    return EFI_SUCCESS;
  }

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to next page.

  @retval EFI_SUCCESS     The operation wa successful.
**/
EFI_STATUS
FileBufferPageDown (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;
  UINTN           Gap;

  Line  = FileBuffer.CurrentLine;

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // has next page
  //
  if (FileBuffer.NumLines >= FRow + (MainEditor.ScreenSize.Row - 2)) {
    Gap = (MainEditor.ScreenSize.Row - 2);
  } else {
    //
    // MOVE CURSOR TO LAST LINE
    //
    Gap = FileBuffer.NumLines - FRow;
  }
  //
  // get correct line
  //
  Line = MoveLine (Gap);

  //
  // if that line, is not that long, so move to the end of that line
  //
  if (Line != NULL && FCol > Line->Size) {
    FCol = Line->Size + 1;
  }

  FRow += Gap;

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to previous screen.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
FileBufferPageUp (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;
  UINTN           Gap;
  INTN            Retreat;

  Line  = FileBuffer.CurrentLine;

  FRow  = FileBuffer.FilePosition.Row;
  FCol  = FileBuffer.FilePosition.Column;

  //
  // has previous page
  //
  if (FRow > (MainEditor.ScreenSize.Row - 2)) {
    Gap = (MainEditor.ScreenSize.Row - 2);
  } else {
    //
    // the first line of file will displayed on the first line of screen
    //
    Gap = FRow - 1;
  }

  Retreat = Gap;
  Retreat = -Retreat;

  //
  // get correct line
  //
  Line = MoveLine (Retreat);

  //
  // if that line is not that long, so move to the end of that line
  //
  if (Line != NULL && FCol > Line->Size) {
    FCol = Line->Size + 1;
  }

  FRow -= Gap;

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to end of the current line.

  @retval EFI_SUCCESS       The operation was successful.
**/
EFI_STATUS
FileBufferEnd (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           FRow;
  UINTN           FCol;

  Line  = FileBuffer.CurrentLine;

  FRow  = FileBuffer.FilePosition.Row;

  //
  // goto the last column of the line
  //
  FCol = Line->Size + 1;

  FileBufferMovePosition (FRow, FCol);

  return EFI_SUCCESS;
}

/**
  Dispatch input to different handler
  @param[in] Key                The input key.  One of:
                                    ASCII KEY
                                    Backspace/Delete
                                    Return
                                    Direction key: up/down/left/right/pgup/pgdn
                                    Home/End
                                    INS

  @retval EFI_SUCCESS           The dispatch was done successfully.
  @retval EFI_LOAD_ERROR        The dispatch was not successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
FileBufferHandleInput (
  IN CONST EFI_INPUT_KEY *Key
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  switch (Key->ScanCode) {
  //
  // ordinary key input
  //
  case SCAN_NULL:
    if (!FileBuffer.ReadOnly) {
      Status = FileBufferDoCharInput (Key->UnicodeChar);
    } else {
      Status = StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
    }

    break;

  //
  // up arrow
  //
  case SCAN_UP:
    Status = FileBufferScrollUp ();
    break;

  //
  // down arrow
  //
  case SCAN_DOWN:
    Status = FileBufferScrollDown ();
    break;

  //
  // right arrow
  //
  case SCAN_RIGHT:
    Status = FileBufferScrollRight ();
    break;

  //
  // left arrow
  //
  case SCAN_LEFT:
    Status = FileBufferScrollLeft ();
    break;

  //
  // page up
  //
  case SCAN_PAGE_UP:
    Status = FileBufferPageUp ();
    break;

  //
  // page down
  //
  case SCAN_PAGE_DOWN:
    Status = FileBufferPageDown ();
    break;

  //
  // delete
  //
  case SCAN_DELETE:
    if (!FileBuffer.ReadOnly) {
      Status = FileBufferDoDelete ();
    } else {
      Status = StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
    }

    break;

  //
  // home
  //
  case SCAN_HOME:
    FileBufferMovePosition (FileBuffer.FilePosition.Row, 1);
    Status = EFI_SUCCESS;
    break;

  //
  // end
  //
  case SCAN_END:
    Status = FileBufferEnd ();
    break;

  //
  // insert
  //
  case SCAN_INSERT:
    FileBuffer.ModeInsert = (BOOLEAN)!FileBuffer.ModeInsert;
    Status = EFI_SUCCESS;
    break;

  default:
    Status = StatusBarSetStatusString (L"Unknown Command");
    break;
  }

  return Status;
}

/**
  Check user specified FileRow is above current screen.

  @param[in] FileRow    The row of file position ( start from 1 ).

  @retval TRUE    It is above the current screen.
  @retval FALSE   It is not above the current screen.
**/
BOOLEAN
AboveCurrentScreen (
  IN UINTN FileRow
  )
{
  //
  // if is to the above of the screen
  //
  if (FileRow < FileBuffer.LowVisibleRange.Row) {
    return TRUE;
  }

  return FALSE;
}

/**
  Check user specified FileRow is under current screen.

  @param[in] FileRow    The row of file position ( start from 1 ).

  @retval TRUE      It is under the current screen.
  @retval FALSE     It is not under the current screen.
**/
BOOLEAN
UnderCurrentScreen (
  IN UINTN FileRow
  )
{
  //
  // if is to the under of the screen
  //
  if (FileRow > FileBuffer.LowVisibleRange.Row + (MainEditor.ScreenSize.Row - 2) - 1) {
    return TRUE;
  }

  return FALSE;
}

/**
  Check user specified FileCol is left to current screen.

  @param[in] FileCol    The column of file position ( start from 1 ).

  @retval TRUE    It is to the left.
  @retval FALSE   It is not to the left.
**/
BOOLEAN
LeftCurrentScreen (
  IN UINTN FileCol
  )
{
  //
  // if is to the left of the screen
  //
  if (FileCol < FileBuffer.LowVisibleRange.Column) {
    return TRUE;
  }

  return FALSE;
}

/**
  Check user specified FileCol is right to current screen.

  @param[in] FileCol    The column of file position ( start from 1 ).

  @retval TRUE    It is to the right.
  @retval FALSE   It is not to the right.
**/
BOOLEAN
RightCurrentScreen (
  IN UINTN FileCol
  )
{
  //
  // if is to the right of the screen
  //
  if (FileCol > FileBuffer.LowVisibleRange.Column + MainEditor.ScreenSize.Column - 1) {
    return TRUE;
  }

  return FALSE;
}

/**
  Advance/Retreat lines and set CurrentLine in FileBuffer to it

  @param[in] Count The line number to advance/retreat
                     >0 : advance
                     <0: retreat

  @retval NULL An error occurred.
  @return The line after advance/retreat.
**/
EFI_EDITOR_LINE *
MoveCurrentLine (
  IN  INTN Count
  )
{
  EFI_EDITOR_LINE *Line;
  UINTN           AbsCount;

  if (Count <= 0) {
    AbsCount  = (UINTN)ABS(Count);
    Line      = InternalEditorMiscLineRetreat (AbsCount,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
  } else {
    Line = InternalEditorMiscLineAdvance ((UINTN)Count,MainEditor.FileBuffer->CurrentLine,MainEditor.FileBuffer->ListHead);
  }

  if (Line == NULL) {
    return NULL;
  }

  MainEditor.FileBuffer->CurrentLine = Line;

  return Line;
}

/**
  According to cursor's file position, adjust screen display

  @param[in] NewFilePosRow    The row of file position ( start from 1 ).
  @param[in] NewFilePosCol    The column of file position ( start from 1 ).
**/
VOID
FileBufferMovePosition (
  IN CONST UINTN NewFilePosRow,
  IN CONST UINTN NewFilePosCol
  )
{
  INTN    RowGap;
  INTN    ColGap;
  UINTN   Abs;
  BOOLEAN Above;
  BOOLEAN Under;
  BOOLEAN Right;
  BOOLEAN Left;

  //
  // CALCULATE gap between current file position and new file position
  //
  RowGap  = NewFilePosRow - FileBuffer.FilePosition.Row;
  ColGap  = NewFilePosCol - FileBuffer.FilePosition.Column;

  Under   = UnderCurrentScreen (NewFilePosRow);
  Above   = AboveCurrentScreen (NewFilePosRow);
  //
  // if is below current screen
  //
  if (Under) {
    //
    // display row will be unchanged
    //
    FileBuffer.FilePosition.Row = NewFilePosRow;
  } else {
    if (Above) {
      //
      // has enough above line, so display row unchanged
      // not has enough above lines, so the first line is at the
      // first display line
      //
      if (NewFilePosRow < (FileBuffer.DisplayPosition.Row - 1)) {
        FileBuffer.DisplayPosition.Row = NewFilePosRow + 1;
      }

      FileBuffer.FilePosition.Row = NewFilePosRow;
    } else {
      //
      // in current screen
      //
      FileBuffer.FilePosition.Row = NewFilePosRow;
      if (RowGap < 0) {
        Abs = (UINTN)ABS(RowGap);
        FileBuffer.DisplayPosition.Row -= Abs;
      } else {
        FileBuffer.DisplayPosition.Row += RowGap;
      }
    }
  }

  FileBuffer.LowVisibleRange.Row  = FileBuffer.FilePosition.Row - (FileBuffer.DisplayPosition.Row - 2);

  Right = RightCurrentScreen (NewFilePosCol);
  Left = LeftCurrentScreen (NewFilePosCol);

  //
  // if right to current screen
  //
  if (Right) {
    //
    // display column will be changed to end
    //
    FileBuffer.DisplayPosition.Column = MainEditor.ScreenSize.Column;
    FileBuffer.FilePosition.Column    = NewFilePosCol;
  } else {
    if (Left) {
      //
      // has enough left characters , so display row unchanged
      // not has enough left characters,
      // so the first character is at the first display column
      //
      if (NewFilePosCol < (FileBuffer.DisplayPosition.Column)) {
        FileBuffer.DisplayPosition.Column = NewFilePosCol;
      }

      FileBuffer.FilePosition.Column = NewFilePosCol;
    } else {
      //
      // in current screen
      //
      FileBuffer.FilePosition.Column = NewFilePosCol;
      if (ColGap < 0) {
        Abs = (UINTN)(-ColGap);
        FileBuffer.DisplayPosition.Column -= Abs;
      } else {
        FileBuffer.DisplayPosition.Column += ColGap;
      }
    }
  }

  FileBuffer.LowVisibleRange.Column = FileBuffer.FilePosition.Column - (FileBuffer.DisplayPosition.Column - 1);

  //
  // let CurrentLine point to correct line;
  //
  FileBuffer.CurrentLine = MoveCurrentLine (RowGap);

}

/**
  Cut current line out and return a pointer to it.

  @param[out] CutLine    Upon a successful return pointer to the pointer to
                        the allocated cut line.

  @retval EFI_SUCCESS             The cut was successful.
  @retval EFI_NOT_FOUND           There was no selection to cut.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
FileBufferCutLine (
  OUT EFI_EDITOR_LINE **CutLine
  )
{
  EFI_EDITOR_LINE *Line;
  EFI_EDITOR_LINE *NewLine;
  UINTN           Row;
  UINTN           Col;

  *CutLine      = NULL;

  if (FileBuffer.ReadOnly) {
    StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
    return EFI_SUCCESS;
  }

  Line = FileBuffer.CurrentLine;

  //
  // if is the last dummy line, SO CAN not cut
  //
  if (StrCmp (Line->Buffer, L"\0") == 0 && Line->Link.ForwardLink == FileBuffer.ListHead
  //
  // last line
  //
  ) {
    //
    // LAST LINE AND NOTHING ON THIS LINE, SO CUT NOTHING
    //
    StatusBarSetStatusString (L"Nothing to Cut");
    return EFI_NOT_FOUND;
  }
  //
  // if is the last line, so create a dummy line
  //
  if (Line->Link.ForwardLink == FileBuffer.ListHead) {
    //
    // last line
    // create a new line
    //
    NewLine = FileBufferCreateLine ();
    if (NewLine == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  FileBuffer.NumLines--;
  Row = FileBuffer.FilePosition.Row;
  Col = 1;
  //
  // move home
  //
  FileBuffer.CurrentLine = CR (
                            FileBuffer.CurrentLine->Link.ForwardLink,
                            EFI_EDITOR_LINE,
                            Link,
                            LINE_LIST_SIGNATURE
                            );

  RemoveEntryList (&Line->Link);

  FileBuffer.Lines = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

  FileBufferMovePosition (Row, Col);

  FileBuffer.FileModified       = TRUE;
  FileBufferNeedRefresh         = TRUE;
  FileBufferOnlyLineNeedRefresh = FALSE;

  *CutLine                      = Line;

  return EFI_SUCCESS;
}

/**
  Paste a line into line list.

  @retval EFI_SUCCESS             The paste was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
FileBufferPasteLine (
  VOID
  )
{
  EFI_EDITOR_LINE *Line;
  EFI_EDITOR_LINE *NewLine;
  UINTN           Row;
  UINTN           Col;

  //
  // if nothing is on clip board
  // then do nothing
  //
  if (MainEditor.CutLine == NULL) {
    return EFI_SUCCESS;
  }
  //
  // read only file can not be pasted on
  //
  if (FileBuffer.ReadOnly) {
    StatusBarSetStatusString (L"Read Only File Can Not Be Modified");
    return EFI_SUCCESS;
  }

  NewLine = LineDup (MainEditor.CutLine);
  if (NewLine == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // insert it above current line
  //
  Line                    = FileBuffer.CurrentLine;
  NewLine->Link.BackLink     = Line->Link.BackLink;
  NewLine->Link.ForwardLink     = &Line->Link;

  Line->Link.BackLink->ForwardLink = &NewLine->Link;
  Line->Link.BackLink        = &NewLine->Link;

  FileBuffer.NumLines++;
  FileBuffer.CurrentLine  = NewLine;

  FileBuffer.Lines        = CR (FileBuffer.ListHead->ForwardLink, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);

  Col                     = 1;
  //
  // move home
  //
  Row = FileBuffer.FilePosition.Row;

  FileBufferMovePosition (Row, Col);

  //
  // after paste, set some value so that refresh knows to do something
  //
  FileBuffer.FileModified       = TRUE;
  FileBufferNeedRefresh         = TRUE;
  FileBufferOnlyLineNeedRefresh = FALSE;

  return EFI_SUCCESS;
}

/**
  Search string from current position on in file

  @param[in] Str    The search string.
  @param[in] Offset The offset from current position.

  @retval EFI_SUCCESS       The operation was successful.
  @retval EFI_NOT_FOUND     The string Str was not found.
**/
EFI_STATUS
FileBufferSearch (
  IN CONST CHAR16  *Str,
  IN CONST UINTN Offset
  )
{
  CHAR16          *Current;
  UINTN           Position;
  UINTN           Row;
  UINTN           Column;
  EFI_EDITOR_LINE *Line;
  CHAR16          *CharPos;
  LIST_ENTRY      *Link;
  BOOLEAN         Found;

  Column = 0;
  Position = 0;

  //
  // search if in current line
  //
  Current = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1 + Offset;

  if (Current >= (FileBuffer.CurrentLine->Buffer + FileBuffer.CurrentLine->Size)) {
    //
    // the end
    //
    Current = FileBuffer.CurrentLine->Buffer + FileBuffer.CurrentLine->Size;
  }

  Found = FALSE;

  CharPos  =  StrStr (Current, Str);
  if (CharPos != NULL) {
    Position = CharPos - Current + 1;
    Found   = TRUE;
  }

  //
  // found
  //
  if (Found) {
    Column  = (Position - 1) + FileBuffer.FilePosition.Column + Offset;
    Row     = FileBuffer.FilePosition.Row;
  } else {
    //
    // not found so find through next lines
    //
    Link  = FileBuffer.CurrentLine->Link.ForwardLink;

    Row   = FileBuffer.FilePosition.Row + 1;
    while (Link != FileBuffer.ListHead) {
      Line      = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
//      Position  = StrStr (Line->Buffer, Str);
      CharPos  =  StrStr (Line->Buffer, Str);
      if (CharPos != NULL) {
        Position = CharPos - Line->Buffer + 1;
        Found   = TRUE;
      }

      if (Found) {
        //
        // found
        //
        Column = Position;
        break;
      }

      Row++;
      Link = Link->ForwardLink;
    }

    if (Link == FileBuffer.ListHead) {
      Found = FALSE;
    } else {
      Found = TRUE;
    }
  }

  if (!Found) {
    return EFI_NOT_FOUND;
  }

  FileBufferMovePosition (Row, Column);

  //
  // call refresh to fresh edit area,
  // because the outer may loop to find multiply occurrence of this string
  //
  FileBufferRefresh ();

  return EFI_SUCCESS;
}

/**
  Replace SearchLen characters from current position on with Replace.

  This will modify the current buffer at the current position.

  @param[in] Replace    The string to replace.
  @param[in] SearchLen  Search string's length.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
FileBufferReplace (
  IN CONST CHAR16   *Replace,
  IN CONST UINTN    SearchLen
  )
{
  UINTN   ReplaceLen;
  UINTN   Index;
  CHAR16  *Buffer;
  UINTN   NewSize;
  UINTN   OldSize;
  UINTN   Gap;

  ReplaceLen  = StrLen (Replace);

  OldSize     = FileBuffer.CurrentLine->Size + 1;
  //
  // include CHAR_NULL
  //
  NewSize = OldSize + (ReplaceLen - SearchLen);

  if (ReplaceLen > SearchLen) {
    //
    // do not have the enough space
    //
    if (FileBuffer.CurrentLine->TotalSize + 1 <= NewSize) {
      FileBuffer.CurrentLine->Buffer = ReallocatePool (
                                        2 * OldSize,
                                        2 * NewSize,
                                        FileBuffer.CurrentLine->Buffer
                                        );
      FileBuffer.CurrentLine->TotalSize = NewSize - 1;
    }

    if (FileBuffer.CurrentLine->Buffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // the end CHAR_NULL character;
    //
    Buffer  = FileBuffer.CurrentLine->Buffer + (NewSize - 1);
    Gap     = ReplaceLen - SearchLen;

    //
    // keep the latter part
    //
    for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - SearchLen + 2); Index++) {
      *Buffer = *(Buffer - Gap);
      Buffer--;
    }
    //
    // set replace into it
    //
    Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1;
    for (Index = 0; Index < ReplaceLen; Index++) {
      Buffer[Index] = Replace[Index];
    }
  }

  if (ReplaceLen < SearchLen) {
    Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1;

    for (Index = 0; Index < ReplaceLen; Index++) {
      Buffer[Index] = Replace[Index];
    }

    Buffer += ReplaceLen;
    Gap = SearchLen - ReplaceLen;

    //
    // set replace into it
    //
    for (Index = 0; Index < (FileBuffer.CurrentLine->Size - FileBuffer.FilePosition.Column - ReplaceLen + 2); Index++) {
      *Buffer = *(Buffer + Gap);
      Buffer++;
    }
  }

  if (ReplaceLen == SearchLen) {
    Buffer = FileBuffer.CurrentLine->Buffer + FileBuffer.FilePosition.Column - 1;
    for (Index = 0; Index < ReplaceLen; Index++) {
      Buffer[Index] = Replace[Index];
    }
  }

  FileBuffer.CurrentLine->Size += (ReplaceLen - SearchLen);

  FileBufferOnlyLineNeedRefresh = TRUE;

  FileBuffer.FileModified       = TRUE;

  MainTitleBarRefresh (MainEditor.FileBuffer->FileName, MainEditor.FileBuffer->FileType, MainEditor.FileBuffer->ReadOnly, MainEditor.FileBuffer->FileModified, MainEditor.ScreenSize.Column, MainEditor.ScreenSize.Row, 0, 0);
  FileBufferRestorePosition ();
  FileBufferRefresh ();

  return EFI_SUCCESS;
}

/**
  Move the mouse cursor position.

  @param[in] TextX      The new x-coordinate.
  @param[in] TextY      The new y-coordinate.
**/
VOID
FileBufferAdjustMousePosition (
  IN CONST INT32 TextX,
  IN CONST INT32 TextY
  )
{
  UINTN CoordinateX;
  UINTN CoordinateY;
  UINTN AbsX;
  UINTN AbsY;

  //
  // TextX and TextY is mouse movement data returned by mouse driver
  // This function will change it to MousePosition
  //
  //
  // get absolute value
  //

  AbsX = ABS(TextX);
  AbsY = ABS(TextY);

  CoordinateX = FileBuffer.MousePosition.Column;
  CoordinateY = FileBuffer.MousePosition.Row;

  if (TextX >= 0) {
    CoordinateX += TextX;
  } else {
    if (CoordinateX >= AbsX) {
      CoordinateX -= AbsX;
    } else {
      CoordinateX = 0;
    }
  }

  if (TextY >= 0) {
    CoordinateY += TextY;
  } else {
    if (CoordinateY >= AbsY) {
      CoordinateY -= AbsY;
    } else {
      CoordinateY = 0;
    }
  }
  //
  // check whether new mouse column position is beyond screen
  // if not, adjust it
  //
  if (CoordinateX >= 1 && CoordinateX <= MainEditor.ScreenSize.Column) {
    FileBuffer.MousePosition.Column = CoordinateX;
  } else if (CoordinateX < 1) {
    FileBuffer.MousePosition.Column = 1;
  } else if (CoordinateX > MainEditor.ScreenSize.Column) {
    FileBuffer.MousePosition.Column = MainEditor.ScreenSize.Column;
  }
  //
  // check whether new mouse row position is beyond screen
  // if not, adjust it
  //
  if (CoordinateY >= 2 && CoordinateY <= (MainEditor.ScreenSize.Row - 1)) {
    FileBuffer.MousePosition.Row = CoordinateY;
  } else if (CoordinateY < 2) {
    FileBuffer.MousePosition.Row = 2;
  } else if (CoordinateY > (MainEditor.ScreenSize.Row - 1)) {
    FileBuffer.MousePosition.Row = (MainEditor.ScreenSize.Row - 1);
  }

}

/**
  Search and replace operation.

  @param[in] SearchStr    The string to search for.
  @param[in] ReplaceStr   The string to replace with.
  @param[in] Offset       The column to start at.
**/
EFI_STATUS
FileBufferReplaceAll (
  IN CHAR16 *SearchStr,
  IN CHAR16 *ReplaceStr,
  IN UINTN  Offset
  )
{
  CHAR16          *Buffer;
  UINTN           Position;
  UINTN           Column;
  UINTN           ReplaceLen;
  UINTN           SearchLen;
  UINTN           Index;
  UINTN           NewSize;
  UINTN           OldSize;
  UINTN           Gap;
  EFI_EDITOR_LINE *Line;
  LIST_ENTRY      *Link;
  CHAR16          *CharPos;

  SearchLen   = StrLen (SearchStr);
  ReplaceLen  = StrLen (ReplaceStr);

  Column      = FileBuffer.FilePosition.Column + Offset - 1;

  if (Column > FileBuffer.CurrentLine->Size) {
    Column = FileBuffer.CurrentLine->Size;
  }

  Link = &(FileBuffer.CurrentLine->Link);

  while (Link != FileBuffer.ListHead) {
    Line      = CR (Link, EFI_EDITOR_LINE, Link, LINE_LIST_SIGNATURE);
    CharPos  =  StrStr (Line->Buffer + Column, SearchStr);
    if (CharPos != NULL) {
      Position = CharPos - Line->Buffer;// + Column;
      //
      // found
      //
      if (ReplaceLen > SearchLen) {
        OldSize = Line->Size + 1;
        //
        // include CHAR_NULL
        //
        NewSize = OldSize + (ReplaceLen - SearchLen);

        //
        // do not have the enough space
        //
        if (Line->TotalSize + 1 <= NewSize) {
          Line->Buffer = ReallocatePool (
                          2 * OldSize,
                          2 * NewSize,
                          Line->Buffer
                          );
          Line->TotalSize = NewSize - 1;
        }

        if (Line->Buffer == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        //
        // the end CHAR_NULL character;
        //
        Buffer  = Line->Buffer + (NewSize - 1);
        Gap     = ReplaceLen - SearchLen;

        //
        // keep the latter part
        //
        for (Index = 0; Index < (Line->Size - Position - SearchLen + 1); Index++) {
          *Buffer = *(Buffer - Gap);
          Buffer--;
        }

      } else if (ReplaceLen < SearchLen){
        Buffer  = Line->Buffer + Position + ReplaceLen;
        Gap     = SearchLen - ReplaceLen;

        for (Index = 0; Index < (Line->Size - Position - ReplaceLen + 1); Index++) {
          *Buffer = *(Buffer + Gap);
          Buffer++;
        }
      } else {
        ASSERT(ReplaceLen == SearchLen);
      }
      //
      // set replace into it
      //
      Buffer = Line->Buffer + Position;
      for (Index = 0; Index < ReplaceLen; Index++) {
        Buffer[Index] = ReplaceStr[Index];
      }

      Line->Size += (ReplaceLen - SearchLen);
      Column += ReplaceLen;
    } else {
      //
      // not found
      //
      Column  = 0;
      Link    = Link->ForwardLink;
    }
  }
  //
  // call refresh to fresh edit area
  //
  FileBuffer.FileModified = TRUE;
  FileBufferNeedRefresh   = TRUE;
  FileBufferRefresh ();

  return EFI_SUCCESS;
}

/**
  Set the modified state to TRUE.
**/
VOID
FileBufferSetModified (
  VOID
  )
{
  FileBuffer.FileModified = TRUE;
}

