/*
 * Copyright (c) 1993 Michael D. Bayne.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *    following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. All advertising materials mentioning features or use of this software must display the following
 *    acknowledgement:
 *
 *       This product includes software developed by Michael D. Bayne.
 *
 * 4. My name may not be used to endorse or promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY MICHAEL D. BAYNE ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL MICHAEL D. BAYNE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <exec/types.h>
#include <dos/dos.h>
#include <libraries/commodities.h>
#include <devices/inputevent.h>

#include <clib/exec_protos.h>
#include <clib/utility_protos.h>
#include <clib/commodities_protos.h>
#include <clib/alib_protos.h>

#include "defs.h"

LONG openMainWindow( VOID );
VOID closeMainWindow( VOID );
VOID CxBFunc( CxMsg *CxMessage, CxObj *CxObject );

extern	struct	NewBroker nbBroker;
extern	struct	Task  *bTask, *Task;
extern	struct	bPrefObject bPrefs;
	struct	MsgPort *bPort;
	CxObj	*bBroker, *pHotKey, *bHotKey, *objectList;
	ULONG	cxSigFlag, cxBlankFlag, timeCount = 0;

VOID __interrupt __saveds CxBFunc( CxMsg *CxMessage, CxObj *CxObject )
{
	struct InputEvent *Event = ( struct InputEvent * )CxMsgData( CxMessage );

	if( Event->ie_Class == IECLASS_TIMER ) {
		if( !bTask ) {
			if( ++timeCount >= bPrefs.bTimeout ) {
				Signal( Task, cxBlankFlag );
				timeCount = 0;
			}
		}
	} else if(( Event->ie_Class != IECLASS_RAWKEY )||(!( Event->ie_Code & IECODE_UP_PREFIX ))) {
		if( bTask ) {
			Signal( bTask, SIGBREAKF_CTRL_C );
			bTask = 0L;
		}
		timeCount = 0;
	}
}

LONG handleCxMess( VOID )
{
	ULONG msgid, msgtype;
	CxMsg *msg;

	while( msg = ( CxMsg * )GetMsg( bPort )) {
		msgid = CxMsgID( msg );
		msgtype = CxMsgType( msg );
		ReplyMsg(( struct Message * )msg );

		switch( msgtype ) {
		case CXM_IEVENT:
			switch( msgid ) {
			case EVT_CX_POPUP:
				openMainWindow();
				break;
			case EVT_CX_BLANK:
				Signal( Task, cxBlankFlag );
				break;
			}
			break;
		case CXM_COMMAND:
		switch( msgid ) {
			case CXCMD_DISABLE:
				ActivateCxObj( bBroker, 0l );
				break;
			case CXCMD_ENABLE:
				ActivateCxObj( bBroker, 1l );
				break;
			case CXCMD_KILL:
				return( QUIT );
				break;
			case CXCMD_APPEAR:
			case CXCMD_UNIQUE:
				openMainWindow();
				break;
			case CXCMD_DISAPPEAR:
				closeMainWindow();
				break;
			default:
				break;
			}
		default:
			break;
		}
	}
	return( OK );
}

VOID ShutdownCX( VOID )
{
	CxMsg *msg;

	if( bPort ) {
		if( bBroker ) DeleteCxObjAll( bBroker );
		bBroker = 0l;
		while( msg = ( CxMsg * )GetMsg( bPort )) ReplyMsg(( struct Message * )msg );
		DeletePort( bPort );
		bPort = 0l;
	}
}

LONG UpdateCX( VOID )
{
	ActivateCxObj( bBroker, 0l );

	DeleteCxObj( objectList );
	DeleteCxObj( pHotKey );
	DeleteCxObj( bHotKey );

	if( objectList = CxCustom( CxBFunc, 0L )) AttachCxObj( bBroker, objectList );
	if( pHotKey = HotKey( bPrefs.pKey, bPort, EVT_CX_POPUP )) AttachCxObj( bBroker, pHotKey );
	if( bHotKey = HotKey( bPrefs.bKey, bPort, EVT_CX_BLANK )) AttachCxObj( bBroker, bHotKey );

	if(!( CxObjError( bBroker ))) ActivateCxObj( bBroker, 1l );
	else {
		ShutdownCX();
		return( QUIT );
	}
	return( OK );
}

LONG SetupCX( VOID )
{
	LONG cxError;

	ShutdownCX();
	if( bPort = CreatePort( 0L, 0 )) {
		nbBroker.nb_Port = bPort;
		cxSigFlag = 1L << bPort->mp_SigBit;
		bBroker = CxBroker( &nbBroker, &cxError );
		switch( cxError ) {
		case CBERR_OK:
			objectList = CxCustom( CxBFunc, NULL );
			AttachCxObj( bBroker, objectList );
			if( pHotKey = HotKey( bPrefs.pKey, bPort, EVT_CX_POPUP )) AttachCxObj( bBroker, pHotKey );
			if( bHotKey = HotKey( bPrefs.bKey, bPort, EVT_CX_BLANK )) AttachCxObj( bBroker, bHotKey );
			if(!( CxObjError( bBroker ))) {
				ActivateCxObj( bBroker, 1l );
				return( OK );
			}
			DeleteCxObjAll( bBroker );
			bBroker = 0l;
		}
		DeletePort( bPort );
		bPort = 0l;
	}
	return( QUIT );
}
