/*
 *	Copyright (c) 1993 Michael D. Bayne.
 *	All rights reserved.
 *
 *	Please see the documentation accompanying the distribution for distribution and disclaimer information.
 */

#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"
#include "Blanker_rev.h"

#include "protos/main.h"
#include "protos/messaging.h"

#ifdef DICE
__interrupt __geta4 VOID CxBFunc( CxMsg *, CxObj * );
#endif
#ifdef SASC
VOID __interrupt __saveds CxBFunc( CxMsg *, CxObj * );
#endif

struct	MsgPort		*bPort;
CxObj			*bBroker, *pHotKey, *bHotKey, *objectList;
ULONG			cxSigFlag, cxBlankFlag, timeCount = 0;
struct	NewBroker	nbBroker = { NB_VERSION, "Blanker", VERS, "A system friendly screen blanker",
			NBU_UNIQUE|NBU_NOTIFY, COF_SHOW_HIDE, 0, 0, 0 };

#ifdef DICE
__interrupt VOID CxBFunc( CxMsg *CxMessage, CxObj *CxObject )
#endif
#ifdef SASC
VOID __interrupt __saveds CxBFunc( CxMsg *CxMessage, CxObj *CxObject )
#endif
{
	struct InputEvent *Event = ( struct InputEvent * )CxMsgData( CxMessage );

	if( Event->ie_Class == IECLASS_TIMER ) {
		if( ++timeCount >= bPrefs->bp_Timeout ) {
			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->bp_PopKey, bPort, EVT_CX_POPUP )) AttachCxObj( bBroker, pHotKey );
	if( bHotKey = HotKey( bPrefs->bp_BlankKey, bPort, EVT_CX_BLANK )) AttachCxObj( bBroker, bHotKey );

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

LONG SetupCX( VOID )
{
	LONG cxError;

	if( bPort = CreatePort( 0L, 0 )) {
		nbBroker.nb_Pri = bPrefs->bp_Priority;
		nbBroker.nb_Port = bPort;
		cxSigFlag = 1L << bPort->mp_SigBit;
		bBroker = CxBroker( &nbBroker, &cxError );
		if( cxError == CBERR_OK ) return( UpdateCX());
		else ShutdownCX();
	}
	return( QUIT );
}

LONG CheckCX( VOID )
{
	LONG cxError;

	bBroker = CxBroker( &nbBroker, &cxError );
	DeleteCxObj( bBroker );
	if( cxError == CBERR_OK ) return( OK );
	return( QUIT );
}
