unit ILists;

interface

uses
	Windows, M2AddOn, XLists, Geomet, GeomCmd;

type
	TDoubleList = class(TRecList)
	private
		function GetID(anIndex: Integer): Double;
		procedure SetID(anIndex: Integer; anID: Double);
	public
		constructor Create;
		function Add(anId: Double):Integer;
		property Values[I: Integer]: Double read GetID write SetID; default;
	end;

	PM2ID = ^TM2ID;
	TM2List = class(TRecList)
	private
		function GetID(anIndex: Integer): TM2ID;
		procedure SetID(anIndex: Integer; const anID: TM2ID);
	public
		constructor Create;
		function Add(const anId: TM2ID):Integer;
		procedure Del(const anId: TM2ID);
		function IndexOf(const anId: TM2ID): Integer;
		property IDs[I: Integer]: TM2ID read GetID write SetID; default;
	end;

	PM2IDPair = ^TM2IDPair;
	TM2IDPair = record
		idFrom : TM2ID;
		idTo:    TM2ID;
	end;
	TM2IDPairList = class(TRecList)
	private
		function GetID(anIndex: Integer): TM2IDPair;
		procedure SetID(anIndex: Integer; const anID: TM2IDPair);
	public
		constructor Create;
    function Add(const anId: TM2IDPair): Integer;
    procedure Del(const anId: TM2IDPair);
    function IndexOf(const anId: TM2IDPair): Integer;
    function IndexOfFrom(const anID: TM2ID): Integer;
		property IDs[I: Integer]: TM2IDPair read GetID write SetID; default;
	end;

	TTMPointList = class(TRecList)
	private
  	function GetPoint(anIndex: Integer): TM2Point;
		procedure SetPoint(anIndex: Integer; const pt: TM2Point);
	public
		constructor Create;
    function Add(const pt: TM2Point):Integer;
    procedure Del(const pt: TM2Point);
		function IndexOf(const pt: TM2Point): Integer;
		property Points[I: Integer]: TM2Point read GetPoint write SetPoint; default;
	end;

	TTDRectList = class(TRecList)
	private
		function GetElem(anIndex: Integer): TDRect;
		procedure SetElem(anIndex: Integer; const e: TDRect);
	public
		constructor Create;
		function Add(const e: TDRect): Integer;
		property Elems[I: Integer]: TDRect read GetElem write SetElem; default;
	end;

	TTDPointList = class(TRecList)
	private
		function GetPoint(anIndex: Integer): TDPoint;
		procedure SetPoint(anIndex: Integer; const pt: TDPoint);
	public
		constructor Create;
    function Add(const pt: TDPoint): Integer;
    function IndexOf(const pt: TDPoint): Integer;
		property Points[I: Integer]: TDPoint read GetPoint write SetPoint; default;
	end;

	TTMCommandList = class(TRecList)
	private
		function GetCommand(anIndex: Integer): TM2ContourCommand;
		procedure SetCommand(anIndex: Integer; const pt: TM2ContourCommand);
	public
		constructor Create;
		function Add(const pt: TM2ContourCommand): Integer;
		procedure Del(const pt: TM2ContourCommand);
		function IndexOf(const pt: TM2ContourCommand): Integer;
		property Commands[I: Integer]: TM2ContourCommand read GetCommand write SetCommand; default;
	end;

  TTMGullyElem = record
    Point: TDPoint;
    Edge: Integer;
    LastEdge: Integer;
  end;

  PTMGullyElem = ^TTMGullyElem;
  function TMGullyElem(_Point: TDPoint; _Edge: Integer; _LastEdge: Integer): TTMGullyElem ;

type
	TTMGullyElemList = class(TRecList)
	private
		function GetElem(anIndex: Integer): TTMGullyElem;
		procedure SetElem(anIndex: Integer; const pt: TTMGullyElem);
	public
		constructor Create;
		function Add(const pt: TTMGullyElem): Integer;
		procedure Del(const pt: TTMGullyElem);
		function IndexOf(const pt: TTMGullyElem): Integer;
		property Elems[I: Integer]: TTMGullyElem read GetElem write SetElem; default;
	end;

	TGConnectBriefList = class(TRecList)
	private
  	function GetElem(anIndex: Integer): TGConnectBrief;
		procedure SetElem(anIndex: Integer; const pt: TGConnectBrief);
	public
		constructor Create;
    function Add(const pt: TGConnectBrief): Integer;
    function IndexOf(const pt: TGConnectBrief): Integer;
		property Elems[I: Integer]: TGConnectBrief read GetElem write SetElem; default;
	end;

	TGConnectBriefListStrict = class(TGConnectBriefList)
	public
		constructor Create;
  end;
	TGBelongEdgePairList = class(TRecList)
	private
  	function GetElem(anIndex: Integer): TGBelongEdgePair;
		procedure SetElem(anIndex: Integer; const pt: TGBelongEdgePair);
	public
		constructor Create;
    function Add(const pt: TGBelongEdgePair): Integer;
    function IndexOf(const pt: TGBelongEdgePair): Integer;
		property Elems[I: Integer]: TGBelongEdgePair read GetElem write SetElem; default;
	end;

{
	TGConnectPairList = class(TRecList)
	private
  	function GetElem(anIndex: Integer): TGConnectPair;
		procedure SetElem(anIndex: Integer; const pt: TGConnectPair);
	public
		constructor Create;
    function Add(const pt: TGConnectPair): Integer;
    function IndexOf(const pt: TGConnectPair): Integer;
		property Elems[I: Integer]: TGConnectPair read GetElem write SetElem; default;
	end;
}
  PGConnectLong = ^TGConnectLong;
	TGConnectLong = object
    Pt1: Integer;
    Pt2: Integer;
    BelongPair: TGBelongPair;
//    shapeList: TLongintList;
    edgeList: TLongintList;
  public
    constructor Create;
    destructor Destroy;
	end;

procedure CopyConnectLongToNew(const cl:TGConnectLong; var clNew: TGConnectLong);
type
	TGConnectLongList = class(TRecList)
	private
  	function GetElem(anIndex: Integer): TGConnectLong;
		procedure SetElem(anIndex: Integer; const pt: TGConnectLong);
	public
		constructor Create;
		destructor Destroy;override;

    function Add(const pt: TGConnectLong): Integer;
    function IndexOf(const pt: TGConnectLong): Integer;
		property Elems[I: Integer]: TGConnectLong read GetElem write SetElem; default;
    procedure DeleteDestroy(anIndex: Integer);
	end;


{
	TGBelongPairList = class(TRecList)
	private
  	function GetElem(anIndex: Integer): TGBelongPair;
		procedure SetElem(anIndex: Integer; const pt: TGBelongPair);
	public
		constructor Create;
    function Add(const pt: TGBelongPair): Integer;
    function IndexOf(const pt: TGBelongPair): Integer;
		property Elems[I: Integer]: TGBelongPair read GetElem write SetElem; default;
	end;
}

function M2IDPair(const idFrom,idTo :TM2ID): TM2IDPair;
procedure CopyIDPairLists(listFrom, listTo: TM2IDPairList);

implementation

uses M2AddOnD;

constructor TGConnectLong.Create;
begin
	edgeList := TLongintList.Create;
	edgeList.Sorted := False;
//  shapeList.Create;
end;
destructor TGConnectLong.Destroy;
begin
	edgeList.Free;
//  shapeList.Free;
end;

procedure CopyConnectLongToNew(const cl:TGConnectLong; var clNew: TGConnectLong);
var
	i: Integer;
begin
	clNew.Pt1 := cl.Pt1;
	clNew.Pt2 := cl.Pt2;
	clNew.BelongPair := cl.BelongPair;
	for i := 0 to cl.edgeList.Count - 1 do
		clNew.EdgeList.Add(cl.edgeList[i]);
//  shapeList.Free;
end;

constructor TDoubleList.Create;
begin
	inherited Create(sizeof(Double));
end;

function TDoubleList.GetID(anIndex: Integer): Double;
begin
	Result := PDouble(Items[anIndex])^;
end;

procedure TDoubleList.SetID(anIndex: Integer; anID: Double);
begin
	PDouble(Items[anIndex])^ := anID;
end;

function TDoubleList.Add(anID: Double): Integer;
begin
	Result := inherited Add(anID);
end;


function CompareTM2ID(const Value1, Value2): Integer;
	var t1: TM2ID absolute Value1;
	var t2: TM2ID absolute Value2;
begin
	if t1 < t2 then Result := -1
	else if t1 = t2 then Result := 0
	else Result := 1;
end;


function TM2List.GetID(anIndex: Integer): TM2ID;
begin
	Result := PM2ID(Items[anIndex])^;
end;

procedure TM2List.SetID(anIndex: Integer; const anID: TM2ID);
begin
	PM2ID(Items[anIndex])^ := anID;
end;

constructor TM2List.Create;
begin
	inherited Create(sizeof(TM2ID));
	sorted := True;
	CompareItems := CompareTM2ID;
end;

function TM2List.Add(const anID: TM2ID): Integer;
begin
	Result := inherited Add(anID);
end;

procedure TM2List.Del(const anID: TM2ID);
var
	index : Integer;
begin
	index := IndexOf(anId);
	if index >=0 then
		Delete(index);
end;

function TM2List.IndexOf(const anID: TM2ID): Integer;
begin
	Result := inherited IndexOf(anID);
end;

function M2IDPair(const idFrom,idTo :TM2ID): TM2IDPair;
begin
	Result.idFrom := idFrom;
	Result.idTo := idTo;
end;

function CompareTM2IDPair(const Value1, Value2): Integer;
  var t1: TM2IDPair absolute Value1;
  var t2: TM2IDPair absolute Value2;
begin
	if t1.idFrom < t2.idFrom then Result := -1
	else if t1.idFrom = t2.idFrom then Result := 0
	else Result := 1;
end;

procedure CopyIDPairLists(listFrom, listTo: TM2IDPairList);
var
  i: Integer;
begin
  listTo.Clear;
  listTo.Sorted := listFrom.Sorted;
  for i:=0 to listFrom.Count-1 do
    listTo.Add(listFrom[i]);
end;


function TM2IDPairList.GetID(anIndex: Integer): TM2IDPair;
begin
	Result := PM2IDPair(Items[anIndex])^;
end;

procedure TM2IDPairList.SetID(anIndex: Integer; const anID: TM2IDPair);
begin
	PM2IDPair(Items[anIndex])^ := anID;
end;

constructor TM2IDPairList.Create;
begin
	inherited Create(sizeof(TM2IDPair));
  sorted := True;
	CompareItems := CompareTM2IDPair;
end;

function TM2IDPairList.Add(const anID: TM2IDPair): Integer;
begin
	Result := inherited Add(anID);
end;

procedure TM2IDPairList.Del(const anID: TM2IDPair);
var
  index : Integer;
begin
  index := IndexOf(anId);
  if index >=0 then
    Delete(index);
end;

function TM2IDPairList.IndexOf(const anID: TM2IDPair): Integer;
begin
	Result := inherited IndexOf(anID);
end;
function TM2IDPairList.IndexOfFrom(const anID: TM2ID): Integer;
var
  t:TM2IDPair;
begin
  t := M2IDPair(anID, anID);
	Result := inherited IndexOf(t);
end;



function CompareTM2Point(const Value1, Value2): Integer;
  var t1: TM2Point absolute Value1;
  var t2: TM2Point absolute Value2;
begin
	if M2PointIsEqual(t1,t2) then Result := 0
	else Result := 1;
end;

constructor TTMPointList.Create;
begin
	inherited Create(sizeof(TM2Point));
  sorted := False;
	CompareItems := CompareTM2Point;
end;

function TTMPointList.GetPoint(anIndex: Integer): TM2Point;
begin
	Result := PM2Point(Items[anIndex])^;
end;

procedure TTMPointList.SetPoint(anIndex: Integer; const pt: TM2Point);
begin
	PM2Point(Items[anIndex])^ := pt;
end;


function TTMPointList.Add(const pt: TM2Point): Integer;
begin
  Result := inherited Add(pt);
end;

procedure TTMPointList.Del(const pt: TM2Point);
var
  index : Integer;
begin
  index := IndexOf(pt);
  if index >=0 then
    Delete(index);
end;

function TTMPointList.IndexOf(const pt: TM2Point): Integer;
begin
	Result := inherited IndexOf(pt);
end;

// --------- TTDPointList ----------------------------

function CompareTDPoint(const Value1, Value2): Integer;
  var t1: TDPoint absolute Value1;
  var t2: TDPoint absolute Value2;
begin
	if t1.IsEqual(t2) then Result := 0
	else Result := 1;
end;

constructor TTDPointList.Create;
begin
	inherited Create(sizeof(TDPoint));
  sorted := False;
	CompareItems := CompareTDPoint;
end;

function TTDPointList.GetPoint(anIndex: Integer): TDPoint;
begin
	Result := PDPoint(Items[anIndex])^;
end;

procedure TTDPointList.SetPoint(anIndex: Integer; const pt: TDPoint);
begin
	PDPoint(Items[anIndex])^ := pt;
end;


function TTDPointList.Add(const pt: TDPoint): Integer;
begin
  Result := inherited Add(pt);
end;

function TTDPointList.IndexOf(const pt: TDPoint): Integer;
begin
	Result := inherited IndexOf(pt);
end;




function CompareTM2ContourCommand(const Value1, Value2): Integer;
  var t1: TM2ContourCommand absolute Value1;
  var t2: TM2ContourCommand absolute Value2;
begin
  Result := 1;
	if t1.CommandType =t2.CommandType then
    case t1.CommandType of
      ccNone:
        Result := 0;
      ccMoveTo:
      	if M2PointIsEqual(t1.MoveTo.Point,t2.MoveTo.Point) then Result := 0;
      ccLineTo:
      	if M2PointIsEqual(t1.LineTo.Point,t2.LineTo.Point) then Result := 0;
      ccArcTo:
      	if M2PointIsEqual(t1.ArcTo.Point,t2.ArcTo.Point) and
           (t1.ArcTo.Convexity = t2.ArcTo.Convexity) then
            Result := 0;
      ccCloseByLine:
        Result := 0;
      ccCloseByArc:
        if t1.ArcTo.Convexity = t2.ArcTo.Convexity then
                    Result := 0;
    end;
end;

constructor TTMCommandList.Create;
begin
	inherited Create(sizeof(TM2ContourCommand));
  sorted := False;
	CompareItems := CompareTM2ContourCommand;
end;

function TTMCommandList.GetCommand(anIndex: Integer): TM2ContourCommand;
begin
	Result := PM2ContourCommand(Items[anIndex])^;
end;

procedure TTMCommandList.SetCommand(anIndex: Integer; const pt: TM2ContourCommand);
begin
	PM2ContourCommand(Items[anIndex])^ := pt;
end;


function TTMCommandList.Add(const pt: TM2ContourCommand): Integer;
begin
  Result := inherited Add(pt);
end;

procedure TTMCommandList.Del(const pt: TM2ContourCommand);
var
  index : Integer;
begin
  index := IndexOf(pt);
  if index >=0 then
    Delete(index);
end;

function TTMCommandList.IndexOf(const pt: TM2ContourCommand): Integer;
begin
	Result := inherited IndexOf(pt);
end;


function TMGullyElem(_Point: TDPoint; _Edge: Integer; _LastEdge: Integer): TTMGullyElem ;
begin
  Result.Point := _Point;
  Result.Edge := _Edge;
  Result.LastEdge := _LastEdge;
end;

function CompareTTMGullyElem(const Value1, Value2): Integer;
  var t1: TTMGullyElem absolute Value1;
  var t2: TTMGullyElem absolute Value2;
begin
	if t1.Point.IsEqual(t2.Point) and (t1.Edge = t2.Edge) then Result := 0 // TEST Not Full
	else Result := 1;
end;

constructor TTMGullyElemList.Create;
begin
	inherited Create(sizeof(TTMGullyElem));
  sorted := False;
	CompareItems := CompareTTMGullyElem;
end;

function TTMGullyElemList.GetElem(anIndex: Integer): TTMGullyElem;
begin
	Result := PTMGullyElem(Items[anIndex])^;
end;

procedure TTMGullyElemList.SetElem(anIndex: Integer; const pt: TTMGullyElem);
begin
	PTMGullyElem(Items[anIndex])^ := pt;
end;


function TTMGullyElemList.Add(const pt: TTMGullyElem): Integer;
begin
  Result := inherited Add(pt);
end;

procedure TTMGullyElemList.Del(const pt: TTMGullyElem);
var
	index : Integer;
begin
	index := IndexOf(pt);
	if index >=0 then
		Delete(index);
end;

function TTMGullyElemList.IndexOf(const pt: TTMGullyElem): Integer;
begin
	Result := inherited IndexOf(pt);
end;



constructor TTDRectList.Create;
begin
	inherited Create(sizeof(TDRect));
	sorted := False;
end;

function TTDRectList.GetElem(anIndex: Integer): TDRect;
begin
	Result := PDRect(Items[anIndex])^;
end;

procedure TTDRectList.SetElem(anIndex: Integer; const e: TDRect);
begin
	PDRect(Items[anIndex])^ := e;
end;


function TTDRectList.Add(const e: TDRect): Integer;
begin
	Result := inherited Add(e);
end;

function CompareTGConnectBriefConstStrict(const Value1, Value2): Integer;
	var t1: TGConnectBrief absolute Value1;
	var t2: TGConnectBrief absolute Value2;
begin
	Result := CompareTGConnectBriefStrict(t1, t2);
end;
function CompareTGConnectBriefConstNotStrict(const Value1, Value2): Integer;
	var t1: TGConnectBrief absolute Value1;
	var t2: TGConnectBrief absolute Value2;
begin
	Result := CompareTGConnectBriefNotStrict(t1, t2);
end;


constructor TGConnectBriefList.Create;
begin
	inherited Create(sizeof(TGConnectBrief));
  sorted := False;
	CompareItems := CompareTGConnectBriefConstNotStrict;
end;
constructor TGConnectBriefListStrict.Create;
begin
	inherited Create;
	CompareItems := CompareTGConnectBriefConstStrict;
end;


function TGConnectBriefList.GetElem(anIndex: Integer): TGConnectBrief;
begin
	Result := PGConnectBrief(Items[anIndex])^;
end;

procedure TGConnectBriefList.SetElem(anIndex: Integer; const pt: TGConnectBrief);
begin
	PGConnectBrief(Items[anIndex])^ := pt;
end;


function TGConnectBriefList.Add(const pt: TGConnectBrief): Integer;
begin
  Result := inherited Add(pt);
end;

function TGConnectBriefList.IndexOf(const pt: TGConnectBrief): Integer;
begin
	Result := inherited IndexOf(pt);
end;



function CompareTGBelongEdgePairConst(const Value1, Value2): Integer;
  var t1: TGBelongEdgePair absolute Value1;
  var t2: TGBelongEdgePair absolute Value2;
begin
  if (t1.aBelong[0] = t2.aBelong[0]) and
            (t1.aBelong[1] = t2.aBelong[1]) then Result :=0
  else
    Result := 1;
end;

constructor TGBelongEdgePairList.Create;
begin
	inherited Create(sizeof(TGBelongEdgePair));
  sorted := False;
	CompareItems := CompareTGBelongEdgePairConst;
end;

function TGBelongEdgePairList.GetElem(anIndex: Integer): TGBelongEdgePair;
begin
	Result := PGBelongEdgePair(Items[anIndex])^;
end;

procedure TGBelongEdgePairList.SetElem(anIndex: Integer; const pt: TGBelongEdgePair);
begin
	PGBelongEdgePair(Items[anIndex])^ := pt;
end;


function TGBelongEdgePairList.Add(const pt: TGBelongEdgePair): Integer;
begin
  Result := inherited Add(pt);
end;

function TGBelongEdgePairList.IndexOf(const pt: TGBelongEdgePair): Integer;
begin
	Result := inherited IndexOf(pt);
end;




{
function CompareTGConnectPairConst(const Value1, Value2): Integer;
  var t1: TGConnectPair absolute Value1;
  var t2: TGConnectPair absolute Value2;
begin
  Result := CompareTGConnectPair(t1, t2);
end;

constructor TGConnectPairList.Create;
begin
	inherited Create(sizeof(TGConnectPair));
  sorted := False;
	CompareItems := CompareTGConnectPairConst;
end;

function TGConnectPairList.GetElem(anIndex: Integer): TGConnectPair;
begin
	Result := PGConnectPair(Items[anIndex])^;
end;

procedure TGConnectPairList.SetElem(anIndex: Integer; const pt: TGConnectPair);
begin
	PGConnectPair(Items[anIndex])^ := pt;
end;


function TGConnectPairList.Add(const pt: TGConnectPair): Integer;
begin
  Result := inherited Add(pt);
end;

function TGConnectPairList.IndexOf(const pt: TGConnectPair): Integer;
begin
	Result := inherited IndexOf(pt);
end;

}
{
function CompareTGBelongPairConst(const Value1, Value2): Integer;
  var t1: TGBelongPair absolute Value1;
  var t2: TGBelongPair absolute Value2;
begin
  if t1.IsEqual(t2) then Result := 0;
    Result := 1;
end;

constructor TGBelongPairList.Create;
begin
	inherited Create(sizeof(TGBelongPair));
  sorted := False;
	CompareItems := CompareTGBelongPairConst;
end;

function TGBelongPairList.GetElem(anIndex: Integer): TGBelongPair;
begin
	Result := PGBelongPair(Items[anIndex])^;
end;

procedure TGBelongPairList.SetElem(anIndex: Integer; const pt: TGBelongPair);
begin
	PGBelongPair(Items[anIndex])^ := pt;
end;


function TGBelongPairList.Add(const pt: TGBelongPair): Integer;
begin
  Result := inherited Add(pt);
end;

function TGBelongPairList.IndexOf(const pt: TGBelongPair): Integer;
begin
	Result := inherited IndexOf(pt);
end;

}
function CompareTGConnectLongConst(const Value1, Value2): Integer;
  var t1: TGConnectLong absolute Value1;
  var t2: TGConnectLong absolute Value2;
begin
  Result := 1;
  if (t1.Pt1 <> t2.Pt1) or (t1.Pt2 <> t2.Pt2) then Exit;
  if (t1.BelongPair.aBelong[0] <> t2.BelongPair.aBelong[0]) or
     (t1.BelongPair.aBelong[1] <> t2.BelongPair.aBelong[1]) then Exit;
	if (t1.edgeList <> t2.edgeList) then Exit;
  Result := 0;
end;

constructor TGConnectLongList.Create;
begin
	inherited Create(sizeof(TGConnectLong));
  sorted := False;
	CompareItems := CompareTGConnectLongConst;
end;

destructor TGConnectLongList.Destroy;
var
  i: Integer;
begin
  for i := 0 to Count-1 do
    Elems[i].Destroy;
  inherited Destroy;
end;

function TGConnectLongList.GetElem(anIndex: Integer): TGConnectLong;
begin
	Result := PGConnectLong(Items[anIndex])^;
end;

procedure TGConnectLongList.SetElem(anIndex: Integer; const pt: TGConnectLong);
begin
	PGConnectLong(Items[anIndex])^ := pt;
end;


function TGConnectLongList.Add(const pt: TGConnectLong): Integer;
begin
  Result := inherited Add(pt);
end;

function TGConnectLongList.IndexOf(const pt: TGConnectLong): Integer;
begin
	Result := inherited IndexOf(pt);
end;
procedure TGConnectLongList.DeleteDestroy(anIndex: Integer);
begin
  Elems[anIndex].Destroy;
  Delete(anIndex);
end;

end.
