
#include <string.h>
#include "proto.h"

void ob_draw_chg(DIAINFO *info,int obj,GRECT *area,int new_state,boolean top)
{
	reg OBJECT *tree = info->di_tree;

	if (!top && _dia_len>0 && info!=_dia_list[_dia_len-1])
		return;

	if (!top && info->di_flag>=WINDOW)
	{
		reg OBJECT *ob = tree + obj;
		GRECT win;

		if (area)
			win = *area;
		else
		{
			objc_offset(tree,obj,&win.g_x,&win.g_y);
			win.g_x -= 3;
			win.g_y -= 3;
			win.g_w = ob->ob_width + 6;
			win.g_h = ob->ob_height + 6;
		}

		if (rc_intersect(&desk,&win))
		{
			reg int handle = info->di_handle,state = ob->ob_state,pxy[4];
			GRECT work;

			wind_update(BEG_UPDATE);
			wind_get(handle,WF_FIRSTXYWH,&work.g_x,&work.g_y,&work.g_w,&work.g_h);
			while (work.g_w>0 && work.g_h>0)
			{
				if (rc_intersect(&win,&work))
				{
					rc_grect_to_array(&work,pxy);
					_set_clip(pxy);
					if (new_state>=0)
					{
						objc_change(tree,obj,0,work.g_x,work.g_y,work.g_w,work.g_h,new_state,1);
						ob->ob_state = state;
					}
					else
						objc_draw(tree,obj,MAX_DEPTH,work.g_x,work.g_y,work.g_w,work.g_h);
				}
				wind_get(handle,WF_NEXTXYWH,&work.g_x,&work.g_y,&work.g_w,&work.g_h);
			}
			if (new_state>=0)
				ob->ob_state = new_state;
			_set_clip((int *) &clip);
			wind_update(END_UPDATE);
		}
	}
	else if (info->di_flag>CLOSED)
	{
		if (!area)
			area = &desk;
		wind_update(BEG_UPDATE);
		if (new_state>FAIL)
			objc_change(tree,obj,0,area->g_x,area->g_y,area->g_w,area->g_h,new_state,1);
		else
			objc_draw(tree,obj,MAX_DEPTH,area->g_x,area->g_y,area->g_w,area->g_h);
		wind_update(END_UPDATE);
	}
}

int ob_radio(OBJECT *tree,int parent,int object)
{
	reg int i,radio = 0,first = tree[parent].ob_head,last = tree[parent].ob_tail;
	reg OBJECT *obj;

	i = first;
	while (i>=first && i<=last)
	{
		obj = tree + i;
		if (obj->ob_flags & RBUTTON)
		{
		 	if (!(obj->ob_state & DISABLED))
		 	{
				if (radio==object)
					obj->ob_state |= SELECTED;
				else if (obj->ob_state & SELECTED)
				{
					if (object>=0)
						obj->ob_state &= ~SELECTED;
					else
						object = radio;
				}
			}
			radio++;
		}
		i = obj->ob_next;
	}
	return (object);
}

int _get_parent(OBJECT *tree,int obj)
{
	reg int index = 0,parent = 0;

	do
	{
		if (tree->ob_head<=obj && tree->ob_tail>=obj)
			parent = index;
		tree++;index++;
	}
	while (!(tree->ob_flags & LASTOB));

	return(parent);
}

int _get_hotkey(OBJECT *tree,int button)
{
	reg OBJECT *obj = &tree[button];
	reg int i,last;

	switch (obj->ob_type & (~G_MODAL))
	{
	case G_IND:
	case G_HOTKEY:
		return (button);
	case G_CHK:
	case G_RB:
		if ((button = obj->ob_next)<0)
			return (FAIL);
		obj = &tree[button];
	case G_TEXT:
	case G_FTEXT:
	case G_BOXTEXT:
	case G_FBOXTEXT:
	case G_STRING:
	case G_BUTTON:
	case G_BOXCHAR:
		if ((i=obj->ob_head)>0)
			for (last=obj->ob_tail,obj=&tree[i];i<=last;i++,obj++)
			{
				switch (obj->ob_type & (~G_MODAL))
				{
				case G_IND:
				case G_HOTKEY:
					return (i);
				}
			}
	}

	return (FALSE);
}

char ob_get_hotkey(OBJECT *tree,int button)
{
	reg int obj = _get_hotkey(tree,button);

	if (obj>0)
		return(tree[obj].ob_state>>8);
	else
		return(0);
}


int ob_set_hotkey(OBJECT *tree,int button,char hot)
{
	reg int obj = _get_hotkey(tree,button);

	if (obj>0)
	{
		reg int width,parent = _get_parent(tree,obj);
		reg OBJECT *ob_ptr = &tree[obj],*par_ptr = &tree[parent];
		reg char *text = ob_get_text(tree,parent,FALSE),*pos;

		if (text && ((pos = strchr(text,_upper(hot)))!=NULL || (pos = strchr(text,_lower(hot)))!=NULL))
		{
			width = (int) strlen(text);

			switch((unsigned char) par_ptr->ob_type)
			{
			case G_TEXT:
			case G_FTEXT:
			case G_BOXTEXT:
			case G_FBOXTEXT:
				if (par_ptr->ob_spec.tedinfo->te_font==SMALL)
					width *= gr_sw;
				else
					width *= gr_cw;

				switch (par_ptr->ob_spec.tedinfo->te_just)
				{
				case TE_LEFT:
					ob_ptr->ob_x = 0;
					break;
				case TE_RIGHT:
					ob_ptr->ob_x = par_ptr->ob_width - width;
					break;
				case TE_CNTR:
					ob_ptr->ob_x = (par_ptr->ob_width - width)>>1;
				}

				if (par_ptr->ob_spec.tedinfo->te_font==SMALL)
					ob_ptr->ob_x += (int) ((long) (pos - text) * gr_sw);
				else
					ob_ptr->ob_x += (int) ((long) (pos - text) * gr_cw);
				break;
			case G_BUTTON:
				width *= gr_cw;
				ob_ptr->ob_x = (par_ptr->ob_width - width)>>1;
				ob_ptr->ob_x += (int) ((long) (pos - text) * gr_cw);
				break;
			case G_STRING:
				ob_ptr->ob_x = (int) ((long) (pos - text) * gr_cw);
				break;
			default:
				return(FALSE);
			}
		}
		else if ((unsigned char) par_ptr->ob_type==G_BOXCHAR)
		{
			if (par_ptr->ob_spec.obspec.character==hot)
				ob_ptr->ob_x = (par_ptr->ob_width - gr_cw)>>1;
			else
				return(FALSE);
		}
		else
			return(FALSE);

		ob_ptr->ob_state &= 0x00ff;
		ob_ptr->ob_state |= _upper(hot)<<8;

		return (TRUE);
	}

	return(FALSE);
}
