unit uSessionList;

interface

uses Rubies, DBTables;

var
  cSessionList: Tvalue;
  vSessionList: Tvalue;

function ap_cSessionList: Tvalue;
function ap_vSessionList: Tvalue;
function ap_iSessionList(real: TSessionList; owner: Tvalue): Tvalue;
procedure Init_SessionList;

implementation

uses Classes, uDefUtils, Pythia, uSession, uRDBExt;

function dl_Session(This: Tvalue): TSessionList;
begin
  result := ap_data_get_struct(This);
end;

function ap_cSessionList: Tvalue;
begin
  result := cSessionList;
end;

function ap_vSessionList: Tvalue;
begin
  result := vSessionList;
end;

function SessionList_alloc(This: Tvalue; real: TSessionList): Tvalue;
begin
  result := TmpAlloc(This, real);
end;

function ap_iSessionList(real: TSessionList; owner: Tvalue): Tvalue;
begin
  result := SessionList_alloc(cSessionList, real);
  ap_owner(result, owner);
end;

function SessionList_aref(This, v: Tvalue): Tvalue; cdecl;
var
  real: TSessionList;
  I: Integer;
  S: string;
begin
  real := ap_data_get_struct(This);
  case RTYPE(v) of
  T_STRING:
    begin
      S := dl_String(v);
      result := ap_iSession(real.List[S], This);
    end;
  T_FIXNUM:
    begin
      I := FIX2INT(v);
      if (I < 0) or (real.Count <= I) then
        ap_raise(ap_eIndexError, sOut_of_range);
      result := ap_iSession(real[I], This);
    end;
  else
    ap_raise(ap_eArgError, sWrong_arg_type);
    result := Qnil;
  end;
end;

function SessionList_get_count(This: Tvalue): Tvalue; cdecl;
var
  real: TSessionList;
begin
  real := ap_data_get_struct(This);
  result := INT2FIX(real.Count);
end;

function SessionList_find_session(This, name: Tvalue): Tvalue; cdecl;
var
  real: TSessionList;
  Session: TSession;
begin
  real := ap_data_get_struct(This);
  Session := real.FindSession(dl_String(name));
  if Session = nil then
    result := Qnil
  else
    result := ap_iSession(Session, This);
end;

function SessionList_open_session(This, name: Tvalue): Tvalue; cdecl;
var
  real: TSessionList;
  Session: TSession;
begin
  real := ap_data_get_struct(This);
  Session := real.OpenSession(dl_String(name));
  if Session = nil then
    result := Qnil
  else
    result := ap_iSession(Session, This);
end;

function SessionList_get_session_names(This: Tvalue): Tvalue; cdecl;
begin
  result := ap_StringList_new;
  dl_Session(This).GetSessionNames(dl_Strings(result));
end;

procedure Regist_SessionList;
var
  real: TSessionList;
  obj, module: Tvalue;
begin
  real := Sessions;
  obj := SessionList_alloc(cSessionList, real);
  vSessionList := obj;
  rb_define_const(ap_mRDB, 'SESSIONS', obj);

  module := rb_module_new;
  rb_extend_object(obj, module);
  rb_iv_set(obj, '@child_attr_module', module);
end;

procedure Init_SessionList;
begin
  cSessionList := rb_define_class_under(ap_mRDB, 'SessionList', ap_cObject);

  rb_define_method(cSessionList, '[]', @SessionList_aref, 1);
  DefineAttrGet(cSessionList, 'count', SessionList_get_count);

  rb_define_method(cSessionList, 'find_session', @SessionList_find_session, 1);
  rb_define_method(cSessionList, 'open_session', @SessionList_open_session, 1);
  rb_define_method(cSessionList, 'session_names', @SessionList_get_session_names, 0);

  Regist_SessionList;
end;

end.
