/********************************************************************
 *																	*
 *	Dispatcher calling module										*
 *	by Karl 0ygard and Ken Hollis									*
 *																	*
 *	Copyright (c) Clever Bits and Bitgate Software 1993 - 1994		*
 *	All Rights Reserved.											*
 *																	*
 *	Handles windows and the dispatching of information between each	*
 *	window.															*
 *																	*
 ********************************************************************
 *																	*
 *	Update log:														*
 *	[12.9.93 - 24.9.93] Karl A. 0ygard								*
 *		not documented												*
 *	[24.9.93 - 24.2.94] Ken Hollis									*
 *		(all dispatchers) - made smarter (checks window type before	*
 *							calling a dispatcher; this assures no	*
 *							bombs in case a wrong dispatcher is		*
 *							called by mistake)						*
 *		WCallTmrDispatcher-	fixed up so calls window structures		*
 *		WCallTMDDispatcher- timer mode change dispatcher added		*
 *																	*
 ********************************************************************/

#include "winlib.h"

#ifdef __TURBOC__
#pragma warn -pia
#endif

void *_MainDispatcher;
void *_MainKeyDispatcher;

#ifndef __DISPATCH__
#define __DISPATCH__
#endif

/*
 *	Calls dispatcher procedures for window win, if existant
 *	Returns TRUE, if dispatcher procedure didn't handle message (returned FALSE),
 *		or if dispatcher procedure does not exist.
 */
LOCAL int WCallWndDispatcherSub(WINDOW *win, int msg_buf[], int Dispatcher(WINDOW *, int[]))
{
	if ((Dispatcher = win->WndDispatcher) && (win->handle > 0))
		return Dispatcher(win, msg_buf) ? FALSE : TRUE;

	return TRUE;
}

GLOBAL int WCallWndDispatcher(WINDOW *win, int msg_buf[])
{ return WCallWndDispatcherSub(win, msg_buf, WCallWndDispatcher); }

GLOBAL int WCallDlgDispatcher(WINDOW *win, int message)
{
	int msg_buf[8] = {WM_DIALOG, 0, 0, 0, 0, 0, 0, 0};

	if (win->state & W_DIALOG) {
		msg_buf[3] = message;
		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallWKeyDispatcher(WINDOW *win, int key)
{
	int msg_buf[8] = {WM_KEYBD, 0, 0, 0, 0, 0, 0, 0};

	if ((win->state & W_DIALOG) ||
		(win->state & W_TEXT) ||
		(win->state & W_DESKTOP) ||
		(win->state & W_TIMER) ||
		(win->state & W_FLYING)) {
		msg_buf[3] = key;
		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallBtnDispatcher(WINDOW *win, int mx, int my, int button, int kstate, int bclicks)
{
	int msg_buf[8] = {WM_BUTTON, 0, 0, 0, 0, 0, 0, 0};

	if ((win->state & W_DIALOG) ||
		(win->state & W_TEXT) ||
		(win->state & W_DESKTOP) ||
		(win->state & W_TIMER) ||
		(win->state & W_FLYING)) {
		msg_buf[3] = mx;
		msg_buf[4] = my;
		msg_buf[5] = button;
		msg_buf[6] = kstate;
		msg_buf[7] = bclicks;
		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallTxtDispatcher(WINDOW *win, int message)
{
	int msg_buf[8] = {WM_TEXT, 0, 0, 0, 0, 0, 0, 0};

	if (win->state & W_TEXT) {
		msg_buf[3] = message;
		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallFKeyDispatcher(WINDOW *win, int fkeynum)
{
	int msg_buf[8] = {WM_FKEY, 0, 0, 0, 0, 0, 0, 0};

	msg_buf[3] = fkeynum;
	return WCallWndDispatcher(win, msg_buf);
}

GLOBAL int WCallHelpDispatcher(WINDOW *win)
{
	int msg_buf[8] = {WM_HELP, 0, 0, 0, 0, 0, 0, 0};

	if ((win->state & W_DIALOG) ||
		(win->state & W_TEXT) ||
		(win->state & W_DESKTOP) ||
		(win->state & W_TIMER) ||
		(win->state & W_FLYING)) {
		if ((win->state & W_DIALOG) ||
			(win->state & W_FLYING))
			msg_buf[3] = 1;

		if (win->state & W_DESKTOP)
			msg_buf[3] = DESKTOP;

		if ((win->state & W_TEXT) ||
			(win->state & W_TIMER))
			msg_buf[3] = 2;

		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallUndoDispatcher(WINDOW *win)
{
	int msg_buf[8] = {WM_UNDO, 0, 0, 0, 0, 0, 0, 0};

	if ((win->state & W_DIALOG) ||
		(win->state & W_TEXT) ||
		(win->state & W_DESKTOP) ||
		(win->state & W_TIMER) ||
		(win->state & W_FLYING)) {
		if ((win->state & W_DIALOG) ||
			(win->state & W_FLYING))
			msg_buf[3] = 1;

		if (win->state & W_DESKTOP)
			msg_buf[3] = DESKTOP;

		if ((win->state & W_TEXT) ||
			(win->state & W_TIMER))
			msg_buf[3] = 2;

		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallResetDispatcher(WINDOW *win, int mode)
{
	int msg_buf[8] = {WM_KBRESET, 0, 0, 0, 0, 0, 0, 0};

	msg_buf[3] = mode;
	return WCallWndDispatcher(win, msg_buf);
}

GLOBAL int WCallHotkeyDispatcher(WINDOW *win, int key, int objnum)
{
	int msg_buf[8] = {WM_HOTKEY, 0, 0, 0, 0, 0, 0, 0};

	if (win->state & W_DIALOG) {
		msg_buf[3] = key;
		msg_buf[4] = objnum;
		return WCallWndDispatcher(win, msg_buf);
	}

	return(TRUE);
}

GLOBAL int WCallTmrDispatcher(WINDOW *win)
{ 
	int msg_buf[8] = {WM_TIMER, 0, 0, 0, 0, 0, 0, 0};

	if (win->state & W_TIMER) {
		msg_buf[3] = win->handle;

		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallTMDDispatcher(WINDOW *win, int mode)
{
	int msg_buf[0] = {WM_TIMECHG, 0, 0, 0, 0, 0, 0};

	if (win->state & W_TIMER) {
		msg_buf[3] = win->handle;
		msg_buf[4] = mode;

		return WCallWndDispatcher(win, msg_buf);
	}

	return TRUE;
}

GLOBAL int WCallIconifyDispatcher(WINDOW *win, int mode)
{
	int msg_buf[0] = { 0, 0, 0, 0, 0, 0, 0};
	BOOL dispret;

	if (win->state & W_FULLERICONIFIES) {
		msg_buf[0] = (mode) ? WM_ICONIFIED : WM_UNICONIFIED;
		msg_buf[3] = win->handle;

		dispret = WCallWndDispatcher(win, msg_buf);

		if (!dispret)
			win->state &= ~W_ICONIFIED;

		return dispret;
	}

	return TRUE;
}

GLOBAL int WCallEtcDispatcherSub(int msg_buf[], int Dispatcher(int[]))
{
	if (Dispatcher = _MainDispatcher)
		return Dispatcher(msg_buf) ? FALSE : TRUE;

	return TRUE;
}

GLOBAL int WCallEtcDispatcher(int msg_buf[])
{ return WCallEtcDispatcherSub(msg_buf, WCallEtcDispatcher); }


LOCAL int WCallKeyDispatcherSub(int key, int Dispatcher(int))
{
	if (Dispatcher = _MainKeyDispatcher)
		return Dispatcher(key) ? FALSE : TRUE;

	return TRUE;
}

GLOBAL int WCallKeyDispatcher(int key)
{ return WCallKeyDispatcherSub(key, WCallKeyDispatcher); }
