unit uDBSelectionListUtils;

interface

uses
  Classes, DB, cxGridTableView, uDADataTable, uIntegerListUtils, cxGridCustomView;

type
  TSelectedRecords = class;

  ISeleccionable = interface
    ['{49B6B6E9-8C91-430B-87BC-7ED070308F2B}']
    function GetSelectedRecords: TSelectedRecords;
    property SelectedRecords : TSelectedRecords read GetSelectedRecords;

    function GetSelected: Boolean;
    procedure SetSelected(const Value: Boolean);
    property Selected : Boolean read GetSelected write SetSelected;
  end;

  ISelectedRecords = interface
    ['{C2037B64-AAA7-4DD7-B9EA-C4973BDAD380}']
    function GetCount: Integer;
    property Count: Integer read GetCount;

    function GetItem(Index: Integer): Integer;
    property Items[Index: Integer]: Integer read GetItem; default;
  end;

  TSeleccionable = class(TInterfacedObject, ISeleccionable)
  protected
    FSelectedRecords : TSelectedRecords;
    function GetSelectedRecords: TSelectedRecords;
    function GetSelected: Boolean;
    procedure SetSelected(const Value: Boolean);
  public
    constructor Create(aDataTable: TDADataTable); 
    destructor Destroy; override;
    property Selected : Boolean read GetSelected write SetSelected;
    property SelectedRecords : TSelectedRecords read GetSelectedRecords;
  end;

  TSelectedRecords = class(TInterfacedObject, ISelectedRecords)
  private
    FDataTable: TDADataTable;
    FListInteger : TIntegerList;
    function GetCount: Integer;
    function GetCurrentRowSelected: Boolean;
    function GetItem(Index: Integer): integer;
    procedure SetCurrentRowSelected(Value: Boolean);
  protected
    function CurrentRow: integer;
    function Compare(const Item1, Item2: integer): Boolean;
  public
    constructor Create(ADataTable : TDADataTable);
    destructor Destroy; override;
    procedure Clear;           // free all bookmarks
    function  Find(const Item: integer; var Index: Integer): Boolean;
    function  IndexOf(const Item: integer): Integer;
    property Count: Integer read GetCount;
    property CurrentRowSelected: Boolean read GetCurrentRowSelected
      write SetCurrentRowSelected;
    property Items[Index: Integer]: integer read GetItem; default;
    function LocateItem(const Index : Integer) : Boolean;
  end;


implementation

uses
  SysUtils, DBConsts, cxGridCustomTableView, cxControls, Math, Variants, Dialogs;

{ TSelectedRowList }

constructor TSelectedRecords.Create(ADataTable : TDADataTable);
begin
  inherited Create;
  FListInteger := TIntegerList.Create;
  
  FDataTable := ADataTable;
end;

destructor TSelectedRecords.Destroy;
begin
  Clear;
  FreeAndNil(FListInteger);//.Free;
  FDataTable := NIL;
  inherited Destroy;
end;

procedure TSelectedRecords.Clear;
begin
  if (not Assigned(FListInteger))
  or (FListInteger.Count = 0) then
     Exit;
     
  FListInteger.Clear;
end;

function TSelectedRecords.Compare(const Item1, Item2: integer): Boolean;
begin
  Result := (Item1 = Item2);
end;

function TSelectedRecords.CurrentRow: integer;
begin
  if not FDataTable.Active then
    raise EDatabaseError.Create(sDataSetClosed);
  Result := FDataTable.GetRowRecIDValue;
end;

function TSelectedRecords.GetCurrentRowSelected: Boolean;
var
  Index: Integer;
begin
  Result := Find(CurrentRow, Index);
end;

function TSelectedRecords.Find(const Item: integer; var Index: Integer): Boolean;
begin
  Result := FListInteger.Find(Item, Index)
end;

function TSelectedRecords.GetCount: Integer;
begin
  Result := FListInteger.Count;
end;

function TSelectedRecords.GetItem(Index: Integer): integer;
begin
  Result := FListInteger.Integers[Index];
end;

function TSelectedRecords.IndexOf(const Item: integer): Integer;
var
  AIndex : Integer;
begin
  Result := -1;
  if FListInteger.Find(Item, AIndex) then
    Result := AIndex
end;

procedure TSelectedRecords.SetCurrentRowSelected(Value: Boolean);
var
  Index: Integer;
  Current: integer;
begin
  Current := CurrentRow;
  if (Find(Current, Index) = Value) then
    Exit;
  if Value then
    FListInteger.Add(Current)
  else
    FListInteger.Delete(Index);
end;

function TSelectedRecords.LocateItem(const Index: Integer) : Boolean;
begin
  if not FDataTable.Active then
    raise EDatabaseError.Create(sDataSetClosed);
  Result := FDataTable.Locate(FDataTable.RecIDField.FieldName, Items[Index], []);

end;


{ TSeleccionable }

constructor TSeleccionable.Create(aDataTable: TDADataTable); 
begin
  inherited Create;
  FSelectedRecords := TSelectedRecords.Create(aDataTable); 
end;

destructor TSeleccionable.Destroy;
begin
  FreeAndNIL(FSelectedRecords);
  inherited;
end;

function TSeleccionable.GetSelected: Boolean;
begin
  Result := FSelectedRecords.CurrentRowSelected;  
end;

function TSeleccionable.GetSelectedRecords: TSelectedRecords;
begin
  Result := FSelectedRecords;
end;

procedure TSeleccionable.SetSelected(const Value: Boolean);
begin
  FSelectedRecords.CurrentRowSelected := True;
end;

end.
