#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "kernel.h"
#include "swis.h"

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

char Me[] = "ClockWork 1.11";

#define  False 0
#define  True  !(False)

typedef union {
	char All[5];
	struct { int Low; char High; } Parts;
} t_OSTimestamp;

typedef struct {
	int Centisecond, Second, Minute, Hour, Day, Month, Year, Weekday, Yearday;
} t_DateTimeOrdinalBlock;

typedef struct {
	int Number;
	char Message[255];
} t_OSError;

#define OSError_OK  (1<<0)
#define OSError_Cancel (1<<1)
#define OSError_DefaultCancel (1<<2)


typedef unsigned long long t_Centiseconds;

_kernel_swi_regs  SWIRegs;

#define SWI(SWIName) _kernel_swi(SWIName,&SWIRegs,&SWIRegs)


t_Centiseconds GetStuff(t_OSTimestamp *Timestamp, char *Legible) {
	t_Centiseconds c = 0;
	t_DateTimeOrdinalBlock DateTime;
	int i;

	SWIRegs.r[0] = -1;
	SWIRegs.r[1] = (int)(Timestamp);
	SWIRegs.r[2] = (int)(&DateTime);
	SWI(Territory_ConvertTimeToOrdinals);
	sprintf(Legible,"%02d.%02d.%04d %02d:%02d",DateTime.Day,DateTime.Month,DateTime.Year,DateTime.Hour,DateTime.Minute);

	for (i=4;i>=0;i--) {
		c = (c<<8) + (t_Centiseconds)(Timestamp->All[i]);
	}
	return(c);
}


int MessageBox(t_OSError *Err,int Oops) {
	Err->Number = 0;
	SWIRegs.r[0] = (int)Err;
	if (Oops) { SWIRegs.r[1] = OSError_OK | OSError_Cancel | OSError_DefaultCancel ;  }
	else      { SWIRegs.r[1] = OSError_OK | OSError_Cancel ; }
	SWIRegs.r[2] = (int)&Me[0];
	SWIRegs.r[3] = 0;
	SWIRegs.r[4] = 0;
	SWIRegs.r[5] = 0;
	SWI(Wimp_ReportError);
BuggyInt("ok",SWIRegs.r[1]);
	return(SWIRegs.r[1] == 1 ? True : False );
}



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

	t_OSTimestamp Timestamp;
	t_Centiseconds now,boot;
	char Now[20], Boot[20];
	int load,exec,age,warn,ok;
	char MyFile[1024];
	char *c;
	t_OSError OSError;

	// Me
	strcpy(MyFile,argv[0]);
	warn = 28;
	c = strrchr(MyFile,'.');
	if (c != NULL) {
		c = strrchr(c,'-');
		if (c != NULL) {
			c++;
			warn = atoi(c);
		}
	}
BuggyInt("w",warn);

	// Last run
	SWIRegs.r[0] = 17;
	SWIRegs.r[1] = (int)(&MyFile);
	SWI(OS_File);
	load = SWIRegs.r[2];
	exec = SWIRegs.r[3];
	Timestamp.Parts.High = (char)(load & 0xff);
	Timestamp.Parts.Low = exec;
	boot = GetStuff(&Timestamp,(char*)&Boot);

BuggyText("",(char*)&Boot);

	// Now
	SWIRegs.r[0] = 14;
	Timestamp.All[0] = 3;
	SWIRegs.r[1] = (int)(&Timestamp);
	SWI(OS_Word);
	now = GetStuff(&Timestamp,(char*)&Now);

BuggyText("",(char*)&Now);

	// Check and talk
	ok = True;
	if (now < boot) {
		sprintf(OSError.Message,"Historic system clock: %s (last boot time was %s)! Click on OK only if system clock is right",(char*)&Now,(char*)&Boot);
BuggyText("old",OSError.Message);
		ok = MessageBox(&OSError,True);
	}
	else {
		age = (int)((now-boot) / (100 * 60 * 60 * 24));
		if ((age > warn) && (warn != 0)) {
			sprintf(OSError.Message,"Last boot was %d days ago on %s - Enter or click on OK to accept %s as good time",age,(char*)&Boot,(char*)&Now);
BuggyText("age",OSError.Message);
			ok = MessageBox(&OSError,False);
		}
	}

	// Stamp
	if (ok) {
BuggyText("ok",MyFile);
		SWIRegs.r[0] = 9;
		SWIRegs.r[1] = (int)(&MyFile);
		SWIRegs.r[2] = Timestamp.Parts.High;
		SWIRegs.r[3] = Timestamp.Parts.Low;
		SWI(OS_File);
	}


	return 0;
}
