#ifndef __ENODE_CALL_H__
#define __ENODE_CALL_H__

/* All arguments passed to enode_call in the arg_list need to be of this
 * type. */

#define LANG_INT          (1<<0)
#define LANG_STRING       (1<<1)
#define LANG_NODE         (1<<2)
#define LANG_BINSTRING    (1<<3)
#define LANG_FLOAT        (1<<4)
#define LANG_DOUBLE       (1<<5)

/* #typedef struct _LangArg LangArg; */

typedef struct {
    void *data;			/* string, binary string, or XML_Node* */
    gint type;			/* A LANG_* */
    gint size;			/* Length of data. */
    gint intdata;		/* Integer, ->data will be set with the
				 * string aswell. */
    gdouble doubledata;		/* double (joze) */
} LangArg;


GSList *enode_call_push_int (GSList * arg_list, gint arg);

GSList *enode_call_push_double (GSList * arg_list, gdouble arg);

GSList *enode_call_push_str (GSList * arg_list, gchar * arg);

GSList *enode_call_push_data (GSList * arg_list, gchar * arg, gint size);

GSList *enode_call_push_node (GSList * arg_list, ENode * node);

/* Free a single argument */
void enode_call_free_arg (LangArg * arg);

/* Free all arguments and the argument list */
void enode_call_free_arg_list_items (GSList * arg_list);


EBufConst *enode_call_with_list (ENode * calling_node,
				 gchar * function, GSList * arg_list);

/* 
 * 
 * This function uses vargs to call the embedded function. The format strings 
 * can have the following items: s     A \0 terminated string. Example:  "s", 
 * "str" b     A binary string. Example:  "b", binarydata, size e     An
 * EBuf*. Example:  "e", ebuff n     An ENode* Example:  "n", node i     An
 * integer. Example:  "i", 7 f     A float. Example:  "f", 5.6 d     A
 * double. Example:  "d", .000000000000000000000000000000000000000000001
 * 
 * For example, lets say that we want to pass the node and three ints:
 * enode_call (node, function, "iii", 1, 2, 3); The calling node is always
 * prepended as the first argument to the function. */

/* call a subroutine in another object independant of implementation language
 * * used in that object. */

EBufFreeMe *enode_call (ENode * calling_node, gchar * function,
			gchar * fmt, ...);

/* Same as enode_call (), except the return value is freed * for you */
void
 enode_call_ignore_return (ENode * calling_node, gchar * function,
			   gchar * fmt, ...);

typedef EBuf *
    (*LangDispatchFunc) (ENode * calling_node, gchar * function,
			 GSList * arg_list);


/* return current namespace for the given language */
gchar *enode_call_get_namespace (gchar * language);


/* For dealing with stacked reference nodes. */
void
 enode_call_reference_push (ENode * node);

ENode *enode_call_reference_pop (void);

ENode *enode_call_reference (void);

/* Register a new language */
void language_register (gchar * language_name, LangDispatchFunc func);

/* For use in entitylang */
GSList *entity_supported_languages (void);



#endif				/* __ENODE_CALL_H__ */


