/* This singleton class contains static information about the stages and events and methods to access that information. Queries on stages are based on the current time, and queries on events use the JSON file eventData.json which gets updated regularly */

if (typeof(XPRIZE) == "undefined") {
    XPRIZE = {};
}
XPRIZE.stages = function() {
	var STAGES = {Shakedown: 0, Knockout: 1, Finals: 2, Validation: 3};
	var STAGES_INFO = [
		{stageName: "Shakedown",
		startDate: "April 26, 2010",
		endDate: "May 7, 2010"
		},
		{stageName: "Knockout",
		startDate: "June 21, 2010",
		endDate: "June 30, 2010"	// add end time?
		},
		{stageName: "Finals",
		startDate: "July 19, 2010",
		endDate: "July 30, 2010"
		},
		{stageName: "Validation",
		startDate: "August, 2010",
		endDate: "August, 2010"
		}
	];
	EVENT_INFO = {
		"01" : {
			stageName : "Shakedown",
			eventName : "Dynamic Safety Test",
			eventTimes : [{
							startTime: "May 5, 2010 9:00", 
							endTime: "May 5, 2010 17:00"
						  }]
		},
		"02" : {
			stageName : "Shakedown",
			eventName : "Emissions Test",
			eventTimes : [{
							startTime: "May 6, 2010 9:00", 
							endTime: "May 6, 2010 17:00"
						  }]
		},
		"03" : {
			stageName : "Shakedown",
			eventName: "Durability Test",
			eventTimes: [{
						 	startTime: "May 6, 2010 13:00", 
							endTime: "May 6, 2010 17:00"
						 },
						 {
						 	startTime: "May 7, 2010 13:00",
							endTime: "May 7, 2010 17:00"
						}]
		},
		"04" : {
			stageName : "Shakedown",
			eventName: "Efficiency Test",
			eventTimes: [{
						 	startTime: "May 7, 2010 9:00",
							endTime: "May 7, 2010 17:00"
						 }]
		},
		"05" : {
			stageName : "Knockout",
			eventName: "Efficiency Test: Urban",
			eventTimes: [{
						 	startTime: "June 21, 2010 9:00",
							endTime: "June 21, 2010 12:00"
						 },
						 {
						 	startTime: "June 23, 2010 8:30",
							endTime: "June 22, 2010 13:00"
						 }]
		},
		"06" : {
			stageName : "Knockout",
			eventName: "Efficiency Test: City",
			eventTimes: [{
						 	startTime: "June 21, 2010 14:00",
							endTime: "June 21, 2010 17:00"
						 },
						 {
						 	startTime: "June 23, 2010 13:30",
							endTime: "June 22, 2010 17:00"
						 }]
		},
		"07" : {
			stageName : "Knockout",
			eventName: "Efficiency Test: Highway",
			eventTimes: [{
						 	startTime: "June 22, 2010 9:00",
							endTime: "June 22, 2010 17:00"
						 },
						 {
						 	startTime: "June 24, 2010 8:00",
							endTime: "June 24, 2010 17:00"
						 }]
		},
		"08" : {
			stageName : "Knockout",
			eventName: "Range Test",
			eventTimes: [{
						 	startTime: "June 25, 2010 8:00",
							endTime: "June 25, 2010 17:00"
						 }]
		},
		"09" : {
			stageName : "Knockout",
			eventName: "Emissions Test",
			eventTimes: [{
						 	startTime: "June 28, 2010 9:00",
							endTime: "June 29, 2010 17:00"
						 }]
		},
		"10" : {
			stageName : "Finals",
			eventName: "Efficiency Test: Urban",
			eventTimes: [{
						 	startTime: "July 19, 2010 9:00",
							endTime: "July 30, 2010 17:00"
						 }]
		},
		"11" : {
			stageName : "Finals",
			eventName: "Efficiency Test: City",
			eventTimes: [{
						 	startTime: "July 19, 2010 9:00",
							endTime: "July 30, 2010 17:00"
						 }]
		},
		"12" : {
			stageName : "Finals",
			eventName: "Efficiency Test: Highway",
			eventTimes: [{
						 	startTime: "July 19, 2010 9:00",
							endTime: "July 30, 2010 17:00"
						 }]
		},
		"13" : {
			stageName : "Finals",
			eventName: "Range Test",
			eventTimes: [{
						 	startTime: "July 19, 2010 9:00",
							endTime: "July 30, 2010 17:00"
						 }]
		},
		"14" : {
			stageName : "Finals",
			eventName: "Race",
			eventTimes: [{
						 	startTime: "July 19, 2010 9:00",
							endTime: "July 30, 2010 17:00"
						 }]
		}
	};
	// haven't loaded teams_events json file yet
	var events_loaded = false;
	// list created from the eventData json file
	var completed_events = [];

	function currentStage(now) {
		if (typeof(now) != "Date") now = new Date(now);
		// TODO add one day to endDate....
		for (var stage=0; stage<STAGES_INFO.length; stage++) {
			if (now >= new Date(STAGES_INFO[stage].startDate) &&
				now <= new Date(STAGES_INFO[stage].endDate)) {
				return STAGES_INFO[stage].stageName;
			}
		}
		return null;
	}
	function currentEvents(stage, now) {//remove
		if (!stage) return null;
		var stageID = STAGES[stage];
		if (typeof(now) != "Date") now = new Date(now);
		var events = [];
		for (var ev in EVENT_INFO) {
			if (EVENT_INFO[ev].stageName != stage) continue;
			var event_times = EVENT_INFO[ev].eventTimes;
			for (var t=0; t<event_times.length; t++) {
				if (now >= new Date(event_times[t].startTime) &&
					now <= new Date(event_times[t].endTime)) {
//					events.push(EVENT_INFO[ev].eventName);
					events.push(ev);
				}
			}
		}
		if (events.length>0) return events;
		return null;
	}
	function nextStage(now) {
		if (typeof(now) != "Date") now = new Date(now);
		for (var stage=0; stage<STAGES_INFO.length; stage++) {
			if (now < new Date(STAGES_INFO[stage].startDate)) {
				return STAGES_INFO[stage].stageName;
			}
		}
		return null;
	}
	function nextEvent(now) {
		if (typeof(now) != "Date") now = new Date(now);
		// get last completed event
		var lastevent = lastEvent();
		var found = false;
		for (var evnt in EVENT_INFO) {
			if (found) {
				// double check dates?
				var event_times = EVENT_INFO[evnt].eventTimes;
				if (now < new Date(event_times[0].startTime))
					return evnt;
			}
			if (evnt == lastevent)
				found = true;
		}
		return null;
	}
	function lastStage(now) {
		if (typeof(now) != "Date") now = new Date(now);
		for (var stage=0; stage<STAGES_INFO.length; stage++) {
			if (now < new Date(STAGES_INFO[stage].startDate)) {
				if (stage == 0) return null;
				return STAGES_INFO[stage-1].stageName;
			}
		}
		return STAGES_INFO[STAGES_INFO.length-1].stageName;
	}
	function lastEvent() {
		var lastevent = "00";
		for (var team in XPRIZE.eventData) {
			var numevents = XPRIZE.eventData[team].length
			if (numevents > 0 && XPRIZE.eventData[team][numevents-1] > lastevent)
				lastevent = XPRIZE.eventData[team][numevents-1];
		}
		return lastevent;
	}
	function stageCompleted(stageID, now) {
		if (typeof(now) != "Date") now = new Date(now);
		return now > new Date(STAGES_INFO[stageID].endDate)
	}
	function eventCompleted(eventID) {
		for (var team in XPRIZE.eventData) {
			if (XPRIZE.eventData[team].indexOf(eventID) != -1)
				return true;
		}
		return false;
	}
	function parseCompletedEvents() {
			completed_events = [];
			for (var ev in EVENT_INFO) {
				if (eventCompleted(ev))
					completed_events.push(ev);
			}
	}
	function getEventInfo(callback) {
		$.getJSON("json/eventData.json", function(data) {
				if (data && typeof data == "object") {
                	XPRIZE.eventData = data;
					events_loaded = true;
					parseCompletedEvents();
					if (callback)
						callback();
				}
		});
	}
	return {
		ready: function() {
			if (XPRIZE.eventData) events_loaded = true;
			return events_loaded;
		},
		init: function(callback) {
			if (XPRIZE.eventData) {
				events_loaded = true;
				parseCompletedEvents();
				if (callback)
					callback();
			}
			else getEventInfo(callback);
		},
		getStageDetails: function(stageName) {
			return STAGES_INFO[STAGES[stageName]] || null;
		},
		getCurrentStage: function(datetime) {
			datetime = datetime || new Date();
			return currentStage(datetime);
		},
		getCurrentEvents: function(stage, datetime) {//remove?
			datetime = datetime || new Date();
			stage = stage || currentStage(datetime);
			return currentEvents(stage, datetime);
		},
		getNextStage: function(datetime) {
			datetime = datetime || new Date();
			return nextStage(datetime);
		},
		getNextEvent: function(datetime) {
			datetime = datetime || new Date();
			return nextEvent(datetime);
		},
		hasCompleted: function(stageName, datetime) {
			var id = STAGES[stageName];
			if (typeof(id) == "undefined") return false;
			datetime = datetime || new Date();
			return stageCompleted(id, datetime);
		},
		lastCompletedStage: function(datetime) {
			datetime = datetime || new Date();
			return lastStage(datetime);
		},
		lastCompletedEvent: function(stage, datetime) {
			datetime = datetime || new Date();
			return lastEvent(stage, datetime);
		},
		getCompletedStages: function(datetime) {//remove?
			datetime = datetime || new Date();
			var stages = [];
			for (var i=0; i<STAGES_INFO.length; i++) {
				if (stageCompleted(i, datetime))
					stages.push(STAGES_INFO[i].stageName);
			}
			return stages;
		},
		getPreviousStage: function(stage) {
			var prev = STAGES[stage] - 1;
			if (prev < 0) return null;
			for (var s in STAGES) {
				if (STAGES[s] == prev) return s;
			}
			return null;
		},
		getStageName: function(eventID) {
			if (!EVENT_INFO.hasOwnProperty(eventID)) return null;
			return EVENT_INFO[eventID].stageName;
		},
		getEventName: function(eventID) {
			if (!EVENT_INFO.hasOwnProperty(eventID)) return null;
			return EVENT_INFO[eventID].stageName + " " + EVENT_INFO[eventID].eventName;
		},
		getCompletedEvents: function() {
			return completed_events;
		},
		getEvents: function() {
		    return EVENT_INFO;
		}
	}
}();
	

