/** @file
  Implementation of various string and line routines

  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 BOOLEAN  HEditorMouseAction;

/**
  Free a line and it's internal buffer.

  @param[in] Src    The line to be freed.
**/
VOID
HLineFree (
  IN  HEFI_EDITOR_LINE *Src
  )
{
  if (Src == NULL) {
    return ;
  }

  SHELL_FREE_NON_NULL (Src);

}

/**
  Advance to the next Count lines.

  @param[in] Count      The line number to advance.

  @retval NULL An error occured.
  @return A pointer to the line after advance.
**/
HEFI_EDITOR_LINE *
HLineAdvance (
  IN  UINTN Count
  )
{
  UINTN             Index;
  HEFI_EDITOR_LINE  *Line;

  Line = HMainEditor.BufferImage->CurrentLine;
  if (Line == NULL) {
    return NULL;
  }

  for (Index = 0; Index < Count; Index++) {
    //
    // if already last line
    //
    if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
      return NULL;
    }

    Line = CR (Line->Link.ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  }

  return Line;
}

/**
  Retreat to the previous Count lines.

  @param[in] Count    The line number to retreat.

  @retval NULL An error occured.
  @return A pointer to the line after retreat.
**/
HEFI_EDITOR_LINE *
HLineRetreat (
  IN  UINTN Count
  )
{
  UINTN             Index;
  HEFI_EDITOR_LINE  *Line;

  Line = HMainEditor.BufferImage->CurrentLine;
  if (Line == NULL) {
    return NULL;
  }

  for (Index = 0; Index < Count; Index++) {
    //
    // already the first line
    //
    if (Line->Link.BackLink == HMainEditor.BufferImage->ListHead) {
      return NULL;
    }

    Line = CR (Line->Link.BackLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
  }

  return Line;
}

/**
  Advance/Retreat lines.

  @param[in] Count      The line number to advance/retreat.
                            >0 : advance
                            <0: retreat

  @retval NULL An error occured.
  @return A pointer to the line after move.
**/
HEFI_EDITOR_LINE *
HMoveLine (
  IN  INTN Count
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             AbsCount;

  //
  // difference with MoveCurrentLine
  //     just return Line
  //     do not set currentline to Line
  //
  if (Count <= 0) {
    AbsCount  = (UINTN)ABS(Count);
    Line      = HLineRetreat (AbsCount);
  } else {
    Line = HLineAdvance ((UINTN)Count);
  }

  return Line;
}

/**
  Advance/Retreat lines and set CurrentLine in BufferImage to it.

  @param[in] Count    The line number to advance/retreat.
                          >0 : advance
                          <0: retreat

  @retval NULL An error occured.
  @return A pointer to the line after move.
**/
HEFI_EDITOR_LINE *
HMoveCurrentLine (
  IN  INTN Count
  )
{
  HEFI_EDITOR_LINE  *Line;
  UINTN             AbsCount;

  //
  // <0: retreat
  // >0: advance
  //
  if (Count <= 0) {
    AbsCount  = (UINTN)ABS(Count);
    Line      = HLineRetreat (AbsCount);
  } else {
    Line = HLineAdvance ((UINTN)Count);
  }

  if (Line == NULL) {
    return NULL;
  }

  HMainEditor.BufferImage->CurrentLine = Line;

  return Line;
}


/**
  Free all the lines in HBufferImage.
    Fields affected:
    Lines
    CurrentLine
    NumLines
    ListHead

  @param[in] ListHead     The list head.
  @param[in] Lines        The lines.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
HFreeLines (
  IN LIST_ENTRY   *ListHead,
  IN HEFI_EDITOR_LINE *Lines
  )
{
  LIST_ENTRY        *Link;
  HEFI_EDITOR_LINE  *Line;

  //
  // release all the lines
  //
  if (Lines != NULL) {

    Line  = Lines;
    Link  = &(Line->Link);
    do {
      Line  = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);
      Link  = Link->ForwardLink;
      HLineFree (Line);
    } while (Link != ListHead);
  }

  ListHead->ForwardLink = ListHead;
  ListHead->BackLink = ListHead;

  return EFI_SUCCESS;
}

/**
  Get the X information for the mouse.

  @param[in] GuidX      The change.

  @return the new information.
**/
INT32
HGetTextX (
  IN INT32 GuidX
  )
{
  INT32 Gap;

  HMainEditor.MouseAccumulatorX += GuidX;
  Gap = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX);
  HMainEditor.MouseAccumulatorX = (HMainEditor.MouseAccumulatorX * (INT32) HMainEditor.ScreenSize.Column) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionX);
  HMainEditor.MouseAccumulatorX = HMainEditor.MouseAccumulatorX / (INT32) HMainEditor.ScreenSize.Column;
  return Gap;
}

/**
  Get the Y information for the mouse.

  @param[in] GuidY      The change.

  @return the new information.
**/
INT32
HGetTextY (
  IN INT32 GuidY
  )
{
  INT32 Gap;

  HMainEditor.MouseAccumulatorY += GuidY;
  Gap = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) / (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY);
  HMainEditor.MouseAccumulatorY = (HMainEditor.MouseAccumulatorY * (INT32) HMainEditor.ScreenSize.Row) % (INT32) (50 * (INT32) HMainEditor.MouseInterface->Mode->ResolutionY);
  HMainEditor.MouseAccumulatorY = HMainEditor.MouseAccumulatorY / (INT32) HMainEditor.ScreenSize.Row;

  return Gap;
}
