var PANES = ['help', 'browse', 'service', 'news'];
var SERVICE_PANES = ['incidents', 'planned-work'];
var LOAD_PANE = 'browse'; // One of 'help', 'browse', 'service', 'news'
var SWITCH_TIMEOUT_TIME = '200';
var PLANNED_WORK_URL = '/services/its/newhomepage/news/plannedwork';
var DID_YOU_KNOW_URL = '/services/its/newhomepage/news/didyouknow';

var daysOfTheWeek = ['Mon','Tue','Wed','Thur','Fri','Sat','Sun'];

var monthsOfTheYear = ['Jan','Feb','Mar','Apr','May','Jun',
	'Jul','Aug','Sep','Oct','Nov','Dec'];

var currentPane = LOAD_PANE;
var switchTimout;
var serviceActivePane;
var miniCal;

Date.prototype.toDDMMYY = function() {
	var day = this.getDate().toPaddedString(2);
	var month = (this.getMonth() + 1).toPaddedString(2);
	var year = this.getFullYear().toString().substr(2);
	return day + month + year;
};

Date.prototype.nextWeek = function() {
	var oneWeekInMilliseconds = 1000*60*60*24*7;
	return new Date(this.valueOf() + oneWeekInMilliseconds);
};

Date.prototype.lastWeek = function() {
	var oneWeekInMilliseconds = 1000*60*60*24*7;
	return new Date(this.valueOf() - oneWeekInMilliseconds);
};

Date.prototype.startOfTheWeek = function() {
	var dayAdjust = (this.getDay()==0) ? 6 : this.getDay()-1; // Monday is the first day of the week says I!
	return new Date(this.valueOf() - (dayAdjust * 1000*60*60*24));
};

Date.prototype.toNiceTimeString = function() {
	return this.getHours().toPaddedString(2) + '.' + this.getMinutes().toPaddedString(2);
};

Date.prototype.atStartOfDay = function() {
	return new Date(this.getFullYear(), this.getMonth(), this.getDate());
};

/**
 * Remove when migrating to Prototype 1.6
 */
String.prototype.times = function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
};

/**
 * Remove when migrating to Prototype 1.6
 */
Number.prototype.toPaddedString = function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
};

var MiniCalendar = Class.create();
MiniCalendar.prototype =  {
	initialize: function(options) {
		options = options || {};
		this.start = options.start || new Date().startOfTheWeek();
		this.itemsPerRow = options.itemsPerRow || 3;
		this.url = options.url;
		this.container = options.container;
		this.variable = options.variable;
		this.loadingWait = options.loadingWait || 400;
		
		this.eventItemOffset = 0;
		this.items = null;
		this.groupedItems = null;
		
		this.isLoaded = false;
	},
	
	groupItemsByDay: function() {
		this.groupedItems = [[],[],[],[],[],[],[]];
		this.items.each(function(item){
			var itemStart = new Date(item.start);
			var itemEnd = new Date(item.end);
			var daySpan = Math.floor((itemEnd.valueOf() - itemStart.valueOf()) / (1000*60*60*24));
			if (daySpan > 0) {
				// If the item spans multiple days...
				$R(0,daySpan).each(function(i){
					// For each day that the item is on...
					var day = (itemStart.getDay() + i)%7;
					var adjustedDate = new Date(itemStart.valueOf());
					adjustedDate.setDate(itemStart.getDate() + i);
					if (adjustedDate.atStartOfDay().valueOf() >= this.start.atStartOfDay().valueOf() && 
							adjustedDate.valueOf() < this.start.nextWeek().atStartOfDay().valueOf()) {
						// If this day is on the week of the calendar...
						
						if (day == 0)
							this.groupedItems[6].push(item);
						else
							this.groupedItems[day - 1].push(item);
					}
				}.bind(this));
			} else {
				if (itemStart.getDay() == 0)
					this.groupedItems[6].push(item);
				else 
					this.groupedItems[itemStart.getDay() - 1].push(item);
			}
		}.bind(this));
	},
	
	load: function() {
		new Ajax.Request('/sitebuilder2/api/rss/news.rss?page=' 
				+ this.url + '&view=upcoming&type=json&start=' 
				+ this.start.toDDMMYY() + '&end=' + this.start.nextWeek().toDDMMYY(),{
			onLoading: function() {
				if (!this.isLoaded) {
					this.loadingTimeout = setTimeout(function(){
						Effect.Appear($('planned-work-cal-overlay'),{duration:0.3, to:0.5});
						Effect.Appear($('planned-work-cal-overlay-content'),{duration:0.3});
					},this.loadingWait);
				} 
			}.bind(this),
			onSuccess: function(response) {
				clearTimeout(this.loadingTimeout);
				this.isLoaded = true;
				Effect.Fade($('planned-work-cal-overlay'),{duration:0.3});
				Effect.Fade($('planned-work-cal-overlay-content'),{duration:0.3});
				var data = eval('(' + response.responseText + ')');
				this.items = data.items;
				this.groupItemsByDay();
				this.renderCalendar();
			}.bind(this)
		});
	},
	
	renderCalendar: function() {
		var rows = this.groupedItems.collect(function(day,i){
			var date = new Date(this.start.valueOf() + (i*1000*60*60*24));
			var today = (date.toDDMMYY() == new Date().toDDMMYY()) ? ' today' : '';
			var weekend = (date.getDay() == 0 || date.getDay() == 6) ? ' weekend ' : '';
			var even = (date.getDay()%2 == 0 & date.getDay() > 0) ? ' even ' : '';
			var cells = [Builder.node('td',{className:'date'+today+weekend+even},[
					Builder.node('span',{className:'day'+today},daysOfTheWeek[i]),
					Builder.node('span',{className:'date-inner'},date.getDate() + ' ' + monthsOfTheYear[date.getMonth()])
			])];
			if (this.eventItemOffset > 0) {
				// If more has been clicked...
				if (day[this.eventItemOffset] != undefined) {
					// If this row has some items...
					cells.push(Builder.node('td',{className:'less' + today},[
							Builder.node('div',{title: 'Previous', className:'less', onclick:this.variable + '.renderLess()'})])
					);
				} else {
					cells.push(Builder.node('td',{className:'less' + today},''));
				}
			}
			$R(this.eventItemOffset,this.eventItemOffset + this.itemsPerRow-1).each(function(j){
				if (day[j] != undefined) {
					var dayStart = new Date(day[j].start);
					var dayEnd = new Date(day[j].end);
					if (dayStart.getDay() == dayEnd.getDay() && dayStart.valueOf() != dayEnd.valueOf())
						// Starts and finishes on the same day and isn't all day
						cells.push(Builder.node('td',{className:'event custom-width ' + today + ' ' + day[j].categories.join(' ')},[
							Builder.node('span',{className:'time'},dayStart.toNiceTimeString() + ' - ' + dayEnd.toNiceTimeString()),
							Builder.node('a',{href:day[j].url.href, title:day[j].summary.unescapeHTML()},day[j].title)
						]));
					else if (dayStart.getDay() == (i+1) && dayStart.valueOf() != dayEnd.valueOf()
						|| i==6 && day[j].start.getDay() == 0 && day[j].start.valueOf() != day[j].end.valueOf())
						// Starts on this day but doesn't end and isn't all day
						cells.push(Builder.node('td',{className:'event custom-width ' + today + ' ' + day[j].categories.join(' ')},[
							Builder.node('span',{className:'time'},day[j].start.toNiceTimeString() + ' onwards'),
							Builder.node('a',{href:day[j].url.href, title:day[j].summary.unescapeHTML()},day[j].title)
						]));
					else if (dayEnd.getDay() == (i+1)  && dayStart.valueOf() != dayEnd.valueOf()
						|| i==6 && dayEnd.getDay() == 0 && dayStart.valueOf() != dayEnd.valueOf())
						// Ends on this day but doesn't start and isn't all day
						cells.push(Builder.node('td',{className:'event custom-width ' + today + ' ' + day[j].categories.join(' ')},[
							Builder.node('span',{className:'time'},'Until ' + day[j].end.toNiceTimeString()),
							Builder.node('a',{href:day[j].url.href, title:day[j].summary.unescapeHTML()},day[j].title)
						]));
					else
						// Doesn't start or end on this day or is all day
						cells.push(Builder.node('td',{className:'event custom-width ' + today + ' ' + day[j].categories.join(' ')},[
							Builder.node('span',{className:'time'},'All day'),
							Builder.node('a',{href:day[j].url.href, title:day[j].summary.unescapeHTML()},day[j].title)
						]));
						
				}
				else
					cells.push(Builder.node('td',{className:'custom-width ' + today},''));
				cells.push(Builder.node('td',{className:'spacer' + today},''));
			}.bind(this));
			if (day.length > (this.eventItemOffset+1)*this.itemsPerRow)
				cells.push(Builder.node('td',{className:'more' + today},[
					Builder.node('div',{className:'more', title: 'Next', onclick:this.variable + '.renderMore()'})
				]));
			else
				cells.push(Builder.node('td',{className:'more' + today},''));
			return Builder.node('tr',{},cells);
		}.bind(this));
		$(this.container).innerHTML = "";
		rows = [Builder.node('tr',{},[
					Builder.node('td',{className:'header',colSpan:rows[0].childNodes.length},[
						Builder.node('div',{className: 'left'},''),
						Builder.node('div',{className: 'right'},''),
						Builder.node('div',{className: 'click', onclick:this.variable +'.renderLastWeek()'},'')
					])
				])
			].concat(rows);
		rows = rows.concat([Builder.node('tr',{},[
				Builder.node('td',{className:'footer',colSpan:rows[1].childNodes.length},[
					Builder.node('div',{className: 'left'},''),
					Builder.node('div',{className: 'right'},''),
					Builder.node('div',{className: 'click', onclick:this.variable +'.renderNextWeek()'},'')
				])
			])
		]);

		$(this.container).appendChild(Builder.node('table',{},[Builder.node('tbody',{},rows)]));
		var width = Math.floor(($(currentPane+'-pane').getWidth() - 46 - 36 - (6*this.itemsPerRow))/3);
		$$('td.custom-width').each(function(n){n.style.width = width + 'px';});
	},
	
	renderMore: function() {
		this.eventItemOffset = this.eventItemOffset + this.itemsPerRow;
		this.renderCalendar();
	},
	
	renderLess: function() {
		this.eventItemOffset = this.eventItemOffset - this.itemsPerRow;
		this.renderCalendar();
	},
	
	renderLastWeek: function() {
		this.start = this.start.lastWeek();
		this.load();
	},
	
	renderNextWeek: function() {
		this.start = this.start.nextWeek();
		this.load();
	}
};

var setActiveButton = function(newPane) {
	// Set link box hover and remove hover from others
	var listItem = $(newPane + '-pane-link');
	listItem.siblings().each(function(sibling){
		var div = sibling.immediateDescendants()[0];
		div.removeClassName('hover');
		div.getElementsBySelector('div').each(function(n){$(n).removeClassName('hover');});
	});
	var div = listItem.immediateDescendants()[0];
	div.addClassName('hover');
	div.getElementsBySelector('div').each(function(n){$(n).addClassName('hover');});
};

var catchNoPanelsVisible = function() {
	if ((!Effect.Queues.get('fades').length && !Effect.Queues.get('appears').length) || (
		Effect.Queues.get('fades').length == 0 && Effect.Queues.get('appears').length == 0)) {
		if (!$(currentPane+'-pane').visible()) {
			$(currentPane+'-pane').style.display = 'block';
		}
	}
};

var clearPaneChange = function() {
	if (switchTimout) clearTimeout(switchTimout);
	setActiveButton(currentPane);
};

var setActivePane = function(newPane, onload) {
	
	setActiveButton(newPane);

	// Set pane to visible
	if (onload) {
		$(newPane+'-pane').style.display = 'block';
		currentPane = newPane;
	} else {
		if (switchTimout) clearTimeout(switchTimout);
		if (newPane == currentPane) return true;
		
		switchTimout = setTimeout(function(){
			Effect.Fade($(currentPane+'-pane'), { duration: 0.6, queue: { position:'end', scope:'fades' }, afterFinish: catchNoPanelsVisible });
			currentPane = newPane;
			var cookie = new WCookie('itshomepage-load-pane',newPane,0.5);
			Effect.Appear($(newPane+'-pane'), { duration: 0.6, queue: { position:'end', scope:'appears' }, afterFinish: catchNoPanelsVisible });
		},SWITCH_TIMEOUT_TIME);
	}
};

var setActiveServicePane = function(pane, nocookie) {
	serviceActivePane = pane;

	if (!nocookie)
		var cookie = new WCookie('itshomepage-load-service-pane',serviceActivePane,0.5);
	
	$(serviceActivePane+'-pane').style.display = 'block';
	$(serviceActivePane+'-pane').style.visibility = 'visible';
	$(serviceActivePane+'-heading').removeClassName('hover');
	$('service-tab-pane').className = 'service-tab-' + serviceActivePane;
	SERVICE_PANES.each(function(p){
		if (p != serviceActivePane) {
			$(p+'-pane').style.display = 'none';
		}		
	});
	if (serviceActivePane != 'incidents') {
		if (miniCal.isLoaded) miniCal.renderCalendar();
		var amberCount = $('statustable').getElementsBySelector('td.amber').length;
		var redCount = $('statustable').getElementsBySelector('td.red').length;
		if (redCount > 0)
			$('incidents-heading').className = 'red';
		else if (amberCount > 0)
			$('incidents-heading').className = 'amber';
		else
			$('incidents-heading').className = 'green';
	} else
		$('incidents-heading').className = '';
};

var loadDidYouKnow = function(container, url) {
	var loaded = false;
	new Ajax.Request('/sitebuilder2/api/rss/news.rss?page=' + url + '&rss=true&type=json&num=1',{
		onLoading: function() { if(!loaded) $(container).innerHTML = '<img src="/static_war/images/tab-spinner.gif" alt="Loading" /> Loading...'; },
		onFailure: function() { $(container).innerHTML = 'There was a problem retrieving the news feed!'; },
		onSuccess: function(response) {
			var data = eval('(' + response.responseText + ')');
			loaded = true;
			$(container).update().appendChild(Builder.node('a',{href:data.items[0].url.href},data.items[0].title));
			var div = Builder.node('div',{className:'inner'});
			div.innerHTML = data.items[0].content
			$(container).appendChild(div);
		}
	});
};

Event.onDOMReady(function(){
	miniCal = new MiniCalendar({
		url: PLANNED_WORK_URL,
		container: 'planned-work-cal-container',
		variable: 'miniCal'
	});
	
	loadDidYouKnow('didyouknow-homepage',DID_YOU_KNOW_URL);
	
	var amberCount = $('statustable').getElementsBySelector('td.amber').length;
	var redCount = $('statustable').getElementsBySelector('td.red').length;
	
	miniCal.load();
	
	PANES.each(function(pane){
		var linkDiv = $(pane + '-pane-link');
		var link = linkDiv.getElementsBySelector('a')[0];
		var linkParent = link.parentNode;
		linkParent.removeChild(link);
		linkParent.innerHTML = linkParent.innerHTML + link.innerHTML;
		
		if (pane == 'service' && (redCount > 0 || amberCount > 0)) {
			link.href = '/services/its/newschanges/incidents/';
			link.title = 'Incidents';
		}
		
		linkDiv.title = link.title;
		
		$(pane+'-pane').style.display = 'none';
		Event.observe(linkDiv, 'mouseover', function(){ setActivePane(pane); });
		Event.observe(linkDiv, 'mouseout', function(){ clearPaneChange(); });
		Event.observe(linkDiv, 'click', function(){ window.location = link.getAttribute('href'); });
	});
	
	SERVICE_PANES.each(function(pane) {
		$(pane+'-pane').style.display = 'none';
		$(pane+'-pane').style.visibility = 'hidden'; // I don't know why this is necessary in IE6 but it is. ARGH!
		var heading = $(pane+'-heading');
		Event.observe(heading,'mouseover',function(){
			if (heading.id.indexOf(serviceActivePane) == -1) heading.addClassName('hover');
		});
		Event.observe(heading,'mouseout',function(){heading.removeClassName('hover');});
		Event.observe(heading,'click',function(){ if (heading.id.indexOf(serviceActivePane) == -1) setActiveServicePane(pane); });
		
	});
	
	$$('#news-pane a.url').each(function(link){link.innerHTML = link.innerHTML.strip() + '&hellip;'});
	
	if (redCount > 0 || amberCount > 0) {
		serviceActivePane = 'incidents';
		LOAD_PANE = 'service';
	}
	else
		serviceActivePane = 'planned-work';
	
	var savedPane = new WCookie('itshomepage-load-pane').value;
	if (savedPane) {
		LOAD_PANE = savedPane;
	}
	var savedServicePane = new WCookie('itshomepage-load-service-pane').value;
	if (savedServicePane) {
		serviceActivePane = savedServicePane;
	}
	
	if (window.location.toString().indexOf('load_status') != -1 ) {
		LOAD_PANE = 'service';
		serviceActivePane = 'incidents';
		setActiveServicePane(serviceActivePane, true);
		$(serviceActivePane+'-pane').style.display = 'block';
		$(serviceActivePane+'-pane').style.visibility = 'visible';
	
		setActivePane(LOAD_PANE, true);
	}
	else {
		setActiveServicePane(serviceActivePane);
		$(serviceActivePane+'-pane').style.display = 'block';
		$(serviceActivePane+'-pane').style.visibility = 'visible';
	
		setActivePane(LOAD_PANE, true);
	}
	
	if(is_ie) {
		document.execCommand("BackgroundImageCache", false, true);
	}

	/* Add "Add to Start" button to the bottom of the service status - Mat Mannion 15/06/10 */
	if (AddToStartButton) { // Defensively code against somebody removing the JS file linked from Start.Warwick
		$('incidents-pane').insert(new Element('p').update(new AddToStartButton().getElement('http://go.warwick.ac.uk/its', 'the ITS Service Status')));
	}
});

