/* Class object implementation */

#include "allobjects.h"

#include "structmember.h"

typedef struct {
	OB_HEAD
	object	*cl_bases;	/* A tuple */
	object	*cl_methods;	/* A dictionary */
} classobject;

object *
newclassobject(bases, methods)
	object *bases; /* NULL or tuple of classobjects! */
	object *methods;
{
	classobject *op;
	op = NEWOBJ(classobject, &Classtype);
	if (op == NULL)
		return NULL;
	if (bases != NULL)
		INCREF(bases);
	op->cl_bases = bases;
	INCREF(methods);
	op->cl_methods = methods;
	return (object *) op;
}

/* Class methods */

static void
class_dealloc(op)
	classobject *op;
{
	int i;
	if (op->cl_bases != NULL)
		DECREF(op->cl_bases);
	DECREF(op->cl_methods);
	free((ANY *)op);
}

static object *
class_getattr(op, name)
	register classobject *op;
	register char *name;
{
	register object *v;
	v = dictlookup(op->cl_methods, name);
	if (v != NULL) {
		INCREF(v);
		return v;
	}
	if (op->cl_bases != NULL) {
		int n = gettuplesize(op->cl_bases);
		int i;
		for (i = 0; i < n; i++) {
			v = class_getattr(gettupleitem(op->cl_bases, i), name);
			if (v != NULL)
				return v;
			err_clear();
		}
	}
	err_setstr(NameError, name);
	return NULL;
}

typeobject Classtype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"class",
	sizeof(classobject),
	0,
	class_dealloc,	/*tp_dealloc*/
	0,		/*tp_print*/
	class_getattr,	/*tp_getattr*/
	0,		/*tp_setattr*/
	0,		/*tp_compare*/
	0,		/*tp_repr*/
	0,		/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
};


/* We're not done yet: next, we define class member objects... */

typedef struct {
	OB_HEAD
	classobject	*cm_class;	/* The class object */
	object		*cm_attr;	/* A dictionary */
} classmemberobject;

object *
newclassmemberobject(class)
	register object *class;
{
	register classmemberobject *cm;
	if (!is_classobject(class)) {
		err_badcall();
		return NULL;
	}
	cm = NEWOBJ(classmemberobject, &Classmembertype);
	if (cm == NULL)
		return NULL;
	INCREF(class);
	cm->cm_class = (classobject *)class;
	cm->cm_attr = newdictobject();
	if (cm->cm_attr == NULL) {
		DECREF(cm);
		return NULL;
	}
	return (object *)cm;
}

/* Class member methods */

static void
classmember_dealloc(cm)
	register classmemberobject *cm;
{
	DECREF(cm->cm_class);
	if (cm->cm_attr != NULL)
		DECREF(cm->cm_attr);
	free((ANY *)cm);
}

static object *
classmember_getattr(cm, name)
	register classmemberobject *cm;
	register char *name;
{
	register object *v = dictlookup(cm->cm_attr, name);
	if (v != NULL) {
		INCREF(v);
		return v;
	}
	v = class_getattr(cm->cm_class, name);
	if (v == NULL)
		return v; /* class_getattr() has set the error */
	if (is_funcobject(v)) {
		object *w = newclassmethodobject(v, (object *)cm);
		DECREF(v);
		return w;
	}
	DECREF(v);
	err_setstr(NameError, name);
	return NULL;
}

static int
classmember_setattr(cm, name, v)
	classmemberobject *cm;
	char *name;
	object *v;
{
	if (v == NULL)
		return dictremove(cm->cm_attr, name);
	else
		return dictinsert(cm->cm_attr, name, v);
}

typeobject Classmembertype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"class member",
	sizeof(classmemberobject),
	0,
	classmember_dealloc,	/*tp_dealloc*/
	0,			/*tp_print*/
	classmember_getattr,	/*tp_getattr*/
	classmember_setattr,	/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
};


/* And finally, here are class method objects */
/* (Really methods of class members) */

typedef struct {
	OB_HEAD
	object	*cm_func;	/* The method function */
	object	*cm_self;	/* The object to which this applies */
} classmethodobject;

object *
newclassmethodobject(func, self)
	object *func;
	object *self;
{
	register classmethodobject *cm;
	if (!is_funcobject(func)) {
		err_badcall();
		return NULL;
	}
	cm = NEWOBJ(classmethodobject, &Classmethodtype);
	if (cm == NULL)
		return NULL;
	INCREF(func);
	cm->cm_func = func;
	INCREF(self);
	cm->cm_self = self;
	return (object *)cm;
}

object *
classmethodgetfunc(cm)
	register object *cm;
{
	if (!is_classmethodobject(cm)) {
		err_badcall();
		return NULL;
	}
	return ((classmethodobject *)cm)->cm_func;
}

object *
classmethodgetself(cm)
	register object *cm;
{
	if (!is_classmethodobject(cm)) {
		err_badcall();
		return NULL;
	}
	return ((classmethodobject *)cm)->cm_self;
}

/* Class method methods */

#define OFF(x) offsetof(classmethodobject, x)

static struct memberlist classmethod_memberlist[] = {
	{"cm_func",	T_OBJECT,	OFF(cm_func)},
	{"cm_self",	T_OBJECT,	OFF(cm_self)},
	{NULL}	/* Sentinel */
};

static object *
classmethod_getattr(cm, name)
	register classmethodobject *cm;
	char *name;
{
	return getmember((char *)cm, classmethod_memberlist, name);
}

static void
classmethod_dealloc(cm)
	register classmethodobject *cm;
{
	DECREF(cm->cm_func);
	DECREF(cm->cm_self);
	free((ANY *)cm);
}

typeobject Classmethodtype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"class method",
	sizeof(classmethodobject),
	0,
	classmethod_dealloc,	/*tp_dealloc*/
	0,			/*tp_print*/
	classmethod_getattr,	/*tp_getattr*/
	0,			/*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
};
