/* ------------------------------------------------------------------------- */
/* ----- Let 'em Fly!   V 1.2 ------------ (c) 1991-93 by Oliver Scheel ---- */
/* ------------------------------------------------------------------------- */
/* ----- Module: ltmf_utl.c   Utilities ------------------------------------ */
/* ------------------------------------------------------------------------- */

#include <stdio.h>
#include <macros.h>
#include <tos.h>
#include <smallaes.h>
#include <vdi.h>
#include <magx_old.h>
#include <portab.h>

#include "ltmf_str.h"
#include "ltmf_def.h"

/* ------------------------------------------------------------------------- */

EXTERN	WORD	global[];
EXTERN	MAGX_COOKIE	*magx;

/* ------------------------------------------------------------------------- */

WORD	vwk_handle = 0,
	planes,
	colors,
	sysfont;

WORD	line_width,
	line_color,
	txt_height,
	txt_color,
	alig_vert,
	alig_hor,
	write_mode;

/* WORD	work_in[11] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2 };
*/
WORD	work_out[57];

WORD	gl_wchar,
	gl_hchar,
	gl_wbox,
	gl_hbox;

WORD	act_mode = 0,
	ind_mode = 0;

GRECT	wi_max;

LONG	oldstack;

/* ------------------------------------------------------------------------- */

CHAR *strrev(CHAR *s);

/* ------------------------------------------------------------------------- */
/* ----- utilities --------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

WORD isupper(WORD ch)
{
	return((ch >= 'A') && (ch <= 'Z'));
}

WORD islower(WORD ch)
{
	return((ch >= 'a') && (ch <= 'z'));
}

WORD isdigit(WORD ch)
{
	return((ch >= '0') && (ch <= '9'));
}

WORD isalpha(WORD ch)
{
	return(isupper(ch) || islower(ch));
}

WORD isalnum(WORD ch)
{
	return(isalpha(ch) || isdigit(ch));
}

WORD isfname(WORD ch)
{
	return(isalnum(ch) || ((ch >= '!') && (ch <= '-'))
			|| ((ch >= ':') && (ch <= '?'))
			|| (ch == '[') || (ch == '@')
			|| ((ch >= ']') && (ch <= '`'))
			|| ((ch >= '{') && (ch <= '~')));
}

WORD ispname(WORD ch)
{
	return(isfname(ch) || (ch == '\\') || (ch == '.'));
}

WORD isedctrl(WORD ch)
{
	return((ch == 27) || (ch == 8) || (ch == 127) || (ch == 0));
}

WORD toupper(WORD ch)
{
	return(ch - (islower(ch) ? 'a' - 'A' : 0));
}

WORD tolower(WORD ch)
{
	return(ch + (isupper(ch) ? 'a' - 'A' : 0));
}

WORD stricmp(CHAR *s1, CHAR *s2)
{
	REG CHAR	c1, c2;

	while((c1 = tolower(*s1++)) == (c2 = tolower(*s2++)))
	{
		if(c1 == '\0')
			return(0);
	}
	return(c1 - c2);
}

WORD strnicmp(CHAR *s1, CHAR *s2, WORD len)
{
	REG CHAR	c1, c2;

	while((c1 = tolower(*s1++)) == (c2 = tolower(*s2++)))
	{
		if((c1 == '\0') || !(--len))
			return(0);
	}
	return(c1 - c2);
}

CHAR	_numstr[] = { "0123456789ABCDEF" };

CHAR *itoa(WORD n, CHAR *buf, WORD radix)
{
	REG CHAR	*p1,
			*p2;

	p1 = buf;
	if(n < 0)
	{
		*p1++ = '-';
		n = -n;
	}
	p2 = p1;
	do
	{
		*p1++ = _numstr[n % radix];
	}
	while((n /= radix) > 0);
	*p1 = '\0';
	strrev(p2);
	return(buf);
}

/* ------------------------------------------------------------------------- */

VOID go_super(VOID)
{
	oldstack = Super( (VOID *) 1L );		/* get current  mode */
	if ( oldstack == 0L )
	{
		oldstack = Super( 0L );
	}
}

VOID go_user(VOID)
{
	if ( oldstack != -1L )
	{
		Super( (VOID *) oldstack );
	}
}

/* ------------------------------------------------------------------------- */
/* ----- get_cookie -------------------------------------------------------- */
/* ------------------------------------------------------------------------- */

LONG *get_cookie(LONG cookie)
{
	COOKJAR	*cookiejar;
	WORD	i = 0;

	go_super();
	cookiejar = *((COOKJAR **)0x05a0l);
	go_user();
	if(cookiejar)
	{
		while(cookiejar[i].id)
		{
			if(cookiejar[i].id == cookie)
				return(cookiejar[i].ptr);
			i++;
		}
	}
	return(0l);
}

/* ------------------------------------------------------------------------- */
/* ----- GEM Utilities ----------------------------------------------------- */
/* ------------------------------------------------------------------------- */

/* ----- workstation handler ----------------------------------------------- */

WORD vwk_init(VOID)
{
	WORD	handle;
	WORD	attrib[10];
	WORD	d;

	handle = graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
/*	v_opnvwk(work_in, &handle, work_out);
*/	vq_extnd(handle, 1, work_out);
	planes = work_out[4];
	vq_extnd(handle, 0, work_out);
	colors = work_out[13];
	vqt_attributes(handle, attrib);
	if(AESVersion() >= 0x0400)
	{
		appl_getinfo(0, &sysfont, &d, &d, &d);
	}
	else
	{
		switch(gl_hchar)
		{
			case 16 :
				sysfont = 13;
				break;
			case 32 :
				sysfont = 26;
				break;
			default :
				sysfont = 6;
				break;
		}
	}
/*	sysfont = (gl_hchar == 16) ? 13 : 6;
*/	txt_height = attrib[7];
	txt_color = attrib[1];
	alig_hor = attrib[3];
	alig_vert = attrib[4];
	vql_attributes(handle, attrib);
	line_color = attrib[1];
	line_width = attrib[3];
	write_mode = attrib[2];
	if((AESVersion() >= 0x0340) && !magx)
	{
		objc_sysvar(0, 1, 0, 0, &ind_mode, &d);
		objc_sysvar(0, 2, 0, 0, &act_mode, &d);
	}
	return(handle);
}

VOID vwk_exit(WORD handle)
{
	WORD	d;

	vst_alignment(handle, alig_hor, alig_vert, &d, &d);
	vst_height(handle, txt_height, &d, &d, &d, &d);
	vst_color(handle, txt_color);
	vswr_mode(handle, write_mode);
	vsl_color(handle, line_color);
	vsl_width(handle, line_width);
}

/* ----- object x/y/w/h ---------------------------------------------------- */

VOID obj_xywh(OBJECT *tree, WORD obj, GRECT *p)
{
	objc_offset(tree, obj, &p->g_x, &p->g_y);
	p->g_w = tree[obj].ob_width;
	p->g_h = tree[obj].ob_height;
}

/* ----- object clipping size ---------------------------------------------- */

VOID STDARGS obj_clsize(OBJECT *tree, WORD obj, WORD *x, WORD *y, WORD *w, WORD *h)
{
	WORD	outl = 0,
		shad = 0;
	OBJECT	*tr;

	objc_offset(tree, obj, x, y);
	tr = &tree[obj];
	switch(tr->ob_type & 0xff)
	{
		case G_BUTTON :	outl--;
				if(tr->ob_flags & EXIT)
				{
					outl--;
					if(tr->ob_flags & DEFAULT)
						outl--;
				}
				break;
		case G_BOX	:
		case G_IBOX	:
		case G_BOXCHAR	: outl = tr->ob_spec.obspec.framesize;
				  break;
		case G_BOXTEXT	:
		case G_FBOXTEXT	: outl = tr->ob_spec.tedinfo->te_thickness;
	}
	if(tr->ob_state & OUTLINED)
	{
		if(outl > -3)
			outl = -3;
	}
	if(tr->ob_state & SHADOWED)
		shad = 2 * ((outl < 0) ? -outl : outl);
	if(outl >= 0)
		outl = 0;

	if((AESVersion() >= 0x0400) && (tr->ob_flags & FL3DIND))
		outl -= 2;

	*x += outl;
	*y += outl;
	*w = tr->ob_width + shad - outl * 2;
	*h = tr->ob_height + shad - outl * 2;
}

/* ----- update object ----------------------------------------------------- */

VOID obj_update(OBJECT *tree, WORD obj)
{
	GRECT	p;

	obj_xywh(tree, obj, &p);
	objc_draw(tree, obj, MAX_DEPTH, p.g_x, p.g_y, p.g_w, p.g_h);
}

/* ----- copy rectangle ---------------------------------------------------- */

VOID rc_copy(GRECT *src, GRECT *dest)
{
	dest->g_x = src->g_x;
	dest->g_y = src->g_y;
	dest->g_w = src->g_w;
	dest->g_h = src->g_h;
}

/* ----- intersection of two rectangles ------------------------------------ */

WORD rc_intersect(VRECT *v1, VRECT *v2)
{
	WORD	x, y, w, h;

	x = max(v2->v_x1, v1->v_x1);
	y = max(v2->v_y1, v1->v_y1);
	w = min(v2->v_x2, v1->v_x2);
	h = min(v2->v_y2, v1->v_y2);

	return((w >= x) && (h >= y));
}

/* ----- convert VRECT to GRECT -------------------------------------------- */

VOID rc_vtog(VRECT *src, GRECT *dest)
{
	dest->g_x = src->v_x1;
	dest->g_y = src->v_y1;
	dest->g_w = src->v_x2 - src->v_x1 + 1;
	dest->g_h = src->v_y2 - src->v_y1 + 1;
}

/* ----- convert GRECT to VRECT -------------------------------------------- */

VOID rc_gtov(GRECT *src, VRECT *dest)
{
	dest->v_x1 = src->g_x;
	dest->v_y1 = src->g_y;
	dest->v_x2 = src->g_x + src->g_w - 1;
	dest->v_y2 = src->g_y + src->g_h - 1;
}
