# include "Mover.h"
# include "Mover.r"

/******************************************************************************
*									      *
*	(C) 1993 by K. Ballueder					      *
*									      *
*	See README and COPYING for details.				      *
*									      *
*		kballued@charon.physik.uni-osnabrueck.de		      *
*		kballued@jupiter.rz.uni-osnabrueck.de			      *
*									      *
**** Changelog: ***************************************************************
*/

/******************************************************************************
*									      *
*	(C) 1993 by K. Ballueder					      *
*									      *
*	See README and COPYING for details.				      *
*									      *
*		kballued@charon.physik.uni-osnabrueck.de		      *
*		kballued@jupiter.rz.uni-osnabrueck.de			      *
*									      *
**** Changelog: ***************************************************************
Sat Dec 25 16:05:50  1993
*/

static int Mover_getxpos (void * _self) {
	struct Mover * self = cast(Mover, _self);

	return (int) xpos(self);
}

static int Mover_getypos (void * _self) {
	struct Mover * self = cast(Mover, _self);

	return (int) ypos(self);
}

static int Mover_gettype (void * _self) {
	struct Mover * self = cast(Mover, _self);

	return (int) self->type;
}

static int Mover_getdir (void * _self) {
	struct Mover * self = cast(Mover, _self);

	return (int) (direction(self));
}

static int Mover_setxpos (void * _self, int x) {
	struct Mover * self = cast(Mover, _self);

	return (int) (xpos(self) = x);
}

static int Mover_setypos (void * _self, int y) {
	struct Mover * self = cast(Mover, _self);

	return (int) (ypos(self) = y);
}

static int Mover_settype (void * _self, int type) {
	struct Mover * self = cast(Mover, _self);

	return (int) (self->type = type);
}

static int Mover_setdir (void * _self, int dir) {
	struct Mover * self = cast(Mover, _self);

	return (int) (direction(self) = dir);
}

static struct Mover * Mover_mdisplay (void * _self) {
	struct Mover * self = cast(Mover, _self);

	godisplay(self->gobject, IMAGEWIDTH*(xpos(self)-gxoffset_x), IMAGEHEIGHT*(ypos(self)-gxoffset_y));
	return (struct Mover *) self;
}

static struct Mover * Mover_mmove (void * _self, int figurnr, int x1, int y1, int x2, int y2) {
	struct Mover * self = cast(Mover, _self);

	D_ENTRY("Mover.mmove");
	debug_printf("using figur %d\n", figur);
	self->gobject = figur[figurnr];
	gomove(self->gobject,IMAGEWIDTH*(x1-gxoffset_x),IMAGEHEIGHT*(y1-gxoffset_y), IMAGEWIDTH*(x2-gxoffset_x),IMAGEHEIGHT*(y2-gxoffset_y));
	level_table[y1][x1]=FELD_LEER;
	level_table[y2][x2]=figurnr;
	D_LEAVE
	return self;
}
static struct Mover * Mover_animate (void * _self) {
	struct Mover * self = cast(Mover, _self);

	int moved = '\0', tested = '\0';

	D_ENTRY("Mover.animate()");

	debug_printf("pos: %d,%d\n", xpos(self), ypos(self));
	while(! moved)
	{	switch(direction(self))
		{ 	case 0:
			if(ypos(self) > 0 && level_table[ypos(self)-1][xpos(self)] < FELD_ERDE)
			{ 	if(level_table[ypos(self)-1][xpos(self)]==FELD_SPIELER_1)
					tod();

				mmove(self, FELD_KAEFER_2+direction(self),xpos(self),ypos(self),
					xpos(self),ypos(self)-1);
				ypos(self)--; moved = '\1';
			}
			else
				direction(self)++;
			break;

			case 1:
			if(xpos(self) < level_x_size-1 &&
				level_table[ypos(self)][xpos(self)+1] < FELD_ERDE)
			{ 	if(level_table[ypos(self)][xpos(self)+1]==FELD_SPIELER_1)
					tod();
				mmove(self, FELD_KAEFER_2+direction(self),xpos(self),ypos(self),
					xpos(self)+1,ypos(self));
				xpos(self)++; moved = '\1';
			}
			else
				direction(self)++;
			break;

			case 2:
			if(ypos(self) < level_y_size-1 &&
				 level_table[ypos(self)+1][xpos(self)] < FELD_ERDE)
			{ 	if(level_table[ypos(self)+1][xpos(self)]==FELD_SPIELER_1)
				    tod();
				mmove(self, FELD_KAEFER_2+direction(self),xpos(self),ypos(self),
					xpos(self),ypos(self)+1);
				ypos(self) ++;
				moved = '\1';
			}
			else
				direction(self)++;

			break;

			case 3:
			if(xpos(self) > 0 && level_table[ypos(self)][xpos(self)-1] < FELD_ERDE)
			{ 	if(level_table[ypos(self)][xpos(self)-1] == FELD_SPIELER_1)
					tod();
				mmove(self, FELD_KAEFER_2+direction(self),xpos(self),ypos(self),
					xpos(self)-1,ypos(self));
				xpos(self)--; moved = '\1';
			}
			else
			{	direction(self) = 0;
				moved = tested;      /* falls eingesperrt, nach 2. Durchlauf */
				tested = '\1';       /* abbrechen */
			}
		}/* switch */
		self->gobject = figur[FELD_KAEFER_2+direction(self)];
	}
	D_LEAVE
	return (struct Mover *) self;
}

static void * Mover_ctor (void * _self, va_list * app) {
	struct Mover *self = super_ctor(Mover, _self, *app);

	self->gobject	= va_arg(*app, void *);
	xpos(self)	= va_arg(*app, int);
	ypos(self)	= va_arg(*app, int);
	self->type	= va_arg(*app, int);
	direction(self) = va_arg(*app, int);
	debug_printf("godisplay: x = %d\ty = %d\n",
	IMAGEWIDTH*(xpos(self)), IMAGEHEIGHT*(ypos(self)));
/* 	godisplay(self->gobject, IMAGEWIDTH*(xpos(self)), IMAGEHEIGHT*(ypos(self))); */

	Mover_mdisplay(self);
	return (void *) self;
}

static void * Mover_dtor (void * _self) {
	struct Mover * self = cast(Mover, _self);

	/*goundisplay(self->gobject, xpos(self), ypos(self));*/
	return (void *) super_dtor(Mover, self);
}

static int Mover_differ (const void * _self, const void * b) {
	const struct Mover * self = cast(Mover, _self);

	return (int) super_differ(Mover, self, b);
}

static int Mover_puto (const void * _self, FILE * fp) {
	const struct Mover * self = cast(Mover, _self);

	return (int) super_puto(Mover, self, fp);
}

static void * Mover_geto (void * _self, FILE * fp) {
	struct Mover * self = cast(Mover, _self);

	return (void *) super_geto(Mover, self, fp);
}

static void * Mover_clone (const void * _self) {
	const struct Mover * self = cast(Mover, _self);

	return (void *) super_clone(Mover, self);
}

int getxpos (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> getxpos.method);
	return ((int (*) ()) class -> getxpos.method)(_self);
}

int super_getxpos (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> getxpos.method);
	return ((int (*) ()) superclass -> getxpos.method)(_self);
}

int getypos (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> getypos.method);
	return ((int (*) ()) class -> getypos.method)(_self);
}

int super_getypos (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> getypos.method);
	return ((int (*) ()) superclass -> getypos.method)(_self);
}

int gettype (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> gettype.method);
	return ((int (*) ()) class -> gettype.method)(_self);
}

int super_gettype (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> gettype.method);
	return ((int (*) ()) superclass -> gettype.method)(_self);
}

int getdir (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> getdir.method);
	return ((int (*) ()) class -> getdir.method)(_self);
}

int super_getdir (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> getdir.method);
	return ((int (*) ()) superclass -> getdir.method)(_self);
}

int setdir (void * _self, int dir) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> setdir.method);
	return ((int (*) ()) class -> setdir.method)(_self, dir);
}

int super_setdir (const void * _class, void * _self, int dir) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> setdir.method);
	return ((int (*) ()) superclass -> setdir.method)(_self, dir);
}

int setxpos (void * _self, int x) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> setxpos.method);
	return ((int (*) ()) class -> setxpos.method)(_self, x);
}

int super_setxpos (const void * _class, void * _self, int x) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> setxpos.method);
	return ((int (*) ()) superclass -> setxpos.method)(_self, x);
}

int setypos (void * _self, int y) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> setypos.method);
	return ((int (*) ()) class -> setypos.method)(_self, y);
}

int super_setypos (const void * _class, void * _self, int y) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> setypos.method);
	return ((int (*) ()) superclass -> setypos.method)(_self, y);
}

int settype (void * _self, int type) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> settype.method);
	return ((int (*) ()) class -> settype.method)(_self, type);
}

int super_settype (const void * _class, void * _self, int type) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> settype.method);
	return ((int (*) ()) superclass -> settype.method)(_self, type);
}

struct Mover * mmove (void * _self, int figurnr, int x1, int y1, int x2, int y2) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> mmove.method);
	return ((struct Mover * (*) ()) class -> mmove.method)(_self, figurnr, x1, y1, x2, y2);
}

struct Mover * super_mmove (const void * _class, void * _self, int figurnr, int x1, int y1, int x2, int y2) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> mmove.method);
	return ((struct Mover * (*) ()) superclass -> mmove.method)(_self, figurnr, x1, y1, x2, y2);
}

struct Mover * mdisplay (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> mdisplay.method);
	return ((struct Mover * (*) ()) class -> mdisplay.method)(_self);
}

struct Mover * super_mdisplay (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> mdisplay.method);
	return ((struct Mover * (*) ()) superclass -> mdisplay.method)(_self);
}

struct Mover * animate (void * _self) {
	const struct MoverClass * class = cast(MoverClass, classOf(_self));

	assert(class -> animate.method);
	return ((struct Mover * (*) ()) class -> animate.method)(_self);
}

struct Mover * super_animate (const void * _class, void * _self) {
	const struct MoverClass * superclass = cast(MoverClass, super(_class));

	assert(superclass -> animate.method);
	return ((struct Mover * (*) ()) superclass -> animate.method)(_self);
}

static void * MoverClass_ctor (void * _self, va_list * app) {
	struct MoverClass * self = super_ctor(MoverClass, _self, app);
	Method selector;
	va_list ap = * app;

	while ((selector = va_arg(ap, Method)))
	{	const char * tag = va_arg(ap, const char *);
		Method method = va_arg(ap, Method);

		if (selector == (Method) getxpos)
		{	if (tag)
				self -> getxpos.tag = tag,
				self -> getxpos.selector = selector;
			self -> getxpos.method = method;
			continue;
		}
		if (selector == (Method) getypos)
		{	if (tag)
				self -> getypos.tag = tag,
				self -> getypos.selector = selector;
			self -> getypos.method = method;
			continue;
		}
		if (selector == (Method) gettype)
		{	if (tag)
				self -> gettype.tag = tag,
				self -> gettype.selector = selector;
			self -> gettype.method = method;
			continue;
		}
		if (selector == (Method) getdir)
		{	if (tag)
				self -> getdir.tag = tag,
				self -> getdir.selector = selector;
			self -> getdir.method = method;
			continue;
		}
		if (selector == (Method) setdir)
		{	if (tag)
				self -> setdir.tag = tag,
				self -> setdir.selector = selector;
			self -> setdir.method = method;
			continue;
		}
		if (selector == (Method) setxpos)
		{	if (tag)
				self -> setxpos.tag = tag,
				self -> setxpos.selector = selector;
			self -> setxpos.method = method;
			continue;
		}
		if (selector == (Method) setypos)
		{	if (tag)
				self -> setypos.tag = tag,
				self -> setypos.selector = selector;
			self -> setypos.method = method;
			continue;
		}
		if (selector == (Method) settype)
		{	if (tag)
				self -> settype.tag = tag,
				self -> settype.selector = selector;
			self -> settype.method = method;
			continue;
		}
		if (selector == (Method) mmove)
		{	if (tag)
				self -> mmove.tag = tag,
				self -> mmove.selector = selector;
			self -> mmove.method = method;
			continue;
		}
		if (selector == (Method) mdisplay)
		{	if (tag)
				self -> mdisplay.tag = tag,
				self -> mdisplay.selector = selector;
			self -> mdisplay.method = method;
			continue;
		}
		if (selector == (Method) animate)
		{	if (tag)
				self -> animate.tag = tag,
				self -> animate.selector = selector;
			self -> animate.method = method;
			continue;
		}
	}
	return self;
}

static const void * initMoverClass (void)
{
	return ((struct Object *) MoverClass) -> class ? MoverClass :
		(MoverClass = new(Class,
			"MoverClass", Class, sizeof(struct MoverClass),
			ctor, "", MoverClass_ctor,
			(void *) 0));
}

static const struct ClassInit _MoverClass = { { MAGIC }, initMoverClass };
const void * MoverClass = & _MoverClass;

static const void * initMover (void)
{
	return ((struct Object *) Mover) -> class ? Mover :
		(Mover = new(MoverClass,
			"Mover", Object, sizeof(struct Mover),
			getxpos, "getxpos", Mover_getxpos,
			getypos, "getypos", Mover_getypos,
			gettype, "gettype", Mover_gettype,
			getdir, "getdir", Mover_getdir,
			setxpos, "setxpos", Mover_setxpos,
			setypos, "setypos", Mover_setypos,
			settype, "settype", Mover_settype,
			setdir, "setdir", Mover_setdir,
			mdisplay, "mdisplay", Mover_mdisplay,
			mmove, "mmove", Mover_mmove,
			animate, "animate", Mover_animate,
			ctor, "ctor", Mover_ctor,
			dtor, "dtor", Mover_dtor,
			differ, "differ", Mover_differ,
			puto, "puto", Mover_puto,
			geto, "geto", Mover_geto,
			clone, "clone", Mover_clone,
			(void *) 0));
}

static const struct ClassInit _Mover = { { MAGIC }, initMover };
const void * Mover = & _Mover;
