/*
\\		Hook functions for editor class
//
\\		These are to interface the class with the host program,
//		with more power than the notification system
\\
*/

	#include "Editor.h"

SAVEDS ULONG h_tab( struct ClassData *data, ULONG xpos )
{
	/* Returns number of characters to next tab position, 	*/
	/* either calculating from data->tabsize, or asking hook */

	ULONG count;
	struct tabmsg tm;

	if( data->tabhook ) 
	{
		tm.currx = xpos;
		count = CallHookPkt( data->tabhook, data->obj, &tm );	/* Call hook */
	}
	else
	{
		count = data->tabsize - (xpos % data->tabsize);	/* Calculate */
		if( count == data->tabsize ) count = 0;
	}

	return( count );
}

SAVEDS ULONG h_input( struct ClassData *data, struct MUIP_HandleInput *msg )
{
	/* Convert imsg to internal format, or ask hook to do so */

	ULONG retcode;
	struct inputmsg mymessage;
	struct IntuiMessage *imsg = msg->imsg;

	/* Parse imsg to get custom message */

	if( imsg->Class & IDCMP_RAWKEY )
	{
		switch( imsg->Code )
		{
			case 0x4E:		/* Cursor right */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_EOL;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_NW;
							else retcode = MSG_SPECIAL|SPC_NC;
							break;
			case 0x4F:		/* Cursor left */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_SOL;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_PW;
							else retcode = MSG_SPECIAL|SPC_PC;
							break;
			case 0x4C:		/* Cursor up */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_PP;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_SOF;
							else retcode = MSG_SPECIAL|SPC_PL;
							break;
			case 0x4D:		/* Cursor down */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_NP;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_EOF;
							else retcode = MSG_SPECIAL|SPC_NL;
							break;
			default:		retcode = MSG_SPECIAL|SPC_NOP;	/* Any unknown chars... */
		}
	}
	else if( imsg->Class & IDCMP_VANILLAKEY )
	{
		switch( imsg->Code )
		{
			case 0x08:		/* Delete (backspace) */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_DSOL;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_DPW;
							else retcode = MSG_SPECIAL|SPC_DPC;
							break;
			case 0x7F:		/* Delete (forwards) */
							if( imsg->Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
								retcode = MSG_SPECIAL|SPC_DEOL;
							else if( imsg->Qualifier & (IEQUALIFIER_LALT|IEQUALIFIER_RALT) )
								retcode = MSG_SPECIAL|SPC_DNW;
							else retcode = MSG_SPECIAL|SPC_DNC;
							break;
			case 0xF8:		/* This gets churned up occasionally... Is it important? */
							retcode = MSG_SPECIAL|SPC_NOP;
							break;
			case 0x0D:		/* A carriage return (use as a newline) */
							retcode = MSG_CHAR|0x0A;
							break;
			default:			/* If it's nothing else... */
							retcode = MSG_CHAR|(imsg->Code&0xFF);
							break;
		}
	}
	if(data->flags&USESYSKEYS)	/* Do they want the MUI defined keys? */
	{
		switch( msg->muikey )	/* Any not used are treated like normal keys */
		{
			case MUIKEY_UP:			retcode = MSG_SPECIAL|SPC_PL;	break;
			case MUIKEY_DOWN:			retcode = MSG_SPECIAL|SPC_NL;	break;
			case MUIKEY_PAGEUP:		retcode = MSG_SPECIAL|SPC_PP;	break;
			case MUIKEY_PAGEDOWN:	retcode = MSG_SPECIAL|SPC_NP;	break;
			case MUIKEY_TOP:			retcode = MSG_SPECIAL|SPC_SOF;	break;
			case MUIKEY_BOTTOM:		retcode = MSG_SPECIAL|SPC_EOF;	break;
			case MUIKEY_LEFT:			retcode = MSG_SPECIAL|SPC_PC;	break;
			case MUIKEY_RIGHT:		retcode = MSG_SPECIAL|SPC_NC;	break;
			case MUIKEY_WORDLEFT:	retcode = MSG_SPECIAL|SPC_PW;	break;
			case MUIKEY_WORDRIGHT:	retcode = MSG_SPECIAL|SPC_NW;	break;
			case MUIKEY_LINESTART:	retcode = MSG_SPECIAL|SPC_SOL;	break;
			case MUIKEY_LINEEND:		retcode = MSG_SPECIAL|SPC_EOL;	break;
			case MUIKEY_GADGET_NEXT:retcode = MSG_SPECIAL|SPC_NOBJ;break;
			case MUIKEY_GADGET_PREV:retcode = MSG_SPECIAL|SPC_POBJ;break;
		}
	}

	/* Call the hook if it's around... */

	if( data->inputhook )
	{
		mymessage.defaction	= retcode;	/* Default action */
		mymessage.imsg			= imsg;		/* Actual imsg */
		retcode = CallHookA( data->inputhook, data->obj, (APTR) &mymessage ); /* User Hook */
	}

	set( data->obj, MUIA_Editor_LastCode, retcode );
	return( retcode );
}

SAVEDS void h_print( struct ClassData *data, struct rendermsg *msg, UWORD ypos )
{
	/* Print specified line, either using internal thingum, or asking user hook */

	if( data->rp.BitMap )		/* Very important we have a bitmap to render into */
	{
		msg->rp				= &data->rp;			/* Fill in misc data */
		msg->tf				= data->font;
		msg->textcol		= data->textcol;
		msg->backcol		= data->backcol;
		msg->marktextcol	= data->seltextcol;
		msg->markbackcol	= data->selbackcol;
		msg->curstextcol	= data->curstextcol;
		msg->cursbackcol	= data->cursbackcol;
		msg->linelen		= data->colsvisible;
		msg->xsize			= _mwidth(data->obj);

		if( msg->xsize )
		{
			if( data->renderhook )
				CallHookPkt( data->renderhook, data->obj, msg );/* Call user hook... */
			else draw_internal( data, msg );							/* ...if there IS one */
		}
		BltBitMapRastPort( data->rp.BitMap, 0, 0, _rp(data->obj), _mleft(data->obj), ypos, _mwidth(data->obj), data->font->tf_YSize, 0xC0 );
	}
}
