{$I OVC.INC}

{$B-} {Complete Boolean Evaluation}
{$I+} {Input/Output-Checking}
{$P+} {Open Parameters}
{$T-} {Typed @ Operator}
{$W-} {Windows Stack Frame}
{$X+} {Extended Syntax}

{$IFNDEF Win32}
{$G+} {286 Instructions}
{$N+} {Numeric Coprocessor}
{$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
{$ENDIF}

{*********************************************************}
{*                  OVCEDITN.PAS 2.00                    *}
{*     Copyright (c) TurboPower Software Co 1995-96      *}
{*                 All rights reserved.                  *}
{*********************************************************}

unit OvcEditN;
  {Editor para node handling}

interface

uses
  OvcConst, OvcData;

{.Z+}

type
  UndoType = (
    utSavePos,   {save a position}
    utInsert,    {an insertion within a paragraph}
    utInsPara,   {an insertion of an entire paragraph before another}
    utPlacePara, {an insertion of an entire paragraph after another}
    utDelete,    {a deletion within a paragraph}
    utDelPara,   {a deletion of an entire paragraph}
    utReplace);  {a replacement of text within a paragraph}

const
  {undo record bit flags}
  urModFlag  = $80;
  urTypeMask = $7F;

type
  PLineMap = ^LineMap;
  LineMap  = array[1..High(SmallInt)] of Word;

type

{*** TUndoRec ***}

  {this variable sized structure is stored in a global undo}
  {buffer and mapped into a TUndoNode as required}
  PUndoRec = ^TUndoRec;
  TUndoRec = record
    PrevSize : Word;       {size of previous record}
    Flags    : Byte;       {contains undo type and flags}
    LinkNum  : Byte;       {link number}
    PNum     : LongInt;    {paragraph number}
    PPos     : Integer;    {position in paragraph}
    DSize    : Word;       {data size}
    Data     : record end; {data-dynamically allocated}
  end;

const
  UndoRecSize = SizeOf(TUndoRec);

type

{*** TUndoNode ***}

  TUndoNode = class(TObject)
  public
    UndoRec : PUndoRec;

    procedure Init(PUR   : PUndoRec;         {location in buffer}
                   UT    : UndoType;
                   Link  : Byte;
                   MF    : Boolean;          {modified flag}
                   PSize : Word;
                   P     : LongInt;
                   Pos   : Integer;
                   D     : PAnsiChar;        {data}
                   DLen  : Word);            {data length}
      {-init the data fields of the object}
    procedure InitReplace(PUR   : PUndoRec;  {location in buffer}
                          Link  : Byte;
                          MF    : Boolean;   {modified flag}
                          PSize : Word;
                          P     : LongInt;
                          Pos   : Integer;
                          D     : PAnsiChar; {data}
                          DLen  : Word;      {data length}
                          R     : PAnsiChar; {replace data}
                          RLen  : Word);     {replace data length}
      {-init the data fields of the object for a replace action}
    procedure Done(PUR : PUndoRec);
      {-conditionall destroy a paragraph node if associated}
    function  GetUndoType(PUR : PUndoRec) : UndoType;
      {-return the undo type for this undo record}
    function  ModFlag(PUR : PUndoRec) : Boolean;
      {-return the state of the modified flag}
    procedure SetModFlag(PUR   : PUndoRec; Value : Boolean);
      {-return the modified flag for this undo record}
  end;


{*** TParaNode ***}

  TParaNode = class(TObject)
  public
    BufSize   : Word;       {size of buffer}
    LineCount : Integer;    {number of lines in this paragraph}
    Map       : PLineMap;   {pointer to line map}
    MapSize   : Word;       {number of elements in line map}
    Next      : TParaNode;  {next paragraph in list}
    Prev      : TParaNode;  {previous paragraph in list}
    S         : PAnsiChar;  {text of paragraph; nil if empty}
    SLen      : Word;       {current length}

    constructor Init(P       : PAnsiChar;
                     WrapCol : Integer;
                     TabSize : Integer);
      {-create paragraph from text of P^}
    constructor InitLen(P       : PAnsiChar;
                        Len     : Word;
                        WrapCol : Integer;
                        TabSize : Integer);
      {-create paragraph with Len characters from P^}
    destructor Destroy;
      override;

    function  GetS : PAnsiChar;
      {-return pointer to text of paragraph}
    function  ExpandToLength(NBS : Word) : Boolean;
      {-expand buffer to size NBS}
    function  EstimateMapSize(Len : Word; WrapCol : Integer) : Word;
      {-return an estimated map size}
    procedure ExpandLineMap(NMS : Word);
      {-expand line map to size NMS}
    procedure Recalc(WrapCol, TabSize : Integer);
      {-calculate the number of lines in this paragraph given the specified
        wrap column}
    procedure RecalcAfterInsDel(WrapCol, TabSize, Pos, RplLen, Count : Integer;
                                var FL, LL : Integer);
      {-calculate the number of lines after an insertion or deletion}
    function  NthLine(N : Integer; var Len : Word) : PAnsiChar;
      {-return a pointer to the Nth line of this paragraph; Len is its length}
    function  PosToLine(Pos : Integer; var Col : Integer) : Integer;
      {-given a position in the paragraph, return the line and Col}
    function  InsertTextPrim(St : PAnsiChar; StLen : Word;
                             Pos, WrapCol, TabSize : Integer;
                             var FL, LL : Integer) : Word;
      {-insert StLen characters from St^ at Pos}
    function  InsertText(St : PAnsiChar; Pos, WrapCol, TabSize : Integer;
                         var FL, LL : Integer) : Word;
      {-insert St^ at Pos}
    procedure DeleteText(Pos, Count, WrapCol, TabSize : Integer;
                         var FL, LL : Integer);
      {-delete count characters at Pos}
    function  ReplaceText(Pos, Count, WrapCol, TabSize : Integer;
                          St : PAnsiChar; StLen : Integer;
                          var FL, LL : Integer) : Word;
      {-replace the next Count characters at Pos with text of St^}
    function  TrimWhiteSpace : Word;
      {-trim trailing white space from end of paragraph}
    function  CountWhiteSpace(Pos : Integer) : Word;
      {-count amount of white space prior to Pos}
  end;
{.Z-}



implementation
