{********************************************************************}
{                                                                    }
{ 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.TMSTableViewBinding;

interface

{$I TMSDEFS.INC}

uses
  FMX.TMSTableView, 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
  TTMSFMXTableViewBindClass = class(TTMSFMXTableView);

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

  TTMSFMXTableViewItemEditorObject = class
  private
    FIndex: Integer;
    FTableView: TTMSFMXTableView;
    function GetBitmap: TBitmap;
    function GetDescription: String;
    procedure SetBitmap(const Value: TBitmap);
    procedure SetCaption(const Value: String);
    procedure SetDescription(const Value: String);
    function GetCaption: String;
  public
    property Caption: String read GetCaption write SetCaption;
    property Description: String read GetDescription write SetDescription;
    property Bitmap: TBitmap read GetBitmap write SetBitmap;
  end;

  TTMSFMXBindTableViewEditor = class(TBindListEditor)
  private
    FEditorObject: TTMSFMXTableViewItemEditorObject;
    function GetIndex: Integer;
    procedure SetIndex(const Value: Integer);
  protected
    property AIndex: Integer read GetIndex write SetIndex;
    function TableView: TTMSFMXTableViewBindClass;
  public
    constructor Create(ATableView: TTMSFMXTableView);
    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;

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

implementation


{ TTMSFMXBindTableViewEditorFactory }

constructor TTMSFMXBindTableViewEditorFactory.Create;
begin
  inherited;
end;

function TTMSFMXBindTableViewEditorFactory.CreateEditor(AIntf: TGuid;
  AObject: TObject): IInterface;
begin
  Result := TTMSFMXBindTableViewEditor.Create(TTMSFMXTableView(AObject));
end;

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

{ TTMSFMXBindTableViewEditor }

function TTMSFMXBindTableViewEditor.AddItem(Select: Boolean): IScope;
var
  AItem: TTMSFMXTableViewItem;
begin
  TableView.BindingsCount := TableView.BindingsCount + 1;
  AItem := TableView.Items.Add;
  AIndex := AItem.Index;
  if Select then
    TableView.SelectedItemIndex := AIndex;
  Result := WrapObject(AItem);
end;

procedure TTMSFMXBindTableViewEditor.BeginUpdate;
begin
  inherited;
  TableView.BeginUpdate;
end;

function TTMSFMXBindTableViewEditor.CanInsertItem: Boolean;
begin
  Result := TableView.SelectedItemIndex <> -1;
end;

procedure TTMSFMXBindTableViewEditor.ClearList;
begin
  inherited;
  TableView.Items.Clear;
  TableView.BindingsCount := 0;
  TableView.ResetBufferSize;
end;

constructor TTMSFMXBindTableViewEditor.Create(ATableView: TTMSFMXTableView);
begin
  FEditorObject := TTMSFMXTableViewItemEditorObject.Create;
  FEditorObject.FTableView := ATableView;
  FEditorObject.FIndex := -1;
  AIndex := -1;
end;

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

procedure TTMSFMXBindTableViewEditor.DeleteToEnd;
begin
  if AIndex = -1 then
    AIndex := TableView.SelectedItemIndex;
  while TableView.BindingsCount > Max(0, AIndex) do
  begin
    TableView.Items.Delete(TableView.BindingsCount - 1);
    TableView.BindingsCount := TableView.BindingsCount - 1;
  end;
  AIndex := TableView.BindingsCount;
end;

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

procedure TTMSFMXBindTableViewEditor.EndUpdate;
begin
  inherited;
  TableView.EndUpdate;
  TableView.SelectedItemIndex := TableView.SelectedItemIndex;
end;

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

function TTMSFMXBindTableViewEditor.GetRowCount: Integer;
begin
  Result := TableView.BindingsCount;
end;

function TTMSFMXBindTableViewEditor.GetSelectedItem: TObject;
begin
  Result := TableView.SelectedItem;
end;

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

function TTMSFMXBindTableViewEditor.InsertItem(Select: Boolean): IScope;
var
  AItem: TTMSFMXTableViewItem;
begin
  TableView.BindingsCount := TableView.BindingsCount + 1;
  AItem := TableView.Items.Insert(TableView.SelectedItemIndex);
  AIndex := AItem.Index;
  Result := WrapObject(AItem);
  TableView.SelectedItemIndex := AItem.Index;
end;

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

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

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

function TTMSFMXBindTableViewEditor.TableView: TTMSFMXTableViewBindClass;
begin
  Result := TTMSFMXTableViewBindClass(FEditorObject.FTableView);

  end;

{ TTMSFMXBindTableViewLink }

constructor TTMSFMXBindDBTableViewLink.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 := 'SelectedItemIndex';
  LItem.SourceExpression := 'Math_Max(0, DBUtils_ActiveRecord(Self))';

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


{ TTMSFMXTableViewItemEditorObject }

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

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

function TTMSFMXTableViewItemEditorObject.GetDescription: String;
begin
  Result := '';
  if Assigned(FTableView) then
  begin
    if (FIndex >= 0) and (FIndex <= FTableView.Items.Count - 1) then
      Result := FTableView.Items[FIndex].Description;
  end;
end;

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

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

procedure TTMSFMXTableViewItemEditorObject.SetDescription(const Value: String);
begin
  if Assigned(FTableView) then
  begin
    if (FIndex >= 0) and (FIndex <= FTableView.Items.Count - 1) then
      FTableView.Items[FIndex].Description := Value;
  end;
end;

initialization
  RegisterBindEditorFactory([TTMSFMXBindTableViewEditorFactory]);

finalization
  UnregisterBindEditorFactory([TTMSFMXBindTableViewEditorFactory]);

end.
