Browse Source

*** empty log message ***

Jean-Francois Goulet 19 years ago
parent
commit
a4da4c14df

+ 119 - 0
LuaEdit/LuaCore/Lua_Classes.pas

@@ -0,0 +1,119 @@
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2006                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//  File        : Lua_Classes.pas   (rev. 1.0)
+//
+//  Description : Access from Lua scripts to Class declared in "Classes.pas"
+//
+//******************************************************************************
+unit Lua_Classes;
+
+interface
+
+uses TypInfo, Variants, Lua_Object;
+
+type
+    TLuaComponent = class(TLuaObject)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+       
+    public
+                                  //TClass         TComponent TComponent
+       function LuaCreate(ObjClass :Integer; AOwner :Integer) :Integer; overload;
+
+       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+       function GetElementType(Name :String) :PTypeInfo; override;
+       function GetElement(Name :String) :Variant; override;
+    end;
+
+
+implementation
+
+uses Classes, SysUtils, StdCtrls;
+
+type
+    TComponentAccess = class(TComponent)
+    published
+       property ComponentIndex;
+       property ComponentCount;
+    end;
+
+
+function TLuaComponent.LuaCreate(ObjClass :Integer; AOwner :Integer) :Integer;
+Var
+   xObjClass :TClass;
+
+begin
+     xObjClass :=TClass(ObjClass);
+     if (xObjClass.InheritsFrom(TComponent))
+     then Result :=Integer(TComponentClass(xObjClass).Create(TComponent(AOwner)))
+     else Result :=Integer(TComponent(LuaCreate(ObjClass)));
+end;
+
+function TLuaComponent.GetArrayPropType(Name :String; index :Variant) :PTypeInfo;
+begin
+     Name :=Uppercase(Name);
+     Result :=nil;
+
+     if (Name='COMPONENTS')
+     then begin
+               if (TComponent(InstanceObj).Components[index]<>nil)
+               then Result :=TypeInfo(TComponent)
+               else Result :=nil;
+          end;
+end;
+
+function TLuaComponent.GetArrayProp(Name :String; index :Variant) :Variant;
+begin
+     Name :=Uppercase(Name);
+     Result :=NULL;
+
+     if (Name='COMPONENTS')
+     then begin
+               if (TComponent(InstanceObj).Components[index]<>nil)
+               then Result :=Integer(TComponent(InstanceObj).Components[index]);
+          end;
+end;
+
+function TLuaComponent.GetElementType(Name :String) :PTypeInfo;
+Var
+   upName :String;
+
+begin
+     upName :=Uppercase(Name);
+     Result :=nil;
+
+     if (upName='COMPONENTS')
+     then Result :=@TypeInfoArray
+     else
+     if (TComponent(InstanceObj).FindComponent(Name)<>nil)
+     then Result :=TypeInfo(TComponent);
+end;
+
+function TLuaComponent.GetElement(Name :String) :Variant;
+Var
+   theComponent :TComponent;
+
+begin
+     Result :=NULL;
+
+     theComponent :=TComponent(InstanceObj).FindComponent(Name);
+     if (theComponent<>nil)
+     then Result :=Integer(theComponent);
+end;
+
+class function TLuaComponent.GetPublicPropertyAccessClass :TClass;
+begin
+     Result :=TComponentAccess;
+end;
+
+
+initialization
+   Lua_Object.RegisterClass(TComponent, TLuaComponent);
+
+end.

+ 163 - 0
LuaEdit/LuaCore/Lua_Controls.pas

@@ -0,0 +1,163 @@
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2006                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//  File        : Lua_Controls.pas   (rev. 1.0)
+//
+//  Description : Access from Lua scripts to Class declared in "Controls.pas"
+//
+//******************************************************************************
+// TO-DO : Record like TRect, TPoint property how can i return in variant(lua)
+unit Lua_Controls;
+
+
+
+interface
+
+uses TypInfo, Variants, Lua_Object, Lua_Classes;
+
+type
+    TLuaControl = class(TLuaComponent)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+    end;
+
+    TLuaWinControl = class(TLuaControl)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+       function GetElementType(Name :String) :PTypeInfo; override;
+    end;
+
+
+implementation
+
+uses Classes, Controls, SysUtils;
+
+type
+    TControlAccess = class(TControl)
+    published
+       property Enabled;
+       property Action;
+       property Align;
+       property Anchors;
+       property BiDiMode;
+       property BoundsRect;
+       property ClientHeight;
+       property ClientOrigin;
+       property ClientRect;
+       property ClientWidth;
+       property Constraints;
+       property ControlState;
+       property ControlStyle;
+       property DockOrientation;
+       property Floating;
+       property FloatingDockSiteClass;
+       property HostDockSite;
+       property LRDockWidth;
+       property Parent;
+       property ShowHint;
+       property TBDockHeight;
+       property UndockHeight;
+       property UndockWidth;
+       property Visible;
+       //property WindowProc;   pericolosa.
+    end;
+
+    TWinControlAccess = class(TWinControl)
+    published
+       // See Comment on TLuaObject.GetPublicPropInfo, it explain why i have no need
+       // to redeclare also the public property of TControl  
+       property DockClientCount;
+       property DockSite;
+       property DockManager;
+       property DoubleBuffered;
+       property AlignDisabled;
+       property VisibleDockClientCount;
+       property Brush;
+       property ControlCount;
+       property Handle;
+       property ParentWindow;
+       property Showing;
+       property TabOrder;
+       property TabStop;
+       property UseDockManager;
+    end;
+
+
+class function TLuaControl.GetPublicPropertyAccessClass :TClass;
+begin
+     Result :=TControlAccess;
+end;
+
+//==============================================================================
+//
+class function TLuaWinControl.GetPublicPropertyAccessClass :TClass;
+begin
+     Result :=TWinControlAccess;
+end;
+
+function TLuaWinControl.GetArrayPropType(Name :String; index :Variant) :PTypeInfo;
+begin
+     Name :=Uppercase(Name);
+     Result :=nil;
+
+     if (Name='CONTROLS')
+     then begin
+               if (TWinControl(InstanceObj).Controls[index]<>nil)
+               then Result :=TypeInfo(TControl);
+          end
+     else
+     if (Name='DOCKCLIENTS')
+     then begin
+               if (TWinControl(InstanceObj).DockClients[index]<>nil)
+               then Result :=TypeInfo(TControl);
+          end
+     else
+     Result :=inherited GetArrayPropType(Name, index);
+end;
+
+function TLuaWinControl.GetArrayProp(Name :String; index :Variant) :Variant;
+begin
+     Name :=Uppercase(Name);
+
+     if (Name='CONTROLS')
+     then begin
+               if (TWinControl(InstanceObj).Controls[index]<>nil)
+               then Result :=Integer(TWinControl(InstanceObj).Controls[index])
+               else Result :=NULL;
+          end
+     else
+     if (Name='DOCKCLIENTS')
+     then begin
+               if (TWinControl(InstanceObj).DockClients[index]<>nil)
+               then Result :=Integer(TWinControl(InstanceObj).DockClients[index])
+               else Result :=NULL;
+          end
+     else
+     Result := inherited GetArrayProp(name, index)
+end;
+
+function TLuaWinControl.GetElementType(Name :String) :PTypeInfo;
+Var
+   upName :String;
+
+begin
+     upName :=Uppercase(Name);
+
+     if (upName='CONTROLS') or (upName='DOCKCLIENTS')
+     then Result :=@TypeInfoArray
+     else Result :=inherited GetElementType(Name);
+end;
+
+initialization
+   Lua_Object.RegisterClass(TControl, TLuaControl);
+   Lua_Object.RegisterClass(TWinControl, TLuaWinControl);
+
+end.

+ 625 - 0
LuaEdit/LuaCore/Lua_DB (old).pas

@@ -0,0 +1,625 @@
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2006                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//  File        : Lua_DB.pas      (rev. 2.0)
+//
+//  Description : Access from Lua scripts to TDataset VCL Components
+//                 (at this time TQuery, TTable)
+//
+//******************************************************************************
+//  Exported functions :
+//
+//   Methods common to all TDataset classes
+//      [descendent of TObject class (see Lua_object.pas)]
+//      TDataset:Active(boolean newValue)              return Status as boolean.
+//      TDataset:First()                               return Status as boolean.
+//      TDataset:Next()                                return Status as boolean.
+//      TDataset:GetCount()                           return RecordCount as Int.
+//      TDataset:GetField(string FieldName)         return FieldValue as String.
+//      TDataset:GetFieldSize(string FieldName)         return FieldSize as Int.
+//      TDataset:Modified()                          return Modified as boolean.
+//      TDataset:SetField(string FieldName,
+//                [int | boolean | string] newValue)   return Status as boolean.
+//      TDataset:Edit()                                return Status as boolean.
+//      TDataset:Post()                                return Status as boolean.
+
+//   CreateDBTable {Database=string, Table=string}         return TTable object.
+//      [descendent of TDataset class]
+//      TTable:Query(string query)                     return Status as boolean.
+//
+//   GetDBTable {Name=string}                     return Existing TTable object.
+//      (same as TTable except that you cannot free it)
+//
+//   CreateDBQuery {Database=string}                       return TQuery object.
+//      [descendent of TDataset class]
+//
+//   GetDBQuery {Name=string}                     return Existing TQuery object.
+//      (same as TQuery except that you cannot free it)
+
+unit Lua_DB;
+
+interface
+
+uses Classes, DB, DBTables, Lua, Lua_Object;
+
+type
+    TGetDataSetFunc = function (DataSetName :String) :TDataSet of object;
+
+
+procedure RegisterFunctions(L: Plua_State;
+                            AOwner :TComponent=Nil;
+                            AOnGetDataSetFunc :TGetDataSetFunc=Nil);
+
+procedure RegisterMethods_TDataset(L: Plua_State;
+                           AComponent :TDataset; CanFree :Boolean;
+                           PropsAccessRights :TLuaPROPSAccess);
+
+procedure RegisterMethods_TQuery(L: Plua_State;
+                           AComponent :TDataset; CanFree :Boolean;
+                           PropsAccessRights :TLuaPROPSAccess);
+
+procedure RegisterMethods_TTable(L: Plua_State;
+                           AComponent :TDataset; CanFree :Boolean;
+                           PropsAccessRights :TLuaPROPSAccess);
+
+implementation
+
+uses LuaUtils, SysUtils;
+
+const
+     HANDLE_OWNER       ='Lua_DB_OWNER';
+     HANDLE_GETDATAFUNC ='Lua_DB_GETDATAFUNC';
+
+
+//========================== Lua Functions TTable ==============================
+
+function GetTDataset(L: Plua_State; Index: Integer): TDataSet;
+begin
+     Result := TDataSet(LuaGetTableLightUserData(L, Index, OBJHANDLE_STR));
+end;
+
+function GetOwner(L: Plua_State): TComponent;
+begin
+     Result := TComponent(LuaGetTableLightUserData(L, LUA_REGISTRYINDEX, HANDLE_OWNER));
+end;
+
+function GetOnGetDataSetFunc(L: Plua_State): TGetDataSetFunc;
+begin
+     Result := TGetDataSetFunc(LuaGetTableTMethod(L, LUA_REGISTRYINDEX, HANDLE_GETDATAFUNC));
+end;
+
+//=== TDataset Methods =========================================================
+//      TDataset:Active(boolean newValue)              return Status as boolean.
+function Lua_TDataset_Active(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+   oldState     :Boolean;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=2)
+     then begin
+               theTable :=Nil;
+               oldState :=False;
+               try
+                  theTable :=GetTDataset(L, 1);
+                  oldState :=theTable.Active;
+                  theTable.Active :=LuaToBoolean(L, 2);
+
+                  LuaPushBoolean(L, True);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       theTable.Active :=oldState;
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:First()                               return Status as boolean.
+function Lua_TDataset_First(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  theTable.First;
+
+                  LuaPushBoolean(L, True);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:Next()                                return Status as boolean.
+function Lua_TDataset_Next(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  theTable.Next;
+
+                  LuaPushBoolean(L, True);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:GetCount()                           return RecordCount as Int.
+function Lua_TDataset_GetCount(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+
+                  LuaPushInteger(L, theTable.RecordCount);
+                  Result := 1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:GetField(string FieldName)         return FieldValue as String.
+function Lua_TDataset_GetField(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+   FieldName    :String;
+   theField     :TField;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=2)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  Fieldname :=LuaToString(L, 2);
+                  theField  :=theTable.FindField(Fieldname);
+                  if (theField<>Nil)
+                  then begin
+                            if not(theField.IsNull)
+                            then begin
+                                      LuaPushString(L, theField.AsString);
+                                      Result := 1;
+                                 end;
+                       end;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:GetFieldSize(string FieldName)         return FieldSize as Int.
+function Lua_TDataset_GetFieldSize(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+   FieldName    :String;
+   theField     :TField;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=2)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  Fieldname :=LuaToString(L, 2);
+                  theField  :=theTable.FindField(Fieldname);
+                  if (theField<>Nil)
+                  then begin
+                            LuaPushInteger(L, theField.Size);
+                            Result := 1;
+                       end;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:Modified()                          return Modified as boolean.
+function Lua_TDataset_Modified(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+
+                  LuaPushBoolean(L, theTable.Modified);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:SetField(string FieldName,
+//                [int | boolean | string] newValue)   return Status as boolean.
+function Lua_TDataset_SetField(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+   FieldName    :String;
+   theField     :TField;
+   valueNEW     :Variant;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=3)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  Fieldname :=LuaToString(L, 2);
+                  theField  :=theTable.FindField(Fieldname);
+                  if (theField<>Nil)
+                  then begin
+                            
+                            if (lua_isnumber(L, 3)<>0)
+                            then valueNEW := LuaToInteger(L, 3)
+                            else
+                            if lua_isboolean(L, 3)
+                            then valueNEW := LuaToBoolean(L, 3)
+                            else valueNEW := LuaToString(L, 3);
+
+                            if (valueNEW<>theField.Value)
+                            then begin
+                                      theTable.Edit;
+                                      theField.Value :=valueNEW;
+                                 end;
+
+                            LuaPushBoolean(L, True);
+                            Result := 1;
+                       end;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:Post()                                return Status as boolean.
+function Lua_TDataset_Post(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  
+                  if (theTable.State in [dsEdit, dsInsert])
+                  then theTable.Post;
+
+                  LuaPushBoolean(L, True);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//      TDataset:Edit()                                return Status as boolean.
+function Lua_TDataset_Edit(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TDataset;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theTable :=GetTDataset(L, 1);
+                  theTable.Edit;
+
+                  LuaPushBoolean(L, True);
+                  Result :=1;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//=== TTable Methods ===========================================================
+//      TTable:Query(string query)                     return Status as boolean.
+function Lua_TTable_Query(L: Plua_State): Integer; cdecl;
+Var
+   theTable     :TTable;
+   NParams      :Integer;
+   xQuery       :TQuery;
+   myOwner      :TComponent;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=2)
+     then begin
+               try
+                  theTable :=TTable(GetTDataset(L, 1));
+                  myOwner :=GetOwner(L);
+                  xQuery :=TQuery.Create(myOwner);
+                  try
+                     xQuery.Active :=False;
+                     xQuery.DatabaseName :=theTable.DatabaseName;
+                     xQuery.SQL.Add(LuaToString(L, 2));
+                     xQuery.ExecSQL;
+                     
+                     LuaPushBoolean(L, True);
+                     Result :=1;
+                  finally
+                     xQuery.Free;
+                  end;
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//=== RegisterMethods_XXX ======================================================
+
+procedure RegisterMethods_TDataset(L: Plua_State;
+                                  AComponent :TDataset; CanFree :Boolean;
+                                  PropsAccessRights :TLuaPROPSAccess);
+begin
+     if CanFree
+     then Lua_Object.RegisterMethods_TObject(L, AComponent, [LOMK_Free]);
+     Lua_Object.RegisterProperties_TObject(L, AComponent, PropsAccessRights);
+
+     LuaSetTableFunction(L, 1, 'Active', Lua_TDataset_Active);
+     LuaSetTableFunction(L, 1, 'First', Lua_TDataset_First);
+     LuaSetTableFunction(L, 1, 'Next', Lua_TDataset_Next);
+     LuaSetTableFunction(L, 1, 'GetCount', Lua_TDataset_GetCount);
+     LuaSetTableFunction(L, 1, 'GetField', Lua_TDataset_GetField);
+     LuaSetTableFunction(L, 1, 'GetFieldSize', Lua_TDataset_GetFieldSize);
+     LuaSetTableFunction(L, 1, 'SetField', Lua_TDataset_SetField);
+     LuaSetTableFunction(L, 1, 'Edit', Lua_TDataset_Edit);
+     LuaSetTableFunction(L, 1, 'Post', Lua_TDataset_Post);
+     LuaSetTableFunction(L, 1, 'Modified', Lua_TDataset_Modified);
+end;
+
+procedure RegisterMethods_TQuery(L: Plua_State;
+                           AComponent :TDataset; CanFree :Boolean;
+                           PropsAccessRights :TLuaPROPSAccess);
+begin
+     RegisterMethods_TDataset(L, AComponent, CanFree, PropsAccessRights);
+end;
+
+procedure RegisterMethods_TTable(L: Plua_State;
+                           AComponent :TDataset; CanFree :Boolean;
+                           PropsAccessRights :TLuaPROPSAccess);
+begin
+     RegisterMethods_TDataset(L, AComponent, CanFree, PropsAccessRights);
+     LuaSetTableFunction(L, 1, 'Query', Lua_TTable_Query);
+end;
+
+//   CreateDBTable {Database=string, Table=string}         return TTable object.
+function Lua_CreateDBTable(L: Plua_State): Integer; cdecl;
+Var
+   DBPath,
+   DBTableName   :String;
+   xResult       :TTable;
+   myOwner       :TComponent;
+
+begin
+     Result := 0;
+     try
+        myOwner :=GetOwner(L);
+        DBPath      :=LuaGetTableString(L, 1, 'Database');
+        DBTableName :=LuaGetTableString(L, 1, 'Table');
+        LuaSetTableNil(L, 1, 'Database');
+        LuaSetTableNil(L, 1, 'Table');
+        xResult := TTable.Create(myOwner);
+        if (xResult=Nil)
+        then raise Exception.Create('Unable to Create Tables');
+
+        xResult.Active :=False;
+        xResult.DatabaseName :=DBPath;
+        xResult.TableName :=DBTableName;
+
+        RegisterMethods_TTable(L, xResult, true, LUAPROPS_ACCESS_READWRITE);
+
+        Result := 1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+     end;
+end;
+
+//   GetDBTable {Name=string}                     return Existing TTable object.
+function Lua_GetDBTable(L: Plua_State): Integer; cdecl;
+Var
+   DBName   :String;
+   xResult  :TDataSet;
+   myOnGetDataSetFunc :TGetDataSetFunc;
+
+begin
+     Result := 0;
+
+     try
+        myOnGetDataSetFunc :=GetOnGetDataSetFunc(L);
+        DBName      :=LuaGetTableString(L, 1, 'Name');
+        LuaSetTableNil(L, 1, 'Name');
+        if Assigned(myOnGetDataSetFunc)
+        then begin
+                  xResult :=myOnGetDataSetFunc(DBName);
+                  if not(xResult is TTable)
+                  then xResult :=Nil;
+             end
+        else xResult :=Nil;
+
+        if (xResult=Nil)
+        then raise Exception.Create('Unable to Get Table '+DBName);
+
+        RegisterMethods_TTable(L, xResult, false, LUAPROPS_ACCESS_READWRITE);
+
+        Result := 1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+     end;
+end;
+
+//   CreateDBQuery {Database=string}                       return TQuery object.
+function Lua_CreateDBQuery(L: Plua_State): Integer; cdecl;
+Var
+   DBPath        :String;
+   xResult       :TQuery;
+   myOwner       :TComponent;
+
+begin
+     Result := 0;
+     try
+        myOwner :=GetOwner(L);
+        DBPath      :=LuaGetTableString(L, 1, 'Database');
+        LuaSetTableNil(L, 1, 'Database');
+        xResult := TQuery.Create(myOwner);
+        if (xResult=Nil)
+        then raise Exception.Create('Unable to Create Queries');
+
+        xResult.Active :=False;
+        xResult.DatabaseName :=DBPath;
+
+        RegisterMethods_TQuery(L, xResult, true, LUAPROPS_ACCESS_READWRITE);
+
+        Result := 1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+     end;
+end;
+
+//   GetDBQuery {Name=string}                     return Existing TQuery object.
+function Lua_GetDBQuery(L: Plua_State): Integer; cdecl;
+Var
+   DBName        :String;
+   xResult       :TDataSet;
+   myOnGetDataSetFunc :TGetDataSetFunc;
+
+begin
+     Result := 0;
+
+     try
+        myOnGetDataSetFunc :=GetOnGetDataSetFunc(L);
+        DBName      :=LuaGetTableString(L, 1, 'Name');
+        LuaSetTableNil(L, 1, 'Name');
+        if Assigned(myOnGetDataSetFunc)
+        then begin
+                  xResult :=myOnGetDataSetFunc(DBName);
+                  if not(xResult is TQuery)
+                  then xResult :=Nil;
+             end
+        else xResult :=Nil;
+
+        if (xResult=Nil)
+        then raise Exception.Create('Unable to Get Query '+DBName);
+
+        RegisterMethods_TQuery(L, xResult, false, LUAPROPS_ACCESS_READWRITE);
+
+        Result := 1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+     end;
+end;
+
+procedure RegisterFunctions(L: Plua_State;
+                            AOwner :TComponent=Nil;
+                            AOnGetDataSetFunc :TGetDataSetFunc=Nil);
+begin
+     //myOwner :=AOwner;
+     //myOnGetDataSetFunc :=AOnGetDataSetFunc;
+     LuaSetTableLightUserData(L, LUA_REGISTRYINDEX,
+                              HANDLE_OWNER, AOwner);
+     LuaSetTableTMethod(L, LUA_REGISTRYINDEX,
+                        HANDLE_GETDATAFUNC, TMethod(AOnGetDataSetFunc));
+
+     LuaRegister(L, 'CreateDBTable', Lua_CreateDBTable);
+     LuaRegister(L, 'CreateDBQuery', Lua_CreateDBQuery);
+     if Assigned(AOnGetDataSetFunc)
+     then begin
+               LuaRegister(L, 'GetDBTable', Lua_GetDBTable);
+               LuaRegister(L, 'GetDBQuery', Lua_GetDBQuery);
+          end;
+end;
+
+
+end.

+ 993 - 0
LuaEdit/LuaCore/Lua_DB.pas

@@ -0,0 +1,993 @@
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2006                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//  File        : Lua_DB.pas      (rev. 2.0)
+//
+//  Description : Access from Lua scripts to TDataset VCL Components
+//                 (at this time TQuery, TTable)
+//
+//******************************************************************************
+//  Exported functions :
+//
+//   Methods common to all TDataset classes
+//      [descendent of TObject class (see Lua_object.pas)]
+//      TDataset:FindField(string FieldName)             return Field as TField.
+
+
+unit Lua_DB;
+
+interface
+
+uses Lua;
+
+procedure RegisterFunctions(L: Plua_State);
+
+
+implementation
+
+uses Classes, SysUtils, LuaUtils, Lua_Object, Lua_Classes,
+     DB, DBTables, BDE, TypInfo, Variants;
+
+type
+//  TComponent <- TDataset <- TBDEDataSet <- TDBDataSet <- TTable
+//                                                      <- TQuery
+//  -------------------------------------------------------------
+//  TLuaComponent <- TLuaDataset <- TLuaBDEDataSet <- TLuaDBDataSet <- TLuaTable
+//                                                                  <- TLuaQuery
+//==============================================================================
+    TLuaDataset = class (TLuaComponent)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+
+    function ActiveBuffer: String;
+    procedure Append;
+    procedure AppendRecord(const Values: array of const);
+    function BookmarkValid(Bookmark: TBookmark): Boolean;
+    procedure Cancel;
+    procedure CheckBrowseMode;
+    procedure ClearFields;
+    procedure Close;
+    function  ControlsDisabled: Boolean;
+    function CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer;
+    function CreateBlobStream(Field: TField; Mode: TBlobStreamMode): TStream;
+    procedure CursorPosChanged;
+    procedure Delete;
+    procedure DisableControls;
+    procedure Edit;
+    procedure EnableControls;
+    function FieldByName(const FieldName: string): TField;
+    function FindField(const FieldName: string): TField;
+    function FindFirst: Boolean;
+    function FindLast: Boolean;
+    function FindNext: Boolean;
+    function FindPrior: Boolean;
+    procedure First;
+    procedure FreeBookmark(Bookmark: TBookmark);
+    function GetBookmark: TBookmark;
+    function GetCurrentRecord(Buffer: String): Boolean;
+    procedure GetDetailDataSets(List: TList);
+    procedure GetDetailLinkFields(MasterFields, DetailFields: TList);
+    function GetBlobFieldData(FieldNo: Integer; var Buffer: TBlobByteData): Integer;
+    function GetFieldData(Field: TField; Buffer: Pointer): Boolean; overload;
+    function GetFieldData(FieldNo: Integer; Buffer: Pointer): Boolean; overload;
+    function GetFieldData(Field: TField; Buffer: Pointer; NativeFormat: Boolean): Boolean; overload;
+    procedure GetFieldList(List: TList; const FieldNames: string);
+    procedure GetFieldNames(List: TStrings);
+    procedure GotoBookmark(Bookmark: TBookmark);
+    procedure Insert;
+    procedure InsertRecord(const Values: array of const);
+    function IsEmpty: Boolean;
+    function IsLinkedTo(DataSource: TDataSource): Boolean;
+    function IsSequenced: Boolean;
+    procedure Last;
+    function Locate(const KeyFields: string; const KeyValues: Variant;
+      Options: TLocateOptions): Boolean;
+    function Lookup(const KeyFields: string; const KeyValues: Variant;
+      const ResultFields: string): Variant;
+    function MoveBy(Distance: Integer): Integer;
+    procedure Next;
+    procedure Open;
+    procedure Post;
+    procedure Prior;
+    procedure Refresh;
+    procedure Resync(Mode: TResyncMode);
+    procedure SetFields(const Values: array of const);
+    function Translate(Src, Dest: String; ToOem: Boolean): Integer;
+    procedure UpdateCursorPos;
+    procedure UpdateRecord;
+    function UpdateStatus: TUpdateStatus;
+    end;
+
+    TDatasetAccess = class(TDataset)
+    published
+       property AggFields;
+       property Bof;
+       property Bookmark;
+       property CanModify;
+       property DataSetField;
+       property DataSource;
+       property DefaultFields;
+       property Designer;
+       property Eof;
+       property BlockReadSize;
+       property FieldCount;
+       property FieldDefs;
+       property FieldDefList;
+       property Fields;
+       property FieldList;
+       //property FieldValues[const FieldName: string]: Variant
+       property Found;
+       property IsUniDirectional;
+       property Modified;
+       property ObjectView;
+       property RecordCount;
+       property RecNo;
+       property RecordSize;
+       property SparseArrays;
+       property State;
+       property Filter;
+       property Filtered;
+       property FilterOptions;
+       property Active;
+       property AutoCalcFields;
+    end;
+
+//==============================================================================
+    TLuaBDEDataSet = class (TLuaDataset)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+(*       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+       function GetElementType(Name :String) :PTypeInfo; override;
+       function GetElement(Name :String) :Variant; override;
+*)
+    procedure ApplyUpdates;
+    procedure CancelUpdates;
+    procedure CommitUpdates;
+    function ConstraintCallBack(Req: DsInfoReq; var ADataSources: DataSources): DBIResult;
+    function ConstraintsDisabled: Boolean;
+    procedure DisableConstraints;
+    procedure EnableConstraints;
+    procedure FetchAll;
+    procedure FlushBuffers;
+    procedure GetIndexInfo;
+    procedure RevertRecord;
+    end;
+
+    TBDEDataSetAccess = class(TBDEDataSet)
+    published
+       property CacheBlobs;
+       property ExpIndex;
+       //property Handle;  Pointer
+       property KeySize;
+       //property Locale;  Pointer
+       property UpdateObject;
+       property UpdatesPending;
+       property UpdateRecordTypes;
+    end;
+
+//==============================================================================
+    TLuaDBDataSet = class (TLuaBDEDataSet)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+(*       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+       function GetElementType(Name :String) :PTypeInfo; override;
+       function GetElement(Name :String) :Variant; override;
+*)
+    function CheckOpen(Status: DBIResult): Boolean;
+    procedure CloseDatabase(Database: TDatabase);
+    function OpenDatabase: TDatabase;
+    end;
+
+    TDBDataSetAccess = class(TDBDataSet)
+    published
+       property Database;
+       //property DBHandle; Pointer
+       //property DBLocale; Pointer
+       property DBSession;
+       //property Handle; Pointer
+    end;
+
+//==============================================================================
+    TLuaTable = class (TLuaDBDataSet)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+
+    function BatchMove(ASource: TBDEDataSet; AMode: TBatchMode): Longint;
+    procedure AddIndex(const Name, Fields: string; Options: TIndexOptions;
+      const DescFields: string = '');
+    procedure ApplyRange;
+    procedure CancelRange;
+    procedure CloseIndexFile(const IndexFileName: string);
+    procedure CreateTable;
+    procedure DeleteIndex(const Name: string);
+    procedure DeleteTable;
+    procedure EditKey;
+    procedure EditRangeEnd;
+    procedure EditRangeStart;
+    procedure EmptyTable;
+    function FindKey(const KeyValues: array of const): Boolean;
+    procedure FindNearest(const KeyValues: array of const);
+    procedure GetIndexNames(List: TStrings);
+    procedure GotoCurrent(Table: TTable);
+    function GotoKey: Boolean;
+    procedure GotoNearest;
+    procedure LockTable(LockType: TLockType);
+    procedure OpenIndexFile(const IndexName: string);
+    procedure RenameTable(const NewTableName: string);
+    procedure SetKey;
+    procedure SetRange(const StartValues, EndValues: array of const);
+    procedure SetRangeEnd;
+    procedure SetRangeStart;
+    procedure UnlockTable(LockType: TLockType);
+    end;
+
+    TTableAccess = class(TTable)
+    published
+       property Exists;
+       property IndexFieldCount;
+       //property IndexFields[Index: Integer]: TField;
+       property KeyExclusive;
+       property KeyFieldCount;
+       property TableLevel;
+    end;
+
+//==============================================================================
+    TLuaQuery = class (TLuaDBDataSet)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+(*       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; override;
+       function GetArrayProp(Name :String; index :Variant) :Variant; override;
+       function GetElementType(Name :String) :PTypeInfo; override;
+       function GetElement(Name :String) :Variant; override;
+*)
+    procedure ExecSQL;
+    function ParamByName(const Value: string): TParam;
+    procedure Prepare;
+    procedure UnPrepare;
+    end;
+
+    TQueryAccess = class(TQuery)
+    published
+       property Prepared;
+       property ParamCount;
+       property Local;
+       //property StmtHandle; Pointer
+       property Text;
+       property RowsAffected;
+       //property SQLBinary; Pointer
+    end;
+
+//==============================================================================
+    TLuaField = class (TLuaComponent)
+    protected
+       class function GetPublicPropertyAccessClass :TClass; override;
+
+    public
+    procedure AssignValue(const Value: TVarRec);
+    procedure Clear;
+    procedure FocusControl;
+    function GetData(Buffer: Pointer; NativeFormat: Boolean = True): Boolean;
+    class function IsBlob: Boolean;
+    function IsValidChar(InputChar: Char): Boolean;
+    procedure RefreshLookupList;
+    procedure SetData(Buffer: Pointer; NativeFormat: Boolean = True);
+    procedure SetFieldType(Value: TFieldType);
+    procedure Validate(Buffer: Pointer);
+    end;
+
+    TFieldAccess = class(TField)
+    published
+       property AsBCD;
+       property AsBoolean;
+       property AsCurrency;
+       property AsDateTime;
+       property AsSQLTimeStamp;
+       property AsFloat;
+       property AsInteger;
+       property AsString;
+       property AsVariant;
+       property AttributeSet;
+       property Calculated;
+       property CanModify;
+       property CurValue;
+       property DataSet;
+       property DataSize;
+       property DataType;
+       property DisplayName;
+       property DisplayText;
+       property EditMask;
+       property EditMaskPtr;
+       property FieldNo;
+       property FullName;
+       property IsIndexField;
+       property IsNull;
+       property Lookup;
+       property LookupList;
+       property NewValue;
+       property Offset;
+       property OldValue;
+       property ParentField;
+       property Size;
+       property Text;
+       //property ValidChars;  Size of published set 'ValidChars' is >4 bytes
+       property Value;
+    end;
+
+procedure RegisterFunctions(L: Plua_State);
+begin
+     Lua_Object.RegisterFunctions(L);
+end;
+
+{ TLuaDataset }
+
+function TLuaDataset.GetArrayPropType(Name: String; index: Variant): PTypeInfo;
+begin
+     Name :=Uppercase(Name);
+     Result :=nil;
+
+     if (Name='FIELDVALUES')
+     then begin
+               if (TDataset(InstanceObj).FieldValues[index]<>NULL)
+               then Result :=TypeInfo(Variant);
+          end
+     else
+     Result :=inherited GetArrayPropType(Name, index);
+end;
+
+function TLuaDataset.GetArrayProp(Name: String; index: Variant): Variant;
+begin
+     if (Name='FIELDVALUES')
+     then begin
+               Result :=TDataset(InstanceObj).FieldValues[index]
+          end
+     else
+     Result := inherited GetArrayProp(name, index)
+end;
+
+class function TLuaDataset.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TDatasetAccess;
+end;
+
+function TLuaDataset.FindLast: Boolean;
+begin
+     Result :=TDataset(InstanceObj).FindLast;
+end;
+
+function TLuaDataset.FieldByName(const FieldName: string): TField;
+begin
+     Result :=TDataset(InstanceObj).FieldByName(FieldName);
+end;
+
+function TLuaDataset.FindPrior: Boolean;
+begin
+     Result :=TDataset(InstanceObj).FindPrior;
+end;
+
+function TLuaDataset.FindField(const FieldName: string): TField;
+begin
+     Result :=TDataset(InstanceObj).FindField(FieldName);
+end;
+
+function TLuaDataset.FindFirst: Boolean;
+begin
+     Result :=TDataset(InstanceObj).FindFirst;
+end;
+
+procedure TLuaDataset.First;
+begin
+     TDataset(InstanceObj).First;
+end;
+
+function TLuaDataset.FindNext: Boolean;
+begin
+     Result :=TDataset(InstanceObj).FindNext;
+end;
+
+function TLuaDataset.IsLinkedTo(DataSource: TDataSource): Boolean;
+begin
+     Result :=TDataset(InstanceObj).IsLinkedTo(DataSource);
+end;
+
+procedure TLuaDataset.ClearFields;
+begin
+    TDataset(InstanceObj).ClearFields;
+end;
+
+procedure TLuaDataset.CursorPosChanged;
+begin
+     TDataset(InstanceObj).CursorPosChanged;
+end;
+
+function TLuaDataset.Lookup(const KeyFields: string; const KeyValues: Variant;
+  const ResultFields: string): Variant;
+begin
+     Result :=TDataset(InstanceObj).Lookup(KeyFields, KeyValues, ResultFields);
+end;
+
+procedure TLuaDataset.Last;
+begin
+     TDataset(InstanceObj).Last;
+end;
+
+function TLuaDataset.Locate(const KeyFields: string; const KeyValues: Variant;
+  Options: TLocateOptions): Boolean;
+begin
+     Result :=TDataset(InstanceObj).Locate(KeyFields, KeyValues, Options);
+end;
+
+procedure TLuaDataset.SetFields(const Values: array of const);
+begin
+     TDataset(InstanceObj).SetFields(Values);
+end;
+
+procedure TLuaDataset.CheckBrowseMode;
+begin
+     TDataset(InstanceObj).CheckBrowseMode;
+end;
+
+function TLuaDataset.UpdateStatus: TUpdateStatus;
+begin
+     Result :=TDataset(InstanceObj).UpdateStatus;
+end;
+
+function TLuaDataset.MoveBy(Distance: Integer): Integer;
+begin
+     Result :=TDataset(InstanceObj).MoveBy(Distance);
+end;
+
+function TLuaDataset.IsSequenced: Boolean;
+begin
+     Result :=TDataset(InstanceObj).IsSequenced;
+end;
+
+procedure TLuaDataset.Prior;
+begin
+     TDataset(InstanceObj).Prior;
+end;
+
+procedure TLuaDataset.UpdateRecord;
+begin
+     TDataset(InstanceObj).UpdateRecord;
+end;
+
+procedure TLuaDataset.Refresh;
+begin
+     TDataset(InstanceObj).Refresh;
+end;
+
+procedure TLuaDataset.Open;
+begin
+     TDataset(InstanceObj).Open;
+end;
+
+procedure TLuaDataset.DisableControls;
+begin
+     TDataset(InstanceObj).DisableControls;
+end;
+
+procedure TLuaDataset.AppendRecord(const Values: array of const);
+begin
+     TDataset(InstanceObj).AppendRecord(Values);
+end;
+
+procedure TLuaDataset.Cancel;
+begin
+     TDataset(InstanceObj).Cancel;
+end;
+
+procedure TLuaDataset.Post;
+begin
+     TDataset(InstanceObj).Post;
+end;
+
+procedure TLuaDataset.InsertRecord(const Values: array of const);
+begin
+     TDataset(InstanceObj).InsertRecord(Values);
+end;
+
+function TLuaDataset.IsEmpty: Boolean;
+begin
+     Result :=TDataset(InstanceObj).IsEmpty;
+end;
+
+procedure TLuaDataset.Close;
+begin
+     TDataset(InstanceObj).Close;
+end;
+
+procedure TLuaDataset.EnableControls;
+begin
+     TDataset(InstanceObj).EnableControls;
+end;
+
+procedure TLuaDataset.Delete;
+begin
+     TDataset(InstanceObj).Delete;
+end;
+
+procedure TLuaDataset.Resync(Mode: TResyncMode);
+begin
+     TDataset(InstanceObj).Resync(Mode);
+end;
+
+procedure TLuaDataset.Edit;
+begin
+     TDataset(InstanceObj).Edit;
+end;
+
+procedure TLuaDataset.Append;
+begin
+     TDataset(InstanceObj).Append;
+end;
+
+function TLuaDataset.ControlsDisabled: Boolean;
+begin
+     Result :=TDataset(InstanceObj).ControlsDisabled;
+end;
+
+procedure TLuaDataset.UpdateCursorPos;
+begin
+     TDataset(InstanceObj).UpdateCursorPos;
+end;
+
+procedure TLuaDataset.Next;
+begin
+     TDataset(InstanceObj).Next;
+end;
+
+procedure TLuaDataset.Insert;
+begin
+     TDataset(InstanceObj).Insert;
+end;
+
+procedure TLuaDataset.GetFieldList(List: TList; const FieldNames: string);
+begin
+     TDataset(InstanceObj).GetFieldList(List, FieldNames);
+end;
+
+function TLuaDataset.GetFieldData(Field: TField; Buffer: Pointer;
+  NativeFormat: Boolean): Boolean;
+begin
+     Result :=TDataset(InstanceObj).GetFieldData(Field, Buffer, NativeFormat);
+end;
+
+function TLuaDataset.GetFieldData(FieldNo: Integer; Buffer: Pointer): Boolean;
+begin
+     Result :=TDataset(InstanceObj).GetFieldData(FieldNo, Buffer);
+end;
+
+function TLuaDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
+begin
+     Result :=TDataset(InstanceObj).GetFieldData(Field, Buffer);
+end;
+
+function TLuaDataset.CreateBlobStream(Field: TField;
+  Mode: TBlobStreamMode): TStream;
+begin
+     Result :=TDataset(InstanceObj).CreateBlobStream(Field, Mode);
+end;
+
+procedure TLuaDataset.GotoBookmark(Bookmark: TBookmark);
+begin
+     TDataset(InstanceObj).GotoBookmark(Bookmark);
+end;
+
+function TLuaDataset.CompareBookmarks(Bookmark1, Bookmark2: TBookmark): Integer;
+begin
+     Result :=TDataset(InstanceObj).CompareBookmarks(Bookmark1, Bookmark2);
+end;
+
+function TLuaDataset.GetBookmark: TBookmark;
+begin
+     Result :=TDataset(InstanceObj).GetBookmark;
+end;
+
+function TLuaDataset.GetCurrentRecord(Buffer: String): Boolean;
+begin
+     Result :=TDataset(InstanceObj).GetCurrentRecord(PChar(Buffer));
+end;
+
+procedure TLuaDataset.GetDetailLinkFields(MasterFields, DetailFields: TList);
+begin
+     TDataset(InstanceObj).GetDetailLinkFields(MasterFields, DetailFields);
+end;
+
+function TLuaDataset.BookmarkValid(Bookmark: TBookmark): Boolean;
+begin
+     Result :=TDataset(InstanceObj).BookmarkValid(Bookmark);
+end;
+
+function TLuaDataset.Translate(Src, Dest: String; ToOem: Boolean): Integer;
+begin
+     Result :=TDataset(InstanceObj).Translate(PChar(Src), PChar(Dest), ToOem);
+end;
+
+procedure TLuaDataset.FreeBookmark(Bookmark: TBookmark);
+begin
+     TDataset(InstanceObj).FreeBookmark(Bookmark);
+end;
+
+function TLuaDataset.GetBlobFieldData(FieldNo: Integer;
+  var Buffer: TBlobByteData): Integer;
+begin
+     Result :=TDataset(InstanceObj).GetBlobFieldData(FieldNo, Buffer);
+end;
+
+procedure TLuaDataset.GetDetailDataSets(List: TList);
+begin
+     TDataset(InstanceObj).GetDetailDataSets(List);
+end;
+
+function TLuaDataset.ActiveBuffer: String;
+begin
+     Result :=TDataset(InstanceObj).ActiveBuffer;
+end;
+
+procedure TLuaDataset.GetFieldNames(List: TStrings);
+begin
+     TDataset(InstanceObj).GetFieldNames(List);
+end;
+
+{ TLuaBDEDataSet }
+
+class function TLuaBDEDataSet.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TBDEDataSetAccess;
+end;
+
+procedure TLuaBDEDataSet.CancelUpdates;
+begin
+     TBDEDataset(InstanceObj).CancelUpdates;
+end;
+
+procedure TLuaBDEDataSet.ApplyUpdates;
+begin
+     TBDEDataset(InstanceObj).ApplyUpdates;
+end;
+
+procedure TLuaBDEDataSet.CommitUpdates;
+begin
+     TBDEDataset(InstanceObj).CommitUpdates;
+end;
+
+procedure TLuaBDEDataSet.DisableConstraints;
+begin
+     TBDEDataset(InstanceObj).DisableConstraints;
+end;
+
+procedure TLuaBDEDataSet.FetchAll;
+begin
+     TBDEDataset(InstanceObj).FetchAll;
+end;
+
+procedure TLuaBDEDataSet.EnableConstraints;
+begin
+     TBDEDataset(InstanceObj).EnableConstraints;
+end;
+
+function TLuaBDEDataSet.ConstraintsDisabled: Boolean;
+begin
+     Result :=TBDEDataset(InstanceObj).ConstraintsDisabled;
+end;
+
+procedure TLuaBDEDataSet.GetIndexInfo;
+begin
+     TBDEDataset(InstanceObj).GetIndexInfo;
+end;
+
+function TLuaBDEDataSet.ConstraintCallBack(Req: DsInfoReq;
+  var ADataSources: DataSources): DBIResult;
+begin
+     Result :=TBDEDataset(InstanceObj).ConstraintCallBack(Req, ADataSources);
+end;
+
+procedure TLuaBDEDataSet.FlushBuffers;
+begin
+     TBDEDataset(InstanceObj).FlushBuffers;
+end;
+
+procedure TLuaBDEDataSet.RevertRecord;
+begin
+     TBDEDataset(InstanceObj).RevertRecord;
+end;
+
+{ TLuaDBDataSet }
+
+class function TLuaDBDataSet.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TDBDataSetAccess;
+end;
+
+procedure TLuaDBDataSet.CloseDatabase(Database: TDatabase);
+begin
+     TDBDataSet(InstanceObj).CloseDatabase(Database);
+end;
+
+function TLuaDBDataSet.CheckOpen(Status: DBIResult): Boolean;
+begin
+     Result :=TDBDataSet(InstanceObj).CheckOpen(Status);
+end;
+
+function TLuaDBDataSet.OpenDatabase: TDatabase;
+begin
+     Result :=TDBDataSet(InstanceObj).OpenDatabase;
+end;
+
+{ TLuaTable }
+
+function TLuaTable.GetArrayPropType(Name: String; index: Variant): PTypeInfo;
+begin
+     Name :=Uppercase(Name);
+     Result :=nil;
+
+     if (Name='INDEXFIELDS')
+     then begin
+               if (TTable(InstanceObj).IndexFields[index]<>nil)
+               then Result :=TypeInfo(TField);
+          end
+     else
+     Result :=inherited GetArrayPropType(Name, index);
+end;
+
+function TLuaTable.GetArrayProp(Name: String; index: Variant): Variant;
+begin
+     if (Name='INDEXFIELDS')
+     then begin
+               if (TTable(InstanceObj).IndexFields[index]<>nil)
+               then Result :=Integer(TTable(InstanceObj).IndexFields[index])
+               else Result :=NULL;
+          end
+     else
+     Result := inherited GetArrayProp(name, index)
+end;
+
+class function TLuaTable.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TTableAccess;
+end;
+
+procedure TLuaTable.SetRange(const StartValues, EndValues: array of const);
+begin
+     TTable(InstanceObj).SetRange(StartValues, EndValues);
+end;
+
+procedure TLuaTable.GetIndexNames(List: TStrings);
+begin
+     TTable(InstanceObj).GetIndexNames(List);
+end;
+
+procedure TLuaTable.SetKey;
+begin
+     TTable(InstanceObj).SetKey;
+end;
+
+procedure TLuaTable.CreateTable;
+begin
+     TTable(InstanceObj).CreateTable;
+end;
+
+procedure TLuaTable.GotoNearest;
+begin
+     TTable(InstanceObj).GotoNearest;
+end;
+
+procedure TLuaTable.RenameTable(const NewTableName: string);
+begin
+     TTable(InstanceObj).RenameTable(NewTableName);
+end;
+
+procedure TLuaTable.CloseIndexFile(const IndexFileName: string);
+begin
+     TTable(InstanceObj).CloseIndexFile(IndexFileName);
+end;
+
+procedure TLuaTable.DeleteIndex(const Name: string);
+begin
+     TTable(InstanceObj).DeleteIndex(Name);
+end;
+
+function TLuaTable.BatchMove(ASource: TBDEDataSet; AMode: TBatchMode): Longint;
+begin
+     Result :=TTable(InstanceObj).BatchMove(ASource, AMode);
+end;
+
+procedure TLuaTable.EditRangeStart;
+begin
+     TTable(InstanceObj).EditRangeStart;
+end;
+
+procedure TLuaTable.CancelRange;
+begin
+     TTable(InstanceObj).CancelRange;
+end;
+
+function TLuaTable.GotoKey: Boolean;
+begin
+     Result :=TTable(InstanceObj).GotoKey;
+end;
+
+procedure TLuaTable.ApplyRange;
+begin
+     TTable(InstanceObj).ApplyRange;
+end;
+
+procedure TLuaTable.LockTable(LockType: TLockType);
+begin
+     TTable(InstanceObj).LockTable(LockType);
+end;
+
+procedure TLuaTable.FindNearest(const KeyValues: array of const);
+begin
+     TTable(InstanceObj).FindNearest(KeyValues);
+end;
+
+procedure TLuaTable.UnlockTable(LockType: TLockType);
+begin
+     TTable(InstanceObj).UnlockTable(LockType);
+end;
+
+procedure TLuaTable.GotoCurrent(Table: TTable);
+begin
+     TTable(InstanceObj).GotoCurrent(Table);
+end;
+
+procedure TLuaTable.SetRangeStart;
+begin
+     TTable(InstanceObj).SetRangeStart;
+end;
+
+procedure TLuaTable.AddIndex(const Name, Fields: string; Options: TIndexOptions;
+  const DescFields: string);
+begin
+     TTable(InstanceObj).AddIndex(Name, Fields, Options, DescFields);
+end;
+
+procedure TLuaTable.EditRangeEnd;
+begin
+     TTable(InstanceObj).EditRangeEnd;
+end;
+
+procedure TLuaTable.EditKey;
+begin
+     TTable(InstanceObj).EditKey;
+end;
+
+procedure TLuaTable.DeleteTable;
+begin
+     TTable(InstanceObj).DeleteTable;
+end;
+
+function TLuaTable.FindKey(const KeyValues: array of const): Boolean;
+begin
+     Result :=TTable(InstanceObj).FindKey(KeyValues);
+end;
+
+procedure TLuaTable.EmptyTable;
+begin
+     TTable(InstanceObj).EmptyTable;
+end;
+
+procedure TLuaTable.SetRangeEnd;
+begin
+     TTable(InstanceObj).SetRangeEnd;
+end;
+
+procedure TLuaTable.OpenIndexFile(const IndexName: string);
+begin
+     TTable(InstanceObj).OpenIndexFile(IndexName);
+end;
+
+{ TLuaQuery }
+
+class function TLuaQuery.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TQueryAccess;
+end;
+
+procedure TLuaQuery.ExecSQL;
+begin
+     TQuery(InstanceObj).ExecSQL;
+end;
+
+function TLuaQuery.ParamByName(const Value: string): TParam;
+begin
+     Result :=TQuery(InstanceObj).ParamByName(Value);
+end;
+
+procedure TLuaQuery.Prepare;
+begin
+     TQuery(InstanceObj).Prepare;
+end;
+
+procedure TLuaQuery.UnPrepare;
+begin
+     TQuery(InstanceObj).UnPrepare;
+end;
+
+{ TLuaField }
+
+class function TLuaField.GetPublicPropertyAccessClass: TClass;
+begin
+     Result :=TFieldAccess;
+end;
+
+procedure TLuaField.AssignValue(const Value: TVarRec);
+begin
+     TField(InstanceObj).AssignValue(Value);
+end;
+
+function TLuaField.GetData(Buffer: Pointer; NativeFormat: Boolean): Boolean;
+begin
+     Result :=TField(InstanceObj).GetData(Buffer, NativeFormat);
+end;
+
+procedure TLuaField.FocusControl;
+begin
+     TField(InstanceObj).FocusControl;
+end;
+
+procedure TLuaField.Clear;
+begin
+     TField(InstanceObj).Clear;
+end;
+
+procedure TLuaField.SetData(Buffer: Pointer; NativeFormat: Boolean);
+begin
+     TField(InstanceObj).SetData(Buffer, NativeFormat);
+end;
+
+procedure TLuaField.SetFieldType(Value: TFieldType);
+begin
+     TField(InstanceObj).SetFieldType(Value);
+end;
+
+procedure TLuaField.Validate(Buffer: Pointer);
+begin
+     TField(InstanceObj).Validate(Buffer);
+end;
+
+procedure TLuaField.RefreshLookupList;
+begin
+     TField(InstanceObj).RefreshLookupList;
+end;
+
+class function TLuaField.IsBlob: Boolean;
+begin
+     Result := False;
+end;
+
+function TLuaField.IsValidChar(InputChar: Char): Boolean;
+begin
+     Result :=TField(InstanceObj).IsValidChar(InputChar);
+end;
+
+initialization
+   Lua_Object.RegisterClass(TDataset, TLuaDataset);
+   Lua_Object.RegisterClass(TBDEDataSet, TLuaBDEDataSet);
+   Lua_Object.RegisterClass(TDBDataSet, TLuaDBDataSet);
+   Lua_Object.RegisterClass(TTable, TLuaTable);
+   Lua_Object.RegisterClass(TQuery, TLuaQuery);
+   Lua_Object.RegisterClass(TField, TLuaField);
+
+end.

+ 1421 - 0
LuaEdit/LuaCore/Lua_Object.pas

@@ -0,0 +1,1421 @@
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2006                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//  File        : Lua_Object.pas   (rev. 1.0)
+//
+//  Description : Access from Lua scripts to TObject Classes
+//                 (at this time only Properties and methods)
+//
+//******************************************************************************
+//  Exported functions :
+//
+//   CreateObject(string className, bool CanFree [, param1, ..paramN])   return a new TObject.
+//   GetObject(string Name)                          return an existing TObject.
+//
+//    TObject.PropertyName                     return Property Value as Variant.
+//    TObject.PropertyName = (variant Value)                 set Property Value.
+//    TObject:<method name>([param1, .., paramN]) call <method name>, return Result as Variant.
+//    TObject:Free()                    free the object, return True on success.
+
+// TO-DO :
+//           funzioni lua da esportare :
+//                 enumval(Type :???, value :string) enumstr(Type :???, value :Integer???)
+//           nei metodi dove c'è var, come lo torno in Lua?
+//           Eventi degli oggetti (una classe per ogni evento + lista con il nome della funzione lua)
+//           Gestione delle property di Tipo Record  Vedi cos'è PFieldTable
+//       +   Metodo x avere le property publiche??? invece di usare SetElement 
+//       *   gestione del garbage collector (metafunction _gc)
+//       *   Gestione di TComponent.<componentname> come se fosse una property tkClass
+//      ++   Migliorare la gestione delle property che sono degli array (se possibile???)
+//       *   Migliorare la registrazione delle classi, andare sempre alla ricerca dell' ancestor
+//          COMMENTARE IL CODICE MENTRO ME LO RICORDO
+
+
+unit Lua_Object;
+{$J+}
+interface
+
+uses TypInfo, SysUtils, ScriptableObject, Lua, LuaUtils, lauxlib, Variants;
+
+type
+{$METHODINFO ON}
+    TLuaObject = class(TObject)
+    protected
+       rInstanceObj :TObject;
+       Owned        :Boolean;
+
+       class function GetPublicPropertyAccessClass :TClass; virtual; abstract;
+
+    public
+       constructor Create(AInstanceObj :TObject; AOwned :Boolean);
+       destructor Destroy; override;
+
+       function CallMethod(MethodName :String; const Args : array of variant;
+                        NeedResult: Boolean): Variant;
+
+
+       //WARNING : if you want parameters when creating an Object you must write
+       //          a function with the following form that create the object.
+       //          You must change every parameter or result of type TClass, TObject
+       //          with type integer (ObjComAuto do not support this types?????)
+       //
+       function LuaCreate(ObjClass :Integer) :Integer; overload;
+
+       function GetDefaultArrayProp :String; virtual; abstract;
+       function GetArrayPropType(Name :String; index :Variant) :PTypeInfo; virtual; abstract;
+       function GetArrayProp(Name :String; index :Variant) :Variant; virtual; abstract;
+       procedure SetArrayProp(Name :String; index :Variant; Value :Variant); virtual; abstract;
+
+       //If the ElementType is tkSet or tkEnumeration (except the boolean) you may return the Value
+       // in GetElement as a String
+       function GetElementType(Name :String) :PTypeInfo; virtual; abstract;
+       function GetElement(Name :String) :Variant; virtual; abstract;
+       procedure SetElement(Name :String; Value :Variant); virtual; abstract;
+
+       function GetPublicPropInfo(Name :String) :PPropInfo;
+       function GetPublicPropValue(Name :String; AsString :Boolean) :Variant;
+       procedure SetPublicPropValue(Name :String; Value :Variant);
+
+
+       property InstanceObj :TObject read rInstanceObj;
+    end;
+{$METHODINFO OFF}
+
+    TLuaObjectClass = class of TLuaObject;
+
+const
+     TypeInfoArray : TTypeInfo = (Kind : tkArray; Name :'');
+     TypeInfoClass : TTypeInfo = (Kind : tkClass; Name :'');
+
+procedure RegisterFunctions(L: Plua_State);
+procedure RegisterClass(ObjClass :TClass; LuaClass :TLuaObjectClass=nil);
+procedure RegisterObject(Obj :TObject; Name :String; LuaClass :TLuaObjectClass=nil);
+
+function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean): string;
+function StringToSet(EnumInfo: PTypeInfo; const Value: string): Integer;
+
+implementation
+
+
+uses MGList, Classes, Controls;
+
+const
+     OBJHANDLE_STR       ='Lua_TObjectHandle';
+     ARRAYPROP_STR       ='Lua_TObjectArrayProp';
+     ARRAYPROPNAME_STR   ='Lua_TObjectArrayPropName';
+     SETPROP_VALUE       ='Lua_TObjectSetPropvalue';
+     SETPROP_INFO       ='Lua_TObjectSetPropINFO';
+
+
+type
+    //Record stored in lua stack to mantain TLuaObject
+    TLuaObjectData = packed record
+       ID  : String[20];
+       Obj :TLuaObject;
+    end;
+    PLuaObjectData =^TLuaObjectData;
+
+    TLuaArrayPropData = record
+       ID  : String[20];
+       Obj :TLuaObject;
+       PropName :string;
+    end;
+
+    TLuaSetPropData = record
+       ID       :String[20];
+       Info     :PTypeInfo;
+       Value    :string;
+    end;
+    PLuaSetPropData = ^TLuaSetPropData;
+
+    //This List associate an Object Class with a LuaObject Class
+    TLuaClassesListData = record
+       ObjClass :TClass;
+       LuaClass :TLuaObjectClass;
+    end;
+    PLuaClassesListData =^TLuaClassesListData;
+
+    TLuaClassesList = class(TMGList)
+    protected
+        InternalData :TLuaClassesListData;
+
+        function allocData :Pointer; override;
+        procedure deallocData(pData :Pointer); override;
+        function internalFind(ObjClassName :String) :PLuaClassesListData; overload;
+        function internalFind(ObjClass :TClass) :PLuaClassesListData; overload;
+    public
+        function Add(ObjClass :TClass; LuaClass :TLuaObjectClass=nil) :PLuaClassesListData; overload;
+        function FindAncestor(ObjClass :TClass) :TLuaObjectClass;
+        function Find(ObjClassName :String) :PLuaClassesListData; overload;
+        function Find(ObjClass :TClass) :PLuaClassesListData; overload;
+    end;
+
+    //This List associate an Existing Object Instance with a Name in the Lua script
+    TLuaExistingObjListData = record
+       Obj :TObject;
+       Name :String;
+    end;
+    PLuaExistingObjListData =^TLuaExistingObjListData;
+
+    TLuaExistingObjList = class(TMGList)
+    protected
+        function allocData :Pointer; override;
+        procedure deallocData(pData :Pointer); override;
+    public
+        function Add(Obj :TObject; Name :String) :PLuaExistingObjListData; overload;
+        function Find(Name :String) :PLuaExistingObjListData; overload;
+    end;
+
+
+Var
+   LuaClassesList :TLuaClassesList =nil;
+   LuaExistingObjList :TLuaExistingObjList =nil;
+
+
+procedure MySetPropValue(Instance: TObject; PropInfo: PPropInfo;
+  const Value: Variant);
+begin
+     //SetPropValue raise an exception when i try to set a class property...
+     // even if it's value is a simple Integer (infact GetPropValue return it as Integer)
+
+     if PropInfo^.PropType^.Kind = tkClass
+     then SetOrdProp(Instance, PropInfo, Value)
+     else SetPropValue(Instance, PropInfo, Value);
+end;
+
+constructor TLuaObject.Create(AInstanceObj :TObject; AOwned :Boolean);
+begin
+     inherited Create;
+     rInstanceObj :=AInstanceObj;
+     Owned :=AOwned;
+end;
+
+destructor TLuaObject.Destroy;
+begin
+     if Owned then rInstanceObj.Free;
+     inherited Destroy;
+end;
+
+function TLuaObject.LuaCreate(ObjClass :Integer) :Integer;
+begin
+     Result :=Integer(TClass(ObjClass).Create);
+end;
+
+function TLuaObject.CallMethod(MethodName :String; const Args : array of variant;
+                               NeedResult: Boolean): Variant;
+Var
+   scripter :TScriptableObject;
+   pRes     :PVariant;
+
+begin
+     Result :=NULL;
+     scripter :=nil;
+     try
+        //Try with My Methods
+        scripter :=TScriptableObject.Create(Self, false);
+        pRes :=scripter.CallMethod(scripter.NameToDispID(MethodName), Args, NeedResult);
+        if (pRes<>nil)
+        then Result :=pRes^;
+        scripter.Free;
+     except
+        scripter.Free;
+        Result :=NULL;
+        try
+           //Try with InstanceObj Methods
+           scripter :=TScriptableObject.Create(rInstanceObj, false);
+           pRes :=scripter.CallMethod(scripter.NameToDispID(MethodName), Args, NeedResult);
+           if (pRes<>nil)
+           then Result :=pRes^;
+           scripter.Free;
+        except
+           scripter.Free;
+           Result :=NULL;
+        end;
+     end;
+end;
+
+function TLuaObject.GetPublicPropInfo(Name :String) :PPropInfo;
+Var
+   _parent :TLuaObjectClass;
+
+begin
+     _parent :=TLuaObjectClass(Self.ClassType);
+
+     repeat
+          Result :=GetPropInfo(_parent.GetPublicPropertyAccessClass, Name, tkProperties);
+          if (Result=nil)
+          then _parent := TLuaObjectClass(_parent.ClassParent);
+     //IF the Property is not public in this Class, try in ancestors.
+     // This method avoid to redeclare property as published in every TXXXAccess class,
+     // for example :
+     //    TLuaControl <- TLuaWinControl
+     //    TControl    <- TWinControl
+     // Without this method, in TLuaWinControl, you might declare every public property
+     // of TWinControl including every public property of TControl.
+     // With this method, in TLuaWinControl, you can declare only public property of TWinControl
+     until (_parent=TLuaObject) or (Result<>nil);
+end;
+
+(*
+begin
+     Result :=GetPropInfo(GetPublicPropertyAccessClass, Name, tkProperties);
+end;
+*)
+
+function TLuaObject.GetPublicPropValue(Name :String; AsString :Boolean) :Variant;
+Var
+   PropInfo :PPropInfo;
+
+begin
+     PropInfo :=GetPublicPropInfo(Name);
+     if (PropInfo<>nil)
+     then Result :=GetPropValue(rInstanceObj, PropInfo, AsString);
+end;
+
+procedure TLuaObject.SetPublicPropValue(Name :String; Value :Variant);
+
+Var
+   PropInfo :PPropInfo;
+
+begin
+     PropInfo :=GetPublicPropInfo(Name);
+     if (PropInfo<>nil)
+     then MySetPropValue(rInstanceObj, PropInfo, Value);
+end;
+
+
+//==============================================================================
+//
+function TLuaClassesList.allocData :Pointer;
+begin
+     GetMem(Result, sizeof(TLuaClassesListData));
+     fillchar(Result^, sizeof(TLuaClassesListData), 0);
+end;
+
+procedure TLuaClassesList.deallocData(pData :Pointer);
+begin
+     FreeMem(pData, sizeof(TLuaClassesListData));
+end;
+
+function TLuaClassesList.Add(ObjClass :TClass; LuaClass :TLuaObjectClass=nil) :PLuaClassesListData;
+begin
+     Result :=Find(ObjClass.ClassName);
+     if (Result=nil)
+     then Result :=Self.Add;
+
+     if (Result<>nil)
+     then begin
+               Result^.ObjClass :=ObjClass;
+               (*if (LuaClass=nil)
+               then Result^.LuaClass :=TLuaObject
+               else*) Result^.LuaClass :=LuaClass;
+          end;
+end;
+
+function TLuaClassesList.FindAncestor(ObjClass :TClass) :TLuaObjectClass;
+Var
+   _parent :TClass;
+   Data    :PLuaClassesListData;
+
+begin
+     _parent :=ObjClass.ClassParent;
+     Data :=nil;
+     while (_parent<>nil) and (Data=nil) do
+     begin
+          Data :=internalFind(_parent);
+          if (Data<>nil)
+          then Result :=Data^.LuaClass
+          else _parent := _parent.ClassParent;
+     end;
+     if (Data=nil)
+     then Result :=TLuaObject;
+end;
+
+function TLuaClassesList.internalFind(ObjClassName :String) :PLuaClassesListData;
+
+   function CompByClassName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+   begin
+     Result := String(PChar(ptData1)) = Uppercase(PLuaClassesListData(ptData2)^.ObjClass.Classname);
+   end;
+
+begin
+     Result :=Self.ExtFind(PChar(Uppercase(ObjClassName)), 0, @CompByClassName);
+end;
+
+function TLuaClassesList.internalFind(ObjClass :TClass) :PLuaClassesListData;
+
+   function CompByClass(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+   begin
+     Result := TClass(ptData1) = PLuaClassesListData(ptData2)^.ObjClass;
+   end;
+
+begin
+     Result :=Self.ExtFind(ObjClass, 0, @CompByClass);
+end;
+
+function TLuaClassesList.Find(ObjClass :TClass) :PLuaClassesListData;
+
+begin
+     Result :=Self.internalFind(ObjClass);
+
+     if (Result<>nil)
+     then begin
+               if (Result^.LuaClass=nil) //The Class is registered, but have no LuaClass,
+                                         //try to find a registered ancestor class
+               then Result^.LuaClass :=FindAncestor(Result^.ObjClass);
+          end
+     else begin
+               //The Class is not registered, try to find a registered ancestor class
+               InternalData.ObjClass :=ObjClass;
+               InternalData.LuaClass :=FindAncestor(ObjClass);
+
+               if (InternalData.LuaClass<>nil)
+               then Result :=@InternalData
+               else Result :=nil;
+          end;
+end;
+
+
+function TLuaClassesList.Find(ObjClassName :String) :PLuaClassesListData;
+begin
+     Result :=Self.internalFind(ObjClassName);
+
+     if (Result<>nil)
+     then begin
+               if (Result^.LuaClass=nil) //The Class is registered, but have no LuaClass,
+                                         //try to find a registered ancestor class
+               then Result^.LuaClass :=FindAncestor(Result^.ObjClass);
+          end
+     else begin
+               Result :=Self.internalFind(FindClass(ObjClassName));
+               if (Result<>nil)
+               then begin
+                         if (Result^.LuaClass=nil) //The Class is registered in VCL, but have no LuaClass,
+                                                   //try to find a registered ancestor class
+                         then Result^.LuaClass :=FindAncestor(Result^.ObjClass);
+                    end
+          end;
+end;
+
+//==============================================================================
+//
+function TLuaExistingObjList.allocData :Pointer;
+begin
+     GetMem(Result, sizeof(TLuaExistingObjListData));
+     fillchar(Result^, sizeof(TLuaExistingObjListData), 0);
+end;
+
+procedure TLuaExistingObjList.deallocData(pData :Pointer);
+begin
+     PLuaExistingObjListData(pData)^.Name :='';
+     FreeMem(pData, sizeof(TLuaExistingObjListData));
+end;
+
+function TLuaExistingObjList.Add(Obj :TObject; Name :String) :PLuaExistingObjListData;
+begin
+     Result :=Find(Name);
+     if (Result=nil)
+     then Result :=Self.Add;
+
+     if (Result<>nil)
+     then begin
+               Result^.Obj :=Obj;
+               Result^.Name :=Uppercase(Name);
+          end;
+end;
+
+function TLuaExistingObjList.Find(Name :String) :PLuaExistingObjListData;
+
+function CompByClass(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+begin
+     Result := String(PChar(ptData1)) = PLuaExistingObjListData(ptData2)^.Name;
+end;
+
+begin
+     Result :=Self.ExtFind(PChar(Uppercase(Name)), 0, @CompByClass);
+end;
+
+//==============================================================================
+
+function GetPropertyArrayObject(var Data : TLuaArrayPropData; L: Plua_State; Index: Integer): boolean; forward;
+function LuaPush_TLuaObject(L :Plua_State; theParams :array of Variant;
+                            Obj :TObject=nil; ObjClassName :String='';
+                            CanFree :Boolean=True) :boolean; forward;
+function LuaPushPropertyArrayObject(L: Plua_State; Obj :TLuaObject; PropName :string): boolean; forward;
+function LuaPushPropertySet(L: Plua_State; TypeInfo :PTypeInfo; PropValue :Variant): boolean; forward;
+
+
+function PushProperty(L :Plua_State; scripter :TLuaObject;
+                      PropName :string; PropValue :Variant; PropType :PTypeInfo) :Integer;
+begin
+     Result :=0;
+
+     if (PropType^.Kind = tkClass)
+     then begin
+               //If this property is a class, push a TLuaObject in the stack
+               if LuaPush_TLuaObject(L, [], TObject(Integer(PropValue)))
+               then Result := 1;
+          end
+     else
+     if (PropType^.Kind =tkArray)
+     then begin //If this property is an array, push an ArrayPropObject in the stack
+               if LuaPushPropertyArrayObject(L, scripter, PropName)
+               then Result := 1;
+          end
+     else
+     if (PropType^.Kind =tkSet)
+     then begin //If this property is an array, push an ArrayPropObject in the stack
+               if LuaPushPropertySet(L, PropType, PropValue)
+               then Result := 1;
+          end
+     else
+     begin //Push the PropValue
+          LuaPushVariant(L, PropValue);
+          Result := 1;
+     end;
+end;
+
+//==============================================================================
+// Array Properties Support
+
+function Lua_IsPropertyArrayObject(L: Plua_State; Index: Integer): boolean;
+begin
+     Result :=False;
+     try
+        Result :=(LuaGetTableString(L, Index, 'ID')=ARRAYPROP_STR);
+     except
+     end;
+end;
+
+function GetPropertyArrayObject(var Data : TLuaArrayPropData; L: Plua_State; Index: Integer): boolean;
+begin
+     Result :=false;
+     try
+        Data.Obj :=TLuaObject(LuaGetTableLightUserData(L, Index, ARRAYPROP_STR));
+        Data.PropName :=LuaGetTableString(L, Index, ARRAYPROPNAME_STR);
+        Result :=true;
+     except
+     end;
+end;
+
+function Lua_ArrayProp_Get(L: Plua_State): Integer; cdecl;
+Var
+   indice,
+   PropValue    :Variant;
+   PropType     :PTypeInfo;
+   GetPropOK    :Boolean;
+   NParams      :Integer;
+   Data         :TLuaArrayPropData;
+
+begin
+     Result := 0;
+     NParams := lua_gettop(L);
+
+     if (NParams=2) then
+     try
+        GetPropertyArrayObject(Data, L, 1);
+        indice :=LuaToVariant(L, 2);
+
+        if (indice<>NULL)
+        then begin
+                  PropType :=Data.Obj.GetArrayPropType(Data.PropName, indice);
+
+                  GetPropOK := (PropType<>nil);
+
+                  if GetPropOK
+                  then PropValue :=Data.Obj.GetArrayProp(Data.PropName, indice)
+                  else PropValue :=NULL;
+
+                  Result :=PushProperty(L, Data.Obj, Data.PropName, PropValue, PropType);
+             end
+        else raise Exception.CreateFmt('Trying to index %s.%s with a NULL index', [Data.Obj.InstanceObj.ClassName, Data.PropName]);
+
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+function Lua_ArrayProp_Set(L: Plua_State): Integer; cdecl;
+begin
+end;
+
+function LuaPushPropertyArrayObject(L: Plua_State; Obj :TLuaObject; PropName :string): boolean;
+begin
+     lua_newtable(L);
+     LuaSetTableString(L, -1, 'ID', ARRAYPROP_STR);
+     LuaSetTableLightUserData(L, -1, ARRAYPROP_STR, Obj);
+     LuaSetTableString(L, -1, ARRAYPROPNAME_STR, PropName);
+     LuaSetTablePropertyFuncs(L, -1, Lua_ArrayProp_Get, Lua_ArrayProp_Set);
+     Result :=true;
+end;
+
+//==============================================================================
+//Set Properties Support
+
+function Lua_IsPropertySet(L: Plua_State; Index: Integer): boolean;
+begin
+     Result :=False;
+     try
+        Result :=lua_istable(L, Index) and (LuaGetTableString(L, Index, 'ID')=SETPROP_VALUE);
+     except
+     end;
+end;
+
+function GetPropertySet(Data :PLuaSetPropData; L: Plua_State; Index: Integer): String;
+begin
+     Result :='';
+     if Data<>nil then FillChar(Data^, Sizeof(TLuaSetPropData), 0);
+     
+     try
+        if lua_istable(L, Index)
+        then begin
+                  Result :=LuaGetTableString(L, Index, SETPROP_VALUE);
+                  if Data<>nil then
+                  begin
+                       Data^.ID :=LuaGetTableString(L, Index, 'ID');
+                       Data^.Info :=LuaGetTableLightUserData(L, Index, SETPROP_INFO);
+                  end;
+             end
+        else begin
+                  if (lua_isString(L, Index)=1)
+                  then Result :=LuaToString(L, Index);
+             end;
+
+        if Data<>nil
+        then Data^.Value :=Result;
+     except
+     end;
+end;
+
+function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean): string;
+var
+  S: TIntegerSet;
+  I: Integer;
+  EnumInfo :PTypeInfo;
+
+begin
+  Result := '';
+  Integer(S) := Value;
+  EnumInfo := GetTypeData(TypeInfo)^.CompType^;
+  for I := 0 to SizeOf(Integer) * 8 - 1 do
+    if I in S then
+    begin
+      if Result <> '' then
+        Result := Result + ',';
+      Result := Result + GetEnumName(EnumInfo, I);
+    end;
+  if Brackets then
+    Result := '[' + Result + ']';
+end;
+
+  // grab the next enum name
+function SetNextWord(var P: PChar): string;
+var
+   i: Integer;
+
+begin
+    i := 0;
+
+    // scan til whitespace
+    while not (P[i] in [',', ' ', #0,']']) do
+      Inc(i);
+
+    SetString(Result, P, i);
+
+    // skip whitespace
+    while P[i] in [',', ' ',']'] do
+      Inc(i);
+
+    Inc(P, i);
+end;
+
+function StringToSet(EnumInfo: PTypeInfo; const Value: string): Integer;
+var
+  P: PChar;
+  EnumName: string;
+  EnumValue: Longint;
+
+begin
+  Result := 0;
+  if Value = '' then Exit;
+  P := PChar(Value);
+
+  // skip leading bracket and whitespace
+  while P^ in ['[',' '] do
+    Inc(P);
+
+  EnumName := SetNextWord(P);
+  while EnumName <> '' do
+  begin
+    EnumValue := GetEnumValue(EnumInfo, EnumName);
+    if EnumValue < 0 then
+      raise EPropertyConvertError.CreateFmt('Invalid Property Element %s', [EnumName]);
+    Include(TIntegerSet(Result), EnumValue);
+    EnumName := SetNextWord(P);
+  end;
+end;
+
+
+function Lua_SetProp_Add(L: Plua_State): Integer; cdecl;
+Var
+   Val1, Val2,
+   EnumName,
+   xResult      :String;
+   NParams      :Integer;
+   pVal2        :PChar;
+
+begin
+     Result := 0;
+     NParams := lua_gettop(L);
+
+     if (NParams=2) then
+     try
+        Val1 :=GetPropertySet(nil, L, 1);
+        if (Val1='')
+        then raise Exception.Create('Left Side is Not a Set');
+
+        Val2 :=GetPropertySet(nil, L, 2);
+        if (Val2='')
+        then raise Exception.Create('Right Side is Not a Set');
+
+        xResult :=Val1;
+        pVal2 :=PChar(Val2);
+        EnumName := SetNextWord(pVal2);
+        while (EnumName<>'') do
+        begin
+             if (Pos(EnumName, Val1)<1)
+             then xResult :=xResult+','+EnumName;
+             EnumName := SetNextWord(pVal2);
+        end;
+        LuaPushPropertySet(L, nil, xResult);
+        Result :=1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+function Lua_SetProp_Sub(L: Plua_State): Integer; cdecl;
+Var
+   Val1, Val2,
+   EnumName,
+   xResult      :String;
+   NParams      :Integer;
+   pVal2        :PChar;
+   xPos         :Integer;
+
+begin
+     Result := 0;
+     NParams := lua_gettop(L);
+
+     if (NParams=2) then
+     try
+        Val1 :=GetPropertySet(nil, L, 1);
+        if (Val1='')
+        then raise Exception.Create('Left Side is Not a Set');
+
+        Val2 :=GetPropertySet(nil, L, 2);
+        if (Val1='')
+        then raise Exception.Create('Right Side is Not a Set');
+
+        xResult :=Val1;
+        pVal2 :=PChar(Val2);
+        EnumName := SetNextWord(pVal2);
+        while (EnumName<>'') do
+        begin
+             xPos := Pos(EnumName, xResult);
+             while (xPos>0) do
+             begin
+                  Delete(xResult, xPos, Length(EnumName)+1);
+                  xPos := Pos(EnumName, xResult);
+             end;
+             EnumName := SetNextWord(pVal2);
+        end;
+        LuaPushPropertySet(L, nil, xResult);
+        Result :=1;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+function LuaPushPropertySet(L: Plua_State; TypeInfo :PTypeInfo; PropValue :Variant): boolean;
+begin
+     lua_newtable(L);
+     LuaSetTableString(L, -1, 'ID', SETPROP_INFO);
+     LuaSetTableLightUserData(L, -1, SETPROP_INFO, TypeInfo);
+
+     if (TVarData(PropValue).VType = varString) or
+        (TVarData(PropValue).VType = varOleStr)
+     then LuaSetTableString(L, -1, SETPROP_VALUE, PropValue)
+     else LuaSetTableString(L, -1, SETPROP_VALUE, SetToString(TypeInfo, PropValue, false));
+
+     LuaSetMetaFunction(L, -1, '__add', Lua_SetProp_Add);
+     LuaSetMetaFunction(L, -1, '__sub', Lua_SetProp_Sub);
+     Result :=true;
+end;
+
+//==============================================================================
+
+function GetTLuaObject(L: Plua_State; Index: Integer): TLuaObject;
+Var
+   pObjData :PLuaObjectData;
+
+begin
+     //Result := TLuaObject(LuaGetTableLightUserData(L, Index, OBJHANDLE_STR));
+
+     Result :=nil;
+     try
+        if (lua_isuserdata(L, Index)=1) then
+        begin
+             pObjData :=lua_touserdata(L, Index);
+             if (pObjData^.ID=OBJHANDLE_STR)
+             then Result :=pObjData^.Obj;
+        end;
+     except
+     end;
+end;
+
+
+//=== Methods Access methods ===================================================
+function Lua_TObject_Methods(L: Plua_State): Integer; cdecl;
+var
+  NParams,
+  iParams,
+  invParams    :Integer;
+  theParams    :array of Variant;
+  xResult      :Variant;
+  ParamISOBJ   :Boolean;
+  MethodName   :String;
+  curComponent :TObject;
+  NewObj,
+  LuaObj       :TLuaObject;
+  PropSetData  :TLuaSetPropData;
+  retValue     :Variant;
+
+begin
+     Result :=0;
+     NParams := lua_gettop(L);
+     try
+        LuaObj :=GetTLuaObject(L, 1);
+
+        MethodName :=LuaGetCurrentFuncName(L);
+
+        //Fill Params for Method call in inverse sequense (why???)
+        SetLength(theParams, (NParams-1));
+        invParams :=0;
+        for iParams :=NParams downto 2  do
+        begin
+             //If Param[iParams] is an Object get it's real value
+             ParamISOBJ :=false;
+             NewObj :=GetTLuaObject(L, iParams);
+             ParamISOBJ :=(NewObj<>nil);
+
+             if ParamISOBJ
+             then xResult :=Integer(NewObj.InstanceObj)
+             else begin
+                       if Lua_IsPropertySet(L, iParams)
+                       then begin
+                                 xResult :=GetPropertySet(@PropSetData, L, iParams);
+                                 //try to convert string value to Real Set Value
+                                 if (PropSetData.Info<>nil)
+                                 then xResult :=StringToSet(PropSetData.Info, xResult);
+                            end
+                       else xResult :=LuaToVariant(L, iParams);
+                  end;
+             theParams[invParams] :=xResult;
+             inc(invParams);
+        end;
+
+        retValue := LuaObj.CallMethod(MethodName, theParams, true);
+        if (retValue<>NULL)
+        then begin
+                  //TO-DO : PushVariant è riduttivo, potrebbe tornare un oggetto etc...
+                  //        Fare una procedura simile a PushProperty
+                  LuaPushVariant(L, retValue);
+                  Result :=1;
+             end;
+
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+function Lua_TObject_GetProp(L: Plua_State): Integer; cdecl; forward;
+function Lua_TObject_SetProp(L: Plua_State): Integer; cdecl; forward;
+function Lua_TObject_Free(L: Plua_State): Integer; cdecl; forward;
+
+function LuaPush_TLuaObject(L :Plua_State; theParams :array of Variant;
+                            Obj :TObject=nil; ObjClassName :String='';
+                            CanFree :Boolean=True) :boolean;
+var
+  NParams,
+  iParams      :Integer;
+  xResult      :Variant;
+  retValue     :Variant;
+  ClassData    :PLuaClassesListData;
+  LuaObj       :TLuaObject;
+  NewObj       :TObject;
+  CanCreate    :Boolean;
+  LuaClass     :TLuaObjectClass;
+  pObjData     :PLuaObjectData;
+  scripter :TScriptableObject;
+
+begin
+     Result :=false;
+
+     CanCreate := (Obj=nil);
+
+     if CanCreate
+     then ClassData :=LuaClassesList.Find(ObjClassName)
+     else ClassData :=LuaClassesList.Find(Obj.ClassType);
+
+     if (ClassData=nil)
+     then LuaClass :=TLuaObject
+     else LuaClass :=ClassData^.LuaClass;
+
+     //lua_newtable(L);
+     pObjData :=lua_newuserdata(L, sizeof(TLuaObjectData));
+
+     if CanCreate
+     then begin
+               if (LuaClass<>nil)
+               then begin
+                         LuaObj :=LuaClass.Create(nil, false);
+                         theParams[High(theParams)] :=Integer(ClassData^.ObjClass);
+                         
+                         try
+                            retValue :=LuaObj.CallMethod('LuaCreate', theParams, true);
+                            if (retValue<>NULL)
+                            then NewObj :=TObject(Integer(retValue))
+                            else NewObj :=ClassData^.ObjClass.Create;
+                         except
+                            NewObj :=ClassData^.ObjClass.Create;
+                         end;
+                         LuaObj.Free;
+                         LuaObj :=LuaClass.Create(NewObj, CanFree);
+                    end
+               else begin
+                         NewObj :=ClassData^.ObjClass.Create;
+                         LuaObj :=LuaClass.Create(NewObj, CanFree);
+                    end;
+          end
+     else begin
+               if (LuaClass<>nil)
+               then LuaObj :=LuaClass.Create(Obj, false)
+               else LuaObj :=TLuaObject.Create(Obj, false);
+          end;
+
+     pObjData^.ID :=OBJHANDLE_STR;
+     pObjData^.Obj :=LuaObj;
+     LuaSetTablePropertyFuncs(L, -1, Lua_TObject_GetProp, Lua_TObject_SetProp);
+     LuaSetMetaFunction(L, -1, '__gc', Lua_TObject_Free);
+
+     Result :=true;
+end;
+
+//=== Properties Access methods ================================================
+
+
+//NON FUNZIONA!!!!!!! PERCHE' FA LA LISTA SOLO DELLE PROPERTY PUBLISHED
+function FindPredefArrayProp(AComponent :TObject):String;
+Var
+   Props       :PPropList;
+   i, n        :Integer;
+   curPropInfo :PPropInfo;
+
+begin
+     Result :='';
+     n :=GetPropList(AComponent, Props);
+     for i:=0 to n-1 do
+     begin
+          curPropInfo :=PPropInfo(Props^[i]);
+          if ((curPropInfo^.Default and $80000000)<>0) and
+             (curPropInfo^.PropType^^.Kind = tkArray)
+          then begin
+                    Result :=curPropInfo^.Name;
+               end;
+     end;
+end;
+
+function Lua_TObject_GetProp(L: Plua_State): Integer; cdecl;
+Var
+   ty           :Integer;
+   PropName     :String;
+   PropValue    :Variant;
+   PropInfo     :PPropInfo;
+   PropType     :PTypeInfo;
+   GetPropOK    :Boolean;
+   NParams      :Integer;
+   ClassData    :PLuaClassesListData;
+   LuaObj       :TLuaObject;
+   NewObj       :TObject;
+
+  function TryGetProp(AComponent :TObject; PropName :String; PropKind :TTypeKinds):Boolean;
+  Var
+     AsString :Boolean;
+
+  begin
+       Result :=false;
+       try
+          PropInfo :=GetPropInfo(AComponent, PropName, PropKind);
+          if (PropInfo<>nil)
+          then begin //This Name is a Property
+                    PropType :=PropInfo^.PropType^;
+
+                    //Return as String only if the property is a Set or an Enum, exclude the Boolean
+                    if (PropType^.Kind=tkEnumeration)
+                    then AsString := not(GetTypeData(PropType)^.BaseType^ = TypeInfo(Boolean))
+                    else AsString := (PropType^.Kind=tkSet);
+
+                    PropValue :=GetPropValue(AComponent, PropInfo, AsString);
+
+                    Result :=true;
+               end;
+       except
+       end;
+  end;
+
+  function TryGetPublicProp:Boolean;
+  Var
+     AsString :Boolean;
+
+  begin
+       Result :=false;
+       try
+          PropInfo :=LuaObj.GetPublicPropInfo(PropName);
+          if (PropInfo<>nil)
+          then begin //This Name is a Property
+                    PropType :=PropInfo^.PropType^;
+
+                    //Return as String only if the property is a Set or an Enum, exclude the Boolean
+                    if (PropType^.Kind=tkEnumeration)
+                    then AsString := not(GetTypeData(PropType)^.BaseType^ = TypeInfo(Boolean))
+                    else AsString := (PropType^.Kind=tkSet);
+
+                    if (PropType^.Kind<>tkArray)
+                    then PropValue :=GetPropValue(LuaObj.InstanceObj, PropInfo, AsString);
+
+                    Result :=true;
+               end;
+       except
+       end;
+  end;
+
+  procedure GetPredefArrayProp(Index: Integer);
+  var
+    indice :Variant;
+
+  begin
+       GetPropOK :=false;
+       try
+          indice :=LuaToVariant(L, Index);
+          PropName :=LuaObj.GetDefaultArrayProp;
+          PropType :=LuaObj.GetArrayPropType(PropName, indice);
+
+          GetPropOK := (PropType<>nil);
+       except
+       end;
+
+       if GetPropOK
+       then PropValue :=LuaObj.GetArrayProp(PropName, indice)
+       else PropValue :=NULL;
+  end;
+
+
+begin
+     Result := 0;
+     GetPropOK := false;
+     NParams := lua_gettop(L);
+
+     if (NParams>0) then
+     try
+        LuaObj :=GetTLuaObject(L, 1);
+
+        ty := lua_type(L, 2);
+        if (ty = LUA_TNUMBER)
+        then GetPredefArrayProp(2)
+        else begin
+                  PropName :=LuaToString(L, 2);
+
+                  GetPropOK :=TryGetProp(LuaObj, PropName, tkProperties);
+                  if not(GetPropOK)
+                  then begin  //Is not a Property published in the TLuaObject, try the TObject
+                            GetPropOK :=TryGetProp(LuaObj.InstanceObj, PropName, tkProperties);
+
+                            if not(GetPropOK)
+                            then begin  //Try with public Properties using scripter.GetPublicXXX
+                                      GetPropOK :=TryGetPublicProp;
+                                 end;
+
+
+                            if not(GetPropOK)
+                            then begin  //Try with public elements using scripter.GetElementXXX
+                                      try
+                                         PropType :=LuaObj.GetElementType(PropName);
+                                         GetPropOK := (PropType<>nil);
+                                      except
+                                      end;
+
+                                      if GetPropOK and (PropType^.Kind<>tkArray)
+                                      then PropValue :=LuaObj.GetElement(PropName);
+                                 end;
+                       end;
+             end;
+
+        if (GetPropOK)
+        then begin //This Name is a Property
+                  Result :=PushProperty(L, LuaObj, PropName, PropValue, PropType);
+             end
+        else begin //This Name may be a Method or an Event ???????????
+                   //TO-DO : Testare se è un evento (OnXXXX), in questo caso
+                   //        tornare l' eventuale nome della funzione lua
+
+                   // (this code is for method)
+                   LuaRawSetTableNil(L, 1, PropName);
+                   LuaRawSetTableFunction(L, 1, PropName, Lua_TObject_Methods);
+
+                   lua_pushcfunction(L, Lua_TObject_Methods);
+                   Result := 1;
+             end;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+
+//      TObject:SetProp(string PropName, variant Value)      set Property Value.
+function Lua_TObject_SetProp(L: Plua_State): Integer; cdecl;
+Var
+   curComponent :TObject;
+   ty           :Integer;
+   PropName     :String;
+   PropInfo     :PPropInfo;
+   PropType     :PTypeInfo;
+   SetPropOK    :Boolean;
+   NewVal       :Variant;
+   NParams      :Integer;
+   ClassData    :PLuaClassesListData;
+   LuaObj       :TLuaObject;
+   NewObj       :TLuaObject;
+   NewValISPropertySet,
+   NewValISOBJ  :Boolean;
+   PropertySetData :TLuaSetPropData;
+
+  function TrySetProp(AComponent :TObject; PropName :String; PropKind :TTypeKinds):Boolean;
+  begin
+       Result :=false;
+       try
+          PropInfo :=GetPropInfo(AComponent, PropName, PropKind);
+          if (PropInfo<>nil)
+          then begin //This Name is a Property
+                    curComponent :=AComponent;
+                    PropType :=PropInfo^.PropType^;
+                    Result :=true;
+               end;
+       except
+       end;
+  end;
+
+  function TrySetPublicProp:Boolean;
+  begin
+       Result :=false;
+       try
+          PropInfo :=LuaObj.GetPublicPropInfo(PropName);
+          if (PropInfo<>nil)
+          then begin //This Name is a Property
+                    curComponent :=LuaObj.InstanceObj;
+                    PropType :=PropInfo^.PropType^;
+                    Result :=true;
+               end;
+       except
+       end;
+  end;
+
+  procedure SetPredefArray(Index: Integer);
+  var
+    indice :Variant;
+
+  begin
+       indice :=LuaToVariant(L, Index);
+       PropName :=LuaObj.GetDefaultArrayProp;
+       PropType :=LuaObj.GetArrayPropType(PropName, indice);
+
+       if (PropType^.Kind=tkClass)
+       then begin
+                 if NewValISOBJ
+                 then LuaObj.SetArrayProp(PropName, indice, Integer(NewObj.InstanceObj))
+                 else raise Exception.Createfmt('Cannot assign %s to %s.%s', [NewVal, curComponent.ClassName, PropName]);
+            end
+       else LuaObj.SetArrayProp(PropName, indice, NewVal);
+  end;
+
+
+begin
+     Result := 0;
+
+     ty :=lua_type(L, 3);
+     if (ty <> LUA_TFUNCTION) then
+     try
+        LuaObj :=GetTLuaObject(L, 1);
+
+        //If the new Value is an Object get it's real value
+        NewValISOBJ :=false;
+        NewObj :=GetTLuaObject(L, 3);
+        NewValISOBJ :=(NewObj<>nil);
+
+        if not(NewValISOBJ)
+        then begin
+                  NewValISPropertySet :=Lua_IsPropertySet(L, 3);
+                  if NewValISPropertySet
+                  then NewVal :=GetPropertySet(@PropertySetData, L, 3)
+                  else NewVal :=LuaToVariant(L, 3);
+             end;
+
+        ty := lua_type(L, 2);
+        if (ty = LUA_TNUMBER)
+        then SetPredefArray(2)
+        else begin
+                  PropName :=LuaToString(L, 2);
+
+                  SetPropOK :=TrySetProp(LuaObj, PropName, tkProperties);
+                  if not(SetPropOK)
+                  then begin  //Is not a Property published in the TLuaObject, try the TObject
+                            SetPropOK :=TrySetProp(LuaObj.InstanceObj, PropName, tkProperties);
+
+                            if not(SetPropOK)
+                            then begin //Try with public Properties using scripter.GetPublicPropInfo
+                                      SetPropOK :=TrySetPublicProp;
+                                 end;
+
+                            if not(SetPropOK)
+                            then begin  //Try with public elements using scripter.SetElementXXX
+                                      try
+                                         PropType :=LuaObj.GetElementType(PropName);
+                                         SetPropOK := (PropType<>nil);
+                                      except
+                                      end;
+
+                                      if SetPropOK then
+                                      begin
+                                           if (PropType^.Kind=tkClass)
+                                           then begin
+                                                     if NewValISOBJ
+                                                     then LuaObj.SetElement(PropName, Integer(NewObj.InstanceObj))
+                                                     else raise Exception.Createfmt('Cannot assign %s to %s.%s', [NewVal, LuaObj.InstanceObj.ClassName, PropName]);
+                                                end
+                                           else begin
+                                                     if NewValISPropertySet  //convert string to real Value
+                                                     then NewVal :=StringToSet(PropertySetData.Info, NewVal);
+                                                     LuaObj.SetElement(PropName, NewVal);
+                                                end;
+                                           Exit;
+                                      end;
+                                 end;
+                       end;
+
+                  if SetPropOK
+                  then begin
+                            if (PropType^.Kind=tkClass)
+                            then begin
+                                      if NewValISOBJ
+                                      then MySetPropValue(curComponent, PropInfo, Integer(NewObj.InstanceObj))
+                                      else raise Exception.Createfmt('Cannot assign %s to %s.%s', [NewVal, curComponent.ClassName, PropName]);
+                                 end
+                            else MySetPropValue(curComponent, PropInfo, NewVal);
+                       end
+                  else begin //This Name may be a Method or an Event ???????????
+                   //TO-DO : se è un evento potremmo mantenere una Lista
+                   //        che associa un oggetto con il nome di una
+                   //        funzione Lua. Settiamo come evento un
+                   //        nostro metodo che cerca nella Lista l' oggetto
+                   //        e chiama la relativa funzione lua
+                       end;
+             end;
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                          end;
+
+     end;
+end;
+
+
+//      TObject:Free()                                          free the object.
+function Lua_TObject_Free(L: Plua_State): Integer; cdecl;
+Var
+   theObject    :TLuaObject;
+   NParams      :Integer;
+
+begin
+     Result := 0;
+
+     NParams := lua_gettop(L);
+     if (NParams=1)
+     then begin
+               try
+                  theObject :=GetTLuaObject(L, 1);
+
+                  //LuaEventsList.Del(theObject.InstanceObj);
+
+                  theObject.Free;
+                  //LuaSetTableClear(L, 1);
+
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+//==============================================================================
+// Main Functions
+
+function Lua_CreateObject(L: Plua_State): Integer; cdecl;
+var
+  NParams,
+  iParams,
+  invParams    :Integer;
+  theParams    :array of Variant;
+  xResult      :Variant;
+  retValue     :PVariant;
+  ObjClassName :String;
+  ClassData    :PLuaClassesListData;
+  scripter     :TLuaObject;
+  NewObj       :TLuaObject;
+  CanFree,
+  ParamISOBJ   :Boolean;
+  PropSetData  :TLuaSetPropData;
+
+begin
+     Result :=0;
+     NParams := lua_gettop(L);
+     if (NParams>1)
+     then begin
+               try
+                  ObjClassName :=LuaToString(L, 1);
+                  CanFree :=LuaToBoolean(L, 2);
+
+                  //Fill Params for Create call in inverse sequense (why???)
+                  SetLength(theParams, NParams-1);
+                  invParams :=0;
+                  for iParams :=NParams downto 3  do
+                  begin
+                       //If Param[iParams] is an Object get it's real value
+                       ParamISOBJ :=false;
+                       NewObj :=GetTLuaObject(L, iParams);
+                       ParamISOBJ :=(NewObj<>nil);
+
+                       if ParamISOBJ
+                       then xResult :=Integer(NewObj.InstanceObj)
+                       else begin
+                                 if Lua_IsPropertySet(L, iParams)
+                                 then begin
+                                           xResult :=GetPropertySet(@PropSetData, L, iParams);
+                                           //try to convert string value to Real Set Value
+                                           if (PropSetData.Info<>nil)
+                                           then xResult :=StringToSet(PropSetData.Info, xResult);
+                                      end
+                                 else xResult :=LuaToVariant(L, iParams);
+                            end;
+                            
+                       theParams[invParams] :=xResult;
+                       inc(invParams);
+                  end;
+                  //LuaPush_TLuaObject sets the last parameter with the Class
+                  theParams[invParams] :=1234;
+
+                  if LuaPush_TLuaObject(L, theParams, nil, ObjClassName, CanFree)
+                  then Result :=1
+                  else raise Exception.Createfmt('Cannot Create class %s', [ObjClassName])
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+
+function Lua_GetObject(L: Plua_State): Integer; cdecl;
+var
+  NParams,
+  iParams,
+  invParams    :Integer;
+  theParams    :array of Variant;
+  xResult      :Variant;
+  retValue     :PVariant;
+  ObjName      :String;
+  ObjData      :PLuaExistingObjListData;
+  scripter     :TLuaObject;
+  NewObj       :TObject;
+
+begin
+     Result :=0;
+     NParams := lua_gettop(L);
+     if (NParams>0)
+     then begin
+               try
+                  ObjName :=LuaToString(L, 1);
+
+                  ObjData := LuaExistingObjList.Find(ObjName);
+                  if (ObjData<>nil)
+                  then begin
+                            if LuaPush_TLuaObject(L, [], ObjData^.Obj)
+                            then Result :=1
+                            else raise Exception.Createfmt('Cannot Interface with class %s', [ObjData^.Obj.ClassName]);
+                       end
+                  else raise Exception.Createfmt('Object "%s" not found', [ObjName]);
+               except
+                  On E:Exception do begin
+                                       LuaError(L, ERR_Script+E.Message);
+                                    end;
+               end;
+          end;
+end;
+
+
+procedure RegisterFunctions(L: Plua_State);
+begin
+     LuaRegister(L, 'CreateObject', Lua_CreateObject);
+     LuaRegister(L, 'GetObject', Lua_GetObject);
+end;
+
+procedure RegisterClass(ObjClass :TClass; LuaClass :TLuaObjectClass=nil);
+begin
+     LuaClassesList.Add(ObjClass, LuaClass);
+end;
+
+procedure RegisterObject(Obj :TObject; Name :String; LuaClass :TLuaObjectClass=nil);
+begin
+     LuaExistingObjList.Add(Obj, Name);
+     LuaClassesList.Add(Obj.ClassType, LuaClass);
+end;
+
+initialization
+   LuaClassesList :=TLuaClassesList.Create;
+   LuaExistingObjList :=TLuaExistingObjList.Create;
+
+finalization
+   LuaClassesList.Free;
+   LuaExistingObjList.Free;
+
+end.

+ 720 - 0
LuaEdit/LuaCore/Lua_VCL.pas

@@ -0,0 +1,720 @@
+// ATTENZIONE
+// Obsoleta, lasciata per compatibilità finchè non si conclude Lua_Object etc...
+
+
+
+//******************************************************************************
+//***                     LUA SCRIPT FUNCTIONS                               ***
+//***                                                                        ***
+//***        (c) Massimo Magnano 2005                                        ***
+//***                                                                        ***
+//***                                                                        ***
+//******************************************************************************
+//***                                                                        ***
+//***  Unit : Lua_VCL.pas                                                    ***
+//***                                                                        ***
+//***     Functions to Get\Set Properties of a Component from Lua Scripts.   ***
+//***     Register component that can be public using AddPublicComponent,    ***
+//***     you can add as public "Application" but i think is not a good idea.***
+//***                                                                        ***
+//******************************************************************************
+//  Exported functions :
+//
+//   GetVCLObject {Name=string}                           return TObject object.
+//      TObject:GetProp(string PropName)       return Property Value as Variant.
+//      TObject:SetProp(string PropName, variant Value)      set Property Value.
+//
+//   CreateVCLObject {ClassName=string}             Create a new TObject object. not yet implemented
+//      TObject:Free()              Free a TObject created with CreateComponent. not yet implemented
+//
+//   GetProp(string FullPropName)              return Property Value as Variant.
+//   SetProp(string FullPropName, variant Value)             set Property Value.
+
+
+unit Lua_VCL;
+
+interface
+
+uses Lua, LuaUtils, Classes;
+
+const
+     LUAVCL_ACCESS_DENY  = 0;
+     LUAVCL_ACCESS_READ  = 1;
+     LUAVCL_ACCESS_WRITE = 2;
+     LUAVCL_ACCESS_READWRITE = LUAVCL_ACCESS_READ or LUAVCL_ACCESS_WRITE;
+
+type
+    TLuaVCLAccess = Integer; //LUAVCL_ACCESS_XXXX Constants
+
+procedure RegisterFunctions(L: Plua_State);
+procedure AddPublicComponent(AComponent :TObject;
+                             ALuaName :String;
+                             AccessRights :TLuaVclAccess=LUAVCL_ACCESS_READ);
+procedure DelPublicComponent(AComponent :TObject); overload;
+procedure DelPublicComponent(ALuaName :String); overload;
+
+procedure AddPublicProperty(AComponent :TObject; APropName :String;
+                            ALuaName :String; AccessRights :TLuaVclAccess);
+procedure DelPublicProperty(AComponent :TObject; APropName :String); overload;
+procedure DelPublicProperty(ALuaName :String); overload;
+function  GetPublicPropertyAccess(AComponent :TObject; APropName :String) :TLuaVCLAccess;
+procedure SetPublicPropertyAccess(AComponent :TObject; APropName :String;
+                                  AccessRights :TLuaVclAccess);
+
+
+implementation
+
+uses MGList, SysUtils, TypInfo;
+
+const
+     HandleVCLObjectStr = 'HandleVCLObject';
+     ERR_Script         = 'Script Error : ';
+     ERR_ACCESS_DENIED  = 'Access Denied Property %s.%s';
+     ERR_UNKNOWN_OBJECT = 'Unknown VCLObject %s';
+     ERR_UNKNOWN_PROP   = 'Unknown Property';
+
+
+Type
+    //Classe che mantiene la lista delle associazioni Lua->TObject
+    TObjectNameData = record
+        LuaName            :String;
+        AccessRights       :TLuaVclAccess;
+        Component          :TObject;
+    end;
+    PComponentNameData =^TObjectNameData;
+
+    TObjectNameList = class(TMGList)
+    protected
+       function allocData :Pointer; override;
+       procedure deallocData(pData :Pointer); override;
+
+       function CompByComponent(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+       function CompByLuaName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+    public
+       function Add(AComponent :TObject;
+                    ALuaName :String; AccessRights :TLuaVclAccess) :PComponentNameData; overload;
+       function Find(AComponent :TObject): Integer; overload;
+       function ExtFind(AComponent :TObject): PComponentNameData; overload;
+       procedure GetAccessRights(AComponent :TObject;
+                                 var AccessRights: TLuaVclAccess);
+       function Find(ALuaName :String): TObject; overload;
+       function ExtFind(ALuaName :String): PComponentNameData; overload;
+       function Delete(ALuaName :String) :Boolean; overload;
+       function Delete(AComponent :TObject) :Boolean; overload;
+    end;
+
+    //Classe che mantiene la lista delle associazioni Lua-> (Component Property)
+    TPropertyNameData = record
+        LuaName            :String;
+        AccessRights       :TLuaVclAccess;
+        Component          :TObject;
+        PropName           :String;
+    end;
+    PPropertyNameData =^TPropertyNameData;
+
+    TPropertyNameList = class(TMGList)
+    protected
+       function allocData :Pointer; override;
+       procedure deallocData(pData :Pointer); override;
+
+       function CompByCompPropName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+       function CompByLuaName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+    public
+       function Add(AComponent :TObject; APropName :String;
+                    ALuaName :String; AccessRights :TLuaVclAccess) :PPropertyNameData; overload;
+       function ExtFind(AComponent :TObject; APropName :String): PPropertyNameData; overload;
+       function ExtFind(ALuaName :String): PPropertyNameData; overload;
+       function Delete(ALuaName :String) :Boolean; overload;
+       function Delete(AComponent :TObject; APropName :String) :Boolean; overload;
+    end;
+
+
+Var
+   ComponentNameList : TObjectNameList =Nil;
+   PropertyNameList  : TPropertyNameList  =Nil;
+
+procedure ProcessDot(var xFullName, ChildName :String);
+Var
+   xPos :Integer;
+
+begin
+     xPos :=Pos('.', xFullName);
+     if (xPos>0)
+     then begin
+               ChildName :=Copy(xFullName, 1, xPos-1);
+               Delete(xFullname, 1, xPos);
+          end
+     else begin
+               ChildName :=xFullName;
+               xFullName :='';
+          end;
+end;
+
+//==============================================================================
+//  TObjectNameList Class
+//==============================================================================
+
+function TObjectNameList.allocData :Pointer;
+begin
+     GetMem(Result, SizeOf(TObjectNameData));
+     FillChar(PComponentNameData(Result)^, SizeOf(TObjectNameData), 0);
+     PComponentNameData(Result)^.LuaName :='';
+end;
+
+procedure TObjectNameList.deallocData(pData :Pointer);
+begin
+     PComponentNameData(pData)^.LuaName :='';
+     FreeMem(pData, SizeOf(TObjectNameData));
+end;
+
+function TObjectNameList.CompByComponent(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+begin
+     Result := (TObject(ptData1)=PComponentNameData(ptData2)^.Component);
+end;
+
+function TObjectNameList.CompByLuaName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+begin
+     Result := (PChar(ptData1)=PComponentNameData(ptData2)^.LuaName);
+end;
+
+function TObjectNameList.Add(AComponent :TObject;
+             ALuaName :String; AccessRights :TLuaVclAccess) :PComponentNameData;
+begin
+     if (ALuaName<>'')
+     then Result :=ExtFind(ALuaName)
+     else Result :=ExtFind(AComponent);
+     if (Result=Nil)
+     then Result :=Add;
+
+     if (Result<>Nil)
+     then begin
+               Result^.Component :=AComponent;
+               if (ALuaName<>'')
+               then Result^.LuaName :=Uppercase(ALuaName);
+               Result^.AccessRights :=AccessRights;
+          end;
+end;
+
+function TObjectNameList.Find(AComponent :TObject): Integer;
+begin
+     Result :=Find(Pointer(AComponent), 0, CompByComponent);
+end;
+
+function TObjectNameList.ExtFind(AComponent :TObject): PComponentNameData;
+begin
+     if (AComponent<>Nil)
+     then Result :=ExtFind(Pointer(AComponent), 0, CompByComponent)
+     else Result :=Nil;
+end;
+
+function TObjectNameList.Find(ALuaName :String): TObject;
+Var
+   theComp :PComponentNameData;
+
+begin
+     Result := Nil;
+     theComp := ExtFind(ALuaName);
+     if (theComp<>Nil)
+     then Result := theComp^.Component;
+end;
+
+function TObjectNameList.ExtFind(ALuaName :String): PComponentNameData;
+begin
+     Result :=ExtFind(PChar(Uppercase(ALuaName)), 0, CompByLuaName);
+end;
+
+function TObjectNameList.Delete(AComponent :TObject) :Boolean;
+begin
+     Result :=Delete(Pointer(AComponent), 0, CompByComponent);
+end;
+
+function TObjectNameList.Delete(ALuaName :String) :Boolean;
+begin
+     Result :=Delete(PChar(Uppercase(ALuaName)), 0, CompByLuaName);
+end;
+
+procedure TObjectNameList.GetAccessRights(AComponent :TObject;
+                                          var AccessRights: TLuaVclAccess);
+Var
+   xCompAccess :PComponentNameData;
+
+begin
+     xCompAccess :=Self.ExtFind(AComponent);
+     if (xCompAccess<>Nil)
+     then AccessRights :=xCompAccess^.AccessRights;
+end;
+
+//==============================================================================
+//  Components Registration\Deregistration
+//==============================================================================
+
+procedure AddPublicComponent(AComponent :TObject;
+                             ALuaName :String;
+                             AccessRights :TLuaVclAccess=LUAVCL_ACCESS_READ);
+begin
+     if (ComponentNameList=Nil)
+     then ComponentNameList := TObjectNameList.Create;
+
+     ComponentNameList.Add(AComponent, ALuaName, AccessRights);
+end;
+
+procedure DelPublicComponent(AComponent :TObject);
+begin
+     if (ComponentNameList<>Nil)
+     then begin
+               ComponentNameList.Delete(AComponent);
+               if (ComponentNameList.Count=0)
+               then begin
+                         ComponentNameList.Free;
+                         ComponentNameList :=Nil;
+                    end;
+          end;
+end;
+
+procedure DelPublicComponent(ALuaName :String); overload;
+begin
+     if (ComponentNameList<>Nil)
+     then begin
+               ComponentNameList.Delete(ALuaName);
+               if (ComponentNameList.Count=0)
+               then begin
+                         ComponentNameList.Free;
+                         ComponentNameList :=Nil;
+                    end;
+          end;
+end;
+
+//==============================================================================
+//     TPropertyNameList Class
+//==============================================================================
+
+function TPropertyNameList.allocData :Pointer;
+begin
+     GetMem(Result, SizeOf(TPropertyNameData));
+     FillChar(PPropertyNameData(Result)^, SizeOf(TPropertyNameData), 0);
+     PPropertyNameData(Result)^.PropName :='';
+     PPropertyNameData(Result)^.LuaName :='';
+end;
+
+procedure TPropertyNameList.deallocData(pData :Pointer);
+begin
+     PPropertyNameData(pData)^.PropName :='';
+     PPropertyNameData(pData)^.LuaName :='';
+     FreeMem(pData, SizeOf(TPropertyNameData));
+end;
+
+function TPropertyNameList.CompByCompPropName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+begin
+     Result := (PPropertyNameData(ptData1)^.Component=PPropertyNameData(ptData2)^.Component) and
+               (PPropertyNameData(ptData1)^.PropName=PPropertyNameData(ptData2)^.PropName);
+end;
+
+function TPropertyNameList.CompByLuaName(Tag :Integer; ptData1, ptData2 :Pointer) :Boolean;
+begin
+     Result := (PChar(ptData1)=PPropertyNameData(ptData2)^.LuaName);
+end;
+
+function TPropertyNameList.Add(AComponent :TObject; APropName :String;
+                    ALuaName :String; AccessRights :TLuaVclAccess) :PPropertyNameData;
+begin
+     Result :=ExtFind(AComponent, APropName);
+     if (Result=Nil)
+     then Result :=Add;
+
+     if (Result<>Nil)
+     then begin
+               Result^.Component :=AComponent;
+               Result^.PropName :=Uppercase(APropName);
+               Result^.LuaName :=Uppercase(ALuaName);
+               Result^.AccessRights :=AccessRights;
+          end;
+end;
+
+function TPropertyNameList.ExtFind(AComponent :TObject; APropName :String): PPropertyNameData;
+Var
+   aux :PPropertyNameData;
+
+begin
+     if (AComponent<>Nil)
+     then begin
+               aux :=allocData;
+               aux^.Component :=AComponent;
+               aux^.PropName :=Uppercase(APropName);
+
+               Result :=ExtFind(aux, 0, CompByCompPropName);
+
+               deallocData(aux);
+          end
+     else Result :=Nil;
+end;
+
+function TPropertyNameList.ExtFind(ALuaName :String): PPropertyNameData;
+begin
+     Result :=ExtFind(PChar(Uppercase(ALuaName)), 0, CompByLuaName);
+end;
+
+function TPropertyNameList.Delete(ALuaName :String) :Boolean;
+begin
+     Result :=Delete(PChar(Uppercase(ALuaName)), 0, CompByLuaName);
+end;
+
+function TPropertyNameList.Delete(AComponent :TObject; APropName :String) :Boolean;
+Var
+   aux :PPropertyNameData;
+
+begin
+     aux :=allocData;
+     aux^.Component :=AComponent;
+     aux^.PropName :=Uppercase(APropName);
+
+     Result :=Delete(aux, 0, CompByCompPropName);
+
+     deallocData(aux);
+end;
+
+//==============================================================================
+//  Properties Registration\Deregistration, AccessRights
+//==============================================================================
+
+procedure AddPublicProperty(AComponent :TObject; APropName :String;
+                            ALuaName :String; AccessRights :TLuaVclAccess);
+begin
+     if (PropertyNameList=Nil)
+     then PropertyNameList := TPropertyNameList.Create;
+     PropertyNameList.Add(AComponent, APropName, ALuaName, AccessRights);
+end;
+
+procedure DelPublicProperty(AComponent :TObject; APropName :String); overload;
+begin
+     if (PropertyNameList<>Nil)
+     then begin
+               PropertyNameList.Delete(AComponent, APropName);
+               if (PropertyNameList.Count=0)
+               then begin
+                         PropertyNameList.Free;
+                         PropertyNameList :=Nil;
+                    end;
+          end;
+end;
+
+procedure DelPublicProperty(ALuaName :String); overload;
+begin
+     if (PropertyNameList<>Nil)
+     then begin
+               PropertyNameList.Delete(ALuaName);
+               if (PropertyNameList.Count=0)
+               then begin
+                         PropertyNameList.Free;
+                         PropertyNameList :=Nil;
+                    end;
+          end;
+end;
+
+function  GetPublicPropertyAccess(AComponent :TObject; APropName :String) :TLuaVCLAccess;
+Var
+   xProp :PPropertyNameData;
+   xComp :PComponentNameData;
+
+begin
+     Result :=LUAVCL_ACCESS_DENY;
+     xProp :=Nil;
+     if (AComponent=Nil)
+     then Exit;
+
+     //Find Property AccessRights for this property
+     if (APropName<>'') and (PropertyNameList<>Nil)
+     then begin
+               xProp :=PropertyNameList.ExtFind(AComponent, APropName);
+               if (xProp<>Nil)
+               then Result :=xProp^.AccessRights;
+          end;
+     if (xProp=Nil) and (ComponentNameList<>Nil)
+     then begin
+               //If not Find Property AccessRights for this property, Try with it's component
+               xComp :=ComponentNameList.ExtFind(AComponent);
+               if (xComp<>Nil)
+               then Result :=xComp^.AccessRights;
+          end;
+end;
+
+procedure SetPublicPropertyAccess(AComponent :TObject; APropName :String;
+                                  AccessRights :TLuaVclAccess);
+begin
+     AddPublicProperty(AComponent, APropName, APropName, AccessRights);
+end;
+
+
+//==============================================================================
+//  Lua Interface  : Components Property
+//==============================================================================
+
+function GetComponentByFullPath(FullCompName: String;
+                                var AccessRights :TLuaVCLAccess):TObject;
+Var
+   xNewParent  :TObject;
+   xParent     :TObject;
+   xFullName,
+   ChildName   :String;
+   xCompAccess :PComponentNameData;
+
+begin
+     xFullName :=FullCompName;
+     AccessRights :=LUAVCL_ACCESS_DENY;
+
+     ProcessDot(xFullName, ChildName);
+     xCompAccess :=ComponentNameList.ExtFind(ChildName);
+     if (xCompAccess<>Nil)
+     then begin
+               xParent :=xCompAccess^.Component;
+               AccessRights :=xCompAccess^.AccessRights;
+           end
+     else xParent :=Nil;
+
+     while (xParent<>Nil) and (xFullName<>'') do
+     begin
+       try
+          xNewParent :=Nil;
+          ProcessDot(xFullName, ChildName);
+
+          //Try find in Components
+          if (xParent is TComponent)
+          then xNewParent :=TComponent(xParent).FindComponent(ChildName);
+          if (xNewParent=Nil)
+          then begin  //Try find in Class Properties
+                    if (PropType(xParent, ChildName)=tkClass)
+                    then xNewParent :=TObject(GetOrdProp(xParent, ChildName));
+               end;
+
+          xCompAccess :=ComponentNameList.ExtFind(xNewParent);
+          if (xCompAccess<>Nil)
+          then AccessRights :=xCompAccess^.AccessRights;
+
+          xParent :=xNewParent;
+        except
+           xParent :=Nil;
+        end;
+     end;
+     Result :=xParent;
+end;
+
+function GetPropertyByFullPath(FullPropName: String;
+                       var ResultComponent :TObject;
+                       var AccessRights    :TLuaVCLAccess):String;
+Var
+   xNewParent  :TObject;
+   xPropType   :TTypeKind;
+   xFullName,
+   ChildName   :String;
+   xCompAccess :PComponentNameData;
+   xPropAccess :PPropertyNameData;
+
+begin
+     Result :='';
+     xFullName :=FullPropName;
+     xPropType :=tkUnknown;
+
+     if (ResultComponent=Nil)
+     then begin
+               //No Parent Object specified, Find from Name
+               ProcessDot(xFullName, ChildName);
+               xCompAccess :=ComponentNameList.ExtFind(ChildName);
+               if (xCompAccess<>Nil)
+               then begin
+                         ResultComponent :=xCompAccess^.Component; //Convert possible Alias
+                         if (ResultComponent<>Nil)
+                         then xPropType :=tkClass;
+                         AccessRights :=xCompAccess^.AccessRights;
+                    end;
+          end
+     else xPropType :=tkClass; //If Parent specified AccessRights is controlled by GetVCLObject
+
+     while (ResultComponent<>Nil) and (xPropType=tkClass) do
+     begin
+        try
+          xNewParent :=Nil;
+          ProcessDot(xFullName, ChildName);
+
+          //Try find in Components
+          if (ResultComponent is TComponent)
+          then begin
+                    xNewParent :=TComponent(ResultComponent).FindComponent(ChildName);
+                    if (xNewParent<>Nil)
+                    then xPropType :=tkClass;
+               end;
+          if (xNewParent=Nil)
+          then begin  //Try find in Class Properties
+                    xPropType :=PropType(ResultComponent, ChildName);
+                    if (xPropType=tkClass)
+                    then xNewParent :=TObject(GetOrdProp(ResultComponent, ChildName));
+               end;
+
+          if (xPropType=tkClass)
+          then begin
+                    //Search if exists AccessRights for this Class
+                    xCompAccess :=ComponentNameList.ExtFind(xNewParent);
+                    if (xCompAccess<>Nil)
+                    then AccessRights :=xCompAccess^.AccessRights;
+
+                    ResultComponent :=xNewParent;
+               end;
+        except
+           ResultComponent :=Nil;
+        end;
+     end;
+     if (ResultComponent<>Nil) and (xPropType<>tkClass) and (Pos('.', ChildName)=0)
+     then begin
+               Result :=ChildName;
+
+               //Get Property AccessRights if Any
+               xPropAccess :=PropertyNameList.ExtFind(ResultComponent, ChildName);
+               if (xPropAccess<>Nil)
+               then AccessRights :=xPropAccess^.AccessRights;
+          end
+     else begin
+               Result :='';
+               ResultComponent :=Nil;
+          end;
+end;
+
+
+function LuaToTObject(L: Plua_State; Index: Integer): TObject;
+begin
+     try
+        Result :=TObject(LuaGetTableLightUserData(L, Index, HandleVCLObjectStr));
+     except
+        Result :=Nil;
+     end;
+end;
+
+function LuaToPropertyName(L: Plua_State;
+                       var Index: Integer;
+                       var ResultComponent :TObject;
+                       var AccessRights    :TLuaVCLAccess):String;
+begin
+     Result :='';
+     ResultComponent :=Nil;
+     AccessRights :=LUAVCL_ACCESS_DENY;
+     Index :=1;
+
+     if lua_istable(L, Index)
+     then begin
+               //The First parameter is a TObject Table,
+               //  Property specified in the 2nd parameter start from this Class
+               ResultComponent := LuaToTObject(L, Index);
+               ComponentNameList.GetAccessRights(ResultComponent, AccessRights);
+               Inc(Index);     //Property is the 2nd parameter
+               if (ResultComponent=Nil) or
+                  (AccessRights=LUAVCL_ACCESS_DENY)
+               then Exit;      //Invalid Object or no Access
+          end;
+
+     if (lua_isString(L, Index)<>0)
+     then begin
+               Result := GetPropertyByFullPath(LuaToString(L, Index),
+                                               ResultComponent,
+                                               AccessRights);
+               Inc(Index);
+          end;
+end;
+
+//      TObject:GetProp(string PropName)       return Property Value as Variant.
+//   GetProp(string FullPropName)              return Property Value as Variant.
+function LuaGetProp(L: Plua_State): Integer; cdecl;
+Var
+   curComponent :TObject;
+   PropName     :String;
+   PropValue    :Variant;
+   PropRights   :TLuaVCLAccess;
+   Index        :Integer;
+
+begin
+     Result := 1;
+
+     try
+        PropName  := LuaToPropertyName(L, Index, curComponent, PropRights);
+        if (PropName='') or (curComponent=Nil)
+        then raise Exception.Create(ERR_UNKNOWN_PROP);
+
+        if ((PropRights and LUAVCL_ACCESS_READ)<>0)
+        then begin
+                  PropValue :=GetPropValue(curComponent, PropName);
+                  LuaPushVariant(L, PropValue);
+             end
+        else raise Exception.CreateFmt(ERR_ACCESS_DENIED, [curComponent.ClassName, PropName]);
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                               Result :=0;
+                          end;
+
+     end;
+end;
+
+//      TObject:SetProp(string PropName, variant Value)      set Property Value.
+//   SetProp(string FullPropName, variant Value)             set Property Value.
+function LuaSetProp(L: Plua_State): Integer; cdecl;
+Var
+   curComponent :TObject;
+   PropName     :String;
+   PropValue    :Variant;
+   PropRights   :TLuaVCLAccess;
+   Index        :Integer;
+
+begin
+     Result := 0;
+
+     try
+        PropName  := LuaToPropertyName(L, Index, curComponent, PropRights);
+        if (PropName='') or (curComponent=Nil)
+        then raise Exception.Create(ERR_UNKNOWN_PROP);
+
+        if ((PropRights and LUAVCL_ACCESS_WRITE)<>0)
+        then begin
+                  PropValue :=LuaToVariant(L, Index);
+                  SetPropValue(curComponent, PropName, PropValue);
+             end
+        else raise Exception.CreateFmt(ERR_ACCESS_DENIED, [curComponent.ClassName, PropName]);
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                               Result :=0;
+                          end;
+     end;
+end;
+
+function LuaGetVCLObject(L: Plua_State): Integer; cdecl;
+Var
+   ComponentName :String;
+   xResult       :TObject;
+   AccessRights  :TLuaVCLAccess;
+
+begin
+     Result := 1;
+
+     try
+        ComponentName :=LuaGetTableString(L, 1, 'Name');
+        LuaSetTableNil(L, 1, 'Name');
+        xResult := GetComponentByFullPath(ComponentName, AccessRights);
+        if (xResult=Nil) or (AccessRights=0)
+        then raise Exception.CreateFmt(ERR_UNKNOWN_OBJECT, [ComponentName]);
+
+        LuaSetTableLightUserData(L, 1, HandleVCLObjectStr, xResult);
+        LuaSetTableFunction(L, 1, 'GetProp', LuaGetProp);
+        LuaSetTableFunction(L, 1, 'SetProp', LuaSetProp);
+     except
+        On E:Exception do begin
+                               LuaError(L, ERR_Script+E.Message);
+                               Result :=0;
+                          end;
+
+     end;
+end;
+
+procedure RegisterFunctions(L: plua_State);
+begin
+     LuaRegister(L, 'GetVCLObject', LuaGetVCLObject);
+     LuaRegister(L, 'GetProp', LuaGetProp);
+     LuaRegister(L, 'SetProp', LuaSetProp);
+end;
+
+end.