#ifndef XCCOM_DEF_H_INCLUDED
#define XCCOM_DEF_H_INCLUDED

#include <windows.h>

typedef struct xc_iface_struct *xc_iface_ptr;
typedef struct xccom_object_struct *xccom_object_ptr;

typedef struct xccom_object_struct {
	IUnknown unk_iface;
	IUnknown *disp_iface;
	xc_iface_ptr iface_list;
	int ref_count;
	void (*delete_fun)(void*);
} xccom_object;

typedef struct xc_iface_struct {
	IUnknown iface;
	const IID *iid;
	xccom_object *root;
	xc_iface_ptr next;
	void (*delete_fun)(void*);
} xc_iface;

void xccom_object_delete(xccom_object *This);
void xccom_object_init(xccom_object *This);
void xccom_object_add_interface(xccom_object *This, REFIID iid, void *pVtbl);
HRESULT xccom_object_create_dispatch_interface(xccom_object *This, REFIID iid, ITypeInfo *ptinfo);
void xccom_object_add_connectionpoint(xccom_object *This, REFIID iid);
HRESULT xccom_object_fire_event(xccom_object *This, REFIID iid, DISPID dispID);

#define TOCOMOBJ(This) ((xc_iface*)This)->root

typedef struct COM_IFACE {
	const IID *iid;
	ITypeInfo *ti;
} COM_IFACE;

#define BEGIN_COM_INTERFACES COM_IFACE __com_iface[] = {
#define DEFINE_COM_INTERFACE(cls) { &IID_I##cls, NULL },
#define END_COM_INTERFACES { &IID_NULL, NULL }};

extern COM_IFACE __com_iface[];
HRESULT COM_init_interfaces(ITypeLib*);
HRESULT COM_term_interfaces();
ITypeInfo* COM_get_typeinfo(REFIID);

#endif /* XCCOM_DEF_H_INCLUDED */
