/** @file
  Defines HBufferImage - the view of the file that is visible at any point,
  as well as the event handlers for editing the file

  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 "HexEditor.h"

extern EFI_HANDLE                 HImageHandleBackup;

extern HEFI_EDITOR_FILE_IMAGE     HFileImage;
extern HEFI_EDITOR_DISK_IMAGE     HDiskImage;
extern HEFI_EDITOR_MEM_IMAGE      HMemImage;

extern HEFI_EDITOR_FILE_IMAGE     HFileImageBackupVar;
extern HEFI_EDITOR_DISK_IMAGE     HDiskImageBackupVar;
extern HEFI_EDITOR_MEM_IMAGE      HMemImageBackupVar;

extern BOOLEAN                    HEditorMouseAction;

extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditor;
extern HEFI_EDITOR_GLOBAL_EDITOR  HMainEditorBackupVar;

HEFI_EDITOR_BUFFER_IMAGE          HBufferImage;
HEFI_EDITOR_BUFFER_IMAGE          HBufferImageBackupVar;

//
// for basic initialization of HBufferImage
//
HEFI_EDITOR_BUFFER_IMAGE          HBufferImageConst = {
  NULL,
  NULL,
  0,
  NULL,
  {
    0,
    0
  },
  {
    0,
    0
  },
  {
    0,
    0
  },
  0,
  TRUE,
  FALSE,
  FileTypeNone,
  NULL,
  NULL,
  NULL
};

//
// the whole edit area needs to be refreshed
//
BOOLEAN                           HBufferImageNeedRefresh;

//
// only the current line in edit area needs to be refresh
//
BOOLEAN                           HBufferImageOnlyLineNeedRefresh;

BOOLEAN                           HBufferImageMouseNeedRefresh;

/**
  Initialization function for HBufferImage

  @retval EFI_SUCCESS       The operation was successful.
  @retval EFI_LOAD_ERROR    A load error occured.
**/
EFI_STATUS
HBufferImageInit (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // basically initialize the HBufferImage
  //
  CopyMem (&HBufferImage, &HBufferImageConst, sizeof (HBufferImage));

  //
  // INIT listhead
  //
  HBufferImage.ListHead = AllocateZeroPool (sizeof (LIST_ENTRY));
  if (HBufferImage.ListHead == NULL) {
    return EFI_LOAD_ERROR;
  }

  InitializeListHead (HBufferImage.ListHead);

  HBufferImage.DisplayPosition.Row    = 2;
  HBufferImage.DisplayPosition.Column = 10;
  HBufferImage.MousePosition.Row      = 2;
  HBufferImage.MousePosition.Column   = 10;

  HBufferImage.FileImage              = &HFileImage;
  HBufferImage.DiskImage              = &HDiskImage;
  HBufferImage.MemImage               = &HMemImage;

  HBufferImageNeedRefresh             = FALSE;
  HBufferImageOnlyLineNeedRefresh     = FALSE;
  HBufferImageMouseNeedRefresh        = FALSE;

  HBufferImageBackupVar.FileImage     = &HFileImageBackupVar;
  HBufferImageBackupVar.DiskImage     = &HDiskImageBackupVar;
  HBufferImageBackupVar.MemImage      = &HMemImageBackupVar;

  Status = HFileImageInit ();
  if (EFI_ERROR (Status)) {
    return EFI_LOAD_ERROR;
  }

  Status = HDiskImageInit ();
  if (EFI_ERROR (Status)) {
    return EFI_LOAD_ERROR;
  }

  Status = HMemImageInit ();
  if (EFI_ERROR (Status)) {
    return EFI_LOAD_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Backup function for HBufferImage. Only a few fields need to be backup.
  This is for making the file buffer refresh as few as possible.

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageBackup (
  VOID
  )
{
  HBufferImageBackupVar.MousePosition   = HBufferImage.MousePosition;

  HBufferImageBackupVar.BufferPosition  = HBufferImage.BufferPosition;

  HBufferImageBackupVar.Modified        = HBufferImage.Modified;

  HBufferImageBackupVar.BufferType      = HBufferImage.BufferType;
  HBufferImageBackupVar.LowVisibleRow   = HBufferImage.LowVisibleRow;
  HBufferImageBackupVar.HighBits        = HBufferImage.HighBits;

  //
  // three kinds of buffer supported
  //   file buffer
  //   disk buffer
  //   memory buffer
  //
  switch (HBufferImage.BufferType) {
  case FileTypeFileBuffer:
    HFileImageBackup ();
    break;

  case FileTypeDiskBuffer:
    HDiskImageBackup ();
    break;

  case FileTypeMemBuffer:
    HMemImageBackup ();
    break;

  default:
    break;
  }

  return EFI_SUCCESS;
}

/**
  Free all the lines in HBufferImage.
    Fields affected:
    Lines
    CurrentLine
    NumLines
    ListHead

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageFreeLines (
  VOID
  )
{
  HFreeLines (HBufferImage.ListHead, HBufferImage.Lines);

  HBufferImage.Lines        = NULL;
  HBufferImage.CurrentLine  = NULL;
  HBufferImage.NumLines     = 0;

  return EFI_SUCCESS;
}

/**
  Cleanup function for HBufferImage

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageCleanup (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // free all the lines
  //
  Status = HBufferImageFreeLines ();

  SHELL_FREE_NON_NULL (HBufferImage.ListHead);
  HBufferImage.ListHead = NULL;

  HFileImageCleanup ();
  HDiskImageCleanup ();

  return Status;

}

/**
  Print Line on Row

  @param[in] Line     The lline to print.
  @param[in] Row      The row on screen ( begin from 1 ).
  @param[in] FRow     The FRow.
  @param[in] Orig     The original color.
  @param[in] New      The color to print with.

  @retval EFI_SUCCESS The operation was successful.
**/
EFI_STATUS
HBufferImagePrintLine (
  IN HEFI_EDITOR_LINE           *Line,
  IN UINTN                      Row,
  IN UINTN                      FRow,
  IN HEFI_EDITOR_COLOR_UNION    Orig,
  IN HEFI_EDITOR_COLOR_UNION    New

  )
{

  UINTN   Index;
  UINTN   Pos;
  BOOLEAN Selected;
  BOOLEAN BeNewColor;
  UINTN   RowStart;
  UINTN   RowEnd;
  UINTN   ColStart;
  UINTN   ColEnd;

  //
  // variable initialization
  //
  ColStart  = 0;
  ColEnd    = 0;
  Selected  = FALSE;

  //
  // print the selected area in opposite color
  //
  if (HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
    RowStart  = (HMainEditor.SelectStart - 1) / 0x10 + 1;
    RowEnd    = (HMainEditor.SelectEnd - 1) / 0x10 + 1;

    ColStart  = (HMainEditor.SelectStart - 1) % 0x10 + 1;
    ColEnd    = (HMainEditor.SelectEnd - 1) % 0x10 + 1;

    if (FRow >= RowStart && FRow <= RowEnd) {
      Selected = TRUE;
    }

    if (FRow > RowStart) {
      ColStart = 1;
    }

    if (FRow < RowEnd) {
      ColEnd = 0x10;
    }

  }

  if (!HEditorMouseAction) {
    ShellPrintEx (
      0,
      (INT32)Row - 1,
      L"%8X ",
      ((INT32)Row - 2 + HBufferImage.LowVisibleRow - 1) * 0x10
      );

  }

  for (Index = 0; Index < 0x08 && Index < Line->Size; Index++) {

    BeNewColor = FALSE;

    if (Selected) {
      if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
        BeNewColor = TRUE;
      }
    }

    if (BeNewColor) {
      gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
    } else {
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
    }

    Pos = 10 + (Index * 3);
    if (Line->Buffer[Index] < 0x10) {
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
      Pos++;
    }

    if (Index < 0x07) {
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
    } else {
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x  ", Line->Buffer[Index]);
    }

  }

  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
  while (Index < 0x08) {
    Pos = 10 + (Index * 3);
    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"    ");
    Index++;
  }

  while (Index < 0x10 && Index < Line->Size) {

    BeNewColor = FALSE;

    if (Selected) {
      if (Index + 1 >= ColStart && Index + 1 <= ColEnd) {
        BeNewColor = TRUE;
      }
    }

    if (BeNewColor) {
      gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
    } else {
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
    }

    Pos = 10 + (Index * 3) + 1;
    if (Line->Buffer[Index] < 0x10) {
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"0");
      Pos++;
    }

    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%x ", Line->Buffer[Index]);
    Index++;
  }

  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);
  while (Index < 0x10) {
    Pos = 10 + (Index * 3) + 1;
    ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"   ");
    Index++;
  }
  //
  // restore the original color
  //
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data & 0x7F);

  //
  // PRINT the buffer content
  //
  if (!HEditorMouseAction) {
    for (Index = 0; Index < 0x10 && Index < Line->Size; Index++) {
      Pos = ASCII_POSITION + Index;

      //
      // learned from shelle.h -- IsValidChar
      //
      if (Line->Buffer[Index] >= L' ') {
        ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", (CHAR16) Line->Buffer[Index]);
      } else {
        ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"%c", '.');
      }
    }

    while (Index < 0x10) {
      Pos = ASCII_POSITION + Index;
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
      Index++;
    }
  }
  //
  // restore the abundant blank in hex edit area to original color
  //
  if (Selected) {
    if (ColEnd <= 7) {
      Pos = 10 + (ColEnd - 1) * 3 + 2;
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
    } else if (ColEnd == 8) {
      Pos = 10 + (ColEnd - 1) * 3 + 2;
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L"  ");
    } else {
      Pos = 10 + (ColEnd - 1) * 3 + 3;
      ShellPrintEx ((INT32)Pos - 1, (INT32)Row - 1, L" ");
    }
  }

  return EFI_SUCCESS;
}

/**
  Function to decide if a column number is stored in the high bits.

  @param[in] Column     The column to examine.
  @param[out] FCol      The actual column number.

  @retval TRUE      The actual column was in high bits and is now in FCol.
  @retval FALSE     There was not a column number in the high bits.
**/
BOOLEAN
HBufferImageIsAtHighBits (
  IN  UINTN Column,
  OUT UINTN *FCol
  )
{
  Column -= 10;

  //
  // NOW AFTER THE SUB, Column start from 0
  // 23 AND 24 ARE BOTH BLANK
  //
  if (Column == 24) {
    *FCol = 0;
    return FALSE;
  }

  if (Column > 24) {
    Column--;
  }

  *FCol = (Column / 3) + 1;

  if (Column % 3 == 0) {
    return TRUE;
  }

  if ((Column % 3 == 2)) {
    *FCol = 0;
  }

  return FALSE;
}

/**
  Decide if a point is in the already selected area.

  @param[in] MouseRow     The row of the point to test.
  @param[in] MouseCol     The col of the point to test.

  @retval TRUE      The point is in the selected area.
  @retval FALSE     The point is not in the selected area.
**/
BOOLEAN
HBufferImageIsInSelectedArea (
  IN UINTN MouseRow,
  IN UINTN MouseCol
  )
{
  UINTN FRow;
  UINTN RowStart;
  UINTN RowEnd;
  UINTN ColStart;
  UINTN ColEnd;
  UINTN MouseColStart;
  UINTN MouseColEnd;

  //
  // judge mouse position whether is in selected area
  //
  //
  // not select
  //
  if (HMainEditor.SelectStart == 0 || HMainEditor.SelectEnd == 0) {
    return FALSE;
  }
  //
  // calculate the select area
  //
  RowStart  = (HMainEditor.SelectStart - 1) / 0x10 + 1;
  RowEnd    = (HMainEditor.SelectEnd - 1) / 0x10 + 1;

  ColStart  = (HMainEditor.SelectStart - 1) % 0x10 + 1;
  ColEnd    = (HMainEditor.SelectEnd - 1) % 0x10 + 1;

  FRow      = HBufferImage.LowVisibleRow + MouseRow - 2;
  if (FRow < RowStart || FRow > RowEnd) {
    return FALSE;
  }

  if (FRow > RowStart) {
    ColStart = 1;
  }

  if (FRow < RowEnd) {
    ColEnd = 0x10;
  }

  MouseColStart = 10 + (ColStart - 1) * 3;
  if (ColStart > 8) {
    MouseColStart++;
  }

  MouseColEnd = 10 + (ColEnd - 1) * 3 + 1;
  if (ColEnd > 8) {
    MouseColEnd++;
  }

  if (MouseCol < MouseColStart || MouseCol > MouseColEnd) {
    return FALSE;
  }

  return TRUE;
}

/**
  Set mouse position according to HBufferImage.MousePosition.

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageRestoreMousePosition (
  VOID
  )
{
  HEFI_EDITOR_COLOR_UNION Orig;
  HEFI_EDITOR_COLOR_UNION New;
  UINTN                   FRow;
  UINTN                   FColumn;
  BOOLEAN                 HasCharacter;
  HEFI_EDITOR_LINE        *CurrentLine;
  HEFI_EDITOR_LINE        *Line;
  UINT8                   Value;
  BOOLEAN                 HighBits;

  Line = NULL;
  if (HMainEditor.MouseSupported) {

    if (HBufferImageMouseNeedRefresh) {

      HBufferImageMouseNeedRefresh = FALSE;

      //
      // if mouse position not moved and only mouse action
      // so do not need to refresh mouse position
      //
      if ((
            HBufferImage.MousePosition.Row == HBufferImageBackupVar.MousePosition.Row &&
          HBufferImage.MousePosition.Column == HBufferImageBackupVar.MousePosition.Column
        ) &&
          HEditorMouseAction
          ) {
        return EFI_SUCCESS;
      }
      //
      // backup the old screen attributes
      //
      Orig                  = HMainEditor.ColorAttributes;
      New.Data              = 0;
      New.Colors.Foreground = Orig.Colors.Background & 0xF;
      New.Colors.Background = Orig.Colors.Foreground & 0x7;

      //
      // if in selected area,
      // so do not need to refresh mouse
      //
      if (!HBufferImageIsInSelectedArea (
            HBufferImageBackupVar.MousePosition.Row,
            HBufferImageBackupVar.MousePosition.Column
            )) {
        gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
      } else {
        gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
      }
      //
      // clear the old mouse position
      //
      FRow = HBufferImage.LowVisibleRow + HBufferImageBackupVar.MousePosition.Row - 2;

      HighBits = HBufferImageIsAtHighBits (
                  HBufferImageBackupVar.MousePosition.Column,
                  &FColumn
                  );

      HasCharacter = TRUE;
      if (FRow > HBufferImage.NumLines || FColumn == 0) {
        HasCharacter = FALSE;
      } else {
        CurrentLine = HBufferImage.CurrentLine;
        Line        = HMoveLine (FRow - HBufferImage.BufferPosition.Row);

        if (Line == NULL || FColumn > Line->Size) {
          HasCharacter = FALSE;
        }

        HBufferImage.CurrentLine = CurrentLine;
      }

      ShellPrintEx (
        (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
        (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
        L" "
        );

      if (HasCharacter) {
        if (HighBits) {
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
          Value = (UINT8) (Value >> 4);
        } else {
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
        }

        ShellPrintEx (
          (INT32)HBufferImageBackupVar.MousePosition.Column - 1,
          (INT32)HBufferImageBackupVar.MousePosition.Row - 1,
          L"%x",
          Value
          );
      }

      if (!HBufferImageIsInSelectedArea (
            HBufferImage.MousePosition.Row,
            HBufferImage.MousePosition.Column
            )) {
        gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);
      } else {
        gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
      }
      //
      // clear the old mouse position
      //
      FRow = HBufferImage.LowVisibleRow + HBufferImage.MousePosition.Row - 2;

      HighBits = HBufferImageIsAtHighBits (
                  HBufferImage.MousePosition.Column,
                  &FColumn
                  );

      HasCharacter = TRUE;
      if (FRow > HBufferImage.NumLines || FColumn == 0) {
        HasCharacter = FALSE;
      } else {
        CurrentLine = HBufferImage.CurrentLine;
        Line        = HMoveLine (FRow - HBufferImage.BufferPosition.Row);

        if (Line == NULL || FColumn > Line->Size) {
          HasCharacter = FALSE;
        }

        HBufferImage.CurrentLine = CurrentLine;
      }

      ShellPrintEx (
        (INT32)HBufferImage.MousePosition.Column - 1,
        (INT32)HBufferImage.MousePosition.Row - 1,
        L" "
        );

      if (HasCharacter) {
        if (HighBits) {
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf0);
          Value = (UINT8) (Value >> 4);
        } else {
          Value = (UINT8) (Line->Buffer[FColumn - 1] & 0xf);
        }

        ShellPrintEx (
          (INT32)HBufferImage.MousePosition.Column - 1,
          (INT32)HBufferImage.MousePosition.Row - 1,
          L"%x",
          Value
          );
      }
      //
      // end of HasCharacter
      //
      gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
    }
    //
    // end of MouseNeedRefresh
    //
  }
  //
  // end of MouseSupported
  //
  return EFI_SUCCESS;
}

/**
  Set cursor position according to HBufferImage.DisplayPosition.

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageRestorePosition (
  VOID
  )
{
  //
  // set cursor position
  //
  gST->ConOut->SetCursorPosition (
        gST->ConOut,
        HBufferImage.DisplayPosition.Column - 1,
        HBufferImage.DisplayPosition.Row - 1
        );

  return EFI_SUCCESS;
}

/**
  Refresh function for HBufferImage.

  @retval EFI_SUCCESS     The operation was successful.
  @retval EFI_LOAD_ERROR  A Load error occured.

**/
EFI_STATUS
HBufferImageRefresh (
  VOID
  )
{
  LIST_ENTRY          *Link;
  HEFI_EDITOR_LINE        *Line;
  UINTN                   Row;
  HEFI_EDITOR_COLOR_UNION Orig;
  HEFI_EDITOR_COLOR_UNION New;

  UINTN                   StartRow;
  UINTN                   EndRow;
  UINTN                   FStartRow;
  UINTN                   Tmp;

  Orig                  = HMainEditor.ColorAttributes;
  New.Data              = 0;
  New.Colors.Foreground = Orig.Colors.Background;
  New.Colors.Background = Orig.Colors.Foreground;

  //
  // if it's the first time after editor launch, so should refresh
  //
  if (HEditorFirst == FALSE) {
    //
    // no definite required refresh
    // and file position displayed on screen has not been changed
    //
    if (!HBufferImageNeedRefresh &&
        !HBufferImageOnlyLineNeedRefresh &&
        HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow
        ) {
      HBufferImageRestoreMousePosition ();
      HBufferImageRestorePosition ();
      return EFI_SUCCESS;
    }
  }

  gST->ConOut->EnableCursor (gST->ConOut, FALSE);

  //
  // only need to refresh current line
  //
  if (HBufferImageOnlyLineNeedRefresh && HBufferImageBackupVar.LowVisibleRow == HBufferImage.LowVisibleRow) {

    HBufferImagePrintLine (
      HBufferImage.CurrentLine,
      HBufferImage.DisplayPosition.Row,
      HBufferImage.BufferPosition.Row,
      Orig,
      New
      );
  } else {
    //
    // the whole edit area need refresh
    //
    if (HEditorMouseAction && HMainEditor.SelectStart != 0 && HMainEditor.SelectEnd != 0) {
      if (HMainEditor.SelectStart != HMainEditorBackupVar.SelectStart) {
        if (HMainEditor.SelectStart >= HMainEditorBackupVar.SelectStart && HMainEditorBackupVar.SelectStart != 0) {
          StartRow = (HMainEditorBackupVar.SelectStart - 1) / 0x10 + 1;
        } else {
          StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
        }
      } else {
        StartRow = (HMainEditor.SelectStart - 1) / 0x10 + 1;
      }

      if (HMainEditor.SelectEnd <= HMainEditorBackupVar.SelectEnd) {
        EndRow = (HMainEditorBackupVar.SelectEnd - 1) / 0x10 + 1;
      } else {
        EndRow = (HMainEditor.SelectEnd - 1) / 0x10 + 1;
      }
      //
      // swap
      //
      if (StartRow > EndRow) {
        Tmp       = StartRow;
        StartRow  = EndRow;
        EndRow    = Tmp;
      }

      FStartRow = StartRow;

      StartRow  = 2 + StartRow - HBufferImage.LowVisibleRow;
      EndRow    = 2 + EndRow - HBufferImage.LowVisibleRow;

    } else {
      //
      // not mouse selection actions
      //
      FStartRow = HBufferImage.LowVisibleRow;
      StartRow  = 2;
      EndRow    = (HMainEditor.ScreenSize.Row - 1);
    }
    //
    // no line
    //
    if (HBufferImage.Lines == NULL) {
      HBufferImageRestoreMousePosition ();
      HBufferImageRestorePosition ();
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);
      return EFI_SUCCESS;
    }
    //
    // get the first line that will be displayed
    //
    Line = HMoveLine (FStartRow - HBufferImage.BufferPosition.Row);
    if (Line == NULL) {
      gST->ConOut->EnableCursor (gST->ConOut, TRUE);
      return EFI_LOAD_ERROR;
    }

    Link  = &(Line->Link);
    Row   = StartRow;
    do {
      Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

      //
      // print line at row
      //
      HBufferImagePrintLine (
        Line,
        Row,
        HBufferImage.LowVisibleRow + Row - 2,
        Orig,
        New
        );

      Link = Link->ForwardLink;
      Row++;
    } while (Link != HBufferImage.ListHead && Row <= EndRow);

    while (Row <= EndRow) {
      EditorClearLine (Row, HMainEditor.ScreenSize.Column, HMainEditor.ScreenSize.Row);
      Row++;
    }
    //
    // while not file end and not screen full
    //
  }

  HBufferImageRestoreMousePosition ();
  HBufferImageRestorePosition ();

  HBufferImageNeedRefresh         = FALSE;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  return EFI_SUCCESS;
}

/**
  Read an image into a buffer friom a source.

  @param[in] FileName     Pointer to the file name.  OPTIONAL and ignored if not FileTypeFileBuffer.
  @param[in] DiskName     Pointer to the disk name.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] DiskOffset   Offset into the disk.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] DiskSize     Size of the disk buffer.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] MemOffset    Offset into the Memory.  OPTIONAL and ignored if not FileTypeMemBuffer.
  @param[in] MemSize      Size of the Memory buffer.  OPTIONAL and ignored if not FileTypeMemBuffer.
  @param[in] BufferType   The type of buffer to save.  IGNORED.
  @param[in] Recover      TRUE for recovermode, FALSE otherwise.

  @return EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
HBufferImageRead (
  IN CONST CHAR16                   *FileName,
  IN CONST CHAR16                   *DiskName,
  IN UINTN                          DiskOffset,
  IN UINTN                          DiskSize,
  IN UINTN                          MemOffset,
  IN UINTN                          MemSize,
  IN EDIT_FILE_TYPE                 BufferType,
  IN BOOLEAN                        Recover
  )
{
  EFI_STATUS                      Status;
  EDIT_FILE_TYPE                  BufferTypeBackup;

  //
  // variable initialization
  //
  Status = EFI_SUCCESS;
  HBufferImage.BufferType = BufferType;

  //
  // three types of buffer supported
  //   file buffer
  //   disk buffer
  //   memory buffer
  //
  BufferTypeBackup = HBufferImage.BufferType;

  switch (BufferType) {
  case FileTypeFileBuffer:
    Status = HFileImageRead (FileName, Recover);
    break;

  case FileTypeDiskBuffer:
    Status = HDiskImageRead (DiskName, DiskOffset, DiskSize, Recover);
    break;

  case FileTypeMemBuffer:
    Status = HMemImageRead (MemOffset, MemSize, Recover);
    break;

  default:
    Status = EFI_NOT_FOUND;
    break;
  }

  if (EFI_ERROR (Status)) {
    HBufferImage.BufferType = BufferTypeBackup;
  }

  return Status;
}

/**
  Save the current image.

  @param[in] FileName     Pointer to the file name.  OPTIONAL and ignored if not FileTypeFileBuffer.
  @param[in] DiskName     Pointer to the disk name.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] DiskOffset   Offset into the disk.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] DiskSize     Size of the disk buffer.  OPTIONAL and ignored if not FileTypeDiskBuffer.
  @param[in] MemOffset    Offset into the Memory.  OPTIONAL and ignored if not FileTypeMemBuffer.
  @param[in] MemSize      Size of the Memory buffer.  OPTIONAL and ignored if not FileTypeMemBuffer.
  @param[in] BufferType   The type of buffer to save.  IGNORED.

  @return EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
HBufferImageSave (
  IN CHAR16                         *FileName,
  IN CHAR16                         *DiskName,
  IN UINTN                          DiskOffset,
  IN UINTN                          DiskSize,
  IN UINTN                          MemOffset,
  IN UINTN                          MemSize,
  IN EDIT_FILE_TYPE                 BufferType
  )
{
  EFI_STATUS                      Status;
  EDIT_FILE_TYPE                  BufferTypeBackup;

  //
  // variable initialization
  //
  Status            = EFI_SUCCESS;
  BufferTypeBackup  = HBufferImage.BufferType;

  switch (HBufferImage.BufferType) {
  //
  // file buffer
  //
  case FileTypeFileBuffer:
    Status = HFileImageSave (FileName);
    break;

  //
  // disk buffer
  //
  case FileTypeDiskBuffer:
    Status = HDiskImageSave (DiskName, DiskOffset, DiskSize);
    break;

  //
  // memory buffer
  //
  case FileTypeMemBuffer:
    Status = HMemImageSave (MemOffset, MemSize);
    break;

  default:
    Status = EFI_NOT_FOUND;
    break;
  }

  if (EFI_ERROR (Status)) {
    HBufferImage.BufferType = BufferTypeBackup;
  }

  return Status;
}

/**
  Create a new line and append it to the line list.
    Fields affected:
    NumLines
    Lines

  @retval NULL    create line failed.
  @return         the line created.

**/
HEFI_EDITOR_LINE *
HBufferImageCreateLine (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;

  //
  // allocate for line structure
  //
  Line = AllocateZeroPool (sizeof (HEFI_EDITOR_LINE));
  if (Line == NULL) {
    return NULL;
  }

  Line->Signature = EFI_EDITOR_LINE_LIST;
  Line->Size      = 0;

  HBufferImage.NumLines++;

  //
  // insert to line list
  //
  InsertTailList (HBufferImage.ListHead, &Line->Link);

  if (HBufferImage.Lines == NULL) {
    HBufferImage.Lines = CR (
                          HBufferImage.ListHead->ForwardLink,
                          HEFI_EDITOR_LINE,
                          Link,
                          EFI_EDITOR_LINE_LIST
                          );
  }

  return Line;
}

/**
  Free the current image.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageFree (
  VOID
  )
{
  //
  // free all lines
  //
  HBufferImageFreeLines ();

  return EFI_SUCCESS;
}

/**
  change char to int value based on Hex.

  @param[in] Char     The input char.

  @return The character's index value.
  @retval -1  The operation failed.
**/
INTN
HBufferImageCharToHex (
  IN CHAR16 Char
  )
{
  //
  // change the character to hex
  //
  if (Char >= L'0' && Char <= L'9') {
    return (Char - L'0');
  }

  if (Char >= L'a' && Char <= L'f') {
    return (Char - L'a' + 10);
  }

  if (Char >= L'A' && Char <= L'F') {
    return (Char - L'A' + 10);
  }

  return -1;
}

/**
  Add character.

  @param[in] Char -- input char.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation failed.
**/
EFI_STATUS
HBufferImageAddChar (
  IN  CHAR16  Char
  )
{
  HEFI_EDITOR_LINE  *Line;
  HEFI_EDITOR_LINE  *NewLine;
  INTN              Value;
  UINT8             Old;
  UINTN             FRow;
  UINTN             FCol;
  BOOLEAN           High;

  Value = HBufferImageCharToHex (Char);

  //
  // invalid input
  //
  if (Value == -1) {
    return EFI_SUCCESS;
  }

  Line  = HBufferImage.CurrentLine;
  FRow  = HBufferImage.BufferPosition.Row;
  FCol  = HBufferImage.BufferPosition.Column;
  High  = HBufferImage.HighBits;

  //
  // only needs to refresh current line
  //
  HBufferImageOnlyLineNeedRefresh = TRUE;

  //
  // not a full line and beyond the last character
  //
  if (FCol > Line->Size) {
    //
    // cursor always at high 4 bits
    // and always put input to the low 4 bits
    //
    Line->Buffer[Line->Size] = (UINT8) Value;
    Line->Size++;
    High = FALSE;
  } else {

    Old = Line->Buffer[FCol - 1];

    //
    // always put the input to the low 4 bits
    //
    Old                     = (UINT8) (Old & 0x0f);
    Old                     = (UINT8) (Old << 4);
    Old                     = (UINT8) (Value + Old);
    Line->Buffer[FCol - 1]  = Old;

    //
    // at the low 4 bits of the last character of a full line
    // so if no next line, need to create a new line
    //
    if (!High && FCol == 0x10) {

      HBufferImageOnlyLineNeedRefresh = FALSE;
      HBufferImageNeedRefresh         = TRUE;

      if (Line->Link.ForwardLink == HBufferImage.ListHead) {
        //
        // last line
        //
        // create a new line
        //
        NewLine = HBufferImageCreateLine ();
        if (NewLine == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        //
        // end of NULL
        //
      }
      //
      // end of == ListHead
      //
    }
    //
    // end of == 0x10
    //
    // if already at end of this line, scroll it to the start of next line
    //
    if (FCol == 0x10 && !High) {
      //
      // definitely has next line
      //
      FRow++;
      FCol  = 1;
      High  = TRUE;
    } else {
      //
      // if not at end of this line, just move to next column
      //
      if (!High) {
        FCol++;
      }

      if (High) {
        High = FALSE;
      } else {
        High = TRUE;
      }

    }
    //
    // end of ==FALSE
    //
  }
  //
  // move cursor to right
  //
  HBufferImageMovePosition (FRow, FCol, High);

  if (!HBufferImage.Modified) {
    HBufferImage.Modified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Delete the previous character.

  @retval EFI_SUCCESS   The operationw as successful.
**/
EFI_STATUS
HBufferImageDoBackspace (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;

  UINTN             FileColumn;
  UINTN             FPos;
  BOOLEAN           LastLine;

  //
  // variable initialization
  //
  LastLine = FALSE;

  //
  // already the first character
  //
  if (HBufferImage.BufferPosition.Row == 1 && HBufferImage.BufferPosition.Column == 1) {
    return EFI_SUCCESS;
  }

  FPos        = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;

  FileColumn  = HBufferImage.BufferPosition.Column;

  Line        = HBufferImage.CurrentLine;
  LastLine    = FALSE;
  if (Line->Link.ForwardLink == HBufferImage.ListHead && FileColumn > 1) {
    LastLine = TRUE;
  }

  HBufferImageDeleteCharacterFromBuffer (FPos - 1, 1, NULL);

  //
  // if is the last line
  // then only this line need to be refreshed
  //
  if (LastLine) {
    HBufferImageNeedRefresh         = FALSE;
    HBufferImageOnlyLineNeedRefresh = TRUE;
  } else {
    HBufferImageNeedRefresh         = TRUE;
    HBufferImageOnlyLineNeedRefresh = FALSE;
  }

  if (!HBufferImage.Modified) {
    HBufferImage.Modified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  ASCII key + Backspace + return.

  @param[in] Char               The input char.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_LOAD_ERROR        A load error occured.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
HBufferImageDoCharInput (
  IN  CHAR16  Char
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  switch (Char) {
  case 0:
    break;

  case 0x08:
    Status = HBufferImageDoBackspace ();
    break;

  case 0x09:
  case 0x0a:
  case 0x0d:
    //
    // Tabs, Returns are thought as nothing
    //
    break;

  default:
    //
    // DEAL WITH ASCII CHAR, filter out thing like ctrl+f
    //
    if (Char > 127 || Char < 32) {
      Status = StatusBarSetStatusString (L"Unknown Command");
    } else {
      Status = HBufferImageAddChar (Char);
    }

    break;
  }

  return Status;
}

/**
  Check user specified FileRow is above current screen.

  @param[in] FileRow  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
HAboveCurrentScreen (
  IN  UINTN FileRow
  )
{
  if (FileRow < HBufferImage.LowVisibleRow) {
    return TRUE;
  }

  return FALSE;
}

/**
  Check user specified FileRow is under current screen.

  @param[in] FileRow    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
HUnderCurrentScreen (
  IN  UINTN FileRow
  )
{
  if (FileRow > HBufferImage.LowVisibleRow + (HMainEditor.ScreenSize.Row - 2) - 1) {
    return TRUE;
  }

  return FALSE;
}

/**
  According to cursor's file position, adjust screen display.

  @param[in] NewFilePosRow    Row of file position ( start from 1 ).
  @param[in] NewFilePosCol    Column of file position ( start from 1 ).
  @param[in] HighBits         Cursor will on high4 bits or low4 bits.
**/
VOID
HBufferImageMovePosition (
  IN UINTN    NewFilePosRow,
  IN UINTN    NewFilePosCol,
  IN BOOLEAN  HighBits
  )
{
  INTN    RowGap;
  UINTN   Abs;
  BOOLEAN Above;
  BOOLEAN Under;
  UINTN   NewDisplayCol;

  //
  // CALCULATE gap between current file position and new file position
  //
  RowGap                = NewFilePosRow - HBufferImage.BufferPosition.Row;

  Under                 = HUnderCurrentScreen (NewFilePosRow);
  Above                 = HAboveCurrentScreen (NewFilePosRow);

  HBufferImage.HighBits = HighBits;

  //
  // if is below current screen
  //
  if (Under) {
    //
    // display row will be unchanged
    //
    HBufferImage.BufferPosition.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 < (HBufferImage.DisplayPosition.Row - 2 + 1)) {
        HBufferImage.DisplayPosition.Row = NewFilePosRow + 2 - 1;
      }

      HBufferImage.BufferPosition.Row = NewFilePosRow;
    } else {
      //
      // in current screen
      //
      HBufferImage.BufferPosition.Row = NewFilePosRow;
      if (RowGap <= 0) {
        Abs = (UINTN)ABS(RowGap);
        HBufferImage.DisplayPosition.Row -= Abs;
      } else {
        HBufferImage.DisplayPosition.Row += RowGap;
      }

    }
  }

  HBufferImage.LowVisibleRow = HBufferImage.BufferPosition.Row - (HBufferImage.DisplayPosition.Row - 2);

  //
  // always in current screen
  //
  HBufferImage.BufferPosition.Column  = NewFilePosCol;

  NewDisplayCol                       = 10 + (NewFilePosCol - 1) * 3;
  if (NewFilePosCol > 0x8) {
    NewDisplayCol++;
  }

  if (!HighBits) {
    NewDisplayCol++;
  }

  HBufferImage.DisplayPosition.Column = NewDisplayCol;

  //
  // let CurrentLine point to correct line;
  //
  HBufferImage.CurrentLine = HMoveCurrentLine (RowGap);

}

/**
  Scroll cursor to right.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageScrollRight (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;

  //
  // scroll right will always move to the high4 bits of the next character
  //
  HBufferImageNeedRefresh         = FALSE;
  HBufferImageOnlyLineNeedRefresh = FALSE;

  Line = HBufferImage.CurrentLine;

  FRow = HBufferImage.BufferPosition.Row;
  FCol = HBufferImage.BufferPosition.Column;

  //
  // this line is not full and no next line
  //
  if (FCol > Line->Size) {
    return EFI_SUCCESS;
  }
  //
  // if already at end of this line, scroll it to the start of next line
  //
  if (FCol == 0x10) {
    //
    // has next line
    //
    if (Line->Link.ForwardLink != HBufferImage.ListHead) {
      FRow++;
      FCol = 1;

    } else {
      return EFI_SUCCESS;
    }
  } else {
    //
    // if not at end of this line, just move to next column
    //
    FCol++;

  }

  HBufferImageMovePosition (FRow, FCol, TRUE);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to left.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageScrollLeft (
  VOID
  )
{

  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;

  HBufferImageNeedRefresh         = FALSE;
  HBufferImageOnlyLineNeedRefresh = FALSE;

  Line = HBufferImage.CurrentLine;

  FRow = HBufferImage.BufferPosition.Row;
  FCol = HBufferImage.BufferPosition.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 != HBufferImage.ListHead) {
      FRow--;
      Line  = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
      FCol  = Line->Size;
    } else {
      return EFI_SUCCESS;
    }
  } else {
    //
    // if not at start of this line, just move to previous column
    //
    FCol--;
  }

  HBufferImageMovePosition (FRow, FCol, TRUE);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to the next line

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageScrollDown (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;
  BOOLEAN           HighBits;

  Line      = HBufferImage.CurrentLine;

  FRow      = HBufferImage.BufferPosition.Row;
  FCol      = HBufferImage.BufferPosition.Column;
  HighBits  = HBufferImage.HighBits;

  //
  // has next line
  //
  if (Line->Link.ForwardLink != HBufferImage.ListHead) {
    FRow++;
    Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    //
    // if the next line is not that long, so move to end of next line
    //
    if (FCol > Line->Size) {
      FCol      = Line->Size + 1;
      HighBits  = TRUE;
    }

  } else {
    return EFI_SUCCESS;
  }

  HBufferImageMovePosition (FRow, FCol, HighBits);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to previous line

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageScrollUp (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;

  Line  = HBufferImage.CurrentLine;

  FRow  = HBufferImage.BufferPosition.Row;
  FCol  = HBufferImage.BufferPosition.Column;

  //
  // has previous line
  //
  if (Line->Link.BackLink != HBufferImage.ListHead) {
    FRow--;

  } else {
    return EFI_SUCCESS;
  }

  HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to next page

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImagePageDown (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;
  UINTN             Gap;
  BOOLEAN           HighBits;

  Line      = HBufferImage.CurrentLine;

  FRow      = HBufferImage.BufferPosition.Row;
  FCol      = HBufferImage.BufferPosition.Column;
  HighBits  = HBufferImage.HighBits;

  //
  // has next page
  //
  if (HBufferImage.NumLines >= FRow + (HMainEditor.ScreenSize.Row - 2)) {
    Gap = (HMainEditor.ScreenSize.Row - 2);
  } else {
    //
    // MOVE CURSOR TO LAST LINE
    //
    Gap = HBufferImage.NumLines - FRow;
  }
  //
  // get correct line
  //
  Line = HMoveLine (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;
    HighBits  = TRUE;
  }

  FRow += Gap;

  HBufferImageMovePosition (FRow, FCol, HighBits);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to previous page

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImagePageUp (
  VOID
  )
{
  UINTN             FRow;
  UINTN             FCol;
  UINTN             Gap;
  INTN              Retreat;

  FRow  = HBufferImage.BufferPosition.Row;
  FCol  = HBufferImage.BufferPosition.Column;

  //
  // has previous page
  //
  if (FRow > (HMainEditor.ScreenSize.Row - 2)) {
    Gap = (HMainEditor.ScreenSize.Row - 2);
  } else {
    //
    // the first line of file will displayed on the first line of screen
    //
    Gap = FRow - 1;
  }

  Retreat = Gap;
  Retreat = -Retreat;

  FRow -= Gap;

  HBufferImageMovePosition (FRow, FCol, HBufferImage.HighBits);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to start of line

  @retval EFI_SUCCESS  The operation was successful.
**/
EFI_STATUS
HBufferImageHome (
  VOID
  )
{
  UINTN             FRow;
  UINTN             FCol;
  BOOLEAN           HighBits;

  //
  // curosr will at the high bit
  //
  FRow      = HBufferImage.BufferPosition.Row;
  FCol      = 1;
  HighBits  = TRUE;

  //
  // move cursor position
  //
  HBufferImageMovePosition (FRow, FCol, HighBits);

  return EFI_SUCCESS;
}

/**
  Scroll cursor to end of line.

  @retval EFI_SUCCESS  Teh operation was successful.
**/
EFI_STATUS
HBufferImageEnd (
  VOID
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             FRow;
  UINTN             FCol;
  BOOLEAN           HighBits;

  //
  // need refresh mouse
  //
  HBufferImageMouseNeedRefresh  = TRUE;

  Line                          = HBufferImage.CurrentLine;

  FRow                          = HBufferImage.BufferPosition.Row;

  if (Line->Size == 0x10) {
    FCol      = Line->Size;
    HighBits  = FALSE;
  } else {
    FCol      = Line->Size + 1;
    HighBits  = TRUE;
  }
  //
  // move cursor position
  //
  HBufferImageMovePosition (FRow, FCol, HighBits);

  return EFI_SUCCESS;
}

/**
  Get the size of the open buffer.

  @retval The size in bytes.
**/
UINTN
HBufferImageGetTotalSize (
  VOID
  )
{
  UINTN             Size;

  HEFI_EDITOR_LINE  *Line;

  //
  // calculate the total size of whole line list's buffer
  //
  if (HBufferImage.Lines == NULL) {
    return 0;
  }

  Line = CR (
          HBufferImage.ListHead->BackLink,
          HEFI_EDITOR_LINE,
          Link,
          EFI_EDITOR_LINE_LIST
          );
  //
  // one line at most 0x10
  //
  Size = 0x10 * (HBufferImage.NumLines - 1) + Line->Size;

  return Size;
}

/**
  Delete character from buffer.

  @param[in] Pos      Position, Pos starting from 0.
  @param[in] Count    The Count of characters to delete.
  @param[out] DeleteBuffer    The DeleteBuffer.

  @retval EFI_SUCCESS Success
**/
EFI_STATUS
HBufferImageDeleteCharacterFromBuffer (
  IN  UINTN         Pos,
  IN  UINTN         Count,
  OUT UINT8         *DeleteBuffer
  )
{
  UINTN             Index;

  VOID              *Buffer;
  UINT8             *BufferPtr;
  UINTN             Size;

  HEFI_EDITOR_LINE  *Line;
  LIST_ENTRY    *Link;

  UINTN             OldFCol;
  UINTN             OldFRow;
  UINTN             OldPos;

  UINTN             NewPos;

  EFI_STATUS        Status;

  Size      = HBufferImageGetTotalSize ();

  if (Size < Count) {
    return EFI_LOAD_ERROR;
  }

  if (Size == 0) {
    return EFI_SUCCESS;
  }

  //
  // relocate all the HBufferImage fields
  //
  OldFRow = HBufferImage.BufferPosition.Row;
  OldFCol = HBufferImage.BufferPosition.Column;
  OldPos  = (OldFRow - 1) * 0x10 + OldFCol - 1;

  if (Pos > 0) {
    //
    // has character before it,
    // so locate according to block's previous character
    //
    NewPos = Pos - 1;

  } else {
    //
    // has no character before it,
    // so locate according to block's next character
    //
    NewPos = 0;
  }

  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);

  Buffer = AllocateZeroPool (Size);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  HBufferImageListToBuffer (Buffer, Size);

  BufferPtr = (UINT8 *) Buffer;

  //
  // pass deleted buffer out
  //
  if (DeleteBuffer != NULL) {
    for (Index = 0; Index < Count; Index++) {
      DeleteBuffer[Index] = BufferPtr[Pos + Index];
    }
  }
  //
  // delete the part from Pos
  //
  for (Index = Pos; Index < Size - Count; Index++) {
    BufferPtr[Index] = BufferPtr[Index + Count];
  }

  Size -= Count;

  HBufferImageFreeLines ();

  Status = HBufferImageBufferToList (Buffer, Size);
  FreePool (Buffer);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Link = HMainEditor.BufferImage->ListHead->ForwardLink;
  for (Index = 0; Index < NewPos / 0x10; Index++) {
    Link = Link->ForwardLink;
  }

  Line                      = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  HBufferImage.CurrentLine  = Line;

  //
  // if current cursor position if inside select area
  // then move it to the block's NEXT character
  //
  if (OldPos >= Pos && OldPos < (Pos + Count)) {
    NewPos = Pos;
  } else {
    if (OldPos < Pos) {
      NewPos = OldPos;
    } else {
      NewPos = OldPos - Count;
    }
  }

  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);

  return EFI_SUCCESS;
}

/**
  Add character to buffer, add before pos.

  @param[in] Pos        Position, Pos starting from 0.
  @param[in] Count      Count of characters to add.
  @param[in] AddBuffer  Add buffer.

  @retval EFI_SUCCESS   Success.
**/
EFI_STATUS
HBufferImageAddCharacterToBuffer (
  IN  UINTN          Pos,
  IN  UINTN          Count,
  IN  UINT8          *AddBuffer
  )
{
  INTN              Index;

  VOID              *Buffer;
  UINT8             *BufferPtr;
  UINTN             Size;

  HEFI_EDITOR_LINE  *Line;

  LIST_ENTRY    *Link;

  UINTN             OldFCol;
  UINTN             OldFRow;
  UINTN             OldPos;

  UINTN             NewPos;

  Size      = HBufferImageGetTotalSize ();

  //
  // relocate all the HBufferImage fields
  //
  OldFRow = HBufferImage.BufferPosition.Row;
  OldFCol = HBufferImage.BufferPosition.Column;
  OldPos  = (OldFRow - 1) * 0x10 + OldFCol - 1;

  //
  // move cursor before Pos
  //
  if (Pos > 0) {
    NewPos = Pos - 1;
  } else {
    NewPos = 0;
  }

  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);

  Buffer = AllocateZeroPool (Size + Count);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  HBufferImageListToBuffer (Buffer, Size);

  BufferPtr = (UINT8 *) Buffer;

  //
  // get a place to add
  //
  for (Index = (INTN) (Size + Count - 1); Index >= (INTN) Pos; Index--) {
    BufferPtr[Index] = BufferPtr[Index - Count];
  }
  //
  // add the buffer
  //
  for (Index = (INTN) 0; Index < (INTN) Count; Index++) {
    BufferPtr[Index + Pos] = AddBuffer[Index];
  }

  Size += Count;

  HBufferImageFreeLines ();

  HBufferImageBufferToList (Buffer, Size);

  FreePool (Buffer);

  Link = HMainEditor.BufferImage->ListHead->ForwardLink;
  for (Index = 0; Index < (INTN) NewPos / 0x10; Index++) {
    Link = Link->ForwardLink;
  }

  Line                      = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  HBufferImage.CurrentLine  = Line;

  if (OldPos >= Pos) {
    NewPos = OldPos + Count;
  } else {
    NewPos = OldPos;
  }

  HBufferImageMovePosition (NewPos / 0x10 + 1, NewPos % 0x10 + 1, TRUE);

  return EFI_SUCCESS;
}

/**
  Delete current character from line.

  @retval EFI_SUCCESS   The operationw as successful.
**/
EFI_STATUS
HBufferImageDoDelete (
  VOID
  )
{

  HEFI_EDITOR_LINE  *Line;

  BOOLEAN           LastLine;
  UINTN             FileColumn;
  UINTN             FPos;

  FPos        = (HBufferImage.BufferPosition.Row - 1) * 0x10 + HBufferImage.BufferPosition.Column - 1;

  FileColumn  = HBufferImage.BufferPosition.Column;

  Line        = HBufferImage.CurrentLine;

  //
  // if beyond the last character
  //
  if (FileColumn > Line->Size) {
    return EFI_SUCCESS;
  }

  LastLine = FALSE;
  if (Line->Link.ForwardLink == HBufferImage.ListHead) {
    LastLine = TRUE;
  }

  HBufferImageDeleteCharacterFromBuffer (FPos, 1, NULL);

  //
  // if is the last line
  // then only this line need to be refreshed
  //
  if (LastLine) {
    HBufferImageNeedRefresh         = FALSE;
    HBufferImageOnlyLineNeedRefresh = TRUE;
  } else {
    HBufferImageNeedRefresh         = TRUE;
    HBufferImageOnlyLineNeedRefresh = FALSE;
  }

  if (!HBufferImage.Modified) {
    HBufferImage.Modified = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Change the raw buffer to a list of lines for the UI.

  @param[in] Buffer   The pointer to the buffer to fill.
  @param[in] Bytes    The size of the buffer in bytes.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
HBufferImageBufferToList (
  IN VOID   *Buffer,
  IN UINTN  Bytes
  )
{
  UINTN             TempI;
  UINTN             TempJ;
  UINTN             Left;
  HEFI_EDITOR_LINE  *Line;
  UINT8             *BufferPtr;

  TempI         = 0;
  Left      = 0;
  BufferPtr = (UINT8 *) Buffer;

  //
  // parse file content line by line
  //
  while (TempI < Bytes) {
    if (Bytes - TempI >= 0x10) {
      Left = 0x10;
    } else {
      Left = Bytes - TempI;
    }

    //
    // allocate a new line
    //
    Line = HBufferImageCreateLine ();
    if (Line == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Line->Size = Left;

    for (TempJ = 0; TempJ < Left; TempJ++) {
      Line->Buffer[TempJ] = BufferPtr[TempI];
      TempI++;
    }

  }

  //
  // last line is a full line, SO create a new line
  //
  if (Left == 0x10 || Bytes == 0) {
    Line = HBufferImageCreateLine ();
    if (Line == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  return EFI_SUCCESS;
}

/**
  Change the list of lines from the UI to a raw buffer.

  @param[in] Buffer   The pointer to the buffer to fill.
  @param[in] Bytes    The size of the buffer in bytes.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HBufferImageListToBuffer (
  IN VOID   *Buffer,
  IN UINTN  Bytes
  )
{
  UINTN             Count;
  UINTN             Index;
  HEFI_EDITOR_LINE  *Line;
  LIST_ENTRY    *Link;
  UINT8             *BufferPtr;

  //
  // change the line list to a large buffer
  //
  if (HBufferImage.Lines == NULL) {
    return EFI_SUCCESS;
  }

  Link      = &HBufferImage.Lines->Link;
  Count     = 0;
  BufferPtr = (UINT8 *) Buffer;

  //
  // deal line by line
  //
  while (Link != HBufferImage.ListHead) {

    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    //@todo shouldn't this be an error???
    if (Count + Line->Size > Bytes) {
      return EFI_SUCCESS;
    }

    for (Index = 0; Index < Line->Size; Index++) {
      BufferPtr[Index] = Line->Buffer[Index];
    }

    Count += Line->Size;
    BufferPtr += Line->Size;

    Link = Link->ForwardLink;
  }

  return EFI_SUCCESS;
}

/**
  Move the mouse in the image buffer.

  @param[in] TextX    The x-coordinate.
  @param[in] TextY    The y-coordinate.
**/
VOID
HBufferImageAdjustMousePosition (
  IN INT32 TextX,
  IN INT32 TextY
  )
{
  UINTN TempX;
  UINTN TempY;
  UINTN AbsX;
  UINTN AbsY;

  //
  // TextX and TextY is mouse movement data returned by mouse driver
  // This function will change it to MousePosition
  //
  //
  // get absolute TempX value
  //
  if (TextX >= 0) {
    AbsX = TextX;
  } else {
    AbsX = -TextX;
  }
  //
  // get absolute TempY value
  //
  if (TextY >= 0) {
    AbsY = TextY;
  } else {
    AbsY = -TextY;
  }

  TempX = HBufferImage.MousePosition.Column;
  TempY = HBufferImage.MousePosition.Row;

  if (TextX >= 0) {
    TempX += TextX;
  } else {
    if (TempX >= AbsX) {
      TempX -= AbsX;
    } else {
      TempX = 0;
    }
  }

  if (TextY >= 0) {
    TempY += TextY;
  } else {
    if (TempY >= AbsY) {
      TempY -= AbsY;
    } else {
      TempY = 0;
    }
  }
  //
  // check whether new mouse column position is beyond screen
  // if not, adjust it
  //
  if (TempX >= 10 && TempX <= (10 + 0x10 * 3 - 1)) {
    HBufferImage.MousePosition.Column = TempX;
  } else if (TempX < 10) {
    HBufferImage.MousePosition.Column = 10;
  } else if (TempX > (10 + 0x10 * 3 - 1)) {
    HBufferImage.MousePosition.Column = 10 + 0x10 * 3 - 1;
  }
  //
  // check whether new mouse row position is beyond screen
  // if not, adjust it
  //
  if (TempY >= 2 && TempY <= (HMainEditor.ScreenSize.Row - 1)) {
    HBufferImage.MousePosition.Row = TempY;
  } else if (TempY < 2) {
    HBufferImage.MousePosition.Row = 2;
  } else if (TempY > (HMainEditor.ScreenSize.Row - 1)) {
    HBufferImage.MousePosition.Row = (HMainEditor.ScreenSize.Row - 1);
  }

}

/**
  Dispatch input to different handler

  @param[in] Key    The input key:
                     the keys can be:
                       ASCII KEY
                        Backspace/Delete
                        Direction key: up/down/left/right/pgup/pgdn
                        Home/End
                        INS

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_LOAD_ERROR        A load error occured.
  @retval EFI_OUT_OF_RESOURCES  A Memory allocation failed.
**/
EFI_STATUS
HBufferImageHandleInput (
  IN  EFI_INPUT_KEY *Key
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  switch (Key->ScanCode) {
  //
  // ordinary key
  //
  case SCAN_NULL:
    Status = HBufferImageDoCharInput (Key->UnicodeChar);
    break;

  //
  // up arrow
  //
  case SCAN_UP:
    Status = HBufferImageScrollUp ();
    break;

  //
  // down arrow
  //
  case SCAN_DOWN:
    Status = HBufferImageScrollDown ();
    break;

  //
  // right arrow
  //
  case SCAN_RIGHT:
    Status = HBufferImageScrollRight ();
    break;

  //
  // left arrow
  //
  case SCAN_LEFT:
    Status = HBufferImageScrollLeft ();
    break;

  //
  // page up
  //
  case SCAN_PAGE_UP:
    Status = HBufferImagePageUp ();
    break;

  //
  // page down
  //
  case SCAN_PAGE_DOWN:
    Status = HBufferImagePageDown ();
    break;

  //
  // delete
  //
  case SCAN_DELETE:
    Status = HBufferImageDoDelete ();
    break;

  //
  // home
  //
  case SCAN_HOME:
    Status = HBufferImageHome ();
    break;

  //
  // end
  //
  case SCAN_END:
    Status = HBufferImageEnd ();
    break;

  default:
    Status = StatusBarSetStatusString (L"Unknown Command");
    break;
  }

  return Status;
}

