// -------------------------------------------------------------
// This defines a object that works with time. We maintain a 
// year, season pair and we can go forwards and backwards.
//
// Usage:
//
//  var t = new Time(season, year, 0)  // day is zero, so not include
//  alert("Season: " + t.season + "\nYear: " + t.year)
//  t.next();
//  t.previous();
//  var t2 = new Time(season, year, 1) // day is 1. season must be a month
//  var r = compare_time(t1, t2);
//  var t = t.season_type();         
//                // Either TIME_ANNUAL, TIME_SEASON, TIME_MONTH, TIME_DAY
//                // or TIME_ANIMATE
//  var t = t.data_pool_time();
//                // This is the time used in the data pool for this time.
//                // (e.g., 12.03.01).
//  var t = t.misr_file_name_time();
//                // This is the time as it appears in the MISR file name.
//
// This makes use of the global variables min_year and max_year,
// that is defined outside of this class.
// -------------------------------------------------------------

// -------------------------------------------------------------
// Constants
// -------------------------------------------------------------

var TIME_ANNUAL = 0, TIME_SEASON = 1, TIME_MONTH = 2, TIME_DAY = 3,
    TIME_ANIMATE = 4;

// -------------------------------------------------------------
// Mapping from a season name to a number, and vice versa.
// -------------------------------------------------------------

var SEASON_TO_NUM = new Array(), NUM_TO_SEASON = new Array(), 
    SEASON_TO_DP  = new Array();
SEASON_TO_NUM["animate"] = 0;
SEASON_TO_NUM["JAN"] = 1;
SEASON_TO_NUM["FEB"] = 2;
SEASON_TO_NUM["MAR"] = 3;
SEASON_TO_NUM["APR"] = 4;
SEASON_TO_NUM["MAY"] = 5;
SEASON_TO_NUM["JUN"] = 6;
SEASON_TO_NUM["JUL"] = 7;
SEASON_TO_NUM["AUG"] = 8;
SEASON_TO_NUM["SEP"] = 9;
SEASON_TO_NUM["OCT"] = 10;
SEASON_TO_NUM["NOV"] = 11;
SEASON_TO_NUM["DEC"] = 12;
SEASON_TO_NUM["WIN"] = 13;
SEASON_TO_NUM["SPR"] = 14;
SEASON_TO_NUM["SUM"] = 15;
SEASON_TO_NUM["FALL"] = 16;
SEASON_TO_NUM["ANN"] = 17;
NUM_TO_SEASON[0] = "animate";
NUM_TO_SEASON[1] = "JAN";
NUM_TO_SEASON[2] = "FEB";
NUM_TO_SEASON[3] = "MAR";
NUM_TO_SEASON[4] = "APR";
NUM_TO_SEASON[5] = "MAY";
NUM_TO_SEASON[6] = "JUN";
NUM_TO_SEASON[7] = "JUL";
NUM_TO_SEASON[8] = "AUG";
NUM_TO_SEASON[9] = "SEP";
NUM_TO_SEASON[10] = "OCT";
NUM_TO_SEASON[11] = "NOV";
NUM_TO_SEASON[12] = "DEC";
NUM_TO_SEASON[13] = "WIN";
NUM_TO_SEASON[14] = "SPR";
NUM_TO_SEASON[15] = "SUM";
NUM_TO_SEASON[16] = "FALL";
NUM_TO_SEASON[17] = "ANN";
SEASON_TO_DP["animate"] = "00";
SEASON_TO_DP["JAN"] = "01";
SEASON_TO_DP["FEB"] = "02";
SEASON_TO_DP["MAR"] = "03";
SEASON_TO_DP["APR"] = "04";
SEASON_TO_DP["MAY"] = "05";
SEASON_TO_DP["JUN"] = "06";
SEASON_TO_DP["JUL"] = "07";
SEASON_TO_DP["AUG"] = "08";
SEASON_TO_DP["SEP"] = "09";
SEASON_TO_DP["OCT"] = "10";
SEASON_TO_DP["NOV"] = "11";
SEASON_TO_DP["DEC"] = "12";
SEASON_TO_DP["WIN"] = "12";
SEASON_TO_DP["SPR"] = "03";
SEASON_TO_DP["SUM"] = "06";
SEASON_TO_DP["FALL"] = "09";
SEASON_TO_DP["ANN"] = "12";

// -------------------------------------------------------------
// Number of days in a month.
// -------------------------------------------------------------

var DAY_MONTH = new Array();
DAY_MONTH["JAN"] = 31;
DAY_MONTH["FEB"] = 28;
DAY_MONTH["MAR"] = 31;
DAY_MONTH["APR"] = 30;
DAY_MONTH["MAY"] = 31;
DAY_MONTH["JUN"] = 30;
DAY_MONTH["JUL"] = 31;
DAY_MONTH["AUG"] = 31;
DAY_MONTH["SEP"] = 30;
DAY_MONTH["OCT"] = 31;
DAY_MONTH["NOV"] = 30;
DAY_MONTH["DEC"] = 31;


// -------------------------------------------------------------
// Constructor
// -------------------------------------------------------------

function Time(s, y, d) {
    this.season = s;
    this.year = y;
    this.day = d;
    if(this.day != 0 &&
       (this.season =="ANN" ||
	this.season =="WIN" ||
	this.season =="SUM" ||
	this.season =="FALL" ||
	this.season =="SPR")) {
	alert("Season must be a month id day !=0. Season: " + this.season
	      + " Day: " + this.day);
    }
    if(this.day != 0 &&
       (this.day < 0 ||
	this.day > DAY_MONTH[this.season])) {
	alert("Day is out of range. Day: " + this.day);
    }
    this.next = time_next;
    this.previous = time_previous;
    this.season_type = time_season_type;
    this.data_pool_time = time_data_pool_time;
    this.misr_file_name_time = time_misr_file_name_time;
}

// -------------------------------------------------------------
// Go to next month/season/year.
// -------------------------------------------------------------

function time_next() {
    if(this.season =="animate") {
	return;
    }
    if(this.day != 0 &&
       this.day !=DAY_MONTH[this.season]) {
				// Fall through if we are at the end of 
				// the month
	++this.day;
	return;
    }
    var t = SEASON_TO_NUM[this.season];
    ++t;
    if(t ==13 ||
       t ==17 ||
       t ==18) {		// Roll over to next year.
	if(this.year ==max_year) {
	    return;
	}
	++this.year;
	if(t ==13) {
	    t = 1;
	} else if(t ==17) {
	    t = 13;
	} else if(t ==18) {
	    t = 17;
	}
    }
    this.season = NUM_TO_SEASON[t];
    if(this.day != 0) {
	this.day = 1;
    }
}

// -------------------------------------------------------------
// Go to previous month/season/year.
// -------------------------------------------------------------

function time_previous() {
    if(this.season =="animate") {
	return;
    }
    if(this.day != 0 &&
       this.day != 1) {		// Fall through if we are at the 
				// begining of the month
	--this.day;
	return;
    }
    var t = SEASON_TO_NUM[this.season];
    --t;
    if(t ===0 ||
       t ==12 ||
       t ==16) {		// Roll over to previous year.
	if(this.year ==min_year) {
	    return;
	}
	--this.year;
	if(t ===0) {
	    t = 12;
	} else if(t ==12) {
	    t = 16;
	} else if(t ==16) {
	    t = 17;
	}
    }
    this.season = NUM_TO_SEASON[t];
    if(this.day != 0) {
	this.day = DAY_MONTH[this.season];
    }
}

// -------------------------------------------------------------
// Return season type.
// -------------------------------------------------------------

function time_season_type() {
    if(this.season =="ANN") {
	return TIME_ANNUAL;
    } 
    if(this.season =="WIN" ||
       this.season =="SPR" ||
       this.season =="SUM" ||
       this.season =="FALL") {
	return TIME_SEASON;
    }
    if(this.season =="animate") {
	return TIME_ANIMATE;
    }
    if(this.day != 0) {
	return TIME_DAY;
    }
    return TIME_MONTH;
}

// -------------------------------------------------------------
// Return data pool time.
// -------------------------------------------------------------

function time_data_pool_time() {
    return (this.season =="ANN" || this.season =="WIN" ? 
	    this.year - 1 : this.year) + "." + 
	SEASON_TO_DP[this.season] + "." + 
	(this.season_type() ==TIME_DAY ?
	 (this.day < 10 ? "0" + this.day : this.day)
	 : "01");
}

// -------------------------------------------------------------
// Return MISR file name time.
// -------------------------------------------------------------

function time_misr_file_name_time() {
    var r = (this.season =="ANN" ? "" : this.season + "_");
    if(this.day !=0) {
	if(this.day < 10) {
	    r = r + "0";
	}
	r = r + this.day + "_";
    }
    return r + this.year;
}


// -------------------------------------------------------------
// Compare two Time, return -1 if A is before B, 0 if A equal B
// and 1 if A is after B.
// -------------------------------------------------------------

function compare_time(t1, t2) {
    if(t1.year < t2.year) {
	return -1;
    }
    if(t1.year > t2.year) {
	return 1;
    }
    if(SEASON_TO_NUM[t1.season] < SEASON_TO_NUM[t2.season]) {
	return -1;
    }
    if(SEASON_TO_NUM[t1.season] > SEASON_TO_NUM[t2.season]) {
	return 1;
    }
    if(t1.day != 0 && t2.day ===0) {
	return -1;
    }
    if(t1.day ===0 && t2.day !=0) {
	return -1;
    }
    if(t1.day != 0 && t2.day != 0) {
	if(parseInt(t1.day) < parseInt(t2.day)) {
	    return -1;
	}
	if(parseInt(t1.day) > parseInt(t2.day)) {
	    return 1;
	}
    }
    return 0;
}
