/*
	GB's Work.  とあるGBの日常
	by setter2002
*/
#include "stdio.h"
#include "signal.h"
#include "GB.h"
#include "beer.h"

#define sugoku_iimono float // Unlimited virtually.
#define cyotto_iimono char

#if defined(SGB)
#define GB_ITEM	sugoku_iimono	
#else
#define GB_ITEM	cyotto_iimono
#endif

typedef struct {
	TRACKABLE travelBug;
	TRACKABLE geoCoin;
} TRACKABLES;

typedef struct {
	GB_ITEM gloves;
	GB_ITEM ballpoint; // 2 or more is recommended.
	GB_ITEM mirror;
	GB_ITEM flashlight; // More than 80 lumens is recommended.
	GB_ITEM swag;
	TRACKABLES tb[100];
#if defined(RAIN)
	GB_ITEM raincoat;
#endif
#if defined(SUMMER)
	GB_ITEM repellent;
#endif
} GB_BAG;

typedef struct {
	GB_ITEM gpsr;	// If using the Force, put on table.
	GB_ITEM flashlight;
	GB_ITEM gloves;
	GB_ITEM mirror;
} GB_HAND;

volatile int g_catchMail;
int g_inventry;			// Who set it? (Proccess 'Hamster' ?)
int g_inventryItems[100]; 

#define SIG_PUBLISHED (SIGRTMIN + 1)
#define NOT_FOUND FALSE
#define NORMAL FALSE
#define HARD TRUE
#define LOOSE (-1)
#define READ FALSE

int found(void)
{
	if(gotFTF())
		return SMILE;
	else if(tooLate())
		return ORZ;
	else
		return NOT_FOUND;
}

int searchGZ(GB_BAG *bug, GB_HAND *hand, int hard)
{
	int status;
	
	if(hard == TRUE)
	{
		bag->flashlight = 0;  
		bag->gloves = 0;
		bag->mirror = 0;
		hand->flashlight = 1;
		hand->gloves = 1;
		hand->mirror = 1;
		putGround(bag);
		putGround(hand->gpsr);		
		doDGZ();
	}
	
	if(hard == LOOSE)
		sleep(600);

	status = found();
	switch status 
	{
		case SMILE:
			printf("FTF!!!¥n");
			break;
		case ORZ:
			printf("ORZ orz...¥n");
			break;
		// No default:
	}
	return status;
}

void recieve_published( int arg ) {
		g_catchMail = TRUE;	
		return;
}

int go_work(void)
{
	int result;
	int hard;
	GB_BAG bag;
	GB_HAND hand;

	if(sleeping())
		wakeupNow();
	
	memset(&bag, 0, sizeof(GB_BAG));
	memset(&hand, 0, sizeof(GB_HAND));

	hand.gpsr = 1;

	bag.gloves = 1;
	bag.ballpoint = 2;	
	bag.mirror = 1;
	bag.flashlight = 1;	
	bag.swag = 10;
	while(--inventry > 0)
	{	if(g_inventryItem[g_inventry - 1] == TB)
			g_tb[g_inventry - 1].travelBug = 1;
		else
			g_tb[g_inventry - 1].geoCoin = 1;
	}
	
	hard = FALSE;
	
	if(arrivedGZ1st())
	{
		while(searchGZ(&bag, &hand, hard) == NOT_FOUND)
			if(anotherGB())
				hard = HARD;
	}
	else if(anotherGB())
	{
		printf("Hello GB\n");
		if(askAlreadyFoundIt() == NOT_FOUND)
			while(result = searchGZ(&bag, &hand, HARD) == NOT_FOUND) {}
		else
			while(result = searchGZ(&bag, &hand, LOOSE) == NOT_FOUND) {}
	}
	else
		while(result = searchGZ(&bag, &hand, NORMAL) == NOT_FOUND) {}
	
	retrurn result; //NOT_FOUND is Not possible.
}

int main( int argc, char ** argv ) {
	int result;
	struct sigaction goGZ;

	g_catchMail = READ;

	memset(&goGZ, 0, sizeof(struct sigaction));
	sigemptyset(&goGZ.sa_mask);
	goGZ.sa_handler = recieve_published;
	sigaddset(&goGZ.sa_mask, SIG_PUBLISHED);
	goGZ.sa_flags = SA_SIGINFO | SA_RESTART;
	sigaction(SIG_PUBLISHED, &goGZ, NULL);

	while(GB)
	{
		if(g_catchMail == TRUE)
		{
			g_catchMail = READ;
			result = go_work();
			writeLog(result);
			if(refrigeratorItem(BEER))
				takeBeer();
		}
	}

	return 0; // Do not reach.
}