/*
 * Gnome Basic Object
 *
 * Author:
 *    Michael Meeks <michael@helixcode.com>
 *
 * Copyright 2000, Helix Code, Inc.
 */

#ifndef GBRUN_OBJECT_H
#define GBRUN_OBJECT_H

#include <gbrun/gbrun.h>
#include <gb/gb-value.h>
#include <gb/gb-expr.h>
#include <gb/gb-object.h>

#define GBRUN_TYPE_OBJECT            (gbrun_object_get_type ())
#define GBRUN_OBJECT(obj)            (GTK_CHECK_CAST ((obj), GBRUN_TYPE_OBJECT, GBRunObject))
#define GBRUN_OBJECT_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GBRUN_TYPE_OBJECT, GBRunObjectClass))
#define GBRUN_IS_OBJECT(obj)         (GTK_CHECK_TYPE ((obj), GBRUN_TYPE_OBJECT))
#define GBRUN_IS_OBJECT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GBRUN_TYPE_OBJECT))
#define GBRUN_IS_AN_OBJECT(t)        (gtk_type_is_a (t, GBRUN_TYPE_OBJECT))
#define GBRUN_OBJECT_GET_CLASS(obj)  (GBRUN_OBJECT_CLASS (GTK_OBJECT (obj)->klass))

typedef struct _GBRunObjectPrivate      GBRunObjectPrivate;
typedef struct _GBRunObjectPrivateClass GBRunObjectPrivateClass;

struct _GBRunObject {
	GBObject parent;

	GBRunObjectPrivate *priv;
};

struct _GBRunObjectClass {
	GBObjectClass parent;

	GBRunObjectPrivateClass *priv;

	/* Virtual methods used to demux GBObject's assign / deref */

	gboolean (*set_arg) (GBRunEvalContext  *ec,
			     GBRunObject       *object,
			     int                property,
			     GBValue           *val);
	
	GBValue *(*get_arg) (GBRunEvalContext  *ec,
			     GBRunObject       *object,
			     int                property);

	GBValue *(*get_ndx) (GBRunEvalContext  *ec,
			     GBRunObject       *object,
			     int		index);
};

typedef enum {
	GBRUN_PROPERTY_READABLE  = 0x1,
	GBRUN_PROPERTY_WRITEABLE = 0x2
} GBRunPropertyType;

struct _GBRunObjMethod {
	char		*name;
	gboolean	 is_sub;

	gboolean	 args_parsed;
	union {
		struct {
			GSList		  *args;
			GtkType            as_type;
			gint               max_args;
			gint               min_args;
			GBRunSecurityFlag  mask;
		} parsed;

		struct {
			char		  *args;
			gboolean	   vararg;
		} unparsed;
	} args;

	enum { GBRUN_METHOD_VAR, GBRUN_METHOD_ARG, GBRUN_METHOD_VB } type;
	union {
		GBRunMethodVar *var;
		GBRunMethodArg *arg;
		GBRoutine      *vb;
	} handler;
};

GtkType           gbrun_object_get_type        (void);

GtkType           gbrun_object_subclass        (GtkType           parent,
						const char       *vb_name,
						GtkClassInitFunc  class_init,
						GtkObjectInitFunc object_init);

GtkType           gbrun_object_subclass_simple (GtkType           parent,
						const char      *vb_name);

GBRunObject      *gbrun_object_new               (GBRunObjectClass *klass);

void              gbrun_object_add_property      (GBRunObjectClass *klass,
						  const char       *name,
						  GtkType           type,
						  int               idx);

void              gbrun_object_add_property_full (GBRunObjectClass *klass,
						  const char       *name,
						  GtkType           type,
						  int               idx,
						  GBRunPropertyType flags);

gboolean          gbrun_object_has_property    (GBRunObjectClass *klass,
						const char       *name,
						GBRunPropertyType type);

void              gbrun_object_add_variables   (GBRunEvalContext *ec,
						GBRunObjectClass *klass,
						GHashTable       *variables);

void              gbrun_object_add_constants   (GBRunEvalContext *ec,
						GBRunObjectClass *klass,
						GHashTable       *constants);

void              gbrun_object_add_method_var   (GBRunObjectClass     *klass,
						 const char           *desc,
						 GBRunMethodVar       *method);

void              gbrun_object_add_method_arg   (GBRunObjectClass     *klass,
						 const char           *desc,
						 GBRunMethodArg       *method);

void              gbrun_object_set_default_method (GBRunObjectClass   *klass,
						   const char         *desc);

void              gbrun_object_add_routine      (GBRunObjectClass     *klass,
						 GBRoutine            *routine);

void              gbrun_object_add_routines     (GBRunEvalContext     *ec,
						 GBRunObjectClass     *klass,
						 GHashTable           *routines);

gboolean          gbrun_object_has_method       (GBRunObjectClass     *klass,
						 const char           *name);

GSList           *gbrun_object_get_methods      (GBRunObjectClass     *klass);

char             *gbrun_object_name             (GBRunObject         *object);

void              gbrun_object_init             (GBEvalContext *ec);

void              gbrun_object_shutdown         (void);


#define           gbrun_object_ref(o)              (gb_object_ref     (GB_OBJECT (o)))
#define           gbrun_object_unref(o)            (gb_object_unref   (GB_OBJECT (o)))

typedef struct {
	GtkType type;
	int     idx;
	char   *name;
	int     flags;
} GBRunObjectProperty;

GBRunObjectProperty *gbrun_object_get_property (GBRunObjectClass  *klass,
			   			const char	  *name,
			   			GBRunObjectClass **on_class,
			   			GBRunPropertyType  flags);


#endif /* GBRUN_OBJECT_H */
