/*
 * Global variables
 */
var cli_timeout;
var cli_timeout_value;

/*
 * The EventSidebar class
 */
function EventSidebar(t){
	//These refer to the open/closed state for home page vs. secondary pages.
	this.collapse = true;
	this.openState = false;
	this.pagination = true;
	
	this.eventXml = false;
	this.events;
	this.event_count = 0;
	this.maxEvents = 4; //number of events per page.
	this.page = 1; //this is a page counter.
	this.targetElement = t;
	this.sortby = new Array('Artist','Date','Genre');
	this.tabSelector = this.sortby[0];
	this.searchAttributes = new Array('altnames','genres', 'years');
	
	this.renderArtistFilterControl = eS_renderArtistFilterControl;
	this.renderDateFilterControl = eS_renderDateFilterControl;
	this.renderGenreFilterControl = eS_renderGenreFilterControl;
	this.renderEventSidebar = eS_renderEventSidebar;
	this.renderItemSet = eS_renderItemSet;
	this.renderTabMenu = eS_renderTabMenu;	
	this.renderPagination = eS_renderPagination;
	this.checkLookupItems = eS_checkLookupItems;
	this.displayPaginatedItems = eS_displayPaginatedItems;
	this.showFilteredElements = eS_showFilteredElements;
	this.showAllEvents = eS_showAllEvents;
	this.createTabMenu = eS_createTabMenu;
	this.pickStartEvent = eS_pickStartEvent;
	this.formatDates = eS_formatDates;
	
	this.dataCheck = eS_dataCheck;
	
	this.__construct = function(){
		this.dataCheck();
	}
}
/*
 * EventSidebar Methods
 */
function eS_dataCheck(){
	var obj = this;
	/*
	 * xhr is a global variable that contains the AJAX-called XML file.
	 */
	if(xhr.constructor != Object){
		this.eventXml = xhr;
		this.renderEventSidebar();
	}
	else{
		setTimeout(function(){
			obj.dataCheck();
		},50);
	}
}


function eS_renderEventSidebar(){
	this.events = $(this.eventXml).find('event');
	this.event_count = this.events.length;	
	this.targetElement.append('<div class="content"><div class="tabs"></div><div class="eventSet"></div></div>');
	
	this.renderItemSet();
	this.renderTabMenu();
		
	//on secondary pages...
	if(this.collapse == true){
		this.targetElement.find('.eventSet, .pagination').hide();
		this.targetElement.css('height','auto');
		var obj = this;
		this.targetElement.click(function(){
			if(obj.openState == false){
				obj.targetElement.animate({
					height: '381px'
				}, 500, function(){
					obj.targetElement.find('.eventSet, .pagination').fadeIn();
				});
				
				obj.openState = true;
			}	
		});
	}
}

function eS_renderItemSet(){
	var obj = this;
	
	//render the max events allowed starting at a specified index.
	for(var n=0; n<obj.event_count; n++){
		
		obj.targetElement.find('.eventSet').append('<a class="eventListing"></a>');
		
		var eventListing = obj.targetElement.find('.eventListing:last');
		
		var name = obj.events.eq(n).find('artist > name').text();
		var altname = obj.events.eq(n).find('artist > altname').text();
		
		//use QA if on qa
		if(window.location.href.indexOf('http://qa') != -1){
			var url = obj.events.eq(n).find('pageUrlQa').text();
		}
		else{
			var url = obj.events.eq(n).find('pageUrl').text();
		}
		eventListing.attr('href',url);
		eventListing.append('<div class="title">'+name+'</div>');
		//add a lowercase version for searching. Could also add alt names here. If we do this, separate them with a | on each side.
		eventListing.attr('altnames',name.toLowerCase()+','+altname.toLowerCase());
		
		//add dates
		
		//get date strings and render
		var dateStr = obj.formatDates(obj.events.eq(n).find('dates'));
		eventListing.append('<div class="date tiny">'+dateStr+'</div>');
			
		//add genres
		var genreStr = '';	
		obj.events.eq(n).find('genres > genre').each(function(){
			genreStr += '|'+$(this).text().toLowerCase()+'|';
		});
		eventListing.attr('genres',genreStr);
		
		
		var years = '';
		var months = '';
		//check all dates for years and months:
		obj.events.eq(n).find('dates > endDate, dates > date').each(function(){
			var timestamp = $(this).text();
			var d = new Date(parseInt(timestamp));
			//add the year if it isn't there yet:
			if(years.indexOf(d.getFullYear()) == -1){
				years += d.getFullYear()+',';
			}	
			if(months.indexOf(monthToString(d.getMonth(),false)) == -1){
				months += monthToString(d.getMonth(),false)+',';
			}
		});	
		eventListing.attr('months',months);
		eventListing.attr('years',years);
	}
	
	if( (obj.event_count > obj.maxEvents) && (obj.pagination == true) ){
		if(obj.targetElement.find('.pagination').length == 0){
			obj.targetElement.append('<div class="pagination"><div class="next"></div><span>More</span><div class="previous"></div><div class="clear"></div></div>');
		}	
		obj.renderPagination();
	}
}

function eS_renderTabMenu(){
	var obj = this;
	
	for(var n=0;n<this.sortby.length;n++){
		this.targetElement.find('.tabs').append('<div class="tab" name="'+this.sortby[n]+'">'+eval('this.render'+this.sortby[n]+'FilterControl()')+'</div>');
	}
	this.targetElement.find('.tabs').append('<div class="clear"></div>');
	//
	/*
	 * Artist lookup event assignment
	 */
	//attach an event to the search input
	var searchbox = this.targetElement.find('.tab form.search .input:first');
	searchbox.focus(function(){
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarSearch', 'focus');
		}
		obj.checkLookupItems();
	});
	//clear the repeating timeout on blur
	searchbox.blur(function(){
		clearTimeout(cli_timeout);
	});
	
	/*
	 * Date lookup event assignment
	 */
	this.targetElement.find('.tab ul.date li').click(function(){
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarDate', $(this).text());
		}
		$(this).parent().children().attr('class','');
		$(this).attr('class','selected');
		
		$(this).parent().parent().find('li:not(.selected)').slideUp();
		$(this).parent().siblings().hide();
		$(this).parent().animate({
			width: '100%'
		}, 500);
		$('.eventSet').fadeIn();
		
		var needle = $(this).text();
		var events = obj.targetElement.find(".eventListing");
		
		events.hide();
		events.each(function(){
			setFilterAttribute($(this),'false');
		});	
		
		events.filter("[months*=\""+needle+"\"]").each(function(){
			setFilterAttribute($(this),'true');
		});
		
		
		obj.showFilteredElements();
		obj.targetElement.find('.pagination .next').click();
	});
	
	/*
	 * Genre lookup event assigment
	 */
	this.targetElement.find('.tab ul.genre li').click(function(){
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarGenre', $(this).text());
		}
		$(this).parent().children().attr('class','');
		$(this).attr('class','selected');
		$(this).parent().parent().find('li:not(.selected)').slideUp();
		$(this).parent().siblings().hide();
		$(this).parent().animate({
			width: '100%'
		}, 500);
		$('.eventSet').fadeIn();
		
		var needle = $(this).text().toLowerCase();
		
		obj.targetElement.find(".eventListing").hide();
		obj.targetElement.find(".eventListing").each(function(){
			setFilterAttribute($(this),'false');
		});
		
		//look in altnames for matches; everything there is lowercase
		obj.targetElement.find(".eventListing[genres*=\"|"+needle+"|\"]").each(function(){
			setFilterAttribute($(this),'true');
		});
		
		obj.showFilteredElements();
		obj.targetElement.find('.pagination .next').click();
	});
	
	//create the tab menu if needed:
	if(obj.sortby.length > 1){
		obj.createTabMenu();
	}	
	
	//Format the menus:
	obj.targetElement.find(".tabs").find(".tab").each(function(){
		var lis = $(this).find("li");
		var half = Math.ceil(lis.length/2);
		lis.filter(":lt("+half+")").wrapAll('<div class="left"></div>');
		lis.filter(":not(:lt("+half+"))").wrapAll('<div class="right"></div>');
	});	
}	

function eS_createTabMenu(){
	var obj = this;
	var tabs = obj.targetElement.find(".tabs");
	tabs.find(".tab").hide();
	tabs.find(".tab:first").show();
	
	tabs.find(".tab:first").before('<ul class="tabMenu"></ul>');
	
	tabs.find(".tab").each(function(){
		tabs.find(".tabMenu").append('<li>'+$(this).attr('name')+'</li>');
	});
	
	tabs.find(".tabMenu li:first").attr("class","selected");
	tabs.find('.tabMenu li:first').attr('id','firstMenuItem');
	
	tabs.find(".tabMenu li").click(function(){
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarMenuChange', $(this).text());
		}
		tabs.find(".tabMenu li").attr("class","");
		var needle = $(this).text();
		$(this).attr("class","selected");
		tabs.find('ul > div').show();
		tabs.find('ul > div').animate({
			width: '45%'
		}, 500);
		
		tabs.find(".tab:visible").slideUp('200',function(){
			tabs.find(".tab").each(function(){
				
				if(needle == $(this).attr('name')){
					
					if( (needle == 'Date') || (needle == 'Genre') ){
						//hide the events listing for these menus until an option is selected.
						$('.eventSet').hide();
					}
					else {
						$('.eventSet').fadeIn();
					}
					$(this).find('li').show();
					$(this).find('li').attr('class','');
					$(this).slideDown('200');
					
					obj.showAllEvents();
				}	
			});
		});	
	});
}


function eS_pickStartEvent(){
	//use endDate timestamp if available; otherwise use the last date node timestamp
	/*
	 * decided to just use last date element
	 */
	var obj = this;
	currentTime = new Date().getTime();
	
	for(var n=0;n<obj.events.length;n++){
		//var timestamp = obj.events.eq(n).find('dates > endDate:last').text();
		
		//if(timestamp == ''){
			//use the last date node
			timestamp = obj.events.eq(n).find('dates > date:last').text();
		//}
		if(parseInt(timestamp) > currentTime){
			return n;
		}	
	}
}

function eS_renderPagination(){
	//initially show the max number of items allowed per page.
	this.targetElement.find('.eventListing').hide();
	
	/*
	 * set the starting element to be the first one based on current date:
	 */
	//var startNode = this.pickStartEvent();	
	var startIndex = this.pickStartEvent();
	
	//var endIndex = startIndex + this.maxEvents + 1;
	var endIndex = startIndex + this.maxEvents;
	this.targetElement.find('.eventListing:lt('+endIndex+'):gt('+startIndex+')').show();
	this.targetElement.find('.eventListing:eq('+startIndex+')').show();
	
	
	this.targetElement.find('.eventListing').each(function(){
		setFilterAttribute($(this),'true');
	});
	this.displayPaginatedItems();
}

function eS_displayPaginatedItems(){
	//define the action of the "next" button
	var obj = this;
	this.targetElement.find('.pagination .next').click(function(){		
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarToggle', $(this).attr('class'));
		}
		var filteredElements = obj.targetElement.find('.eventListing[filter="true"]');
		
		//find the last visible element and display the correct number of siblings.
		var startElement;		
		if(filteredElements.filter(':last').is(':visible')){
			startElement = filteredElements.filter(':first');
		}
		else{
			startElement = filteredElements.filter(':visible:last').nextAll('[filter="true"]:first');
		}
		obj.targetElement.find('.eventListing').hide();
		
		var showThese = new Array();
		showThese.push(startElement);
		
		for(var n=1; n<obj.maxEvents; n++){
			showThese.push(showThese[n-1].nextAll('[filter="true"]:first'));
		}
		
		$(showThese).each(function(){
			checkOffset($(this));
		});			
	});
	
	this.targetElement.find('.pagination .previous').click(function(){		
		if(typeof(siteTracker) != 'undefined'){
			siteTracker._trackEvent('EventSidebarToggle', $(this).attr('class'));
		}
		var filteredElements = obj.targetElement.find('.eventListing[filter="true"]');
		
		//find the last visible element and display the correct number of siblings.
		var startElement;		
		if(filteredElements.filter(':first').is(':visible')){
			startElement = filteredElements.filter(':last');
		}
		else{
			startElement = filteredElements.filter(':visible:first').prevAll('[filter="true"]:first');
		}
		obj.targetElement.find('.eventListing').hide();
		
		var showThese = new Array();
		showThese.push(startElement);
		
		for(var n=1; n<obj.maxEvents; n++){
			showThese.push(showThese[n-1].prevAll('[filter="true"]:first'));
		}
		showThese.reverse();
		$(showThese).each(function(){
			checkOffset($(this));
		});			
	});
}

function checkOffset(me){
	if(me.length != 0){
		me.fadeIn();
		var top = me.position().top;
		var height = me.height();
		var p_height = me.parent().height();
		if((height+top) >= p_height){
			me.hide();
		}	
		//me.attr('coords',height+','+top)
	}
}

/*
 * Filtering controllers
 */
function eS_renderArtistFilterControl(){
	return '<form class="search"><input class="input" type="text" /><input class="submit" type="button" /></form>';
}

function eS_checkLookupItems(){
	var obj = this;
	//obj.displayPaginatedItems();
	
	if(obj.targetElement){
		var needle = obj.targetElement.find(".tab form.search .input").val();
		/*
		 * This if clause keeps the rewriting portion of the script from occuring if the 
		 * search input hasn't changed since the last check.
		 */
		if (cli_timeout_value != needle){
			cli_timeout_value = needle;
			//escape apostrophes
			needle = needle.replace(/'/g,"\'");
			
			//Replace banned Characters:
			needle = needle.replace(/"/g,"");
			
			//make everything lowercase
			needle = needle.toLowerCase();	
			
			if(needle != ''){
				obj.targetElement.find(".eventListing").hide();
				obj.targetElement.find(".eventListing").each(function(){
					setFilterAttribute($(this),'false');
				});
				
				//use the searchAttributes array for attributes to search
				
				for(var n=0; n< obj.searchAttributes.length; n++){
					obj.targetElement.find(".eventListing["+obj.searchAttributes[n]+"*=\""+needle+"\"]").each(function(){
						setFilterAttribute($(this),'true');
					});
				}	
				obj.showFilteredElements();
				obj.targetElement.find('.pagination .next').click();
			}	
			else{
				obj.showAllEvents();
			}
		}		
		cli_timeout = setTimeout(function(){
			obj.checkLookupItems();
		},500);
			
	}	
}

function eS_showAllEvents(){
	var obj = this;
	
	obj.targetElement.find(".eventListing").each(function(){
		setFilterAttribute($(this),'true');
	});
	obj.showFilteredElements();
	obj.targetElement.find('.pagination .next').click();
	if( (obj.targetElement.find(".eventListing[filter='true']").length > obj.maxEvents) && (obj.targetElement.find('.eventSet:first').is(':visible')) ){
		obj.targetElement.find('.pagination').fadeIn();
	}
	else{
		obj.targetElement.find('.pagination').hide();
	}
}

function eS_renderGenreFilterControl(){
	var genres = $(this.eventXml).find('genre');
	var genreStore = new Array();
	
	var genreList = '<ul class="genre">';
	$(genres).each(function(){
		var g = '|'+$(this).text()+'|';
		if(genreStore.toString().indexOf(g) == -1){
			genreList += '<li>'+$(this).text()+'</li>';
			genreStore.push(g);
		}
	});
	genreList += '</ul>';
	
	return genreList;
}

function eS_renderDateFilterControl(){
	var dateLinks = '<ul class="date">';
	this.targetElement.find(".eventListing").each(function(){
		var months = $(this).attr('months').split(',');
		for(var n=0; n<months.length; n++){
			if(dateLinks.indexOf(months[n]) == -1){
				dateLinks += '<li>'+months[n]+'</li>';	
			}	
		}	
	});
	
	dateLinks += '</ul>';
	return dateLinks;
}

function eS_showFilteredElements(){
	var obj = this;
	
	obj.targetElement.find(".eventListing[filter='true']").show();
	obj.targetElement.find(".eventListing[filter!='true']").hide();
	
	if( (obj.targetElement.find(".eventListing[filter='true']").length > obj.maxEvents) && (obj.targetElement.find('.eventSet:first').is(':visible')) ){
		obj.targetElement.find('.pagination').fadeIn();
	}
	else{
		obj.targetElement.find('.pagination').hide();
	}
}

/*
 * Global functions
 */

function eS_formatDates(o){
	var obj = this;
	/*
	 * Date Formatting
	 * 
	 * Rules:
	 * always output day of week, month, and date for start
	 * output year on start and end if different
	 * output day of week, month, and date on start and end if different
	 * output times if not dateAllDay
	 * 
	 * Test to see if start dates have matching end dates (matched on index).
	 */
	
	var dateStr = '';
	
	var startDates = $(o).find('date');
	var endDates = $(o).find('endDate');
		
	for(var n=0;n<startDates.length;n++){	
		//start date
		var startDateNode = $(startDates[n]);
		var timestamp = startDateNode.text();
		var d = new Date(parseInt(timestamp));
		var startDate = {
				day: dayToString(d.getDay(),3), 
				month: monthToString(d.getMonth(),3), 
				date: d.getDate(), 
				year: d.getFullYear(), 
				time: timeToString(d)
		};
		
		dateStr += startDate.day+', '+startDate.month+' '+startDate.date;
		
		//end date
		if(endDates.length != 0){
			var endDateNode = $(endDates[n]);
			var endDate = false;
			if( (endDateNode.length != 0) && (endDateNode.text() != '') ){
				timestamp = endDateNode.text();
				var end_d = new Date(parseInt(timestamp));
				
				endDate = {
						day: dayToString(end_d.getDay(),3), 
						month: monthToString(end_d.getMonth(),3), 
						date: end_d.getDate(), 
						year: end_d.getFullYear(), 
						time: timeToString(end_d)
				};				
			}	
			
			if( (endDate == false) || (startDate.year != endDate.year) || ((startDate.date == endDate.date) && (startDate.month == endDate.month))){
				dateStr += ', '+startDate.year;
			}	
			
			if($(o).find('dateAllDay').text() != 'Yes'){
				//add times
				dateStr += ', '+startDate.time;
			}
			
			if(endDate){
				var addComma = false;
				dateStr += ' - ';
				
				if( (startDate.date != endDate.date) || (startDate.month != endDate.month) ){
					addComma = true;
					dateStr += endDate.day+', '+endDate.month+' '+endDate.date+', '+endDate.year;
				}	
					
				if($(o).find('dateAllDay').text() != 'Yes'){
					//add times
					if(addComma){
						dateStr += ', ';
					}	
					dateStr += endDate.time;
				}
			}	
		}	
		dateStr += '<br/>';
	}
	//add registration URL
	/*var register = '';
	if($(trip).find('registration:first').text() != ''){
		register= '<br /><a href="'+$(trip).find('registration:first').text()+'">Register</a>';
	}*/
	return dateStr;
	
}

function setFilterAttribute(o,value){
	o.attr('filter',value);
}

function dayToString(v, length){
	var days = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
	var d = days[v];
	if(length){
		d = days[v].substring(0,length)+'.';
	}
	return d;
}

function monthToString(v,length){
	var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
	var m = months[v];
	if(length){
		if(months[v].length > 3){
			m = months[v].substring(0,length)+'.';
		}
	}
	return m;
}

function timeToString(v){
	var hours = v.getHours();
	var minutes = v.getMinutes();
	var t;
	
	if(hours > 11){
		t = hours - 12;
		var a = 'pm';
	}
	else if (hours > 0){
		t = hours
		var a = 'am';
	}
	else{
		t = 12;
		var a = 'pm';
	}
	
	if(minutes < 10){
		var m = '0'+minutes;
	}
	else{
		var m = minutes;
	}
	
	return t+':'+m+' '+a;
}
