/** @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 - 2017, 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;
}

