{ ------------------------------------------------------------- }
{ Purpose : Next Common 6                                       }
{ By      : Bojan Nikolic                                       }
{ For     : BergSoft                                            }
{ ------------------------------------------------------------- }
{ Copyright (C) BergSoft.net 2014. All Rights Reserved.         }
{ ------------------------------------------------------------- }
{ mm/dd/yy comment                                              }
{ -------- ---------------------------------------------------- }
{ 07/21/14 Added: Moved code from NxIntf6.pas                   }
{ ------------------------------------------------------------- }
{ Todo :                                                        }
{ ------------------------------------------------------------- }
unit NxNodes6;

interface

uses
  { Common }
  Classes, Types, Messages, Windows, Graphics,
  { Controls }
  Controls, StdCtrls,
  { Next Standard 6 }
  NxTypes6, NxIntf6;

type
  TNxNodeList = class;

  { TNxNodeComponent }

  TNxNodeComponent = class(TComponent, INxNode, INxBase)
  private
    FParentNode: INxNode;
    { Property Accessors }
  protected
    { INxNode }
    function GetAbsoluteIndex: Integer; virtual;
    function GetChildCount: Integer; virtual;
    function GetChildNode(Index: Integer): INxNode; virtual;
    function GetCount: Integer;
    function GetHasChildren: Boolean;
    function GetHidden: Boolean;
    function GetIndex: Integer; virtual; abstract;
    function GetIsNull: Boolean; virtual;
    function GetLevel: Integer; virtual;
    function GetParentNode: INxNode;
    procedure DoChildAdd(const Node: INxNode); virtual; abstract;
    procedure SetIndex(const Value: Integer); virtual; abstract;
    procedure SetParentNode(const Value: INxNode);
    { INxObject }
    function ToObject: TObject;
    { INxBase }
    function GetAsBoolean: Boolean; virtual; abstract;
    function GetAsDateTime: TDateTime; virtual; abstract;
    function GetAsFloat: Double; virtual; abstract;
    function GetAsInteger: Integer; virtual; abstract;
    function GetAsString: WideString; virtual; abstract;
    function GetAsUTF8String: UTF8String; virtual; abstract;
    procedure SetAsBoolean(const Value: Boolean); virtual; abstract;
    procedure SetAsDateTime(const Value: TDateTime); virtual; abstract;
    procedure SetAsFloat(const Value: Double); virtual; abstract;
    procedure SetAsInteger(const Value: Integer); virtual; abstract;
    procedure SetAsString(const Value: WideString); virtual; abstract;
    procedure SetAsUTF8String(const Value: UTF8String); virtual; abstract;
    { Property Accessors }
    function GetChildNodes: INxNodeList; virtual; abstract;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Methods }
    procedure AssignValue(Source: INxBase);
    procedure ClearChildren;
    function IndexOf(const Node: INxNode): Integer;
    function IsTopLevel: Boolean;
    function NextSibling: INxNode;
    function PrevSibling: INxNode;
    procedure Release;
    procedure Remove;
    procedure RemoveChild;
    { Properties }
    property AbsoluteIndex: Integer read GetAbsoluteIndex;
    property ChildCount: Integer read GetChildCount;
    property ChildNode[Index: Integer]: INxNode read GetChildNode;
    property ChildNodes: INxNodeList read GetChildNodes;
    property Count: Integer read GetCount;
    property HasChildren: Boolean read GetHasChildren;
    property Index: Integer read GetIndex write SetIndex;
    property Level: Integer read GetLevel;
    property ParentNode: INxNode read GetParentNode write SetParentNode;
  end;

  { TNxNodeList }

  TNxNodeList = class(TInterfacedObject, INxNodeList)
  private
    FList: TInterfaceList;
    FOwnerNode: INxNode;
    { Property Accessors }
    function GetNode(const IndexOrName: Variant): INxNode;
  public
    { INxNodeList }
    function GetCount: Integer;
    function GetOwnerNode: INxNode;
    { Methods }
    constructor Create(AOwnerNode: INxNode); virtual;
    function Add(const Node: INxNode): Integer; overload;
    procedure Clear;
    function HasChild: Boolean;
    function HasOwner: Boolean;
    function IndexOf(const Node: INxNode): Integer;
    function Remove(const Node: INxNode): Integer;
    { Properties }
    property Count: Integer read GetCount;
    property Node[const IndexOrName: Variant]: INxNode read GetNode; default;
    property OwnerNode: INxNode read GetOwnerNode;
  end;

implementation

{ TNxNodeComponent }

procedure TNxNodeComponent.AssignValue(Source: INxBase);
begin

end;

procedure TNxNodeComponent.ClearChildren;
begin
  ChildNodes.Clear;
end;

constructor TNxNodeComponent.Create(AOwner: TComponent);
begin
  inherited;

end;

destructor TNxNodeComponent.Destroy;
begin

  inherited;
end;

function TNxNodeComponent.GetAbsoluteIndex: Integer;
begin
  Result := -1;
end;

function TNxNodeComponent.GetChildCount: Integer;
begin
  Result := ChildNodes.Count;
end;

function TNxNodeComponent.GetChildNode(Index: Integer): INxNode;
begin
  Result := ChildNodes[Index];
end;

function TNxNodeComponent.GetCount: Integer;
begin
  Result := 0;
end;

function TNxNodeComponent.GetHasChildren: Boolean;
begin
  Result := ChildCount > 0;
end;

function TNxNodeComponent.GetHidden: Boolean;
begin
  Result := False;
end;

function TNxNodeComponent.GetIsNull: Boolean;
begin
  Result := False;
end;

function TNxNodeComponent.GetLevel: Integer;
begin
  if ParentNode = nil then Result := 0
    else Result := Succ(ParentNode.Level);
end;

function TNxNodeComponent.GetParentNode: INxNode;
begin
  Result := FParentNode;
end;

function TNxNodeComponent.IndexOf(const Node: INxNode): Integer;
begin
  Result := ChildNodes.IndexOf(Node);
end;

function TNxNodeComponent.IsTopLevel: Boolean;
begin
  Result := Level = 0;
end;

function TNxNodeComponent.NextSibling: INxNode;
begin
  if Index < Pred(ChildCount) then Result := ChildNode[Index + 1];
end;

function TNxNodeComponent.PrevSibling: INxNode;
begin
  if Index < 0 then Result := ChildNode[Index - 1];
end;

procedure TNxNodeComponent.Release;
begin

end;

procedure TNxNodeComponent.Remove;
begin

end;

procedure TNxNodeComponent.RemoveChild;
begin

end;

procedure TNxNodeComponent.SetParentNode(const Value: INxNode);
begin
  if Value <> FParentNode then
  begin
    FParentNode := Value;

    if Assigned(FParentNode) then
    begin
      FParentNode.ChildNodes.Add(Self as INxNode);

      FParentNode.DoChildAdd(Value);
    end;
  end;
end;

function TNxNodeComponent.ToObject: TObject;
begin
  Result := Self;
end;

{ TNxNodeList }

function TNxNodeList.Add(const Node: INxNode): Integer;
begin
  if (Node.ParentNode <> FOwnerNode)
    or not HasOwner then
  begin
    Node.ParentNode := OwnerNode;
    FList.Add(Node as INxNode);
    Result := Node.Index;
  end else Result := -1;
end;

procedure TNxNodeList.Clear;
begin
  FList.Clear;
end;

constructor TNxNodeList.Create(AOwnerNode: INxNode);
begin
  FOwnerNode := AOwnerNode;
  FList := TInterfaceList.Create;
end;

function TNxNodeList.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TNxNodeList.GetNode(const IndexOrName: Variant): INxNode;
begin
  Result := FList[IndexOrName] as INxNode;
end;

function TNxNodeList.GetOwnerNode: INxNode;
begin
  Result := FOwnerNode;
end;

function TNxNodeList.HasChild: Boolean;
begin
  Result := FList.Count > 0;
end;

function TNxNodeList.HasOwner: Boolean;
begin
  Result := Assigned(FOwnerNode);
end;

function TNxNodeList.IndexOf(const Node: INxNode): Integer;
begin
  Result := FList.IndexOf(Node as INxNode);
end;

function TNxNodeList.Remove(const Node: INxNode): Integer;
begin
  Result := FList.Remove(Node as INxNode);
end;

end.

