#include <stdlib.h>
#ifdef __MINT__
#include <macros.h>
#include <support.h>
#define itoa(a,b,c)	_itoa(a,b,c)
#define ltoa(a,b,c)	_ltoa(a,b,c)
#define ultoa(a,b,c)	_ultoa(a,b,c)
#endif

#include "intern.h"


/*****************************************************************************/
int get_obtype(OBJECT *tree, int obj, short *ud)
{
	int	type;

	if (ud != NULL)
		*ud = FALSE;
	type = tree[obj].ob_type & 0x00FF;

	/* Special: im Falle UserDef steht im oberen Byte der Original-Typ! */
	if (type == G_USERDEF)
	{
		type = (tree[obj].ob_type & 0xFF00) >> 8;
		if (ud != NULL)
			*ud = TRUE;
	}
	return type;
}

/*****************************************************************************/
void set_obspec(OBJECT *tree, int obj, long spec)
{
	short	ud;

	get_obtype(tree, obj, &ud);
	if (ud)
		tree[obj].ob_spec.userblk->ub_parm = spec;
	else
		tree[obj].ob_spec.index = spec;
}

long get_obspec(OBJECT *tree, int obj)
{
	short	ud;

	get_obtype(tree, obj, &ud);
	if (ud)
		return tree[obj].ob_spec.userblk->ub_parm;
	else
		return tree[obj].ob_spec.index;
}

/*****************************************************************************/
void set_string(OBJECT *tree, int obj, char *text)
{
	long	spec;
	int	type;

	spec = get_obspec(tree, obj);
	type = get_obtype(tree, obj, NULL);
	switch (type)
	{
		case G_BUTTON  :
		case G_STRING  :
		case G_TITLE   :
		case G_SHORTCUT:
			strcpy((char *)spec, text);
			break;

		case G_CICON   :
		case G_ICON    :
			strcpy (((ICONBLK*)spec)->ib_ptext, text);
			break;

		case G_TEXT    :
		case G_BOXTEXT :
		case G_FTEXT   :
		case G_FBOXTEXT:
			strcpy(((TEDINFO*)spec)->te_ptext, text);
			break;

		default:
		{
			char	s[30];
			sprintf(s, "[3][CF-Lib Panic: set_string()!|Objekt %d hat unbekannten Typ %d|!][Abbruch]", obj, type);
			form_alert(1, s);
		}
			break;
	}
}

void get_string(OBJECT *tree, int obj, char *text)
{
	long	spec;
	int	type;

	spec = get_obspec(tree, obj);
	type = get_obtype(tree, obj, NULL);
	switch (type)
	{
		case G_BUTTON  :
		case G_STRING  :
		case G_TITLE   :
		case G_SHORTCUT:
			strcpy(text, (char*)spec);
			break;

		case G_CICON   :
		case G_ICON    :
			strcpy(text, ((ICONBLK*)spec)->ib_ptext);
			break;

		case G_TEXT    :
		case G_BOXTEXT :
		case G_FTEXT   :
		case G_FBOXTEXT:
			strcpy(text, ((TEDINFO*)spec)->te_ptext);
			break;
		
		default:
		{
			char	s[30];
			sprintf(s, "[3][CF-Lib Panic: get_string()!|Objekt %d hat unbekannten Typ %d|!][Abbruch]", obj, type);
			form_alert(1, s);
		}
			text[0] = EOS;
			break;
	}
}

void set_int(OBJECT *tree, int obj, int i)
{
	char	tmp[20];
	
	itoa(i, tmp, 10);
	set_string(tree, obj, tmp);
}

int get_int(OBJECT *tree, int obj)
{
	char	tmp[20];
	
	get_string(tree, obj, tmp);
	return atoi(tmp);
}

void set_long(OBJECT *tree, int obj, long l)
{
	char	tmp[20];
	
	ltoa(l, tmp, 10);
	set_string(tree, obj, tmp);
}

void set_ulong(OBJECT *tree, int obj, unsigned long l)
{
	char	tmp[20];
	
	ultoa(l, tmp, 10);
	set_string(tree, obj, tmp);
}

long get_long(OBJECT *tree, int obj)
{
	char	tmp[20];
	
	get_string(tree, obj, tmp);
	return atol(tmp);
}

/*****************************************************************************/

void set_state(OBJECT *tree, int obj, int state, int set)
{
	if (set)
		tree[obj].ob_state |= state;			/* Status setzen */
	else
  		tree[obj].ob_state &= ~ state;		/* Status l”schen */
}

int get_state(OBJECT *tree, int obj, int state)
{
	return (tree[obj].ob_state & state);
}

void tree_state(OBJECT *tree, int start_obj, int state, int set)
{
	int	i;

	for (i = tree[start_obj].ob_head; i <= tree[start_obj].ob_tail; i++)
	{
		set_state(tree, i, state, set);
	}
}

/*****************************************************************************/
void set_flag(OBJECT *tree, int obj, int flag, int set)
{
	if (set)
		tree[obj].ob_flags |= flag;		/* Flag setzen */
	else
  		tree[obj].ob_flags &= ~flag;		/* Flag l”schen */
}

int get_flag(OBJECT *tree, int obj, int flag)
{
	return (tree[obj].ob_flags & flag);
}

int find_flag(OBJECT *tree, int flag)
{
	int obj = -1;

	do
	{
		obj++;
		if (tree[obj].ob_flags & flag)
			return obj;
	}
	while (!(tree[obj].ob_flags & LASTOB));
	return -1;
}

/*****************************************************************************/
void get_objframe(OBJECT *tree, int obj, GRECT *r)
{
	int	d, i;
	int	type,
			shadow = 0,
			outline = 0,
			line = 0;

	objc_offset(tree, obj, &r->g_x, &r->g_y);
	r->g_w = tree[obj].ob_width;
	r->g_h = tree[obj].ob_height;

	type = get_obtype(tree, obj, NULL);
	switch (type)
	{
		case G_STRING :
		case G_SHORTCUT :
		case G_ICON :
		case G_CICON :
			/* nichts mehr zu tun */
			return;

		case G_BUTTON:
			line = 1;
			if (tree[obj].ob_flags & DEFAULT)
				line++;
			if (tree[obj].ob_flags & EXIT)
				line++;
			if (line && tree[obj].ob_state & SHADOWED)
				shadow = 2 * line;
			break;

		case G_TEXT:
		case G_FTEXT:
			line = -(tree[obj].ob_spec.tedinfo->te_thickness);
			if (line && (tree[obj].ob_state & SHADOWED))
				shadow = abs(line * 2);
			else
				line = 0;
			break;

		case G_BOXTEXT :
		case G_FBOXTEXT:
			line = -(tree[obj].ob_spec.tedinfo->te_thickness);
			if (line && (tree[obj].ob_state & SHADOWED))
				shadow = abs (line * 2);
			break;

		case G_BOX:
		case G_IBOX:
		case G_BOXCHAR:
			line = -(tree[obj].ob_spec.obspec.framesize);
			if (line && tree[obj].ob_state & SHADOWED)
				shadow = abs (line * 2);
			break;

		default:
/*
		{
			char	s[80];
			sprintf(s, "[3][CF-Lib Hinweis: get_objframe()!|Objekt %d hat unbekannten Typ %d|!][soso]", obj, type);
			form_alert(1, s);
		}
*/
			return ;
	}

	if (tree[obj].ob_state & OUTLINED)
		outline = 3;

	if (line > 0)
	{
		outline = max(outline, line);
		shadow += line;
	}

	if (outline)
	{
		r->g_x -= outline;
		r->g_y -= outline;
		r->g_w += outline;
		r->g_h += outline;
	}

	if (shadow)
	{
		r->g_w += max(outline, shadow);
		r->g_h += max(outline, shadow);
	}
	else
	{
		r->g_w += outline;
		r->g_h += outline;
	}

	if ((appl_xgetinfo(13, &d, &i, &d, &d) && i == 1) &&
		 (tree[obj].ob_flags & FL3DACT))
	{
		int	hinc = 0, vinc = 0;

		objc_sysvar(0, 6, 0, 0, &hinc, &vinc);
		r->g_x -= hinc;
		r->g_y -= vinc;
		r->g_w += 2 * hinc;
		r->g_h += 2 * vinc;
	}
}

/*****************************************************************************/
void redraw_obj(OBJECT *tree, int obj)
{
	GRECT	r;
	
	get_objframe(tree, obj, &r);
#ifdef __MTAES__
	objc_draw(tree, ROOT, MAX_DEPTH, &r);
#else
	objc_draw(tree, ROOT, MAX_DEPTH, r.g_x, r.g_y, r.g_w, r.g_h);
#endif
}
