#ifndef ORBIT_C_BACKEND
#define ORBIT_C_BACKEND 1

#include "config.h"
#include <stdio.h>
#ifdef HAVE_STDDEF_H
#  include <stddef.h>
#endif
#if defined(HAVE_WCHAR_H)
#  include <wchar.h>
#elif defined(HAVE_WCSTR_H)
#  include <wcstr.h>
#endif
#include <glib.h>
#include <libIDL/IDL.h>
#include <ORBitutil/basic_types.h>
#define _ORBIT_H_	/* nasty kludge, but we only want ORBIT_SERIAL */
#include <orb/orbit.h>

#include "orbit-idl.h"

void orbit_cbe_write_header(FILE *outfile, IDL_ns ns, IDL_tree tree);
void orbit_cbe_write_stubs(FILE *outfile, IDL_ns ns, IDL_tree tree,
			   const char *header_filename);
void orbit_cbe_write_skeletons(FILE *outfile, IDL_ns ns, IDL_tree tree,
			       const char *header_filename);
void orbit_cbe_write_common(FILE *outfile, IDL_ns ns, IDL_tree tree,
			    const char *header_filename);
void orbit_cbe_write_skelimpl(FILE *outfile, IDL_ns ns, IDL_tree tree,
			      const char *hdrname);
void orbit_output_typecode(FILE *of, IDL_tree ts);

/* Utility functions common to skels, stubs, header, and common */
void orbit_cbe_write_typespec(FILE *of, IDL_tree tree);
void orbit_cbe_write_const(FILE *of, IDL_tree tree);
void orbit_cbe_write_typename(FILE *of, IDL_tree tree);
char *orbit_cbe_get_typename(IDL_tree tree);
void cbe_print_param_dcl(FILE *of, IDL_tree tree);
void cbe_print_var_dcl(FILE *of, IDL_tree tree, gboolean for_skels);

typedef enum { DATA_IN=1, DATA_INOUT=2, DATA_OUT=4, DATA_RETURN=8 } IDL_ParamRole;
IDL_ParamRole cbe_attr_to_paramrole(enum IDL_param_attr attr);
void orbit_cbe_param_printptrs(FILE *of, IDL_tree param, IDL_ParamRole role);
gint orbit_cbe_param_numptrs(IDL_tree param, IDL_ParamRole role);
gboolean cbe_type_is_fixed_length(IDL_tree ts);
IDL_tree cbe_get_typespec(IDL_tree node);
int cbe_get_type_head_alignment(IDL_tree typespec);
int cbe_get_type_tail_alignment(IDL_tree typespec);
void IDL_tree_traverse_parents(IDL_tree p, GFunc f, gconstpointer func_data);
int cbe_op_dcl_nparams(IDL_tree op, IDL_ParamRole);
gboolean cbe_type_is_endian_sensitive(IDL_tree typespec);

/* Debugging */
void orbit_cbe_print_node(IDL_tree node, int indent_level);

typedef struct {
  FILE *of;
  IDL_tree param;
  IDL_tree previous_param;
  IDL_tree typespec;
  char *param_name;
  gboolean require_indirect;
} CBEMarshalInfo;

typedef struct {
  FILE *of;
  IDL_tree param;
  IDL_tree previous_param;
  IDL_tree typespec;
  char *param_name;
  gboolean byteswap_version;
  gboolean allocate_memory;
  char *orb_name;
  gboolean had_default;
} CBEDemarshalInfo;

void cbe_output_marshaller(CBEMarshalInfo *mi);
void cbe_output_demarshaller(CBEDemarshalInfo *dmi);

#endif
