/*
	ZOONIC RELEASE 2

	(c)1997 by Tinic Urou
*/
#ifndef __ZOONIC__
#define __ZOONIC__

#include <stdarg.h>
#include <string.h>
#include <memory.h>
#ifdef __cplusplus
#include <StorageKit.h>
#include <SupportKit.h>
#endif

#define MAX_CLASSNAMELENGTH		63

struct			Class;
struct			Object;
struct 			TagItem;
int32 			CreatezOOnic(void);
void 			DestroyzOOnic(void);
struct TagItem 	*FindTagItem(struct TagItem *tags, int32 TagID );
int32			GetTagData(struct TagItem *tags, int32 defval, int32 TagID );
int32 			CreateObjectList(Object ***list, const char *path, int32 minversion);
int32 			DeleteObjectList(Object ***list);

#pragma export on
char *class_superclass();
int32 class_instancesize();
int32 class_superversion();
int32 class_version();
int32 class_dispatcher(Class *c, Object *o, uint32 MethodID, uint32 *data);
#pragma export off

#ifndef __cplusplus
Class 	*CreateClass	(Class *superclass,char *superclassname,int32 instancesize, int32 (*dispatcher)(Class *c, Object *o,uint32 MethodID, uint32 *data));
void 	DestroyClass	(Class *c);
void 	SetClassError	(Class *c, int32 errorcode);
int32 	ClassError		(Class *c);
Class 	*OpenClass		(char *baseclassname);

Object 	*CreateObject	(Class *baseclass,char *baseclassname, ...);
void 	DestroyObject	(Object *o);
int32	DoMethod		(Object *o, uint32 MethodID, ...);
void	SetObjectError	(Object *o, int32 errorcode);
int32 	ObjectError		(Object *o);
int32 	DoSuperMethod	(Class *c,Object *o,uint32 MethodID, uint32 *data);
void 	*Instance		(Class *c,Object *o);
#endif

enum
{
	TAG_END=0,
	TAG_DONE=0,
	TAG_SKIP=-1,
	TAG_MORE=-2
};

struct TagItem
{
	int32	TagID;
	int32	TagData;
};

enum
{
	B_METHOD_CONSTRUCT=0x7F000000,
	B_METHOD_DESTROY,
	B_METHOD_SETATTR,
	B_METHOD_GETATTR
};

enum
{
	B_UNKNOWN_CLASS = B_ERRORS_END + 1,
	B_BAD_SUPERCLASS,
	B_FALSE_VERSION,
	B_UNKNOWN_METHOD,
	B_UNKNOWN_ATTRIBUTE
};

struct Class
{
	Class		*_nextclass;
	int32 	   (*_dispatcher)(Class *c, Object *o, uint32 MethodID, uint32 *data);
	Class		*_superclass;
	int32		 _instanceoffset;
	int32		 _instancesize;
	int32		 _error;

	char		*_classname;
	int32 		 _version;
	char		*_superclassname;

	image_id	 _image_id;

#ifdef __cplusplus
				Class(Class *superclass, int32 instancesize, int32 (*dispatcher)(Class *c, Object *o,uint32 MethodID, uint32 *data));
				Class(char *superclassname, int32 superminversion, int32 instancesize, int32 (*dispatcher)(Class *c, Object *o,uint32 MethodID, uint32 *data));
				~Class();

	void		SetError(int32 errorcode);
	int32		Error();
	
#endif
};

struct Object
{
	Class		*_baseclass;
	void		*_instance;
	int32		 _error;

#ifdef __cplusplus
				Object(Class *baseclass, ...);
				Object(char *baseclassname, int32 minversion ...);
				~Object();

	inline int32 DoMethod(uint32 MethodID, ...)
	{
		_error=B_NO_ERROR;
	
		va_list	argptr;
		va_start (argptr,MethodID);
		int32 ret=_baseclass->_dispatcher(_baseclass,this,MethodID,(uint32 *)argptr);
		va_end(argptr);
	
		return ret;
	};
	
	inline int32 DoSuperMethod(Class *c,uint32 MethodID, uint32 *data)
	{
		_error=B_NO_ERROR;		
		return c->_superclass->_dispatcher(c->_superclass,this,MethodID,data);
	};

	inline void	*Instance(Class *c)
	{
		_error=B_NO_ERROR;
		return (void *)((uchar *)_instance+c->_instanceoffset);
	};	

	inline void SetError(int32 errorcode)
	{
		_error=errorcode;
	};
	
	inline int32 Error()
	{
		return _error;
	};
#endif
};
#endif
