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