// JavaScript Document

// programs is an array of valid program types
var programs = new Array();
var programName = new Array();
programs.push("art");
programName.push("Art");

programs.push("business");
programName.push("Business");

programs.push("credit_courses");
programName.push("Credit Courses");

programs.push("education");
programName.push("Education");

programs.push("health_care");
programName.push("Health Care");

programs.push("human_services");
programName.push("Human Services");

programs.push("languages/cultures");
programName.push("Languages &amp; Cultures");

programs.push("personal_enrichment");
programName.push("Personal Enrichment");

programs.push("sciences");
programName.push("Sciences");

programs.push("undergraduate");
programName.push("Undergraduate");

programs.push("youth");
programName.push("Youth");

programs.sort();
programName.sort();
var multiplier = 1; // used to tell if its ASC=1 or DESC=-1 

/*
startDate of event is date Object
endDate of event is date Object
name of event
location of event
link to the event
program is a string --> "youth", "art", "human_services", "business", "languages/cultures", "credit_courses", personal_enrichment", "education", "sciences", "health_care", "undergraduate"
properties is a comma separated list of strings, EX can be "full", "cancelled", "closed", "save_the_date"
*/
function CeEvent(startDate, endDate, name, location, href, registerNow, program, properties) {
	this.startDate=startDate;
	this.endDate=endDate;
	this.name=name;
	this.location=location;
	this.href=href;
	this.registerNow=registerNow;
	this.program=program;
	this.properties=properties;
	this.toString=CeEvent_toString;
	this.displayHtml=CeEvent_displayHtml;
	this.generateHtml=CeEvent_generateHtml;
	this.generateChunkedHtml=CeEvent_generateChunkedHtml;
	this.spansOneMonth=CeEvent_spansOneMonth;
}

function CeEvent_toString(){
	document.write("CeEvent - start:"+convertToMMDDYYYYFromDate(this.startDate)+"; end:"+
		convertToMMDDYYYYFromDate(this.endDate)+"; name:"+this.name+"; location:"+
		this.location+"; href:"+this.href+"; program:"+this.program+"; properties: "+this.properties+"<br \/>\n");
}

function CeEvent_displayHtml(){
	document.write(this.generateHtml());
}

function CeEvent_generateChunkedHtml(){
	var className = "CeEvent";
	if(this.properties.indexOf("save_the_date") != -1){
		className += " saveTheDate";
	}
	if(this.startDate == null){
		className += " comingSoon";
	}
	var result = '';
	result += '<div class="'+className+'">';
	if(this.properties.indexOf("save_the_date") != -1){
		result += '<span class="saver">Save The Date<\/span>';
	}
	if(this.startDate == null){
		result += '<span class="soon">Coming Soon<\/span>';
	}
	result += '	<h3 class="name">'; 
	if(this.href != ""){
		result += '<a href="'+this.href+'">';
	}
	result += this.name;
	if(this.href != ""){
		result += '</a>';
	}
	result += '</h3>';
	if(this.startDate != null && this.endDate != null){
		result += '	<span class="dates">'+convertToMMDDYYYYFromDate(this.startDate)+' &mdash; '+convertToMMDDYYYYFromDate(this.endDate)+'</span>';
	}
	result += '	<span class="location">'+this.location+'</span>';
	if(this.registerNow != ""){
		result += '	<span class="register"><a href="'+this.registerNow+'">Register Now</a></span>';
	}
	result += '</div>';
	return result;
}

function CeEvent_generateHtml(){
	var heading = convertToMMDDYYYYFromDate(this.startDate);
	// if event spans multiple months, diplay end date as well
	if(!this.spansOneMonth()){
		heading += "&mdash;"+convertToMMDDYYYYFromDate(this.endDate);
	}
	var className = "MonthCeEvent";
	if(this.properties.indexOf("save_the_date") != -1){
		heading += " &mdash; Save The Date";
		className += " MonthSaveTheDate";
	}
	if(this.startDate == null){
		heading = "Coming Soon";
		className += " MonthComingSoon";
	}
	var result = '<div class="'+className+'">';
	result += '<h2>'+heading+'</h2>';
	result += '<span class="name">';
	if(this.href != ""){
		result += '<a href="'+this.href+'">';
	}
	result += this.name;
	if(this.href != ""){
		result += '</a>';
	}
	result += '<\/span>';
	result += '<span class="location">'+this.location+'<\/span>';
	if(this.registerNow != ""){
		result += '	<span class="register"><a href="'+this.registerNow+'">Register Now</a></span>';
	}
	result += '<\/div>';
	return result;
}


function CeEvent_spansOneMonth(){
	var result = true;
	if (this.startDate != null && this.endDate != null){
		result = this.startDate.getMonth() == this.endDate.getMonth();
	}
	return result;
}

function Events(){
	this.eventList = new Array();
	this.addEvent = addEvent;
	this.toString = Events_toString;
	this.sort = Events_sort;
	this.display = Events_display;
	this.getEvents = Events_getEvents;
	this.chunkedDisplay = Events_chunkedDisplay;
}
function Events_toString(){
	document.write("<p>Events<br \/>");
	for(var i = 0; i < this.eventList.length; i++){
		this.eventList[i].toString();
	}
	document.write("<\/p>");
}

// start and end date in format : MM/DD/YYYY
function addEvent(startDate, endDate, name, location, href, registerNow, program, properties){
	//convert startDate
	var start = convertToDateFromMMDDYYYY(startDate);
	//convert endDate
	var end = convertToDateFromMMDDYYYY(endDate);
	var theEvent = new CeEvent(start, end, name, location, href, registerNow, program, properties);
	this.eventList.push(theEvent);
}

// sort the array of events in either "ASC" or "DESC" and by what type of property EX: startDate
function Events_sort(order, property){
	if (order == "ASC") {
		multiplier=1;
		this.eventList.sort(CeEvent_compare_startDate);
	}else if (order == "DESC"){
		multiplier=-1;
		this.eventList.sort(CeEvent_compare_startDate);
	} else {
		alert("Events_sort received an improper order.");
	}
}

// displays dates from startDate to endDate, and display up to numOfDates, if numOfDates is null, display as many events as tehre is
function Events_display(startDate, lastDate, numOfDates){
	this.sort("ASC","startDate");
	if (numOfDates == null){
		numOfDates = Number.MAX_VALUE;
	}
	var events = this.getEvents(startDate, lastDate);
	for(var i = 0; i < numOfDates && i < events.length; i++){
		events[i].displayHtml();
	}
}

// displays all programs for a year, segmented into program areas
function Events_chunkedDisplay(){
	var start = new Date();

	var end = new Date();	
	end.setYear(end.getFullYear() + 1);
	var events = this.getEvents(start, end); // all the events in ascending order
	
	// create array to store html data of the different events.
	var generatedHTML = new Array(programs.length);
	// initialize to empty strings
	for(var i = 0; i < generatedHTML.length; i++){
		generatedHTML[i]="";
	}
	var programPos = -1;
	for(var i = 0; i < events.length; i++){
		programPos = binarySearch(programs, events[i].program, 0, programs.length);// programs.indexOf(events[i].program);
		generatedHTML[programPos]+=events[i].generateChunkedHtml();
	}
	
	for(var i = 0; i < generatedHTML.length; i++){
		document.write('<a name="'+programs[i]+'"></a><h2>'+programName[i]+'</h2>'+generatedHTML[i]);
		if(generatedHTML[i]==""){
			document.write('<p>There are no events for this program.<\/p>')
		}
		document.write('<p><a href="#top">Go To The Top<\/a><\/p>')
		
	}
}

// gets an array of all events whose startdate is between startDate and lastDate inclusive and whose enddate is between startDate and lastDate
function Events_getEvents(startDate, lastDate){
	var result = new Array();
	this.sort("ASC","startDate");
	for(var i = 0; i < this.eventList.length; i++){
		var ceEvent = this.eventList[i];
		if(
			(convertToYYYYMMDDFromDate(ceEvent.startDate) - convertToYYYYMMDDFromDate(startDate) >= 0 && 
			convertToYYYYMMDDFromDate(ceEvent.startDate) - convertToYYYYMMDDFromDate(lastDate) <= 0) ||
			(convertToYYYYMMDDFromDate(ceEvent.endDate) - convertToYYYYMMDDFromDate(startDate) >= 0 && 
			convertToYYYYMMDDFromDate(ceEvent.endDate) - convertToYYYYMMDDFromDate(lastDate) <= 0)
			|| ceEvent.startDate == null){
			result.push(ceEvent);
		}
	}	
	return result;
}

function CeEvent_compare_startDate(a,b){
		var aDate = convertToYYYYMMDDFromDate(a.startDate);
		var bDate = convertToYYYYMMDDFromDate(b.startDate);
		return (aDate - bDate)*multiplier;
}

function convertToDateFromMMDDYYYY(textVersion){
	var result = new Date();
	var date = textVersion.split("/");
	var year = date[2]*1;
	var month = date[0]*1-1;
	var date = date[1]*1;
	result.setFullYear(year,month,date);
	if(textVersion == ""){
		result = null;
	}
	return result;
}

function convertToMMDDYYYYFromDate(date){
	var result = "";
	if (date != null){
		if(date.getMonth() < 9 ){
			result+= "0";
		}
		result += (date.getMonth()+1) + "/";
		if(date.getDate() < 10 ){
			result+= "0";
		}
		result += date.getDate() + "/";
		result += date.getFullYear();
	}
	return result;
}

function convertToYYYYMMDDFromDate(date){
	var result = "";
	if (date != null){
		result+=date.getFullYear();
		if(date.getMonth() < 9 ){
			result+= "0";
		}
		result += (date.getMonth()+1);
		if(date.getDate() < 10 ){
			result+= "0";
		}
		result += date.getDate();
	}
	return result;
}

// returns position of item in the array
function binarySearch(a, value, left, right) {
	var result = -1;
	var found = false;
	while (!found && left <= right){
		var mid = Math.floor((left+right)/2);
		if (value > a[mid]){
			left = mid + 1;
		}else if (value < a[mid]){
			right = mid - 1;
		}else{
			result = mid;
			found = true;
		}
	}
	return result;
}

// return month full name from date object
function getMonthname(aDate){
	var result = "";
	if(aDate != null){
		var result = aDate.toLocaleString().split(",");
		result = result[1];
		result = result.slice(1,result.length-3);
	}
	return result;	
}

function generateProgramLinkList(){
	var result = "<ul class='jumpPrograms'>";
	for (var i = 0; i < programName.length; i++){
		result += '<li>';
		result += '<a href="#'+programs[i]+'">';
		result += programName[i];
		result += '<\/a>';
		if (i != programName.length -1){
			result += ' &ndash;';
		}
		result += '<\/li>';
	}
	result += "<\/ul>";
	return result;
}

function generateMonthPicker(month,year){
	var result = '';
	var result = "<ul class='monthJumper'>";
	var aDate = new Date();
	var begLink;
	var endLink;
	var className;
	for (var i = 0; i < 12; i++){
		begLink = '<a href="?'+aDate.getFullYear();
			if(aDate.getMonth()+1 < 10){
				begLink += "0";
			}
			begLink += (aDate.getMonth()+1)+'">';
		endLink = "<\/a>";
		className = "";
		if(month-1 == aDate.getMonth()&&year == aDate.getFullYear()){ // if it is the current one
			className = "current";
			begLink = "";
			endLink = "";
		}
		result += '<li class="'+className+'">';
		result += begLink + getMonthname(aDate) +" " + aDate.getFullYear() + endLink;
		result += '<\/li>';
		aDate.setMonth(aDate.getMonth()+1);
	}
	result += "<\/ul>";
	return result;
}