/* Intuition handler for MRBackup
 * Filename:	IntuiHandler.c
 * Date:		11/21/87
 *
 * History:		(most recent change first)
 *
 * 11/21/87 -MRR- This file was created for version 2.0.
 */

#include "MRBackup.h"
#include "Screen.c"

extern struct GfxBase *GfxBase;

extern struct Gadget curVolumeGadget;
extern struct Gadget errorGadget;

struct Window *OpenPathWindow();

/* Close all Intuition items. */

CloseIntuition()
{
	if ( IntuitionBase ) {
		if ( mainScreen ) {
			if ( mainWindow ) {
				ClearMenuStrip( mainWindow );
				CloseWindow( mainWindow );
			}
			if ( pathWindow )	CloseWindow( pathWindow );
			CloseScreen( mainScreen );
		}
		if ( progressConsole ) DeleteConsole( progressConsole );
		if ( progressWindow ) CloseWindow( progressWindow );

#ifdef DEBUG
		if ( debugConsole ) DeleteConsole( debugConsole );
		if ( debugWindow ) CloseWindow( debugWindow );
#endif

		if ( GfxBase ) CloseLibrary( GfxBase );
		CloseLibrary( IntuitionBase );
	}						/* end if IntuitionBase */
}
^L
/* Handle a gadget action.
 * Called with:
 *      window:		window that gadget is displayed in
 *		class:		message class (GADGETUP/GADGETDOWN/?)
 *		addr:		pointer to gadget structure
 */
DoGadget(window, class, addr)
	struct Window *window; ULONG class; struct Gadget *addr;
{
	USHORT id;					/* gadget identifier */
	struct Gadget *upGad;
	ULONG upClass;
	struct IntuiMessage *upMsg;	/* require gadget up to complete */

	id = addr->GadgetID;

	if (class == GADGETUP) {
#ifdef DEBUG
		sprintf(debugMsg,"GADGETUP: %d\n",id);
		DebugWrite(debugMsg);
#endif
		switch (id) {
			case HOMEPATH:
				GetHomePath(addr);
				break;
			case BACKPATH:
				GetBackPath(addr);
				break;
			case LISTPATH:
				GetListPath(addr);
				break;
			case XCLDPATH:
				GetXcldPath(addr);
				break;
			case STOP:
				TypeAndSpeak(
	"Use the STOP gadget during backup and restore operations.\n");
				break;
			default:
#ifdef DEBUG
				sprintf(conmsg, "Unknown gadget, ID %d.  Program error!\n",
						id);
				TypeAndSpeak(conmsg);
#endif
				break;
		}
	}
}
int
InitIntuition()
{
	struct ViewPort vP;
	struct RastPort *rpG;
 
	IntuitionBase = (struct IntuitionBase *)
		OpenLibrary("intuition.library", 0L);
	if ( ! IntuitionBase ) {
		puts("I can't open Intuition!\n");
		return ERR_ABORT;
	}

	GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L);
	if ( ! GfxBase ) {
		puts("I can't open the graphics library!\n");
		return ERR_ABORT;
	}

	mainScreen = OpenScreen(&NewScreenStructure);
	if ( ! mainScreen ) {
		puts("I can't open the screen!\n");
		return ERR_ABORT;
	}

	vP = mainScreen->ViewPort;
	LoadRGB4(&vP, &Palette, (long) PaletteColorCount);

	NewWindowStructure1.Screen = mainScreen;
	mainWindow = OpenWindow(&NewWindowStructure1);	/* open the window */
	if ( mainWindow == NULL )
	{
		puts("I can't open the main window!\n");
		return ERR_ABORT;
	}

	if (!OpenPathWindow()) return ERR_ABORT;



	rpG = mainWindow->RPort;	/* get a rastport pointer for the window */

	SetMenuStrip(mainWindow, &MenuList1);

	/* Open the console(s) and related windows. */

	NewWindowStructure4.Screen = mainScreen;
	if ( ! (progressWindow = OpenWindow( &NewWindowStructure4 ) ) ) {
		puts("I can't open the progress window!\n");
		return ERR_ABORT;
	}

	if ( ! (progressConsole = CreateConsole( progressWindow ) ) ) {
		puts("I can't create the progress window console!\n");
		return ERR_ABORT;
	}

#ifdef DEBUG
	NewWindowStructure5.Screen = mainScreen;
	if ( ! (debugWindow = OpenWindow( &NewWindowStructure5 ) ) ) {
		puts("I can't open the debug window!\n");
		return ERR_ABORT;
	}

	if ( ! (debugConsole = CreateConsole( debugWindow ) ) ) {
		puts("I can't create the debug window console!\n");
		return ERR_ABORT;
	}
#endif

#ifdef IntuiTextList1
	PrintIText(rpG,&IntuiTextList1,0L,0L);	/* Print the text if any. */
#endif

#ifdef BorderList1
	DrawBorder(rpG,&BorderList1,0L,0L);	/* Draw the borders if any */
#endif

#ifdef ImageList1
	DrawImage(rpG,&ImageList1,0L,0L);	/* Draw the images if any. */
#endif
	return ERR_NONE;
}

/* Open the pathname specification window.
 * Returns:
 *		pointer to new window (success) or NULL (failure)
 * Side-Effects:
 *		sets pathWindow to new window pointer
 */

struct Window *
OpenPathWindow()
{
	if (!pathWindow) {				/* only if not already open */
		NewWindowStructure3.Screen = mainScreen;
		if (! ( pathWindow = OpenWindow(&NewWindowStructure3)) ) {
			TypeAndSpeak(
				"I can't open the pathname specifications window!\n");
		}
	}
	return pathWindow;
}

/* Set the current backup volume name into the curVolumeGadget. */

SetCurVolumeGadget(name)
	char *name;
{
	long position;
	char *s;

	position = RemoveGadget(mainWindow, &curVolumeGadget);
	s = GadgetString((&curVolumeGadget));
	strncpy(s, name, 30);
	AddGadget(mainWindow, &curVolumeGadget, position);
	RefreshGList(&curVolumeGadget, mainWindow, NULL, 1L);
}

^L
/* Set the current errorCount value into the errorGadget. */

SetErrorGadget()
{
	ULONG position;
	UBYTE *buffer;

	position = RemoveGadget(mainWindow, &errorGadget);
	buffer = GadgetString((&errorGadget));
	sprintf(buffer, "%4u", errorCount);
	AddGadget(mainWindow, &errorGadget, position);
	RefreshGList(&errorGadget, mainWindow, NULL, 1L);
}

/* Adjust the disk "gauge" to show how full it currently is.
 * Called with:
 * 		current:	number of blocks currently in use
 *		maxValue:	total number of blocks available
 */

SetGauge(current, maxValue)
	LONG current, maxValue;
{
	ULONG hPot;
	struct PropInfo *oldProp;
	LONG range, used;

#ifdef DEBUG
	sprintf(debugMsg,"SetGauge(%ld,%ld)\n",current,maxValue);
	DebugWrite(debugMsg);
#endif
	oldProp = (struct PropInfo *) gaugeGadget.SpecialInfo;

	range = maxValue + 1;
	used = maxValue - current;
	hPot = (used << 16L) / range;
	ModifyProp(
		&gaugeGadget, 				/* gadget pointer */
		mainWindow,					/* window pointer */
		NULL, 						/* requester */
		(ULONG) oldProp->Flags, 	/* flags */
		hPot, 						/* horizPot */
		0L,							/* vertPot */
		(ULONG) oldProp->HorizBody, /* horizBody */
		(ULONG) oldProp->VertBody	/* vertBody */
		);
}

/* Handle IDCMP messages generated by user actions. */

User()
{
	ULONG class;				/* message class */
	USHORT code;				/* message code */
	USHORT gadgetID;				/* gadget ID */
	APTR Iadr;					/* address field from message */
	struct IntuiMessage *msg;	/* Intuition message pointer */
	struct Window *msgWindow;	/* window message occurred in */
	USHORT quit = 0;
	SHORT x,y;					/* mouse x and y position */
	ULONG waitBits;


#ifdef DEBUG
	sprintf(debugMsg,"User: waitBits = %08lx\n", waitBits);
	DebugWrite(debugMsg);
#endif

	while (!quit) {
		ActivateWindow(mainWindow);

		waitBits = (1L << mainWindow->UserPort->mp_SigBit);
		if (pathWindow)
			waitBits = waitBits | (1L << pathWindow->UserPort->mp_SigBit);
			Wait(waitBits);

		while (!quit) {
			if (!(msg = (struct IntuiMessage *) 
				GetMsg(mainWindow->UserPort)))

			if ( ! (pathWindow && 
				    (msg = (struct IntuiMessage *)
					 GetMsg(pathWindow->UserPort) ) ) ) 
				break;

			class = msg->Class;
			code = msg->Code;
			Iadr = msg->IAddress;
			x = msg->MouseX;
			y = msg->MouseY;
			msgWindow = msg->IDCMPWindow;
			ReplyMsg(msg);		/* acknowledge the message */
#ifdef DEBUG
			sprintf(debugMsg,"Message class: 0x%lx, code: 0x%x\n",
				class, code);
#endif
			switch (class) {
			case CLOSEWINDOW:
				if (msgWindow == mainWindow)
					++quit;
				else if (msgWindow == pathWindow) {
					CloseWindow(pathWindow);
					pathWindow = NULL;
				}
				break;

			case GADGETUP:
			case GADGETDOWN:
				DoGadget(msgWindow, class, Iadr);
				break;

			case MENUPICK:
				quit = UserMenu(code);
				break;

			default:
				break;			/* ignore the rest */
			}					/* end switch(class) */
		}
	}
}
/* Handle a menu selection. 
 * Called with:
 *		xcode:		menu selection code
 * Returns:
 *		status code (1 => Quit was selected)
 */

int
UserMenu(xcode)
	USHORT xcode;
{
	USHORT code = xcode;
	struct MenuItem *item;
	USHORT itemNum,menuNum;

	while (code != MENUNULL) {
		menuNum = MENUNUM(code);
		itemNum = ITEMNUM(code);
		item = ItemAddress(&MenuList1, (long) code);

#ifdef DEBUG
		sprintf(debugMsg,
				"menu = %d, item = %d, flags = %04x\n",
				menuNum, itemNum, item->Flags);
		DebugWrite(debugMsg);
#endif

		switch (menuNum) {
		case MENU_PROJECT:			/* Project Menu */
			switch (itemNum) {
			case ITEM_BACKUP:		/* Backup */
				Backup();
				break;
			case ITEM_RESTORE:		/* Restore */
				Restore();
				break;
			case ITEM_LOADPREFS:	/* Load Preferences */
				GetUserPrefs();
				break;
			case ITEM_SAVEPREFS:	/* Save Preferences */
				PutUserPrefs();
				break;
			case ITEM_ABOUT:		/* About */
				About();
				break;
			case ITEM_QUIT:			/* Quit */
				return 1;			
			default:
				DisplayBeep(NULL);
				break;
			}
			break;

		case MENU_FLAGS:			/* Flags Menu */
			switch ( itemNum ) {
			case ITEM_COMPRESS:		/* Compression */
				doCompress = IsChecked( item ); 
				break;
			case ITEM_BIGFILES:		/* Do Big Files */
				doBigFiles = IsChecked( item );
				break;
			case ITEM_LIST:			/* Listing */
				doListing = IsChecked( item );
				break;
			case ITEM_SPEECH:		/* Speech */
				doSpeech = IsChecked( item );
				SetSpeech();
				break;
			case ITEM_FORMAT:		/* Format output disks */
				doFormat = IsChecked( item );
				break;
			default:
				DisplayBeep(NULL);
				break;
			}
			break;

		case MENU_WINDOWS:			/* Windows Menu */
			OpenPathWindow();		/* There's only one item. */
			break;
		}
#define EXTENDED_SELECT_WORKS
#ifdef EXTENDED_SELECT_WORKS
		code = item->NextSelect; 
		/* This next line is a kludge.  Testing has revealed that
		 * the NextSelect field is returning 0000x.  Why?
		 */
		if (!code) break;
#else
		break;
#endif
	}
	return 0;
}
