{********************************************************************}
{                                                                    }
{ written by TMS Software                                            }
{            copyright © 2013                                        }
{            Email : info@tmssoftware.com                            }
{            Web : http://www.tmssoftware.com                        }
{                                                                    }
{ The source code is given as is. The author is not responsible      }
{ for any possible damage done due to the use of this code.          }
{ The complete source code remains property of the author and may    }
{ not be distributed, published, given or sold in any form as such.  }
{ No parts of the source code can be included in any other component }
{ or application without written authorization of the author.        }
{********************************************************************}

unit FMX.TMSTileListBinding;

interface

{$I TMSDEFS.INC}

uses
  FMX.TMSTileList, Classes, FMX.Bind.DBLinks, Math, System.Bindings.EvalProtocol, Data.Bind.Components,
  Data.Bind.Editors, System.Bindings.ObjEval, FMX.Dialogs, SysUtils, FMX.Types
  {$IFDEF DELPHIXE5_LVL}
  , FMX.Graphics
  {$ENDIF}
  ;

type
  TTMSFMXTileListBindClass = class(TTMSFMXTileList);

  TTMSFMXBindDBTileListLink = class(TBindGridLink)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  TTMSFMXTileListItemEditorObject = class
  private
    FIndex: Integer;
    FTileList: TTMSFMXTileList;
    function GetBitmap: TBitmap;
    function GetDetailNotes: String;
    procedure SetBitmap(const Value: TBitmap);
    procedure SetCaption(const Value: String);
    procedure SetDetailNotes(const Value: String);
    function GetCaption: String;
    function GetNotes: String;
    procedure SetNotes(const Value: String);
  public
    property Caption: String read GetCaption write SetCaption;
    property Notes: String read GetNotes write SetNotes;
    property DetailNotes: String read GetDetailNotes write SetDetailNotes;
    property Bitmap: TBitmap read GetBitmap write SetBitmap;
  end;

  TTMSFMXBindTileListEditor = class(TBindListEditor)
  private
    FEditorObject: TTMSFMXTileListItemEditorObject;
    function GetIndex: Integer;
    procedure SetIndex(const Value: Integer);
  protected
    property AIndex: Integer read GetIndex write SetIndex;
    function TileList: TTMSFMXTileListBindClass;
  public
    constructor Create(ATileList: TTMSFMXTileList);
    destructor Destroy; override;
    procedure BeginUpdate; override;
    procedure EndUpdate; override;
    procedure DeleteToEnd; override;
    function AddItem(Select: Boolean): IScope; override;
    function InsertItem(Select: Boolean): IScope; override;
    function CanInsertItem: Boolean; override;
    function MoveNext: Boolean; override;
    function GetRowCount: Integer; override;
    function CurrentItem: IScope; override;
    procedure ClearList; override;
    function GetSelectedText: string; override;
    procedure SetSelectedText(const AValue: string); override;
    function GetSelectedItem: TObject; override;
  end;

  TTMSFMXBindTileListEditorFactory = class(TBindEditorFactory)
  public
    constructor Create; override;
    function Supports(AIntf: TGuid; AObject: TObject): Boolean; override;
    function CreateEditor(AIntf: TGuid;
      AObject: TObject): IInterface; override;
  end;

implementation


{ TTMSFMXBindTileListEditorFactory }

constructor TTMSFMXBindTileListEditorFactory.Create;
begin
  inherited;
end;

function TTMSFMXBindTileListEditorFactory.CreateEditor(AIntf: TGuid;
  AObject: TObject): IInterface;
begin
  Result := TTMSFMXBindTileListEditor.Create(TTMSFMXTileList(AObject));
end;

function TTMSFMXBindTileListEditorFactory.Supports(AIntf: TGuid;
  AObject: TObject): Boolean;
begin
  Result := False;
  if AIntf = IBindListEditor then
    if AObject.InheritsFrom(TTMSFMXTileList) then
      Result := True;
end;

{ TTMSFMXBindTileListEditor }

function TTMSFMXBindTileListEditor.AddItem(Select: Boolean): IScope;
var
  AItem: TTMSFMXTile;
begin
  TileList.BindingsCount := TileList.BindingsCount + 1;
  AItem := TileList.Tiles.Insert(TileList.SelectedTileIndex);
  AIndex := AItem.Index;
  Result := WrapObject(AItem);
  TileList.SelectedTileIndex := AItem.Index;
end;

procedure TTMSFMXBindTileListEditor.BeginUpdate;
begin
  inherited;
  TileList.BeginUpdate;
end;

function TTMSFMXBindTileListEditor.CanInsertItem: Boolean;
begin
  Result := TileList.SelectedTileIndex <> -1;
end;

procedure TTMSFMXBindTileListEditor.ClearList;
begin
  inherited;
  TileList.Tiles.Clear;
  TileList.BindingsCount := 0;
end;

constructor TTMSFMXBindTileListEditor.Create(ATileList: TTMSFMXTileList);
begin
  FEditorObject := TTMSFMXTileListItemEditorObject.Create;
  FEditorObject.FTileList := ATileList;
  FEditorObject.FIndex := -1;
  AIndex := -1;
end;

function TTMSFMXBindTileListEditor.CurrentItem: IScope;
begin
  Result := WrapObject(FEditorObject);
end;

procedure TTMSFMXBindTileListEditor.DeleteToEnd;
begin
  if AIndex = -1 then
    AIndex := TileList.SelectedTileIndex;
  while TileList.BindingsCount > Max(0, AIndex) do
  begin
    TileList.Tiles.Delete(TileList.BindingsCount - 1);
    TileList.BindingsCount := TileList.BindingsCount - 1;
  end;
  AIndex := TileList.BindingsCount;
end;

destructor TTMSFMXBindTileListEditor.Destroy;
begin
  FEditorObject.Free;
  inherited;
end;

procedure TTMSFMXBindTileListEditor.EndUpdate;
begin
  inherited;
  TileList.EndUpdate;
  TileList.SelectedTileIndex := TileList.SelectedTileIndex;
end;

function TTMSFMXBindTileListEditor.GetIndex: Integer;
begin
  Result := FEditorObject.FIndex;
end;

function TTMSFMXBindTileListEditor.GetRowCount: Integer;
begin
  Result := TileList.BindingsCount;
end;

function TTMSFMXBindTileListEditor.GetSelectedItem: TObject;
begin
  Result := nil;
  if (TileList.SelectedTileIndex >= 0) and (TileList.SelectedTileIndex <= TileList.Tiles.Count - 1) then
    Result := TileList.Tiles[TileList.SelectedTileIndex];
end;

function TTMSFMXBindTileListEditor.GetSelectedText: string;
begin
  Result := '';
end;

function TTMSFMXBindTileListEditor.InsertItem(Select: Boolean): IScope;
var
  AItem: TTMSFMXTile;
begin
  AItem := TileList.Tiles.Add;
  AIndex := AItem.Index;
  if Select then
    TileList.SelectedTileIndex := AIndex;
  Result := WrapObject(AItem);
end;

function TTMSFMXBindTileListEditor.MoveNext: Boolean;
begin
  if TileList.BindingsCount = 0 then
    Exit(False);
  if AIndex = -1 then
  begin
    AIndex := TileList.SelectedTileIndex;
    if AIndex < 0 then
      AIndex := 0;
  end
  else
    AIndex := AIndex + 1;
  Result := (AIndex >= 0) and (AIndex <= TileList.BindingsCount - 1);
end;

procedure TTMSFMXBindTileListEditor.SetIndex(const Value: Integer);
begin
  FEditorObject.FIndex := Value
end;

procedure TTMSFMXBindTileListEditor.SetSelectedText(const AValue: string);
begin
  inherited;
end;

function TTMSFMXBindTileListEditor.TileList: TTMSFMXTileListBindClass;
begin
  Result := TTMSFMXTileListBindClass(FEditorObject.FTileList);
end;

{ TTMSFMXBindTileListLink }

constructor TTMSFMXBindDBTileListLink.Create(AOwner: TComponent);
var
  LItem: TExpressionItem;
begin
  inherited;
  Assert(ColumnExpressions.Count = 0);
  Assert(FormatControlExpressions.Count = 0);
  Assert(ClearControlExpressions.Count = 0);
  Assert(PosSourceExpressions.Count = 0);
  Assert(PosControlExpressions.Count = 0);

  LItem := PosControlExpressions.AddExpression;
  LItem.ControlExpression := 'SelectedTileIndex';
  LItem.SourceExpression := 'Math_Max(0, DBUtils_ActiveRecord(Self))';

  LItem := PosSourceExpressions.AddExpression;
  LItem.ControlExpression := 'SelectedTileIndex+1';
  LItem.SourceExpression := 'DBUtils_ValidRecNo(Self)';
end;

{ TTMSFMXTileListItemEditorObject }

function TTMSFMXTileListItemEditorObject.GetBitmap: TBitmap;
begin
  Result := nil;
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      Result := FTileList.Tiles[FIndex].Bitmap;
  end;
end;

function TTMSFMXTileListItemEditorObject.GetCaption: String;
begin
  Result := '';
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      Result := FTileList.Tiles[FIndex].Caption;
  end;
end;

function TTMSFMXTileListItemEditorObject.GetDetailNotes: String;
begin
  Result := '';
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      Result := FTileList.Tiles[FIndex].DetailNotes;
  end;
end;

function TTMSFMXTileListItemEditorObject.GetNotes: String;
begin
  Result := '';
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      Result := FTileList.Tiles[FIndex].Notes;
  end
end;

procedure TTMSFMXTileListItemEditorObject.SetBitmap(const Value: TBitmap);
begin
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      FTileList.Tiles[FIndex].Bitmap.Assign(Value);
  end;
end;

procedure TTMSFMXTileListItemEditorObject.SetCaption(const Value: String);
begin
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      FTileList.Tiles[FIndex].Caption := Value;
  end;
end;

procedure TTMSFMXTileListItemEditorObject.SetDetailNotes(const Value: String);
begin
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      FTileList.Tiles[FIndex].DetailNotes := Value;
  end;
end;

procedure TTMSFMXTileListItemEditorObject.SetNotes(const Value: String);
begin
  if Assigned(FTileList) then
  begin
    if (FIndex >= 0) and (FIndex <= FTileList.Tiles.Count - 1) then
      FTileList.Tiles[FIndex].Notes := Value;
  end;
end;

initialization
  RegisterBindEditorFactory([TTMSFMXBindTileListEditorFactory]);

finalization
  UnregisterBindEditorFactory([TTMSFMXBindTileListEditorFactory]);

end.
