{***************************************************************************}
{ TMS IntraWeb Component Pack Pro                                           }
{ for Delphi & C++Builder                                                   }
{                                                                           }
{ written by TMS Software                                                   }
{            copyright © 2002 - 2012                                        }
{            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 component can be freely used in any application. 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 IWDBAdvCheckGroup;

interface

{$I TMSDEFS.INC}

uses
  IWHTMLTag, DB, IWDBStdCtrls, Classes, IWTMSBase, IWAdvCheckGroup, SysUtils,
  IWDBCommon, IWRenderContext, IWXMLTag;

type
  TTIWDataMapModeType = (dmIndex, dmBinary);

  TTIWDBAdvCheckGroup = class(TTIWAdvCheckGroup)
  private
    FDataField: string;
    FDataSource: TDataSource;
    FDataMapMode: TTIWDataMapModeType;
    FDataLink: TTIWTMSControlDataLink;
    FAutoEditable: Boolean;
    procedure SetDataSource(const Value: TDataSource);
  public
    procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
    procedure SetValue(const AValue: string); override;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function RenderAsync(AContext: TIWBaseHTMLComponentContext): TIWXMLTag; override;
    function RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag; override;
  published
    property AutoEditable: Boolean read FAutoEditable write FAutoEditable default true;
    property DataField: string read FDataField write FDataField;
    property DataSource: TDataSource read FDataSource write SetDataSource;
    property DataMapMode: TTIWDataMapModeType read FDataMapMode write FDataMapMode default dmIndex;
  end;

implementation

{ TTIWDBAdvCheckGroup }

function TTIWDBAdvCheckGroup.RenderAsync(
  AContext: TIWBaseHTMLComponentContext): TIWXMLTag;
var
  LField: TField;
  i, binVal: integer;
  checkedItems, tempval: string;
begin
  if CheckDataSource(DataSource, DataField, LField) then
  begin
    if AutoEditable then
      Editable := InEditMode(DataSource.Dataset);

    checkedItems := LField.AsString;
    if (DataMapMode <> dmIndex) and (checkedItems = EmptyStr) then
      checkedItems := '0';
    binVal := 1;

    for I := 0 to Items.Count - 1 do
    begin

      if DataMapMode = dmIndex then
      begin

        if Length(CheckedItems) > i then
        begin
          tempval := checkedItems[i + 1];
          Checked.Items[i] := StrToInt(tempval);
        end;

      end
      else
      begin

        if StrToInt(checkedItems) and binVal = binVal then
          Checked.Items[i] := 0
        else
          Checked.Items[i] := 1;

        binVal := binVal * 2;

      end;
    end;

  end
  else
  begin
    for I := 0 to Items.Count - 1 do
      Checked.Items[i] := 1;
  end;

  Result := inherited RenderAsync(AContext);
end;

function TTIWDBAdvCheckGroup.RenderHTML(AContext: TIWBaseComponentContext): TIWHTMLTag;
var
  LField: TField;
  i, binVal: integer;
  checkedItems, tempval: string;
begin

  if CheckDataSource(DataSource, DataField, LField) then
  begin
    if AutoEditable then
      Editable := InEditMode(DataSource.Dataset);

    checkedItems := LField.AsString;
    if (DataMapMode <> dmIndex) and (checkedItems = EmptyStr) then
      checkedItems := '0';
    binVal := 1;

    for I := 0 to Items.Count - 1 do
    begin

      if DataMapMode = dmIndex then
      begin

        if Length(CheckedItems) > i then
        begin
          tempval := checkedItems[i + 1];
          Checked.Items[i] := StrToInt(tempval);
        end;

      end
      else
      begin

        if StrToInt(checkedItems) and binVal = binVal then
          Checked.Items[i] := 0
        else
          Checked.Items[i] := 1;

        binVal := binVal * 2;

      end;
    end;
    
  end
  else
  begin
    for I := 0 to Items.Count - 1 do
      Checked.Items[i] := 1;
  end;

  Result := inherited RenderHTML(AContext);
end;

constructor TTIWDBAdvCheckGroup.Create(AOwner: TComponent);
begin
  inherited;
  FAutoEditable := true;
  FDataLink :=  TTIWTMSControlDataLink.Create(self);
end;

destructor TTIWDBAdvCheckGroup.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

procedure TTIWDBAdvCheckGroup.Notification(AComponent: TComponent; AOperation: TOperation);
begin
  inherited Notification(AComponent, AOperation);
  if AOperation = opRemove then begin
    if FDatasource = AComponent then begin
      FDatasource := nil;
    end;
  end;
end;

procedure TTIWDBAdvCheckGroup.SetDataSource(const Value: TDataSource);
begin
  FDataSource := Value;
  FDataLink.DataSource := FDataSource;
end;

procedure TTIWDBAdvCheckGroup.SetValue(const AValue: string);
var
  LField: TField;
  i, binVal, tempVal: integer;
  isEditing: boolean;
var
  su: string;
  vp: integer;
begin
  inherited SetValue(AValue);
  if CheckDataSource(DataSource, DataField, LField) and Editable then
  begin
    isEditing := (dsEdit = DataSource.DataSet.State);

    Datasource.Edit;

    if DataMapMode = dmIndex then
    begin
      su := AValue;
      vp := pos('|', AValue);
      if vp > 0 then
        su := copy(AValue, 1, vp - 1);
      LField.AsString := su;
    end
    else
    begin
      binVal := 1;
      tempVal := 0;

      for I := 0 to Items.Count - 1 do
      begin
        if Checked.Items[i] = 0 then
         tempVal := tempVal + binVal;
        binVal := binVal * 2;
      end;

      LField.AsInteger := tempVal;

    end;

    DataSource.DataSet.Post;

    if isEditing then
      DataSource.DataSet.Edit;
  end;
end;

end.
