library socket;

uses
  SysUtils, Classes, Controls, Psock,
  Rubies, uDefUtils,
{$IFDEF PHIEMBED}
  {PhiMainUnit, }uHandle, uProp, uPhi, uComponent,
{$ELSE}
  Pythia,
{$ENDIF}
  SocketHandle;

{$E so}

function ap_cSocket: Tvalue;
begin
  result := cSocket;
end;

procedure Socket_setup(obj: Tvalue; real: TPowerSock);
begin
  if @real.OnConnect = nil then real.OnConnect := GetSocketHandle.doConnect;
  if @real.OnDisconnect  = nil then real.OnDisconnect := GetSocketHandle.doDisconnect;
  if @real.OnPacketRecvd = nil then real.OnPacketRecvd := GetSocketHandle.doPacketRecv ;
  if @real.OnPacketSent  = nil then real.OnPacketSent  := GetSocketHandle.doPacketSent ;
end;

function Socket_connected(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  result := ap_bool(real.Connected);
end;

function Socket_connect(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  try
    real.Connect;
    GetSocketHandle.doSuccess(real, 'connect');
  except
    GetSocketHandle.doFailure(real, 'connect');
  end;
  result := This;
end;

function Socket_Disconnect(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  try
    real.Disconnect;
    GetSocketHandle.doSuccess(real, 'disconnect');
  except
    GetSocketHandle.doFailure(real, 'disconnect');
  end;
  result := This;
end;

function Socket_abort(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  try
    real.Abort;
    GetSocketHandle.doSuccess(real, 'abort');
  except
    GetSocketHandle.doFailure(real, 'abort');
  end;
  result := This;
end;

function Socket_get_bytes_recv(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  result := INT2FIX(real.BytesRecvd);
end;

function Socket_get_bytes_sent(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  result := INT2FIX(real.BytesSent);
end;

function Socket_get_bytes_total(This: Tvalue): Tvalue; cdecl;
var
  real: TPowerSock;
begin
  real := ap_data_get_struct(This);
  result := INT2FIX(real.BytesTotal);
end;

procedure Init_socket; cdecl;
begin
  PhiStart;

  cSocket := DefinePersistentClass(ap_mPhi, TPowersock, ap_cPersistent, nil);

  rb_define_method(cSocket, 'abort', @Socket_abort, 0);
  rb_define_method(cSocket, 'connected', @Socket_connected, 0);
  rb_define_method(cSocket, 'connect', @Socket_connect, 0);
  rb_define_method(cSocket, 'disconnect', @Socket_disconnect, 0);
  DefineAttrGet(cSocket, 'bytes_recv', Socket_get_bytes_recv);
  DefineAttrGet(cSocket, 'bytes_sent', Socket_get_bytes_sent);
  DefineAttrGet(cSocket, 'bytes_total', Socket_get_bytes_total);

  rb_iv_set(cSocket, '@events', rb_hash_new);
  DefineModuleAttrMethod(cSocket, 'on_packet_recv');
  DefineModuleAttrMethod(cSocket, 'on_packet_sent');
end;

exports
  ap_cSocket,
  Socket_setup,
  Init_socket;

end.
