unit Apollo;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ActnList;

type
  TApollo = class(TComponent)
  private
    FScript: TStrings;
    FParams: TStrings;
    FAfterExec: TNotifyEvent;
    FBeforeExec: TNotifyEvent;
    FKcode: string;
  protected
    procedure SetScript(AScript: TStrings);
    procedure SetParams(AParams: TStrings);
    procedure DoBeforeExec; virtual;
    procedure DoAfterExec; virtual;
    procedure SetKcode(AKcode: string);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Execute(AOutput: TStrings);
  published
    property Script: TStrings read FScript write SetScript;
    property Params: TStrings read FParams write SetParams;
    property AfterExec: TNotifyEvent read FAfterExec write FAfterExec;
    property BeforeExec: TNotifyEvent read FBeforeExec write FBeforeExec;
    property Kcode: string read FKcode write SetKcode;
  end;

  TRubyAction = class(TAction)
  private
    FScript: TStrings;
    FParams: TStrings;
    FOutput: TCustomEdit;
  protected
    procedure SetScript(AScript: TStrings);
    procedure SetParams(AParams: TStrings);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure ExecuteTarget(Target: TObject); override;
    function HandlesTarget(Target: TObject): Boolean; override;
  published
    property Script: TStrings read FScript write SetScript;
    property Params: TStrings read FParams write SetParams;
    property Output: TCustomEdit read FOutput write FOutput;
  end;

procedure Register;

implementation

uses
  Rubies, Pseudo, uAppInit;

procedure Register;
begin
  RegisterComponents('Samples', [TApollo]);
  RegisterActions('Apollo', [TRubyAction], nil);
end;

var
  rubyInitialized: Boolean = False;

procedure InitializeRuby;
begin
  if rubyInitialized then Exit;
  PhiAppInit;
//  ruby_init;
//  ruby_init_loadpath;
  rubyInitialized := True;
end;

{ TApollo }

constructor TApollo.Create(AOwner: TComponent);
begin
  inherited;

  FScript := TStringList.Create;
  FParams := TStringList.Create;

  if not (csDesigning in ComponentState) then
    InitializeRuby;
end;

destructor TApollo.Destroy;
begin
  FParams.Free;
  FScript.Free;
  inherited;
end;

procedure TApollo.SetScript(AScript: TStrings);
begin
  FScript.Assign(AScript);
end;

procedure TApollo.SetParams(AParams: TStrings);
begin
  FParams.Assign(AParams);
end;

procedure TApollo.Execute(AOutput: TStrings);
begin
  rb_ary_clear(ap_argv);
  DoBeforeExec;
  RubyEvalStrings(FScript, FParams, AOutput);
  DoAfterExec;
end;

procedure TApollo.DoBeforeExec;
begin
  if Assigned(FBeforeExec) then FBeforeExec(Self);
end;

procedure TApollo.DoAfterExec;
begin
  if Assigned(FAfterExec) then FAfterExec(Self);
end;

procedure TApollo.SetKcode(AKcode: string);
begin
  FKcode := AKcode;
  rb_set_kcode(dl_String(FKcode));
end;

{ TRubyAction }

constructor TRubyAction.Create;
begin
  inherited;

  FScript := TStringList.Create;
  FParams := TStringList.Create;

  if not (csDesigning in ComponentState) then
    InitializeRuby;
end;

destructor TRubyAction.Destroy;
begin
  FParams.Free;
  FScript.Free;
  inherited;
end;

procedure TRubyAction.SetScript(AScript: TStrings);
begin
  FScript.Assign(AScript);
end;

procedure TRubyAction.SetParams(AParams: TStrings);
begin
  FParams.Assign(AParams);
end;

procedure TRubyAction.ExecuteTarget(Target: TObject);
var
  lines: TStringList;
begin
  lines := TStringList.Create;
  try
    rb_ary_clear(ap_argv);
    RubyEvalStrings(FScript, FParams, lines);
    if FOutput <> nil then
    begin
      FOutput.SelStart := -1;
      FOutput.SelText := lines.Text;
    end;
  finally
    lines.Free
  end;
end;

function TRubyAction.HandlesTarget(Target: TObject): Boolean;
begin
  Result := true;
end;

end.
