{ ------------------------------------------------------------- }
{ Purpose : Next Standard 6                                     }
{ By      : Bojan Nikolic                                       }
{ For     : BergSoft                                            }
{ ------------------------------------------------------------- }
{ Copyright (C) BergSoft.net 2015. All Rights Reserved.         }
{ ------------------------------------------------------------- }
unit NxAssociates6;

interface

uses
  { Standard }
  Classes, Types, Messages, Windows, Graphics, SysUtils,
  { Controls }
  Controls, Forms, ImgList,
  { TypeInfo }
  TypInfo,
  { Next Standard 6 }
  NxIntf6, NxConsts6;

type
  { TNxInspectorAssciates }

  TNxAssociates6 = class
  private
    { Private Fields }
    FAssociateList: TList;
    function GetCount: Integer;
    function GetAssociate(Index: Integer): TObject;
  protected
    { Event Handlers }
    procedure DoReadProp(Sender: TObject; PropType: TTypeKind;
      PropName: string); dynamic;
    { Virtual Methods }
  public
    procedure Add(AObject: TObject);
    procedure Clear;
    constructor Create;
    destructor Destroy; override;
    procedure GetPropValue(PropName: string; Value: INxBase);
    procedure Remove(AObject: TObject);
    procedure SetPropValue(PropName: string; Value: INxBase);
    { Properties }
    property Associate[Index: Integer]: TObject read GetAssociate; default;
    property Count: Integer read GetCount;
  end;

implementation

uses
  { Standard }
  Dialogs,
  { Next Standard 6 }
  NxStdCtrls6, NxTypInfo6;

{ TNxInspectorAssciates }

procedure TNxAssociates6.Add(AObject: TObject);
begin
  { Add if not already added }
  if FAssociateList.IndexOf(AObject) = -1 then
  begin
    FAssociateList.Add(AObject);
    { ToDo: Notify Inspector }
  end;
end;

procedure TNxAssociates6.Clear;
begin
  FAssociateList.Clear;
end;

constructor TNxAssociates6.Create;
begin
  FAssociateList := TList.Create;
end;

destructor TNxAssociates6.Destroy;
begin
  FAssociateList.Free;
  inherited;
end;

procedure TNxAssociates6.DoReadProp(Sender: TObject; PropType: TTypeKind;
  PropName: string);
begin

end;

function TNxAssociates6.GetAssociate(Index: Integer): TObject;
begin
  Result := TObject(FAssociateList[Index]);
end;

function TNxAssociates6.GetCount: Integer;
begin
  Result := FAssociateList.Count;
end;

procedure TNxAssociates6.GetPropValue(PropName: string; Value: INxBase);
var
	PropInfo: PPropInfo;
  Ref: TObject;
  i: Integer;
begin
  { Run trough Associates }
  for i := 0 to Pred(Count) do
  begin
    Ref := Associate[i];

    if Assigned(Ref) then
    begin
      { Isolate Obj. & Property }
      ResolveProperty(Ref, PropName);

      { Read Info }
      PropInfo := GetPropInfo(Ref, PropName);

      if Assigned(PropInfo) then
      begin

        { Prop. Kind }
        case PropInfo^.PropType^.Kind of
          { String & WideString }
          {$IFDEF UNICODE}tkUString, {$ENDIF}
          tkString,
          tkChar,
          tkLString: Value.AsString := GetStrProp(Ref, PropName);
          tkWString, tkWChar: Value.AsString := {$IFDEF UNICODE}GetStrProp{$ELSE}GetWideStrProp{$ENDIF}(Ref, PropName);
          { Other }
          tkInteger: Value.AsInteger := GetOrdProp(Ref, PropName);
          tkFloat: Value.AsFloat := GetFloatProp(Ref, PropName);
          tkEnumeration: Value.AsString := GetEnumProp(Ref, PropName);
          tkSet: Value.AsString := GetSetProp(Ref, PropName);
        end;

      end; { if Assigned PropInfo }

    end; { if Assigned Ref }

  end; { for }

end;

procedure TNxAssociates6.Remove(AObject: TObject);
var
  Index: Integer;
begin
  Index := FAssociateList.IndexOf(AObject);
  if Index > -1 then
  begin
    FAssociateList.Delete(Index);
    { ToDo: Notify Inspector }
  end;
end;

procedure TNxAssociates6.SetPropValue(PropName: string; Value: INxBase);
var
	PropInfo: PPropInfo;
  Ref: TObject;
  i: Integer;
begin
  { Run trough Associates }
  for i := 0 to Pred(Count) do
  begin
    Ref := Associate[i];

    if Assigned(Ref) then
    begin
      { Isolate Obj. & Property }
      ResolveProperty(Ref, PropName);

      { Read Info }
      PropInfo := GetPropInfo(Ref, PropName);

      if Assigned(PropInfo) and
        (PropInfo^.SetProc <> nil) then
      begin

        { Prop. Kind }
        case PropInfo^.PropType^.Kind of
          { String & WideString }
          {$IFDEF UNICODE}tkUString, {$ENDIF}
          tkString,
          tkChar,
          tkLString: SetStrProp(Ref, PropName, Value.AsString);
          tkWString, tkWChar: {$IFDEF UNICODE}SetStrProp{$ELSE}SetWideStrProp{$ENDIF}(Ref, PropName, Value.AsString);
          { Other }
          tkInteger: SetOrdProp(Ref, PropName, Value.AsInteger);
          tkFloat: SetFloatProp(Ref, PropName, Value.AsFloat);
          tkEnumeration: SetEnumProp(Ref, PropName, Value.AsString);
          tkSet: SetSetProp(Ref, PropName, Value.AsString); { Error ! }
        end;

      end; { if Assigned PropInfo }

    end; { if Assigned Ref }

  end; { for }

end;

end.
