#include <time.h>
#include <string.h>
#include <date_time.h>

#define NONE -1

// PROTOS //
int cmpdate(struct Date, struct Date, int prefix);
int cmptime(struct Time, struct Time, int prefix);
int findchr(char string[],int c);
char *CalcField(char text[],short calctype, struct Date datenow);
int CountDays(struct Date date1, struct Date datenow);
int checkdate(struct Date eventdate, struct Date datenow,
							int prefix, int days, int repeat);

int cmpdate(struct Date eventdate, struct Date datenow,int prefix) {

	switch(prefix) {

		case Exact:
			return ((eventdate.DD==datenow.DD | eventdate.DD==NONE) &
							(eventdate.MM==datenow.MM | eventdate.MM==NONE) &
							(eventdate.YY==datenow.YY | eventdate.YY==NONE));
			break;

		case Before:
			if(datenow.YY<=eventdate.YY | eventdate.YY==NONE)
				if(datenow.MM<eventdate.MM | eventdate.MM==NONE)
					return 1;
				else if(datenow.MM==eventdate.MM)
					if(datenow.DD<eventdate.DD | eventdate.DD==NONE)
						return 1;
			break;

		case After:
			if(datenow.YY>=eventdate.YY | eventdate.YY==NONE)
				if(datenow.MM>eventdate.MM | eventdate.MM==NONE)
					return 1;
				else if(datenow.MM==eventdate.MM)
					if(datenow.DD>eventdate.DD | eventdate.DD==NONE)
						return 1;
			break;
	}
	return 0;
}

int cmptime(struct Time time1,struct Time time2, int prefix) {

	switch(prefix) {

		case Exact:
			return ((time1.HH==time2.HH | time1.HH==NONE) &
							(time1.MM==time2.MM | time1.HH==NONE));
			break;

		case Before:
			if(time2.HH<time1.HH | time1.HH==NONE)
				return 1;
			else if(time2.HH==time1.HH)
				if(time2.MM<time1.MM | time1.MM==NONE)
					return 1;
			break;

		case After:
			if(time2.HH>time1.HH | time1.HH==NONE)
				return 1;
			else if(time2.HH==time1.HH)
				if(time2.MM>=time1.MM | time1.MM==NONE)
					return 1;
			break;
	}
	return 0;
}


int findchr(char string[],int f) {
	char c;
	int i;

	for(i=0; (c=string[i])!=f & c!='\0'; ++i);
	if(c!='\0')
		return i+1;
	else
		return 0;
}


char *CalcField(char text[],short type, struct Date datenow) {
	char calc[7],newtext[SIZE],calcstr[7],end[SIZE];
	int i;
	struct Date date;

	if(i=findchr(text,'{')) {
		if(!strmid(text,calc,i+1,6)) {
			date=to_date(calc,DDMMYY);

			if(type==0)
				stcl_d(calcstr,(long)(datenow.YY-date.YY));
			else
				stcl_d(calcstr,(long)(CountDays(date,datenow)));

			strmid(text,newtext,1,i-1);
			strcat(newtext,calcstr);
			strmid(text,end,i+8,strlen(text)-i-7);
			strcat(newtext,end);

			strcpy(text,newtext);
		}
	}
	return text;
}

int CountDays(struct Date eventdate, struct Date datenow) {
	struct tm input;
	int days1,days2,diff;

	input.tm_sec=		0;
	input.tm_hour=	0;
	input.tm_min=		0;
	input.tm_mday=	datenow.DD;
	input.tm_mon=		datenow.MM;
	input.tm_year=	datenow.YY;
	input.tm_isdst=	1;
	days1=(time_t)mktime(&input);

	input.tm_mday=	((eventdate.DD==0) ? datenow.DD : eventdate.DD);
	input.tm_mon=		((eventdate.MM==0) ? datenow.MM : eventdate.MM);
	input.tm_year=	((eventdate.YY==0) ? datenow.YY : eventdate.YY);
	days2=(time_t)mktime(&input);

	diff=abs((days2-days1)/86400);
	if(eventdate.MM<datenow.MM)
		--diff;
	else if(eventdate.MM>datenow.MM)
		++diff;

	if(datenow.YY<eventdate.YY)
		--diff;
	else if(datenow.YY>eventdate.YY)
		++diff;

	return diff;
}

int checkdate(struct Date eventdate, struct Date datenow,
							int prefix, int days, int repeat) {
	BOOL mod=FALSE;
	int count=0;

		if(prefix==Exact)
			return cmpdate(eventdate,datenow,prefix);
		else {
			count=CountDays(eventdate,datenow);
			if(prefix==Before)
				--count;
			else
				++count;
			if(repeat==0) {
				if(count<=days | days==0)
					return (cmpdate(eventdate,datenow,prefix));
				}
			else {
				if((CountDays(eventdate,datenow)+1)%repeat==0) {
					mod=TRUE;
					if(CountDays(eventdate,datenow)<=days | days==0)
						return (cmpdate(eventdate,datenow,prefix) && mod);
				}
			}
		}
	return 0;
}
