/*--------------------------------------------------------------------------*/
/*	File name:	WIN_OBJS.C						Revision date:	1999.12.15	*/
/*	Revised by:	Ronald Andersson				Revision start:	1999.12.13	*/
/*--------------------------------------------------------------------------*/
/*	This source text contains the actual routines for						*/
/*	the window-frame manager												*/
/*--------------------------------------------------------------------------*/
/*	Tabulator width: 4														*/
/*--------------------------------------------------------------------------*/
#include <tos.h>
#include <magic\mt_aes.h>
#include <string.h>
#include "globals.h"
#include "win_objs.h"
#include "winframe.h"

int t_bar_l_rim, t_bar_r_rim;
int	t_bar_height;
int	v_bar_x_end, v_bar_width;
int	h_bar_l_rim, h_bar_r_rim;
int	h_bar_y_end, h_bar_height;

int	l_rim, r_rim, h_rim;
int	t_rim, b_rim, v_rim;

int	max_obj = 19;				/* highest object index used	*/

#define	T_BAR_SZ	5
#define	H_BAR_SZ	3
#define	V_BAR_SZ	3

int	t_bar_ob[T_BAR_SZ] =
{	O_CLOSER,	O_NAME,			O_BDROP,	O_ICONIFIER,	O_FULLER
};
int	t_bar_kf[T_BAR_SZ] =
{	CLOSER,		TOP_WINOBJS,	-1,			ICONIFIER,		FULLER
};

int	v_bar_ob[V_BAR_SZ] =
{	O_UP,		O_VSCROLL,		O_DOWN
};
int	v_bar_kf[V_BAR_SZ] =
{	UPARROW,	RGT_WINOBJS,	DNARROW
};

int	h_bar_ob[H_BAR_SZ] =
{	O_LEFT,		O_HSCROLL,		O_RIGHT
};
int	h_bar_kf[H_BAR_SZ] =
{	LFARROW,	BOT_WINOBJS,	RTARROW
};

int	t_bar_flex_ix	=	1;
int	v_bar_flex_ix	=	1;
int	h_bar_flex_ix = 1;

/*--------------------------------------------------------------------------*/
/*	global initialisation stage one											*/
/*--------------------------------------------------------------------------*/
void global_init1()
{
	register int i, j;
	int	xmin, xmax, ymin, ymax, tmp1;
	int	winw = win_tree[O_FRAME].ob_width;
	int	winh = win_tree[O_FRAME].ob_height;

	int	abs_objs[] =
	{	O_CLOSER,O_NAME,O_BDROP,O_ICONIFIER,O_FULLER,
		O_UP,O_VSCROLL,O_DOWN,
		O_LEFT,O_HSCROLL,O_RIGHT,
		O_SIZER,0
	};
		
/*	win_tree[O_FRAME].ob_type = G_IBOX;	*/
	while( win_tree[O_FRAME].ob_tail >= O_UP_IMG )
		objc_delete( win_tree, win_tree[O_FRAME].ob_tail );

	if	(win_tree[O_UP].ob_type != G_BOXCHAR)
	{	win_tree[O_UP_IMG].ob_x = 0;
		win_tree[O_UP_IMG].ob_y = 0;
		objc_add(win_tree, O_UP, O_UP_IMG);
	}

	if	(win_tree[O_DOWN].ob_type != G_BOXCHAR)
	{	win_tree[O_DOWN_IMG].ob_x = 0;
		win_tree[O_DOWN_IMG].ob_y = 0;
		objc_add(win_tree, O_DOWN, O_DOWN_IMG);
	}

	if	(win_tree[O_LEFT].ob_type != G_BOXCHAR)
	{	win_tree[O_LEFT_IMG].ob_x = 0;
		win_tree[O_LEFT_IMG].ob_y = 0;
		objc_add(win_tree, O_LEFT, O_LEFT_IMG);
	}

	if	(win_tree[O_RIGHT].ob_type != G_BOXCHAR)
	{	win_tree[O_RIGHT_IMG].ob_x = 0;
		win_tree[O_RIGHT_IMG].ob_y = 0;
		objc_add(win_tree, O_RIGHT, O_RIGHT_IMG);
	}

	xmin=16;  ymin=16;  xmax=winw-16;  ymax=winh-16;
	for	(i = 0; ((j = abs_objs[i]) != 0); i++)
	{	if	(win_tree[j].ob_x < xmin)
			xmin = win_tree[j].ob_x;
		if	(win_tree[j].ob_x+win_tree[j].ob_width > xmax)
			xmax = win_tree[j].ob_x+win_tree[j].ob_width;
		if	(win_tree[j].ob_y < ymin)
			ymin = win_tree[j].ob_y;
		if	(win_tree[j].ob_y+win_tree[j].ob_height > ymax)
			ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	}
	l_rim = (xmin > 0) ? xmin : 0;
	t_rim = (ymin > 0) ? ymin : 0;
	r_rim = ((winw-xmax) > 0) ? winw-xmax : 0;
	b_rim = ((winh-ymax) > 0) ? winh-ymax : 0;

	h_rim = l_rim + r_rim;
	v_rim = t_rim + b_rim;

	xmin = winw;  xmax = 0;  ymin = winh;  ymax = 0;
	for	(i = 0;  i < T_BAR_SZ; i++)
	{	for	(j = i+1;  j < T_BAR_SZ; j++)
		{	if	(win_tree[t_bar_ob[j]].ob_x<win_tree[t_bar_ob[i]].ob_x)
			{	tmp1 = t_bar_ob[i];
				t_bar_ob[i] = t_bar_ob[j];
				t_bar_ob[j] = tmp1;
				tmp1 = t_bar_kf[i];
				t_bar_kf[i] = t_bar_kf[j];
				t_bar_kf[j] = tmp1;
			}
		}
		j = t_bar_ob[i];
		if	(j == O_NAME)
			t_bar_flex_ix =	i;
		if  (win_tree[j].ob_x < xmin)
			xmin = win_tree[j].ob_x;
		if  (win_tree[j].ob_x+win_tree[j].ob_width > xmax)
			xmax = win_tree[j].ob_x+win_tree[j].ob_width;
		if  (win_tree[j].ob_y < ymin)
			ymin = win_tree[j].ob_y;
		if  (win_tree[j].ob_y+win_tree[j].ob_height > ymax)
			ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	}
	t_bar_l_rim	= (xmin > 0) ? xmin : 0;
	t_bar_r_rim = ((winw - xmax) > 0) ? winw-xmax : 0;
	t_bar_height = ymax-t_rim;

	xmin = winw;  xmax = 0;  ymin = winh;  ymax = 0;
	for	(i = 0;  i < V_BAR_SZ; i++)
	{	for	(j = i+1;  j < V_BAR_SZ; j++)
		{	if	(win_tree[v_bar_ob[j]].ob_x<win_tree[v_bar_ob[i]].ob_x)
			{	tmp1 = v_bar_ob[i];
				v_bar_ob[i] = v_bar_ob[j];
				v_bar_ob[j] = tmp1;
				tmp1 = v_bar_kf[i];
				v_bar_kf[i] = v_bar_kf[j];
				v_bar_kf[j] = tmp1;
			}
		}
		j = v_bar_ob[i];
		if	(j == O_VSCROLL)
			v_bar_flex_ix =	i;
		if  (win_tree[j].ob_x < xmin)
			xmin = win_tree[j].ob_x;
		if  (win_tree[j].ob_x+win_tree[j].ob_width > xmax)
			xmax = win_tree[j].ob_x+win_tree[j].ob_width;
		if  (win_tree[j].ob_y < ymin)
			ymin = win_tree[j].ob_y;
		if  (win_tree[j].ob_y+win_tree[j].ob_height > ymax)
			ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	}
	j = O_SIZER;
	if  (win_tree[j].ob_x < xmin)
		xmin = win_tree[j].ob_x;
	if  (win_tree[j].ob_x+win_tree[j].ob_width > xmax)
		xmax = win_tree[j].ob_x+win_tree[j].ob_width;
	if  (win_tree[j].ob_y < ymin)
		ymin = win_tree[j].ob_y;
	if  (win_tree[j].ob_y+win_tree[j].ob_height > ymax)
		ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	v_bar_x_end	= xmax;
	v_bar_width = xmax-xmin;

	xmin = winw;  xmax = 0;  ymin = winh;  ymax = 0;
	for	(i = 0;  i < H_BAR_SZ; i++)
	{	for	(j = i+1;  j < H_BAR_SZ; j++)
		{	if	(win_tree[h_bar_ob[j]].ob_x<win_tree[h_bar_ob[i]].ob_x)
			{	tmp1 = h_bar_ob[i];
				h_bar_ob[i] = h_bar_ob[j];
				h_bar_ob[j] = tmp1;
				tmp1 = h_bar_kf[i];
				h_bar_kf[i] = h_bar_kf[j];
				h_bar_kf[j] = tmp1;
			}
		}
		j = h_bar_ob[i];
		if	(j == O_VSCROLL)
			h_bar_flex_ix =	i;
		if  (win_tree[j].ob_x < xmin)
			xmin = win_tree[j].ob_x;
		if  (win_tree[j].ob_x+win_tree[j].ob_width > xmax)
			xmax = win_tree[j].ob_x+win_tree[j].ob_width;
		if  (win_tree[j].ob_y < ymin)
			ymin = win_tree[j].ob_y;
		if  (win_tree[j].ob_y+win_tree[j].ob_height > ymax)
			ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	}
	j = O_SIZER;
	if  (win_tree[j].ob_x < xmin)
		xmin = win_tree[j].ob_x;
	if  (win_tree[j].ob_x+win_tree[j].ob_width > xmax)
		xmax = win_tree[j].ob_x+win_tree[j].ob_width;
	if  (win_tree[j].ob_y < ymin)
		ymin = win_tree[j].ob_y;
	if  (win_tree[j].ob_y+win_tree[j].ob_height > ymax)
		ymax = win_tree[j].ob_y+win_tree[j].ob_height;
	h_bar_l_rim	= (xmin > 0) ? xmin : 0;
	h_bar_r_rim = ((winw - xmax) > 0) ? winw-xmax : 0;
	h_bar_y_end = ymax;
	h_bar_height	= ymax-ymin;
}
/*--------------------------*/
/*	ends:	global_init1	*/
/*--------------------------------------------------------------------------*/
/*	global initialisation stage two											*/
/*--------------------------------------------------------------------------*/
void global_init2()
{
	TEDINFO *te;
	int		i;

	win_tree[O_INFO].ob_height = h_inw;
	te = win_tree[O_INFO].ob_spec.tedinfo;
	te->te_just  = 3;			/* TE_SPECIAL */
	te->te_font  = 4;			/* PFINFO */
	te->te_junk1 = (WORD) (((LONG) (settings->finfo_inw)) >> 16L);
	te->te_junk2 = (WORD) (((LONG) (settings->finfo_inw)));

	if	(settings->flags & NO_BDROP)
		for	(i = 0; i < T_BAR_SZ; i++)
			if	(t_bar_ob[i] == O_BDROP)
				t_bar_kf[i] = 0;
}
/*--------------------------*/
/*	ends:	global_init2	*/
/*--------------------------------------------------------------------------*/
/*	Calculate slider size or position										*/
/*																			*/
/* promille:		0..1000													*/
/* maxpos:			Actual region is 0..maxpos-1							*/
/*--------------------------------------------------------------------------*/
static WORD calc_slider( WORD promille, WORD maxpos )
{
	LONG u;

	promille <<= 1;
	u = ((LONG) promille) * ((LONG) maxpos);
	u /= 1000L;
	u += 1L;
	u >>= 1L;
	return((WORD) u);
}
/*--------------------------*/
/*	ends:	calc_slider		*/
/*--------------------------------------------------------------------------*/
/*	Calculates the size of the frame for wind_calc().						*/
/*	The frame can then either be added to the internal size 				*/
/*	or subtracted from the external size.									*/
/*--------------------------------------------------------------------------*/
static void wcalc_frame( WININFO *wi, WORD *fg )
{	*fg++ = (l_rim) ? l_rim : 1;	/* Left frame */
	*fg = t_rim;					/* Top frame */
	if	(wi->kind & TOP_WINOBJS)
		*fg += t_bar_height;
	if	(wi->is_info)
		*fg += h_inw;
	if	(*fg == 0)
		*fg = 1;
	fg++;
	*fg = r_rim;					/* Right frame */
	if	(wi->is_rgtobjects)
		*fg += v_bar_width;
	if	(*fg == 0)
		*fg = 1;
	fg++;
	*fg = b_rim;					/* Bottom frame */
	if	(wi->is_botobjects)
		*fg += h_bar_height;
	if	(*fg == 0)
		*fg = 1;
}
/*--------------------------*/
/*	ends:	wcalc_frame		*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Initialises a window, i.e. creates the object tree						*/
/*--------------------------------------------------------------------------*/
void wbm_create( WININFO *wi )
{
	/* Copy object tree */
	/* ----------------- */

	memcpy(wi->tree, win_tree, N_OBJS*sizeof(OBJECT));
	memcpy(&(wi->ted_name),
			win_tree[O_NAME].ob_spec.tedinfo,
			sizeof(TEDINFO));
	memcpy(&(wi->ted_info),
			win_tree[O_INFO].ob_spec.tedinfo,
			sizeof(TEDINFO));

	wi->ted_name.te_ptext = wi->name;
	wi->ted_info.te_ptext = wi->info;
	wi->tree[O_NAME].ob_spec.tedinfo = &wi->ted_name;
	wi->tree[O_INFO].ob_spec.tedinfo = &wi->ted_info;
}
/*----------------------*/
/*	ends:	wbm_create	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Initialises a window whose type has been established					*/
/*	i.e. the object tree will be chained.									*/
/*	At this all immovable objects are already assigned their				*/
/*	correct position														*/
/*--------------------------------------------------------------------------*/
void wbm_skind( WININFO *wi )
{
	register int	i, j;
	register OBJECT	*tree;
	int				tmp1, tmp2;
	WORD			xl,xr,yt,yb,next_yb;


	/* Calculate minimum size */
	/* ---------------------- */

	wi->min.g_h = v_rim;
	if	(wi->kind & TOP_WINOBJS)
		wi->min.g_h += t_bar_height;
	if	(wi->kind & INFO)
		wi->min.g_h += h_inw;
	if	(wi->kind & UPARROW)
		wi->min.g_h += win_tree[O_UP].ob_height;
	if	(wi->kind & DNARROW)
		wi->min.g_h += win_tree[O_DOWN].ob_height;
	if	(wi->kind & VSLIDE)
		wi->min.g_h += 4;
	if	(wi->kind & (SIZER | RGT_WINOBJS))
		wi->min.g_h += h_bar_height;
	if	(wi->min.g_h == 0)
		wi->min.g_h = 2;

	wi->min.g_w = h_bar_l_rim + h_bar_r_rim;
	if	(wi->kind & LFARROW)
		wi->min.g_w += win_tree[O_LEFT].ob_width;
	if	(wi->kind & HSLIDE)
		wi->min.g_w += 4;
	if	(wi->kind & RTARROW)
		wi->min.g_w += win_tree[O_RIGHT].ob_width;
	if	(wi->kind & SIZER)
		wi->min.g_w += v_bar_width;

	i = t_bar_l_rim + t_bar_r_rim;
	if	(wi->kind & CLOSER)
		i += win_tree[O_CLOSER].ob_width;
	if	(wi->kind & NAME)
		i += 4;
	if	((wi->kind & TOP_WINOBJS) && !(settings->flags & NO_BDROP))
		i += win_tree[O_BDROP].ob_width;
	if	(wi->kind & ICONIFIER)
		i += win_tree[O_ICONIFIER].ob_width;
	if	(wi->kind & FULLER)
		i += win_tree[O_FULLER].ob_width;

	if	(i > wi->min.g_w)
		wi->min.g_w = i;

	if	(wi->min.g_w == 0)
		wi->min.g_w = 2;

	/* First of all remove all objects */
	/* ------------------------------- */

	for	(i = 0, tree = wi->tree; i <= max_obj; i++,tree++)
	{	tree->ob_next = -1;
		if	((i != O_UP) && (i != O_DOWN) &&
			 (i != O_LEFT) && (i != O_RIGHT))
			tree->ob_head = tree->ob_tail = -1;
	}
	tree = wi->tree;
	
	/* Case: Iconified window */
	/* ---------------------- */

	if	(wi->state & ICONIFIED)
	{	tree[O_NAME].ob_x = 0;
		objc_add(tree, O_FRAME, O_NAME);
		wi->is_rgtobjects = wi->is_botobjects =
			wi->is_sizer = wi->is_info = 0;
		return;
	}


	if	(wi->state & SHADED)
		wi->is_rgtobjects = wi->is_sizer =
				wi->is_botobjects = wi->is_info = 0;
	else
	{	wi->is_rgtobjects =
			(	wi->kind & RGT_WINOBJS)
			||	(	(wi->kind & SIZER)
			&&	!(wi->kind & BOT_WINOBJS)
			);
		wi->is_sizer	=	(wi->kind & SIZER)
						||	(	(wi->kind & RGT_WINOBJS)
							&&	(wi->kind & BOT_WINOBJS)
							);
		wi->is_botobjects = (wi->kind & BOT_WINOBJS);
		wi->is_info = (wi->kind & INFO);
	}

	/* Take frame into consideration */
	/* ----------------------------- */

	yt = t_rim;

	/* Top elements */
	/* ------------ */

	if	(wi->kind & TOP_WINOBJS)
	{	xl = t_bar_l_rim;
		xr = tree[O_FRAME].ob_width - t_bar_r_rim;

		for	(i = 0; i < t_bar_flex_ix; i++)
		{	if	(wi->kind & t_bar_kf[i])
			{	j = t_bar_ob[i];
				tree[j].ob_x = xl;
				tree[j].ob_y = win_tree[j].ob_y;
				xl += win_tree[j].ob_width;
				objc_add(tree, O_FRAME, j);
			}
		}

		for	(i = T_BAR_SZ-1; i > t_bar_flex_ix; i--)
		{	if	(wi->kind & t_bar_kf[i])
			{	j = t_bar_ob[i];
				xr -= win_tree[j].ob_width;
				tree[j].ob_x = xr;
				tree[j].ob_y = win_tree[j].ob_y;
				objc_add(tree, O_FRAME, j);
			}
		}
		j = O_NAME;
		tree[j].ob_x = xl;
		tree[j].ob_y = win_tree[j].ob_y;
		tree[j].ob_width = ((xr-xl) > 0) ? xr-xl : 0;
		objc_add(tree, O_FRAME, j);
		yt += t_bar_height;
	}

	/* INFO */
	/* ---- */

	if	(wi->is_info)
	{	tree[O_INFO].ob_x = win_tree[O_INFO].ob_x;
		tree[O_INFO].ob_y = yt;
		tree[O_INFO].ob_width = win_tree[O_INFO].ob_width
				+ tree[O_FRAME].ob_width-win_tree[O_FRAME].ob_width;
		objc_add(tree, O_FRAME, O_INFO);
		yt += h_inw;
	}

	/* Bottom elements */
	/* --------------- */

	yb = tree[O_FRAME].ob_height - b_rim;
	next_yb = yb;
	xl = h_bar_l_rim;
	xr = tree[O_FRAME].ob_width - h_bar_r_rim;

	if	(wi->is_botobjects)
	{	for	(i = 0; i < h_bar_flex_ix; i++)
		{	if	(wi->kind & h_bar_kf[i])
			{	j = h_bar_ob[i];
				tree[j].ob_x = xl;
				tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
				xl += win_tree[j].ob_width;
				objc_add(tree, O_FRAME, j);
			}
		}
		next_yb = yb - h_bar_height;
	}
	if	(wi->is_sizer && (wi->kind & SIZER))
	{	j = O_SIZER;
		xr -= win_tree[j].ob_width;
		tree[j].ob_x = xr;
		tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
		objc_add(tree, O_FRAME, j);
		next_yb = yb - h_bar_height;
	}
	if	(wi->is_botobjects)
	{	for	(i = H_BAR_SZ-1; i > h_bar_flex_ix; i--)
		{	if	(wi->kind & h_bar_kf[i])
			{	j = h_bar_ob[i];
				xr -= win_tree[j].ob_width;
				tree[j].ob_x = xr;
				tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
				objc_add(tree, O_FRAME, j);
			}
		}
		j = O_HSCROLL;
		tree[j].ob_x = xl;
		tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
		tree[j].ob_width = ((xr-xl) > 0) ? xr-xl : 0;
		objc_add(tree, O_FRAME, j);

		if	(wi->kind & HSLIDE)
		{	objc_add(tree, O_HSCROLL, O_HSLIDE);
			i = LBLACK;
		}
		else
		{	i = LWHITE;
		}
		tree[O_HSCROLL].ob_spec.obspec.interiorcol = i;
	}
	yb = next_yb;

	/* Right elements */
	/* -------------- */

	if	(wi->is_rgtobjects)
	{	xr = tree[O_FRAME].ob_width - r_rim;

		for	(i = 0; i < v_bar_flex_ix; i++)
		{	if	(wi->kind & v_bar_kf[i])
			{	j = v_bar_ob[i];
				tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
				tree[j].ob_y = yt;
				yt += win_tree[j].ob_height;
				objc_add(tree, O_FRAME, j);
			}
		}
		for	(i = V_BAR_SZ-1; i > v_bar_flex_ix; i--)
		{	if	(wi->kind & v_bar_kf[i])
			{	j = v_bar_ob[i];
				yb -= win_tree[j].ob_height;
				tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
				tree[j].ob_y = yb;
				objc_add(tree, O_FRAME, j);
			}
		}
		j = O_VSCROLL;
		tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
		tree[j].ob_y = yt;
		tree[j].ob_height =  ((yb-yt) > 0) ? yb-yt : 0;
		objc_add(tree, O_FRAME, j);

		if	(wi->kind & VSLIDE)
		{	objc_add(tree, O_VSCROLL, O_VSLIDE);
			i = LBLACK;
		}
		else
		{	i = LWHITE;
		}
		tree[O_VSCROLL].ob_spec.obspec.interiorcol = i;
	}
}
/*----------------------*/
/*	ends:	wbm_skind	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Sets slider position and size.											*/
/*	Is only called if a corresponding VSLIDE/HSLIDE							*/
/*	has been registered.													*/
/*--------------------------------------------------------------------------*/
void wbm_sslid( WININFO *wi, WORD vertical )
{	WORD i,j;
	register OBJECT *tree = wi->tree;

	if	(vertical)
	{	j = tree[O_VSCROLL].ob_height;
		if	(wi->vslsize < 0)
			i = win_tree[O_VSLIDE].ob_height;
		else
			i = calc_slider(wi->vslsize, j);

		if	(i < win_tree[O_VSLIDE].ob_height)
			i = win_tree[O_VSLIDE].ob_height;
		if	(i >= j)
		{	i = j;
		}
		tree[O_VSLIDE].ob_height = i;

		j -= i;				/* Subtract minimum slider width */
		if	(j < 0)
			j = 0;
		i = calc_slider(wi->vslide, j);
		tree[O_VSLIDE].ob_y = i;
	}
	else
	{	j = tree[O_HSCROLL].ob_width;
		if	(wi->hslsize < 0)
			i = win_tree[O_HSLIDE].ob_width;
		else
			i = calc_slider(wi->hslsize, j);

		if	(i < win_tree[O_HSLIDE].ob_width)
			i = win_tree[O_HSLIDE].ob_width;
		if	(i >= j)
			i = j;
		tree[O_HSLIDE].ob_width = i;

		j -= i;				/* Subtract minimum slider width */
		if	(j < 0)
			j = 0;
		i = calc_slider(wi->hslide, j);
		tree[O_HSLIDE].ob_x = i;
	}
}
/*----------------------*/
/*	ends:	wbm_sslid	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Window position and/or size has altered.								*/
/*--------------------------------------------------------------------------*/
void wbm_ssize( WININFO *wi )
{
	WORD frame[4];
	register int i,j,xl,xr,yt,yb;
	register OBJECT *tree = wi->tree;
	register GRECT *og;
	GRECT g;
	int	next_yb;


	/* Update window structure */
	/* ----------------------- */

	wi->overall = wi->curr;

	if	(wi->state & SHADED)
	{	i = (wi->state & ICONIFIED) ? NAME+MOVER : wi->kind;
		wbm_calc(i, frame);
	}
	else
		wcalc_frame(wi, frame);

	wi->work.g_x = wi->curr.g_x + frame[0];
	wi->work.g_y = wi->curr.g_y + frame[1];
	frame[0] += frame[2];
	frame[1] += frame[3];
	wi->work.g_w = wi->curr.g_w - frame[0];
	if	(wi->work.g_w < 0)
		wi->work.g_w = 0;
	wi->work.g_h = wi->curr.g_h - frame[1];
	og = (GRECT *) &(tree[O_FRAME].ob_x);
	og->g_x = wi->curr.g_x;
	og->g_y = wi->curr.g_y;
	if	((og->g_w == wi->curr.g_w) && (og->g_h == wi->curr.g_h))
		return;
	og->g_w = wi->curr.g_w;
	og->g_h = wi->curr.g_h;

	/* Case: Iconified window */
	/* ---------------------- */

	if	(wi->state & ICONIFIED)
	{	tree[O_NAME].ob_width = wi->curr.g_w;
		return;
	}

	/* Take frame into consideration */
	/* ----------------------------- */

	g = wi->curr;
	g.g_x = 0;
	g.g_y = t_rim;
	g.g_h -= v_rim;

	/* Top elements */
	/* ------------ */

	if	(wi->kind & TOP_WINOBJS)
	{
		xl = g.g_x + t_bar_l_rim;
		xr = g.g_x + g.g_w - t_bar_r_rim;

		/* Top left elements */
		/* ------------------ */

		for	(i = 0; i < t_bar_flex_ix; i++)
		{	if	(wi->kind & t_bar_kf[i])
			{	j = t_bar_ob[i];
				xl += win_tree[j].ob_width;
			}
		}

		/* Top right elements */
		/* ------------------- */

		for	(i = T_BAR_SZ-1; i > t_bar_flex_ix; i--)
		{	if	(wi->kind & t_bar_kf[i])
			{	j = t_bar_ob[i];
				xr -= win_tree[j].ob_width;
				tree[j].ob_x = xr;
			}
		}

		/* Top centred elements */
		/* -------------------- */

		tree[O_NAME].ob_width = ((xr-xl) > 0) ? xr-xl : 0;
		g.g_y += t_bar_height;
		g.g_h -= t_bar_height;
	}

	/* INFO */
	/* ---- */

	if	(wi->is_info)
	{	tree[O_INFO].ob_width = win_tree[O_INFO].ob_width
				+ tree[O_FRAME].ob_width-win_tree[O_FRAME].ob_width;
		g.g_y += h_inw;
		g.g_h -= h_inw;
	}

	/* Bottom elements */
	/* --------------- */

	yb = g.g_y + g.g_h;
	xr = g.g_x + g.g_w - h_bar_r_rim;
	next_yb = yb;
	
	if	(wi->is_botobjects)
	{	xl = g.g_x + h_bar_l_rim;

		for	(i = 0; i < h_bar_flex_ix; i++)
		{	if	(wi->kind & h_bar_kf[i])
			{	j = h_bar_ob[i];
				tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
				xl += win_tree[j].ob_width;
			}
		}
		next_yb = yb - h_bar_height;
	}

	if	(wi->kind & SIZER)
	{	j = O_SIZER;
		xr -= win_tree[j].ob_width;
		tree[j].ob_x = xr;
		tree[j].ob_y =  win_tree[j].ob_y - h_bar_y_end + yb;
		next_yb = yb - h_bar_height;
	}

	if	(wi->is_botobjects)
	{	for	(i = H_BAR_SZ-1; i > h_bar_flex_ix; i--)
		{	if	(wi->kind & h_bar_kf[i])
			{	j = h_bar_ob[i];
				xr -= win_tree[j].ob_width;
				tree[j].ob_x = xr;
				tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
			}
		}
		j = O_HSCROLL;
		tree[j].ob_y = win_tree[j].ob_y - h_bar_y_end + yb;
		tree[j].ob_width = ((xr-xl) > 0) ? xr-xl : 0;

		if	(wi->kind & HSLIDE)
		{	j = O_HSLIDE;
			if	(wi->hslsize < 0)
				i = win_tree[j].ob_width;
			else
				i = calc_slider(wi->hslsize, tree[O_HSCROLL].ob_width);
			if	(i < win_tree[j].ob_width)
				i = win_tree[j].ob_width;
			if	(i >= tree[O_HSCROLL].ob_width)
				i = tree[O_HSCROLL].ob_width;
			tree[j].ob_width = i;

			i = tree[O_HSCROLL].ob_width - i;	/* Subtract min slider width */
			if	(i < 0)
				i = 0;
			else
				i = calc_slider(wi->hslide, i);
			tree[j].ob_x = i;
		}
	}
	g.g_h	-= yb-next_yb;
	yb = next_yb;

	/* Right elements */
	/* -------------- */

	if	(wi->is_rgtobjects)
	{	yt = g.g_y;
		xr = g.g_x + g.g_w - r_rim;

		for	(i = 0; i < v_bar_flex_ix; i++)
		{	if	(wi->kind & v_bar_kf[i])
			{	j = v_bar_ob[i];
				tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
				yt += win_tree[j].ob_height;
			}
		}
		for	(i = V_BAR_SZ-1; i > v_bar_flex_ix; i--)
		{	if	(wi->kind & v_bar_kf[i])
			{	j = v_bar_ob[i];
				yb -= win_tree[j].ob_height;
				tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
				tree[j].ob_y = yb;
			}
		}
		j = O_VSCROLL;
		tree[j].ob_x = win_tree[j].ob_x - v_bar_x_end + xr;
		tree[j].ob_height = ((yb-yt) > 0) ? yb-yt : 0;

		if	(wi->kind & VSLIDE)
		{	j = O_VSLIDE;
			if	(wi->vslsize < 0)
				i = win_tree[j].ob_height;
			else
				i = calc_slider(wi->vslsize, yb);
			if	(i < win_tree[j].ob_height)
				i = win_tree[j].ob_height;
			if	(i >= tree[O_VSCROLL].ob_height)
				i = tree[O_VSCROLL].ob_height;
			tree[j].ob_height = i;

			i = tree[O_VSCROLL].ob_height - i;	/* Subtract min slider width */
			if	(i < 0)
				i = 0;
			else
				i = calc_slider(wi->vslide, i);
			tree[j].ob_y = i;
		}
	}
}
/*----------------------*/
/*	ends:	wbm_ssize	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	The text for INFO or NAME has changed.									*/
/*--------------------------------------------------------------------------*/

void wbm_sstr( WININFO *wi )
{
	wi->ted_name.te_ptext = wi->name;
	wi->ted_info.te_ptext = wi->info;
}
/*----------------------*/
/*	ends:	wbm_sstr	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	The attribute bit has changed, i.e.										*/
/*	SHADED, ACTIVE or ICONIFIED												*/
/*--------------------------------------------------------------------------*/
void wbm_sattr( WININFO *wi, WORD chbits )
{
	WORD newfont;


	if	(chbits & ACTIVE)
	{	if	(wi->state & ACTIVE)
		{	wi->ted_name.te_ucolor.te_color &= ~0x800;	/* Black text */
			wi->ted_info.te_ucolor.te_color &= ~0x800;
			if	(wi->kind & VSLIDE)
				wi->tree[O_VSCROLL].ob_spec.obspec.interiorcol = LBLACK;
			if	(wi->kind & HSLIDE)
				wi->tree[O_HSCROLL].ob_spec.obspec.interiorcol = LBLACK;
		}
		else
		{	wi->ted_name.te_ucolor.te_color |= 0x800;	/* Grey text */
			wi->ted_info.te_ucolor.te_color |= 0x800;
			if	(wi->kind & VSLIDE)
				wi->tree[O_VSCROLL].ob_spec.obspec.interiorcol = LWHITE;
			if	(wi->kind & HSLIDE)
				wi->tree[O_HSCROLL].ob_spec.obspec.interiorcol = LWHITE;
		}
	}

	if	(chbits & ICONIFIED)
	{	if	(wi->state & ICONIFIED)
		{	newfont = SMALL;
		}
		else
		{	newfont = IBM;
		}
		wi->ted_name.te_font = newfont;
	}

	if	(chbits & (SHADED | ICONIFIED))
		wbm_skind(wi);
}
/*----------------------*/
/*	ends:	wbm_sattr	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Returns the frame for window type <kind>.								*/
/*--------------------------------------------------------------------------*/
void wbm_calc( WORD kind, WORD *fg )
{
	WORD is_rgtobjects,is_botobjects;


	is_rgtobjects = (kind & RGT_WINOBJS) ||
			((kind & SIZER) && !(kind & BOT_WINOBJS));
	is_botobjects = (kind & BOT_WINOBJS);


	*fg++ = (l_rim) ? l_rim : 1;			/* Left frame */
	*fg = t_rim;			/* Top frame */
	if	(kind & TOP_WINOBJS)
		*fg += t_bar_height;
	if	(kind & INFO)
		*fg += h_inw;
	if	(*fg == 0)
		*fg = 1;
	fg++;
	*fg = r_rim;			/* Right frame */
	if	(is_rgtobjects)
		*fg += v_bar_width;
	if	(*fg == 0)
		*fg = 1;
	fg++;
	*fg = b_rim;			/* Bottom frame */
	if	(is_botobjects)
		*fg += h_bar_height;
	if	(*fg == 0)
		*fg = 1;
}
/*----------------------*/
/*	ends:	wbm_calc	*/
/*--------------------------------------------------------------------------*/
/*	MANAGER FUNCTION														*/
/*																			*/
/*	Returns the associated object for the mouse position (x,y).				*/
/*--------------------------------------------------------------------------*/
WORD wbm_obfind( WININFO *wi, WORD x, WORD y )
{
	WORD obj;

	obj = objc_find(wi->tree, 0, 8, x, y);
	if	(obj >= O_UP_IMG)
		obj	-= O_UP_IMG-O_UP;
	return(obj);
}
/*--------------------------*/
/*	ends:	wbm_obfind		*/
/*--------------------------------------------------------------------------*/
/*	End of file:	WIN_OBJS.C												*/
/*--------------------------------------------------------------------------*/
