/********************************************************************
 *																	*
 *	WinLIB PRO Revision II: Dialog manipulation module				*
 *	by Ken Hollis													*
 *																	*
 *	Copyright (C) 1994, Bitgate Software							*
 *																	*
 ********************************************************************/

#include <aes.h>
#include <stdio.h>

#include "winlib.h"

#ifdef __TURBOC__
#pragma warn -pia
#endif

#ifndef __DIALOG__
#define __DIALOG__
#endif

/*
 *	Update dialog box in window
 *
 *	win = Window to update
 *	x, y, w, h = Area to redraw
 */
GLOBAL void WUpdateWindowDlg(WINDOW *win, int x, int y, int w, int h, int obj)
{
	if (win->tree) {
		GRECT own, temp;

		own.g_x = x;
		own.g_y = y;
		own.g_w = w;
		own.g_h = h;

		wind_update(BEG_UPDATE);
		wind_update(BEG_MCTRL);

		WWindGet(win, WF_FIRSTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h);
		while (temp.g_w && temp.g_h) {
			if (rc_intersect(&temp, &own))
				if ((obj == 0) || ((win->tree[obj].ob_type & 0x0F) == G_IMAGE))
					objc_draw(win->tree, 0, 99, temp.g_x, temp.g_y, temp.g_w, temp.g_h);
				else
					objc_draw(win->tree, obj, 2, temp.g_x, temp.g_y, temp.g_w, temp.g_h);

			WWindGet(win, WF_NEXTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h);
		}

		wind_update(END_MCTRL);
		wind_update(END_UPDATE);
	}
}

GLOBAL void WUpdateWindowDlgLevel(WINDOW *win, int x, int y, int w, int h, int obj, int level)
{
	if (win->tree) {
		GRECT own, temp;

		own.g_x = x;
		own.g_y = y;
		own.g_w = w;
		own.g_h = h;

		wind_update(BEG_UPDATE);
		wind_update(BEG_MCTRL);

		WWindGet(win, WF_FIRSTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h);
		while (temp.g_w && temp.g_h) {
			if (rc_intersect(&temp, &own))
				objc_draw(win->tree, obj, level, temp.g_x, temp.g_y, temp.g_w, temp.g_h);

			WWindGet(win, WF_NEXTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h);
		}

		wind_update(END_MCTRL);
		wind_update(END_UPDATE);
	}
}

/*
 *	Custom replacement for form_button
 *
 *	Should match pretty exactly the workings of form_button
 *	except that it handles dialogboxes in windows correctly, as
 *	well as being able to handle background clicks.
 */
GLOBAL int WForm_button(WINDOW *win, int obj, int clicks, int *nxtobj)
{
	OBJECT *tree = win->tree, *obptr = tree + obj;
	int flags = obptr->ob_flags;
	int state = obptr->ob_state;

	wind_update(BEG_MCTRL);

	if (clicks == 2) {}
	if (clicks == 3) {}
	if ((flags & SELECTABLE) && ! (state & DISABLED)) {
		*nxtobj = obj;

		if ((flags & RBUTTON) && (state & SELECTED))
			no_click();
		else {
			state ^= SELECTED;
			if (flags & (RBUTTON | TOUCHEXIT)) {
				if (flags & SELECTABLE)
					Objc_Change(win->tree, obj, 0, state, 1);

				if (flags & RBUTTON) {
					register int act = obj, lst, new;

					for (;;) {
						lst = act;
						new = obptr->ob_next;

						for (;;) {
							act = new;
							obptr = tree + act;

							if (obptr->ob_tail == lst) {
								new = obptr->ob_head;
								lst = act;
							} else {
								if (act == obj)
									goto rb_exit;

								if ((obptr->ob_state & SELECTED) && (obptr->ob_flags & RBUTTON)) {
									Objc_Change(win->tree, act, 0, obptr->ob_state ^ SELECTED, 1);
									goto rb_exit;
								} else
									break;
							}
						}
					}
rb_exit:			no_click();
				}
			} else {
				register OBJECT *ob = tree + obj;
				EVENT event;
				int x, y, dummy, events;

				event.ev_mflags = MU_BUTTON | MU_M1;
				event.ev_mbclicks = 1;
				event.ev_bmask = 0x11;
				event.ev_mbstate = 0;

				objc_offset(tree, obj, &event.ev_mm1x, &event.ev_mm1y);
				event.ev_mm1width = ob->ob_width;
				event.ev_mm1height = ob->ob_height;

				graf_mkstate(&x, &y, &dummy, &dummy);
				if (rc_inside(x, y, (GRECT *) &event.ev_mm1x)) {
					event.ev_mm1flags = 1;
					Objc_Change(win->tree, obj, 0, ob->ob_state ^ SELECTED, 1);
				} else
					event.ev_mm1flags = 0;

				do {
					events = EvntMulti(&event);
					if (events & MU_M1)	{
						event.ev_mm1flags = 1 - event.ev_mm1flags;
						Objc_Change(win->tree, obj, 0, ob->ob_state ^ SELECTED, 1);
					}
				}
				while (!(events & MU_BUTTON));

				if (!(ob->ob_state & SELECTED))
					*nxtobj = 0;
			}
		}
	} else
		if (flags & EDITABLE)
			*nxtobj = obj;
		else
			*nxtobj = 0;

	wind_update(END_MCTRL);

	if (*nxtobj)
		if (win->tree[*nxtobj].ob_flags & (EXIT | TOUCHEXIT))
			return 0;

	return 1;
}