------------------------------------------------------------------------------
--                                                                          --
--                 An Ada2005 binding to the Qt C++ library                 --
--                                                                          --
------------------------------------------------------------------------------
--                                                                          --
-- Copyright © 2007-2010 Vadim Godunko <vgodunko@gmail.com>                 --
--                                                                          --
-- QtAda is free software;  you can  redistribute it and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion. QtAda is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License distributed with QtAda;  see file COPYING.  If not, write --
-- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
-- Boston, MA 02110-1301, USA.                                              --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
------------------------------------------------------------------------------
--  This unit provide integration of the Ada tagged types into the Qt's meta
--  system.
--
--  It maintain three registries: registry for Ada proxy objects, Ada director
--  objects and Ada derived objects; and provide implementation for the
--  QObject::metaObject, QObject::qt_metacall and QObject::qt_metacast
--  methods.
--
--  Integration complitely hidden from the QtAda's users. All required
--  information for uesr define derived types generated by Ada-aware Meta
--  Object Compiler.
------------------------------------------------------------------------------
with Ada.Tags;
with Interfaces.C;
with System;

with Qt_Ada.Internals.Objects;
with Qt4.Meta_Objects;

package Qt_Ada.Internals.Object_Registry is

   type Q_Object_Meta_Descriptor;

   type Q_Object_Meta_Descriptor_Access is
     access constant Q_Object_Meta_Descriptor;

   function To_Q_Object
    (Item : not null access Qt_Ada.Internals.Objects.QObject)
       return not null access Qt_Ada.Internals.Objects.Q_Object_Base'Class;
   --  Convert specified C++ object to the corresponding Ada object. Creates
   --  proxy object if necessary.

   function To_Q_Object
    (Item        : not null access Qt_Ada.Internals.Objects.QObject;
     Known_Class : String)
       return not null access Qt_Ada.Internals.Objects.Q_Object_Base'Class;
   --  Convert specified C++ object to the corresponding Ada object. Creates
   --  proxy object if necessary. Create proxy of the Known_Class if detected
   --  class not a subclass of the Known_Class.

   function Meta_Descriptor (Item : Ada.Tags.Tag)
     return Q_Object_Meta_Descriptor_Access;
   --  Returns meta information descriptor for the tagged type with specified
   --  tag.

   --  Associate Ada proxy object with C++ object.

   --  Ada tagged type descriptor.

   type Q_Object_Meta_Descriptor is limited record
      Parent      : Q_Object_Meta_Descriptor_Access;
      Meta_Object : not null access constant Qt4.Meta_Objects.Q_Meta_Object;
      Meta_Cast   : not null access function
       (Self  : not null Qt_Ada.Internals.Objects.Q_Object_Base_Access;
        Class : String)
          return System.Address;
      Meta_Call   : not null access function
       (Self  : not null Qt_Ada.Internals.Objects.Q_Object_Base_Access;
        Kind : Qt4.Meta_Objects.Call;
        Id   : Qt4.Q_Integer;
        Args : Qt4.Address_Pointer)
          return Qt4.Q_Integer;
   end record;

   procedure Register_QObject_Derived_Type
    (Tag        : Ada.Tags.Tag;
     Descriptor : Q_Object_Meta_Descriptor_Access);

   --  Ada proxy object's constructor registry.

   type Q_Object_Proxy_Constructor is
     not null access function
      (Object : not null Qt_Ada.Internals.Objects.QObject_Access)
         return not null Qt_Ada.Internals.Objects.Q_Object_Base_Access;
   --  Returns new proxy object. Construction is responsible to establish
   --  Ada<->C++ objects association for all supported typed views to the
   --  specified object. This allows to support multiple inheritance,
   --  QObject/QGraphicsItem for example.

   type Qt_Metacast_Operation is
     not null access function
      (Self  : not null access Qt_Ada.Internals.Objects.QObject;
       Class : Interfaces.C.char_array)
         return System.Address;
   pragma Convention (C, Qt_Metacast_Operation);

   type Qt_Metacall_Operation is
     not null access function
      (Self : not null access Qt_Ada.Internals.Objects.QObject;
       Kind : Qt4.Meta_Objects.Call;
       Id   : Qt4.Q_Integer;
       Args : Qt4.Address_Pointer)
         return Qt4.Q_Integer;
   pragma Convention (C, Qt_Metacall_Operation);

   procedure Register_Proxy
    (Class_Name  : String;
     Constructor : Q_Object_Proxy_Constructor);
   --  Register proxy object's constructor for the specified class.

   procedure Register_Director
    (Class_Name : String;
     Meta_Cast  : Qt_Metacast_Operation;
     Meta_Call  : Qt_Metacall_Operation);
   --  Register director object's fallback operations for the specified class.

end Qt_Ada.Internals.Object_Registry;
