// sattool - visual satellite tracking and prediction tool.
// Copyright 2000 Tom Rothamel <tom-idbg@onegeek.org>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

/* This file defines the date parser, as well as some utility routines
 * to assist in calling the date parser.
 */

%{
#include "sattool.h"
#include <time.h>
	
#define YYSTYPE int

struct tm tm_buf;
struct tm *tm;
 
static int dpe;
static int result;
 
int date_error(char *);
int date_lex();
int y2k(int);
 
%}

%token NUM

%token TODAY
%token YESTERDAY
%token TOMORROW

%token NOON
%token MIDNIGHT

%token NOW

%token SECONDS
%token MINUTES
%token HOURS
%token DAYS

%%

fullspec: datetime {
	result = mktime(tm);
}
| fullspec '+' offspec {
	result += $3;
}
| fullspec '-' offspec {
	result -= $3;
}
;

offspec: { $$ = 0; }
| offspec NUM offtype {
	$$ += $2 * $3;
}
;

offtype:
SECONDS { $$ = 1; }
| MINUTES { $$ = 60; }
| HOURS { $$ = 3600; }
| DAYS { $$ = 86400; }
;

datetime: date time
| time date
| time {
	if (mktime(tm) < time(NULL)) {
		tm->tm_mday += 1;
	}
}
| NOW
;

date: NUM '-' NUM '-' NUM {
	tm->tm_year = y2k($1) - 1900;
	tm->tm_mon = $3 - 1;
	tm->tm_mday = $5;
}
| NUM '/' NUM '/' NUM {
	tm->tm_year = y2k($5) - 1900;
	tm->tm_mon = $1 - 1;
	tm->tm_mday = $3;
}
| TODAY
| TOMORROW {
	tm->tm_mday += 1;
}
| YESTERDAY {
	tm->tm_mday -= 1;
}
;

time: NUM ':' NUM ':' NUM {
	tm->tm_sec = $5;
	tm->tm_min = $3;
	tm->tm_hour = $1;
}
| NUM ':' NUM {
	tm->tm_sec = 0;
	tm->tm_min = $3;
	tm->tm_hour = $1;
}	
| MIDNIGHT {
	tm->tm_sec = 0;
	tm->tm_min = 0;
	tm->tm_hour = 0;
}
| NOON {
	tm->tm_sec = 0;
	tm->tm_min = 0;
	tm->tm_hour = 12;
}
;

%%

// This is the routine that handles the conversion of years from
// two digit to four digit form... it also handles the y2k factor
// in the process.
int y2k(int y) {
	if (y < 70) return y + 2000;
	if (y < 100) return y + 1900;
	return y;
}

// Report a date parsing error.
int yyerror(char *s) {
	error("Parsing date: %s\n", s);
	dpe = 1;
}

void date_scan_string(char *);

// This function parses a date string, returning it as a time_t value.
time_t parse_date(char *string) {
	time_t now;	

	dpe = 0;
	
	now = time(NULL);
	tm = localtime(&now);
	tm_buf = *tm;
	tm = &tm_buf;

	date_scan_string(string);
	date_parse();

	if (dpe) return 0;
	
	return result;
}

// This function parsed a date string, returning it as an epoch date.
double parse_sgp_date(char *string) {
	time_t date;

	date = parse_date(string);
	if (date == 0) {
		return HUGE_VAL;
	}

	return -10957.5 + (SECDAY * (double) date);
}