{
    This file is part of restemplate.

    Copyright (C) 2015 Andreas Schneider

    restemplate is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    restemplate is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with restemplate.  If not, see <http://www.gnu.org/licenses/>.
}
unit UFilter;

{$mode objfpc}{$H+}
{$modeswitch advancedrecords}

interface

uses
  Classes, SysUtils, RegExpr, fgl;

type

  { THighlightFilter }

  THighlightFilter = class
    Expression: TRegExpr;
    FGColor: Byte;
    BGColor: Byte;
    constructor Create(AString: String);
    destructor Destroy; override;
  class var
    FilterExpression: TRegExpr;
    ParamExpression: TRegExpr;
  end;
  TFilterList = specialize TFPGObjectList<THighlightFilter>;

  { THighlight }

  THighlight = record
    FGColor: Byte;
    BGColor: Byte;
    Start: Integer;
    Length: Integer;
    class operator =(A, B: THighlight): Boolean;
  end;
  THighlights = specialize TFPGList<THighlight>;

function CompareHighlights(const AHL1: THighlight; const AHL2: THighlight): Integer;

implementation

{ THighlightFilter }

constructor THighlightFilter.Create(AString: String);
begin
  FGColor := $FF;
  BGColor := $FF;
  if FilterExpression.Exec(AString) then
  begin
    Expression := TRegExpr.Create(Copy(AString, 1, FilterExpression.MatchPos[0] - 1));
    if ParamExpression.Exec(FilterExpression.Match[0]) then
      repeat
        if ParamExpression.Match[1] = 'FG' then
          FGColor := StrToInt(ParamExpression.Match[2])
        else if ParamExpression.Match[1] = 'BG' then
          BGColor := StrToInt(ParamExpression.Match[2]);
      until not ParamExpression.ExecNext;
  end else
    Expression := TRegExpr.Create(AString);
end;

destructor THighlightFilter.Destroy;
begin
  Expression.Free;
  inherited Destroy;
end;

{ THighlight }

class operator THighlight. = (A, B: THighlight): Boolean;
begin
  Result := (A.Start = B.Start) and (A.Length = B.Length);
end;

function CompareHighlights(const AHL1: THighlight; const AHL2: THighlight): Integer;
begin
  if AHL1.Start = AHL2.Start then
  begin
    Result := AHL1.Length - AHL2.Length;
  end else
    Result := AHL1.Start - AHL2.Start;
end;

initialization
  THighlightFilter.FilterExpression := TRegExpr.Create('( (FG|BG)(\d+))*$');
  THighlightFilter.ParamExpression := TRegExpr.Create('(FG|BG)(\d+)');
finalization
  THighlightFilter.FilterExpression.Free;
  THighlightFilter.ParamExpression.Free;
end.

