/* Gnome Scan - Scan as easy as you print
 * Copyright © 2007  Étienne Bersac <bersace03@laposte.net>
 *
 * Gnome Scan is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * gnome-scan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with gnome-scan.  If not, write to:
 *
 *	the Free Software Foundation, Inc.
 *	51 Franklin Street, Fifth Floor
 *	Boston, MA 02110-1301, USA
 */

#ifndef _GNOME_SCAN_MODULE_H_
#define _GNOME_SCAN_MODULE_H_

#include <glib-object.h>
#include <gmodule.h>

G_BEGIN_DECLS

#define GNOME_TYPE_SCAN_MODULE             (gnome_scan_module_get_type ())
#define GNOME_SCAN_MODULE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_SCAN_MODULE, GnomeScanModule))
#define GNOME_SCAN_MODULE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_SCAN_MODULE, GnomeScanModuleClass))
#define GNOME_IS_SCAN_MODULE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_SCAN_MODULE))
#define GNOME_IS_SCAN_MODULE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_SCAN_MODULE))
#define GNOME_SCAN_MODULE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_SCAN_MODULE, GnomeScanModuleClass))

#define	NOT_IMPLEMENTED	g_warning("%s:%i '%s' not implemented", __FILE__, __LINE__, __FUNCTION__)

/**
 * GS_DEFINE_MODULE_TYPE:
 * @TN: Capitalized type name
 * @t_n: Type function prefix
 * @T_P: Parent GType macro
 *
 * Convenient macro used to declare a dynamicly registered type.
 *
 * For example:
 * <programlisting>
GS_DEFINE_MODULE_TYPE (FooBar, foo_bar, G_TYPE_OBJECT)
 * </programlisting>
 *
 * expands to:
 *
 * <programlisting>
static void     foo_bar_init       (FooBar      *self);	
static void     foo_bar_class_init (FooBarClass *klass);	

static GType foo_bar_type = 0;	
GType	
foo_bar_get_type () 
{ return foo_bar_type; } 

void 
foo_bar_register_type (GTypeModule *module)	
{	
  if (!foo_bar_type)
    {	
      static const GTypeInfo type_info =	
      {	
        sizeof (FooBarClass),						
        (GBaseInitFunc) NULL,					
        (GBaseFinalizeFunc) NULL,				
        (GClassInitFunc) foo_bar_class_init, 		
        NULL,
        NULL,
        sizeof (FooBar),							
        0,
        (GInstanceInitFunc) foo_bar_init			
      }; 

      foo_bar_type =	
        g_type_module_register_type (module, G_TYPE_OBJECT,	
                                     g_intern_static_string ("FooBar"), &type_info, 0);	
    } 
}
 * </programlisting>
 *
 * See: G_DEFINE_TYPE
 **/
#define GS_DEFINE_MODULE_TYPE(TN, t_n, T_P)			static void     t_n##_init       (TN      *self);	\
static void     t_n##_class_init (TN##Class *klass);	\
\
static GType t_n##_type = 0;	\
GType	\
t_n##_get_type () \
{ return t_n##_type; } \
\
void \
t_n##_register_type (GTypeModule *module)	\
{	\
  if (!t_n##_type)\
    {	\
      static const GTypeInfo type_info =	\
      {	\
        sizeof (TN##Class),						\
        (GBaseInitFunc) NULL,					\
        (GBaseFinalizeFunc) NULL,				\
        (GClassInitFunc) t_n##_class_init, 		\
        NULL,           /* class_finalize */	\
        NULL,           /* class_data     */	\
        sizeof (TN),							\
        0,              /* n_preallocs    */	\
        (GInstanceInitFunc) t_n##_init			\
      }; \
\
      t_n##_type =	\
        g_type_module_register_type (module, T_P,	\
                                     g_intern_static_string (#TN), &type_info, 0);	\
    } \
}


typedef struct _GnomeScanModuleClass GnomeScanModuleClass;
typedef struct _GnomeScanModule GnomeScanModule;

struct _GnomeScanModuleClass
{
	GTypeModuleClass parent_class;
};

/**
 * GnomeScanModule:
 *
 * A #GnomeScanModule handle the loading, initialization, finalization
 * and unloading of a module. If you want to extends Gnome Scan, you
 * must implement two function, one for @init and one for @finalize,
 * called gnome_scan_module_init() and
 * gnome_scan_module_finalize(). You should prefix function prototypes
 * with #G_MODULE_EXPORT.
 */
struct _GnomeScanModule
{
	/*< private >*/
	GTypeModule parent_instance;
	
	gchar*		filename;
	GModule*	library;
	
	/* GnomeScanModule very complex API */
	/*< public >*/
	void (* init)		(GnomeScanModule *module);
	void (* finalize)	(GnomeScanModule *module);
};

GType	gnome_scan_module_get_type (void) G_GNUC_CONST;
GnomeScanModule*
		gnome_scan_module_new (gchar *filename);

G_END_DECLS

#endif /* _GNOME_SCAN_MODULE_H_ */
