
/*
 *	Function	HandleEvents
 *	Programmer	N.d'Alterio
 *	Date		11/09/95
 *
 *  Synopsis:	This is the event handler for the GUI of SpoolWatch
 *		it watches for the normal IDCMP messages and also
 *		watches for CTRL-C and update signals. Also changes
 *		window size in line with number of files. Ignores any
 *		files which cannot be placed in a max size window.
 *
 *  Arguments:	struct Window    *win		Pointer to window.
 *		struct IntuiText *it		IntuiText template
 *		struct SWArgs    *swa		Program arguments.
 *		struct FullInfo  *nfi		News FullInfo structure.
 *		struct FullInfo  *mfi		Mail FullInfo structure.
 *
 *  Returns:	0				If successfull.
 *		>0				If error.
 *
 *  Variables:	 done				Loop exit flag
 *		 exit_code			Function return code.
 *		 cur_display			What window is showing flag.
 *		 timer_on			Timer success flag.
 *		 num_mail			Number of mail in spool.
 *		 num_news			Number of news in spool.
 *		 max_lines			Max number of msgs.
 *		 max_screen_lines		Number of lines that a screen can take.
 *		 max_win_height			Height of large window.
 *		*nit				News IntuiText struct.
 *		*mit				Mail IntuiText struct.
 *		*title_str			Small window title.
 *		 signals			Returned from Wait().
 *		*msg				Message from IDCMP.
 *		*tr				Time request struct.
 *		*time_msgp			Pointer to timer message port.
 * 
 *  Functions:	UpdateTitleStr			Updates small window title string (SW)
 *		MaxLinesForScreen		Returns how many text lines can fit on screen (SW)
 *		SetWindowTitles			Sets title for window (INT)
 *		CountSpool			Counts message in spool (SW)
 *		BuildIntuiText			Creates IntuiText linked list (SW)
 *		Wait				Waits for a signal (EXEC)
 *		GT_GetIMsg			Gadtools get message (GADTOOLS)
 *		GT_ReplyIMsg			Gadtool reply to a message (GADTOOLS)
 *		PrintIText			Prints text to window. (INT)
 *		ChangeWindowBox			Changes size + position of window (INT)
 *		GT_BeginRefresh			Gadtools refresh window (GADTOOLS)
 *		GT_EndRefresh			Gadtool stop window refresh (GADTOOLS)
 *		FreeIntuiText			Frees IntuiText linked list (SW)
 *		SWError				Display error message (SW)
 *		SendIO				Sends IO request (EXEC)
 *		WaitIO				Waits for IO request to finish (EXEC)
 *		OpenDevice			Opens a device (EXEC)
 *		CloseDevice			Closes a device (EXEC)
 *		CreatePort			Creates a message port (EXEC)
 *		DeletePort			Deletes a message port (EXEC)
 *		CreateExtIO			Creates an IO request (ALIB)
 *		DeleteExtIO			Deletes IO request (ALIB)
 *		
 *  $Id: HandleEvents.c 2.10 1995/09/30 22:02:21 daltern Exp $
 *
 */

#include "SpoolWatch.h"

#define NEWS 0
#define MAIL 1

int HandleEvents( struct Window *win, struct Gadget *gad, struct IntuiText *it, struct SWArgs *swa,
                                      struct FullInfo *nfi, struct FullInfo *mfi )

{

  int done;
  int exit_code;
  int cur_display;
  int timer_on;

  int num_mail;
  int num_news;
  int max_lines;
  int max_screen_lines;

  long int max_win_height;

  struct IntuiText *nit;
  struct IntuiText *mit;

  char title_str[25];

  ULONG signals;

  struct IntuiMessage *msg;

  struct timerequest *tr;
  struct MsgPort     *time_msgp;
 
  timer_on = FALSE;
  if ( time_msgp = (struct MsgPort *)CreatePort( NULL, 0 ) ) {
	if ( tr = (struct timerequest *)CreateExtIO( time_msgp, sizeof( struct timerequest ) ) ) {
		if ( !OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)tr, 0 ) ) {

			tr->tr_node.io_Command = TR_ADDREQUEST;
  			tr->tr_time.tv_secs    = swa->delay;
			tr->tr_time.tv_micro   = 0;

			SendIO( (struct IORequest *)tr );
			timer_on = TRUE;
			
		} else {

			DeleteExtIO( (struct IORequest *)tr );
			DeletePort( time_msgp );

		}   /* end if OpenDev */
	} else {

		DeletePort( time_msgp );

	}   /* end if CreateExtIo */
  }   /* end if CreatePort */

  if ( timer_on ) { 

/*
 *   Set title until 1st event occurs.
 */

  	UpdateTitleStr( title_str, nfi, mfi );
 	SetWindowTitles( win, title_str, (UBYTE *) -1 );
  
  	num_mail = CountSpool( mfi );
  	num_news = CountSpool( nfi );

  	max_lines = (num_news>num_mail) ? num_news : num_mail;

	if ( max_lines > ( max_screen_lines = MaxLinesForScreen( win, gad ) ) ) {
		max_lines = max_screen_lines;;
		SWError( swa, win, "Max window size too small\n Ignoring some articles" );
	}   /* end if max_lines */

  	nit = BuildIntuiText( it, nfi, max_lines ); 
  	mit = BuildIntuiText( it, mfi, max_lines );

  	if ( nit && mit ) {

		max_win_height = win->MaxHeight;
		done = FALSE;
		while ( !done ) {

			signals = Wait( (1L<<win->UserPort->mp_SigBit) | (1L<<time_msgp->mp_SigBit) | SIGBREAKF_CTRL_C );

/*
 *   Time update signal received.
 */

			if ( signals & (1L<<time_msgp->mp_SigBit) ) {
	
				GetMsg( time_msgp );

/*
 *   Free old FullInfo structures and make new updated 
 *   structs. Then if any change update the text structures
 *   and the window size. Number of text lines is limited to
 *   the number of lines that can fit on screen - anything else
 *   is ignored.
 */

				FreeFullInfo( nfi );
				FreeFullInfo( mfi );

				nfi            = FullSpoolInfo( swa, NEWS_TYPE );
				mfi            = FullSpoolInfo( swa, MAIL_TYPE );
				num_mail       = CountSpool( mfi );
				num_news       = CountSpool( nfi );
				max_lines  = (num_news>num_mail) ? num_news : num_mail;

				UpdateTitleStr( title_str, nfi, mfi );

				FreeIntuiText( nit );
				FreeIntuiText( mit );

				if ( max_lines > max_screen_lines ) {
					max_lines = max_screen_lines;;
					SWError( swa, win, "Max window size too small\n Ignoring some articles" );
				}  /* end if max_lines */

				nit = BuildIntuiText( it, nfi, max_lines );
				mit = BuildIntuiText( it, mfi, max_lines );

				if ( !nit && !mit ) {
					done      = TRUE;
					exit_code = FAIL;
					SWError( swa, win, "Could not allocate IntuiText" );
				}   /* end if !nit && !mit */

				max_win_height = win->BorderTop + win->BorderBottom + 15 + gad->Height + ((max_lines+2) * it->ITextFont->ta_YSize);
					
				if ( win->Width EQ win->MinWidth ) {
					SetWindowTitles( win, title_str, (UBYTE *)-1 );
				} else {
					ChangeWindowBox( win, (long)win->LeftEdge, (long)win->TopEdge, (long)win->MaxWidth, max_win_height );
				}   /* end if */


/*
 *   Send new timer request.
 */

				tr->tr_node.io_Command = TR_ADDREQUEST;
  				tr->tr_time.tv_secs    = swa->delay;
				tr->tr_time.tv_micro   = 0;

				SendIO( (struct IORequest *)tr );

			}   /* end if have a timer signal */

			if ( signals & SIGBREAKF_CTRL_C ) {

				WaitIO( (struct IORequest *)tr );
				done      = TRUE;
				exit_code = SUCCESS;

			}   /* end if CTRL-C break */


/*
 *   IDCMP Events.
 */

			if ( signals & (1L<<win->UserPort->mp_SigBit) ) {
	
				while ( msg = GT_GetIMsg( win->UserPort ) ) {

					switch ( msg->Class ) {

						case IDCMP_CLOSEWINDOW:
	
							WaitIO( (struct IORequest *)tr );
							done      = TRUE;
							exit_code = SUCCESS;
							break;

						case IDCMP_MOUSEBUTTONS:

/*
 *   RMB press - size window if there is anything to display.
 */

							if ( msg->Code EQ MENUUP ) {
								if ( max_lines ) {
									if ( win->Width EQ win->MinWidth ) {
										ChangeWindowBox( win, (long)win->LeftEdge, (long)win->TopEdge, (long)win->MaxWidth, max_win_height );
									} else {
										ChangeWindowBox( win, (long)win->LeftEdge, (long)win->TopEdge, (long)win->MinWidth, (long)win->MinHeight );
									}     /* end if */
								}   /* end if */
							}   /* end if RMB press */
							break;
	
						case IDCMP_NEWSIZE:

/*
 *   Redraw text once window has resized.
 */

							if ( win->Width EQ win->MaxWidth ) {
	
								if ( nfi ) {
									SetWindowTitles( win, "News Spool Contents", (UBYTE *)-1 );
									PrintIText( win->RPort, nit, (long)(win->BorderLeft+5),(long)(win->BorderTop+15+win->FirstGadget->Height) );
									cur_display = NEWS;
  								} else {
									SetWindowTitles( win, "Mail Spool Contents", (UBYTE *)-1 );
									PrintIText( win->RPort, mit, (long)(win->BorderLeft+5),(long)(win->BorderTop+15+win->FirstGadget->Height) );
									cur_display = MAIL;
  								}   /* end if */
							} else {
								SetWindowTitles( win, title_str, (UBYTE *) -1 );
							}   /* end if */
							break;

						case IDCMP_REFRESHWINDOW:
			
							GT_BeginRefresh( win );
							GT_EndRefresh( win, NULL );
							break;

						case IDCMP_GADGETUP:


/*
 *   Gadget pressed - toggle news/mail display. If only news or mail
 *   then do nothing.
 */


						switch ( cur_display ) {
	
								case NEWS:

									if ( mfi ) {
										SetWindowTitles( win, "Mail Spool Contents", (UBYTE *)-1 );
										PrintIText( win->RPort, mit, (long)(win->BorderLeft+5),(long)(win->BorderTop+15+win->FirstGadget->Height) );
										cur_display = MAIL;
									}   /* end if !no_mail */
									break;

								case MAIL:

									if ( nfi ) {
										SetWindowTitles( win, "News Spool Contents", (UBYTE *)-1 );
										PrintIText( win->RPort, nit, (long)(win->BorderLeft+5),(long)(win->BorderTop+15+win->FirstGadget->Height) );
										cur_display = NEWS;
									}   /* end if !no_news */
						
							}    /* end switch */
							break;

					}   /* end switch msg class */

					GT_ReplyIMsg( msg );

				}   /* end while msgs at port */					

			}   /* end if IDCMP message */

  		}   /* end while messages at port */

	} else {

		WaitIO( (struct IORequest *)tr );
		SWError( swa, win, "Could not allocate IntuiText" );
		exit_code = FAIL;

	}   /* end if mit && nit */

	FreeFullInfo( nfi );
	FreeFullInfo( mfi );

	FreeIntuiText( mit );
	FreeIntuiText( nit );

	CloseDevice( (struct IORequest *)tr );
	DeleteExtIO( (struct IORequest *)tr );
	DeletePort( time_msgp );

  } else {

	SWError( swa, win, "Could not use time - No Updates" );
	exit_code = FAIL;

  }   /* end if timer_on */

  return exit_code;

}   /* end function HandleEvents */

/*========================================================================*
			END FUNCTION HandleEvents
 *========================================================================*/
