#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"

#define Buggy "<Obey$Dir>.Buggy"
#include "Buggy.h" // my debugging code
#include "Wimpy.h" // some Wimp definitions

// Some global variables so I need not pass them on over and over again
// ... or create them over and over again for subroutine calls
_kernel_swi_regs SWIRegs;
_kernel_oserror *OSError;
const char MyTaskName[] = "BarIcon";
t_TaskHandle MyTaskHandle = 0;
t_IconHandle MyBarIcon = 0;
int  MyPollMask = PollMask_Standard;
t_WimpPollBlock WimpPollBlockStorage;
t_WimpPollBlock *WimpPollBlock;

// Function for SWI Wimp_CloseDown
void WimpCloseDown(char *Notes) {
	// Call Wimp_CloseDown if I have a TaskHandle
	if (MyTaskHandle != 0) {
		SWIRegs.r[0] = TASK;
		SWIRegs.r[1] = MyTaskHandle;
		_kernel_swi(Wimp_CloseDown,&SWIRegs,&SWIRegs);
	}
	// If there was an error say so
	if (OSError != NULL) {
		BuggyError(Notes);
		SWIRegs.r[0] = (int)OSError;
		SWIRegs.r[1] = 1;
		SWIRegs.r[2] = (int)Notes;
		_kernel_swi(Wimp_ReportError,&SWIRegs,&SWIRegs);
	}
	// Exit
	_kernel_swi(OS_Exit,&SWIRegs,&SWIRegs);
	exit(0);
}

// Function for SWI Wimp_Initalise
void WimpInitialise(void) {
	SWIRegs.r[0] = 310;
	SWIRegs.r[1] = TASK;
	SWIRegs.r[2] = (int)&MyTaskName;
	SWIRegs.r[3] = (int)NULL;
	if((OSError = _kernel_swi(Wimp_Initialise,&SWIRegs,&SWIRegs)) != NULL) { WimpCloseDown("Wimp_Initialise"); }
	MyTaskHandle = SWIRegs.r[1];
}

// Function for SWI Wimp_Poll
int WimpPoll(void) {
	SWIRegs.r[0] = MyPollMask;
	SWIRegs.r[1] = (int)&WimpPollBlockStorage;
	if((OSError = _kernel_swi(Wimp_Poll,&SWIRegs,&SWIRegs)) != NULL) { WimpCloseDown("Wimp_Poll"); }
	// I would expect that the block I pass to Wimp_Poll is the one filled but the PRMs do not guarantee that!
	WimpPollBlock = (t_WimpPollBlock *)SWIRegs.r[1];
	return(SWIRegs.r[0]);
}

// Function to put Icon on icon bar with SWI Wimp_CreateIcon
t_IconHandle WimpCreateIconBarIcon(char *Sprite, t_WindowHandle LeftRight) {
	t_WimpCreateIconBlock WimpCreateIconBlock;
	WimpCreateIconBlock.Window = LeftRight;
	WimpCreateIconBlock.Icon.MinX = 0;
	WimpCreateIconBlock.Icon.MinY = 0;
	WimpCreateIconBlock.Icon.MaxX = 69;
	WimpCreateIconBlock.Icon.MaxY = 68;
	WimpCreateIconBlock.Icon.IconFlags = IconBarIconFlags;
	WimpCreateIconBlock.Icon.IconData.IconSpriteIndirect.Sprite = Sprite;
	WimpCreateIconBlock.Icon.IconData.IconSpriteIndirect.Area = WimpSpriteArea;
	WimpCreateIconBlock.Icon.IconData.IconSpriteIndirect.Length = strlen(Sprite);
	SWIRegs.r[0] = 0;
	SWIRegs.r[1] = (int)&WimpCreateIconBlock;
	if((OSError = _kernel_swi(Wimp_CreateIcon,&SWIRegs,&SWIRegs)) != NULL) { BuggyError("CreateIcon"); WimpCloseDown("Wimp_CreateIcon"); }
	return(SWIRegs.r[0]);
}

int main (int argc, char *argv[]) {

	int ReasonCode;

	BuggyClear;

	WimpInitialise();

	MyBarIcon = WimpCreateIconBarIcon("Switcher",IconBarIconRight);

	while (True) {
		ReasonCode = WimpPoll();
		
		// Handle the request
		switch(ReasonCode) {
		// Mouse click
		case ReasonCode_MouseClick:
			if (WimpPollBlock->MouseClick.Icon == MyBarIcon) {
				if (WimpPollBlock->MouseClick.Buttons == MouseButtonRight) {
					WimpCloseDown(""); // note that OSError is NULL here
				}
			}
			break;
		// User message
		case ReasonCode_UserMessage:
		case ReasonCode_UserMessageRecorded:
			if (WimpPollBlock->UserMessage.MessageCode == UserMessage_Quit) {
				WimpCloseDown(""); // note that OSError is NULL here
			}
			break;
		}
	}

}

