var Papercut = {
	version:'0.1.5'
};

Papercut.Base = Class.create({
	initialize: function(options) {
		this.setOptions(options);
	}
	,setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	}
});

//Date Prototypes
var dayName = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
var monthName = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');

Date.prototype.getMonthName = function() {
	return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][this.getMonth()];
}
Date.prototype.getDayName = function() {
	return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][this.getDay()];
}

Date.prototype.dayDifference = function(otherDate) {
	return Math.round((this.getTime() - otherDate.getTime()) / 1000 / 60 / 60 / 24);
}

Date.prototype.firstSunday = function() {
	var d = new Date();
	d.setTime(this.getTime()); 
	d.setFullYear(d.getFullYear(), d.getMonth(), 1);
	d.setFullYear(d.getFullYear(), d.getMonth(), 1 - d.getDay());
	return d;
}
Date.prototype.lastSaturday = function() {
	var d = new Date();
	d.setTime(this.getTime());
	d.setFullYear(d.getFullYear(), d.getMonth()+1, 0);
	d.setFullYear(d.getFullYear(), d.getMonth(), d.getDate() + 6 - d.getDay());
	return d;
}
Date.prototype.nextDay = function() {
	var d = new Date();
	d.setTime(this.getTime());
	d.setFullYear(d.getFullYear(), d.getMonth(), d.getDate() + 1);
	return d;
}
Date.prototype.getAmpm = function() {
	if (this.getHours() >= 12) {
		return 'pm';
	}
	else {
		return 'am';
	}
}
Date.prototype.getHours12 = function() {
	if (this.getHours() == 0) {
		return 12;
	}
	else if(this.getHours() > 12) {
		return this.getHours() - 12;
	}
	else {
		return this.getHours();
	}
}
Date.prototype.getFullSeconds = function() {
	if (this.getSeconds() < 10) {
		return '0' + this.getSeconds().toString();
	}
	else {
		return this.getSeconds();
	}
}
Date.prototype.getMinutes2 = function() {
	if (this.getMinutes() < 10) {
		return '0' + this.getMinutes().toString();
	}
	else {
		return this.getMinutes();
	}
}


Papercut.TimeSelector = Class.create({
	version: 0.1,
	container:false,
	textField:false,
	isHovering:false,
	currentTime:false,
	times:['12:00am','12:15am', '12:30am', '12:45am', '1:00am','1:15am', '1:30am', '1:45am', '2:00am','2:15am', '2:30am', '2:45am', '3:00am','3:15am', '3:30am', '3:45am', '4:00am','4:15am', '4:30am', '4:45am', '5:00am','5:15am', '5:30am', '5:45am', '6:00am','6:15am', '6:30am', '6:45am', '7:00am','7:15am', '7:30am', '7:45am', '8:00am','8:15am', '8:30am', '8:45am', '9:00am','9:15am', '9:30am', '9:45am', '10:00am','10:15am', '10:30am', '10:45am', '11:00am','11:15am', '11:30am', '11:45am', '12:00pm','12:15pm', '12:30pm', '12:45pm', '1:00pm','1:15pm', '1:30pm', '1:45pm', '2:00pm','2:15pm', '2:30pm', '2:45pm', '3:00pm','3:15pm', '3:30pm', '3:45pm', '4:00pm','4:15pm', '4:30pm', '4:45pm', '5:00pm','5:15pm', '5:30pm', '5:45pm', '6:00pm','6:15pm', '6:30pm', '6:45pm', '7:00pm','7:15pm', '7:30pm', '7:45pm', '8:00pm','8:15pm', '8:30pm', '8:45pm', '9:00pm','9:15pm', '9:30pm', '9:45pm', '10:00pm','10:15pm', '10:30pm', '10:45pm', '11:00pm','11:15pm', '11:30pm', '11:45pm'],
	slider:false,
	
	initialize: function(id, options) {
		this.setOptions();
		this.textField = $(id);
		this.createContainer();
		var d = new Date();
		var time = d.getHours12() + ':' + d.getMinutes2() + d.getAmpm(); 
		this.currentTime = time;
		
		this.textField.observe('focus', function() {
			this.show();
		}.bindAsEventListener(this));
		
		this.textField.observe('blur', function() {
			this.hide();
		}.bindAsEventListener(this));
		
		this.container.observe('mouseover', function() {
			this.isHovering = true;
		}.bindAsEventListener(this));
		
		this.container.observe('mouseout', function() {
			this.isHovering = false;
		}.bindAsEventListener(this));
		
		Event.observe(window, 'mousedown', function() {
			this.hide();
		}.bindAsEventListener(this));
	},
	createContainer:function() {
		var div = document.createElement('div');
		$(document.body).insert(div);
		this.container = $(div);
		this.container.innerHTML = 'time!';
		this.container.hide();
		this.container.addClassName('timeSelector');
		this.container.innerHTML = '<div id="timeTrack'+this.textField.id+'" class="timeTrack"><div id="timeHandle'+this.textField.id+'" class="timeHandle"></div></div>';
	},
	show: function() {
		if (this.container) {
			var p = this.textField.cumulativeOffset();
			if (p.top + this.textField.offsetHeight + this.container.offsetHeight > document.viewport.getHeight()) {
				
			}
			
			this.container.setStyle({
				left:(p.left + 1) + 'px',
				top:(p.top + this.textField.offsetHeight + 1) + 'px'
			});
			
			this.container.show();
			
			if (!this.slider) {
				this.slider = new Control.Slider('timeHandle'+this.textField.id, 'timeTrack'+this.textField.id, {
					range:$R(0,this.times.length-1),
					onSlide: function(v){
						this.toTime(v);
					}.bind(this),
					onChange: function(v){
						//this.toTime(v);
					}.bind(this)
				});
			}
			this.setTime();
		}
	},
	
	toTime:function(value) {
		var percent = parseFloat(value).toFixed(0);
		this.textField.value = this.times[percent];
	},
	
	setTime:function() {
		var minutes = this.calculateMinutes(this.textField.value);
		var index = (minutes/1440*this.times.length); // 1440 = minutes in a day
		this.slider.setValue(index);
	},
	hide: function(override) {
		if (override == null) {
			override = false;
		}
		if (override || (this.container && !this.isHovering)) {
			this.container.hide();
		}
	},
	
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	},
	calculateMinutes: function(str) {
		var minutes = 0;
		var pieces = this.parseTime(str);
		minutes += pieces.minutes;
		if ((pieces.ampm == 'am' && pieces.hours < 12) || (pieces.ampm == 'pm' && pieces.hours == 12)) {
			// 1am-12pm
			minutes += pieces.hours*60;
		}
		else if (pieces.ampm == 'pm' && pieces.hours < 12) {
			// 1pm-11pm
			minutes += (pieces.hours+12) * 60;
		}
		return minutes;
	},
	parseTime: function(str) {
		if (this.textField.value.match(/\d\d?:\d\d[ap]m/)) {
			var pieces = this.textField.value.split(':');
			return {
				hours:parseInt(pieces[0]),
				minutes:parseInt(pieces[1].substr(0,2)),
				ampm:pieces[1].substr(2)
			};
		}
		return {};
	}
});

Papercut.DateSelector = Class.create({
	version: 0.1,
	container:false,
	textField:false,
	isHovering:false,
	currentDate:false,
	textboxDates:false,
	
	//Events
	onDateChange: function(){},
	
	initialize: function(id, options) {
		this.setOptions();
		this.textField = $(id);
		this.createContainer();
		this.textboxDates = new Array();
		this.currentDate = new Date();
		
		this.textField.observe('focus', function() {
			this.showCalendar();
		}.bindAsEventListener(this));
		
		this.textField.observe('blur', function() {
			this.hideCalendar();
		}.bindAsEventListener(this));
		
		this.container.observe('mouseover', function() {
			this.isHovering = true;
		}.bindAsEventListener(this));
		
		this.container.observe('mouseout', function() {
			this.isHovering = false;
		}.bindAsEventListener(this));
		
		Event.observe(window, 'mousedown', function() {
			this.hideCalendar();
		}.bindAsEventListener(this));
		
		if (this.textField.value.length) {
			this.setDate();
		}
	},
	
	createContainer:function() {
		var div = document.createElement('div');
		document.body.appendChild(div);
		this.container = $(div);
		this.container.hide();
		
		this.container.addClassName('dateSelector');
		
		var str = '';
		str += '<table cellpadding="0" cellspacing="0" width="140" class="calendarSmall">';
		str += '<tr><td>';
		str += '<table width="100%"><tr>';
		str += '<td width="10%" class="smallArrow leftArrow">&lt;&lt;</td>';
		str += '<td width="80%" class="monthName" align="center"></td>';
		str += '<td width="10%" class="smallArrow rightArrow">&gt;&gt;</td>';
		str += '</tr></table></td></tr>';
		str += '<tr><td><table width="100%" class="calendarDayNames">';
		str += '<tr><td width="20">S</td><td width="20">M</td><td width="20">T</td><td width="20">W</td><td width="20">T</td><td width="20">F</td><td width="20">S</td></tr></table></td></tr>';
		str += '<tr><td><div class="calendarDates">';
		str +='</div></td></tr></table>';
		this.container.innerHTML = str;
		
		this.previousArrows = this.container.select('.leftArrow')[0];
		this.monthName = this.container.select('.monthName')[0];
		this.nextArrows = this.container.select('.rightArrow')[0];
		this.calendarDates = this.container.select('.calendarDates')[0];
		
		this.previousArrows.observe('click', function() {
			this.currentDate.setFullYear(this.currentDate.getFullYear(), this.currentDate.getMonth()-1, 1);
			this.draw();
		}.bindAsEventListener(this));
		
		this.nextArrows.observe('click', function() {
			this.currentDate.setFullYear(this.currentDate.getFullYear(), this.currentDate.getMonth()+1, 1);
			this.draw();
		}.bindAsEventListener(this));
		
		
	},
	
	draw:function() {
		var str = '<table>';
		this.monthName.innerHTML = this.currentDate.getMonthName() + ' ' + this.currentDate.getFullYear();
		var firstSunday = this.currentDate.firstSunday();
		var lastSaturday = this.currentDate.lastSaturday();
		for (var i = firstSunday; i.getTime() < lastSaturday.getTime(); i = i.nextDay()) {
			if (i.getDay() == 0) {
				str += '<tr>';
			}
			str += '<td><a id="' + this.textField.id + '-date-' + (i.getMonth() + 1) + '/' + i.getDate() + '/' + i.getFullYear().toString().substr(2) + '" class="smallDate">' + i.getDate() + '</a></td>';
		}
		str += '</table>';
		this.calendarDates.innerHTML = str;
		this.calendarDates.select('.smallDate').each(function(e) {
			e.onclick = function(e) {
				var newValue = e.id.split(this.textField.id+ '-date-')[1];
				this.textField.value = newValue;
				e.addClassName('active');
				this.hideCalendar(true);
				this.onDateChange();
			}.bind(this, e);
		}.bind(this));
		
		this.getDates();
		this.highlightDates();
	},
	
	getDates:function() {
		this.textboxDates = new Array();
		if (this.textField) {
			var dates = this.textField.value.split(',');
			for (var i = 0; i < dates.length; i++) {
				if (dates[i].match(/(\d{1,2}\/){2}\d{2,4}/)) {
					this.textboxDates.push(dates[i]);
				}
			}
		}
	},
	highlightDates:function() {
		for (var i = 0; i < this.textboxDates.length; i++) {
			if ($(this.textField.id + '-date-' + this.textboxDates[i]) != null) {
				$(this.textField.id + '-date-' + this.textboxDates[i]).addClassName('active');
			}
		}
	},
	showCalendar: function() {
		if (this.container) {
			this.setDate();
			this.draw();
			var p = this.textField.cumulativeOffset();
			if (p.top + this.textField.offsetHeight + this.container.offsetHeight > document.viewport.getHeight()) {
				
			}
			
			this.container.setStyle({
				left:(p.left + 1) + 'px',
				top:(p.top + this.textField.offsetHeight + 1) + 'px'
			});
			
			this.container.show();
		}
	},
	setDate:function() {
		if (this.textField.value.match(/(\d{1,2}\/){2}\d{2,4}/)) {
			var parts = this.textField.value.split('/');
			this.currentDate.setFullYear('20'+parts[2], parts[0]-1, parts[1]);
		}
	},
	hideCalendar: function(override) {
		if (override == null) {
			override = false;
		}
		if (override || (this.container && !this.isHovering)) {
			this.container.hide();
		}
	},
	
	createDateFromValue: function(){
		var val = this.textField.value;
        var splits = val.split('/');
        
        if(splits.length == 3){
            //Parse the date data
            var month = parseInt(splits[0]);
            var day = parseInt(splits[1]);
            var year = parseInt(splits[2], 10) + 2000;

            //Create the new arrival date
			var d = new Date();
			d.setFullYear(year, month-1, day);
			return d;
        }
        return false;
	},
	
	setTextFieldValue: function() {
		this.textField.value = (this.currentDate.getMonth() + 1) + '/' + this.currentDate.getDate() + '/' + this.currentDate.getFullYear().toString().substr(2);
	},
	
	createFormattedDate: function(d){
		return (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear().toString().substr(2);
	},
	
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	}
});

Papercut.AjaxContent = Class.create({
	version: 0.1,
	
	initialize: function(url, pars, id) {
		if (typeof pars != 'string') {
			pars = Object.toQueryString(pars);
		}
		new Ajax.Request(url, {
			method: 'post',
			postBody: pars,
			onComplete: function(transport) {
				$(id).innerHTML = transport.responseText;
			}.bind(this)
		});
	}
});

Papercut.Ajax = Class.create({
	version: 0.1,
	url: false,
	response: false,
	onComplete: false,
	
	initialize: function(url, pars) {
		//this.setOptions(options);
		pars = Object.toQueryString(pars);
		new Ajax.Request(url, {
			method: 'post',
			postBody: pars,
			onComplete: function(transport) {
				this.response = transport.responseJSON;
				if (this.onComplete) {
					this.onComplete(this.reponse);
				}
			}.bind(this)
		});
	}
});


Papercut.FormSubmit = Class.create({
	version: 0.1,
	redirect: false,
	callback: false,
	waitTime: false,
	redirectWait: 0,
	
	initialize: function(formId, options) {
		this.setOptions(options);
		
		this.form = $(formId);
		this.messageDiv = this.form.select('.message')[0];
		this.url = this.form.action;
		
		this.messageDiv.innerHTML = 'Submitting...';
		
		if (this.waitTime) {
			setTimeout(function() {
				this.sendRequest();
			}.bind(this), 0);
		}
		else {
			this.sendRequest();
		}
		
		this.unlockTimeout = setTimeout(function() {
			this.messageDiv.innerHTML = 'There was a problem submitting your form. Please try re-submitting';
			Form.enable(this.form);
		}.bind(this), 10000);
	},
	
	onBeforeSend: function(){},
	
	sendRequest: function() {
		this.onBeforeSend();
		this.pars = Form.serialize(this.form);
		Form.disable(this.form);
		myAjax = new Ajax.Request(this.url, {
			method: 'post',
			postBody: this.pars,
			onLoading: function() { },
			onComplete: function(transport) {
				var status = transport.responseJSON;
				if (status.good) {
					this.messageDiv.innerHTML = status.messages;
					if (this.callback) {
						this.callback(status);
					}
					else if (this.redirect) {
						location.href = status.redirect;
					}
					else if (status.redirect) {
						if(this.redirectWait){
							setTimeout(function(){
								location.href = status.redirect;
							}.bind(this), this.redirectWait*1000).bind(this);
						}
						else{
							location.href = status.redirect;
						}
					}
				}
				else {
					this.messageDiv.innerHTML = status.errors;
				}
				Form.enable(this.form);
				clearTimeout(this.unlockTimeout);
			}.bind(this)
		});
	},
	
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	}
});

Papercut.TabContainer = Class.create({
	version: 0.1,
	tabs:[],
	tabMap:{},
	items:[],
	activeTab:null,
	className:'papercutTabs',
	containerSize:'auto',
	containerHeight:false,
	
	initialize: function(containerId, options) {
		this.container = $(containerId);
		this.setOptions(options);
		this.container.addClassName('tabContainer');
		this.container.innerHTML = '<div class="papercutTabSection"><ul class="'+this.className+'"></ul></div><div class="papercutTabContentSection"></div>';
		this.tabSection = this.container.childNodes[0];
		this.tabContentSection = this.container.childNodes[1];
		this.tabList = this.tabSection.childNodes[0];
		if (this.containerHeight) {
			
			// set height or min-height and scroll setting
			if (this.containerSize == 'auto') {
				// treat the height as min-height
				this.tabContentSection.style.minHeight = this.containerHeight;
			}
			else if (this.containerSize == 'fixed') {
				this.tabContentSection.style.height = this.containerHeight;
				this.tabContentSection.style.overflow = 'auto';
			}
		}
		this.addInitialItems();
		this.showTab(0);
	},
	
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	},
	
	addInitialItems: function() {
		for (var i = 0; i < this.items.length; i++) {
			this.addTab(this.items[i]);
		}
	},
	
	getTab:function(tab) {
		var tabObject;
		if (typeof tab == 'string') {
			tabObject = this.tabMap[tab];
		}
		else if (typeof tab == 'number') {
			tabObject = this.tabs[tab]; 
		}
		else if (typeof tab == 'object') {
			
		}
		return tabObject;
	},
	
	addTab: function(tabObject) {
		if (tabObject.length && typeof tabObject != 'string') {
			for (var i = 0; i < tabObject.length; i++) {
				this.addTab(tabObject[i]);
			}
			return;
		}
		if (typeof tabObject == 'string' || tabObject.innerHTML != null) {
			tabObject = $(tabObject);
			tabObject = {
				title:tabObject.title,
				contentEl:tabObject
			};
		}
		else if (tabObject.html != null) {
			tabObject.contentEl = document.createElement('div');
			tabObject.contentEl.innerHTML = tabObject.html;
		}
		else if (typeof tabObject.contentEl == 'string') {
			tabObject.contentEl = $(tabObject.contentEl);
		}
		
		if (this.getTab(tabObject.title) != null) {
			this.getTab(tabObject.title).contentEl.appendChild(tabObject.contentEl);
		}
		else {
			tabObject.contentEl.style.display = 'none';
			this.tabContentSection.appendChild(tabObject.contentEl);
			if (tabObject.enabled == null) {
				tabObject.enabled = true;
			}
			if (tabObject.title != null) {
				newTab = document.createElement('li');
				newTab.innerHTML = tabObject.title;
				this.tabList.appendChild(newTab);
				tabObject.index = this.tabs.length;
				tabObject.tab = $(newTab);
				this.tabs.push(tabObject);
				this.tabMap[tabObject.title] = tabObject;
				
				// set event handlers
				if (!tabObject.enabled) {
					$(tabObject.tab).addClassName('disabled');
				}
				
				tabObject.tab.observe('mouseover', function(tab) {
					tab.addClassName('hover');
				}.bind(this, tabObject.tab));
				
				tabObject.tab.observe('mouseout', function(tab) {
					tab.removeClassName('hover');
				}.bind(this, tabObject.tab));
				
				tabObject.tab.observe('click', function(tabObject) {
					this.showTab(tabObject.index);
				}.bind(this, tabObject));
			}
		}
	},
	
	showTab: function(tab) {
		var tabObject = this.getTab(tab);
		if (tabObject != null && tabObject.enabled) {
			if (this.activeTab != null) {
				this.tabs[this.activeTab].tab.removeClassName('active');
				this.tabs[this.activeTab].contentEl.hide();
			}
			
			tabObject.tab.addClassName('active');
			this.activeTab = tabObject.index;
			tabObject.contentEl.show();			
		}
	},
	
	enable:function(tabObject) {
		if (typeof tabObject != 'object') {
			tabObject = this.getTab(tabObject);
		}
		tabObject.enabled = true;
		tabObject.tab.removeClassName('disabled');
	},
	
	disable:function(tabObject) {
		if (typeof tabObject != 'object') {
			tabObject = this.getTab(tabObject);
		}
		tabObject.enabled = false;
		tabObject.tab.addClassName('disabled');
	},
	
	enableAll: function() {
		for (var i = 0; i < this.tabs.length; i++) {
			this.enable(this.tabs[i]);
		}
	},
	
	disableAll: function() {
		for (var i = 0; i < this.tabs.length; i++) {
			this.disable(this.tabs[i]);
		}
	}
});

Papercut.Scroller = Class.create({
	version: 0.1,
	scrollSpeed: .05,
	scrollDistance: 1,
	width:0,
	height:0,
	scrollTimer:null,
	direction:'down',
	overControls:false,
	overScroller:false,
	defaultDirection:'down',
	
	initialize: function(containerId, options) {
		this.container = $(containerId);
		this.setOptions(options);
		this.container.style.overflow = 'hidden';
		this.container.style.position = 'relative';
		
		if (this.width) {
			this.container.style.width = this.width;
		}
		if (this.height) {
			this.container.style.height = this.height;
		}
		
		this.container.observe('mouseover', function() {
			this.overScroller = true;
		}.bindAsEventListener(this));
		this.container.observe('mouseout', function() {
			this.overScroller = false;
		}.bindAsEventListener(this));
		
		this.container.innerHTML = '<div>'+this.container.innerHTML+'</div><div class="topControl"></div><div class="bottomControl"></div>';
		this.scrollingContent = $(this.container.childNodes[0]);
		this.scrollingContentHeight = this.scrollingContent.offsetHeight * -1;
		this.scrollingContent.setStyle({
			position:'absolute',
			top:'0'
		});
		
		// set listeners on controllers
		this.topControl = this.container.select('.topControl')[0];
		this.bottomControl = this.container.select('.bottomControl')[0];
		this.topControl.setStyle({
			position:'absolute',
			width:'100%',
			height:'20px',
			top:0
		});
		this.topControl.observe('mouseover', function() {
			this.direction = 'up';
			this.overControls = true;
		}.bindAsEventListener(this));
		this.bottomControl.setStyle({
			position:'absolute',
			width:'100%',
			height:'20px',
			top:this.container.offsetHeight - 20 + 'px'
		});
		this.bottomControl.observe('mouseover', function() {
			this.direction = 'down';
			this.overControls = true;
		}.bindAsEventListener(this));
		this.bottomControl.observe('mouseout', function() {
			this.direction = this.defaultDirection;
			this.overControls = false;
		}.bindAsEventListener(this));
		this.topControl.observe('mouseout', function() {
			this.direction = this.defaultDirection;
			this.overControls = false;
		}.bindAsEventListener(this));
		
		this.unpause();
	},
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	},
	
	scroll: function() {
		switch (this.direction) {
			case 'down':
				newTop = parseInt(this.scrollingContent.style.top) - this.scrollDistance;
				if (this.overControls) {
					newTop = parseInt(this.scrollingContent.style.top) - (this.scrollDistance * 3);
				}
				if (!this.overScroller || this.overControls) {
					if (newTop > this.scrollingContentHeight) {
						this.scrollingContent.style.top = newTop + 'px';
					}
					else {
						this.scrollingContent.style.top = this.container.offsetHeight + 'px';
					}
				}
			break;
			case 'up':
				newTop = parseInt(this.scrollingContent.style.top) + this.scrollDistance;
				if (this.overControls) {
					newTop = parseInt(this.scrollingContent.style.top) + (this.scrollDistance * 3);
				}
				if (!this.overScroller || this.overControls) {
					if (newTop < this.scrollingContent.offsetHeight) {
						this.scrollingContent.style.top = newTop + 'px';
					}
					else {
						this.scrollingContent.style.top = 0 - this.scrollingContent.offsetHeight + 'px';
					}
				}
			break;
		}
	},
	
	unpause: function() {
		this.pause();
		this.scrollTimer = new PeriodicalExecuter(this.scroll.bind(this), this.scrollSpeed);
	},
	
	pause: function() {
		if (this.scrollTimer != null) {
			this.scrollTimer.stop();
			delete this.scrollTimer;
		}
	}
});

Papercut.SlideShows = new Array();

Papercut.SlideShow = Class.create({
	version: 0.11,
	fadeTime: 1,
	waitTime: 5,
	directory: './',
	items: [],
	totalItems: 0,
	currentIndex:0,
	interval:null,
	paused:false,
	stopped:false,
	repeat:true,
	pauseOnMouse:true,
	changeOnClick:true,
	direction:'forward',
	
	inTransition:false,
		
	initialize: function(containerId, options) {
		this.container = $(containerId);
		this.container.addClassName('slideshowContainer');
		this.setOptions(options);
		if (this.height) {
			this.container.style.height = this.height;
		}
		if (this.width) {
			this.container.style.width = this.width;
		}
		
		this.container.style.position = 'relative';
		this.container.style.overflow = 'hidden';
		this.container.observe('mouseover', function() {
			if (this.pauseOnMouse) {
				this.pause();
			}
		}.bindAsEventListener(this));
		this.container.observe('mouseout', function() {
			this.resume();
		}.bindAsEventListener(this));
		
		this.container.observe('mousedown', function(e) {
			if (this.changeOnClick) {
				if (e.isLeftClick()) {
					this.next();
				}
				else {
					this.previous();
				}
			}
		}.bindAsEventListener(this));
		
		for (var i = 0; i < this.items.length; i++) {
			if (typeof this.items[i] == 'string') {
				if (this.isImage(this.items[i])) {
					this.container.innerHTML += '<img src="' + this.directory + this.items[i] + '" style="display:none;" />';
				}
				else {
					$(this.items[i]).hide();
					this.container.appendChild($(this.items[i]));
				}
			}
			else if (typeof this.items[i] == 'object') {
				if (this.isImage(this.items[i].item)) {
					str = '';
					if (this.items[i].url) {
						str += '<a href="'+this.items[i].url+'" style="display:none;">';
					}
					str += '<img title="'+this.items[i].title+'" alt="'+this.items[i].title+'" src="' + this.directory + this.items[i].item + '" border="0" />';
					if (this.items[i].url) {
						str += '</a>';
					}
					this.container.innerHTML += str;
				}
				else {
					$(this.items[i]).hide();
					this.container.appendChild($(this.items[i]));
				}
			}
		}
		
		this.totalItems = this.container.childNodes.length;
		for (var i = 0; i < this.totalItems; i++) {
			this.items[i] = $(this.container.childNodes[i]);
			// set ids if they don't exist
			if (!this.items[i].id) {
				this.items[i].id = this.container.id + '-' + i;
			}
			this.items[i].style.position = 'absolute';
			this.items[i].style.display = 'none';
			this.items[i].style.left = 0;
			this.items[i].style.top = 0;
			if (this.customSize) {
				if (this.customSize[0]) {
					this.items[i].style.width = this.customSize[0] + 'px';
				}
				if (this.customSize[1]) {
					this.items[i].style.height = this.customSize[1] + 'px';
				}
			}
		}
		
		if (this.totalItems) {
			this.items[0].show();
			if (this.container.getStyle('height') == '0px') {
				this.container.style.height = this.items[0].offsetHeight + 'px';
			}
			this.start();
		}
		Papercut.SlideShows.push(this);
	},
	
	pause: function() {
		this.paused = true;
	},
	resume: function() {
		this.paused = false;
	},
	
	start: function() {
		clearInterval(this.interval);
		if (this.totalItems > 1) {
			this.stopped = false;
			this.interval = setInterval(function() {
				if (!this.paused && !this.stopped) {
					if (this.direction == 'forward') {
						this.next();
					}
					else if (this.direction == 'random') {
						this.random();
					}
					else {
						this.previous();
					}
				}
			}.bind(this), (this.waitTime + this.fadeTime) * 1000);
		}
	},
	
	showSlide: function(num) {
		num = (parseInt(num) % this.totalItems);
		if (num == this.currentIndex) return;
		clearInterval(this.interval);
		if (!this.inTransition) {
			this.inTransition = true;
			new Effect.Fade(this.items[this.currentIndex].id, {
				duration: this.fadeTime,
				afterFinish: function() {
					this.currentIndex = num;
					this.inTransition = false;
					this.onChange();
					this.start();
				}.bind(this)
			});
			new Effect.Appear(this.items[num].id, {
				duration: this.fadeTime
			});
		}
		return num;
	},
	
	next: function() {
		if (!this.inTransition) {
			if (this.getNextIndex() || this.repeat) {
				this.inTransition = true;
				new Effect.Fade(this.items[this.currentIndex].id, {
					duration: this.fadeTime,
					afterFinish: function() {
						this.currentIndex = this.getNextIndex();
						this.inTransition = false;
						this.onChange();
					}.bind(this)
				});
				new Effect.Appear(this.items[this.getNextIndex()].id, {
					duration: this.fadeTime
				});
			}
			else {
				this.stop();
			}
		}
	},
	previous: function() {
		if (!this.inTransition) {
			this.inTransition = true;
			new Effect.Fade(this.items[this.currentIndex].id, {
				duration: this.fadeTime,
				afterFinish: function() {
					this.currentIndex = this.getPreviousIndex();
					this.inTransition = false;
					this.onChange();
				}.bind(this)
			});
			new Effect.Appear(this.items[this.getPreviousIndex()].id, {
				duration: this.fadeTime
			});
		}
	},
	random: function() {
		if (!this.inTransition) {
			this.inTransition = true;
			randomIndex = this.getRandomIndex();
			new Effect.Fade(this.items[this.currentIndex].id, {
				duration: this.fadeTime,
				afterFinish: function() {
					this.currentIndex = randomIndex;
					this.inTransition = false;
					this.onChange();
				}.bind(this)
			});
			new Effect.Appear(this.items[randomIndex].id, {
				duration: this.fadeTime
			});
		}
	},
	
	stop: function() {
		this.stopped = true;
	},
	
	getNextIndex: function() {
		return ((this.currentIndex+1) % this.totalItems);
	},
	getPreviousIndex: function() {
		return ((this.totalItems + this.currentIndex - 1) % this.totalItems);
	},
	getRandomIndex: function() {
		randomIndex = this.currentIndex;
		if (this.totalItems > 1) {
			while (randomIndex == this.currentIndex) {
				randomIndex = Math.floor(Math.random() * (this.totalItems));
			}
		}
		return randomIndex;
	},
	
	isImage: function(str) {
		return str.match(/\.\w{3,4}$/);
	},
	
	onChange: function() {
		
	},
	
	initControls: function() {
		str = '<ul id="bannerNav">';
		for (var i = 0; i < this.items.length; i++) {
			str += '<li><a href="javascript:;">'+(i+1)+'</a></li>';
		}
		str += '</ul>';
		this.controlContainer.innerHTML = str;
		this.controlContainer.select('a').each(function(el) {
			el.observe('click', function(el) {
				this.showSlide(parseInt(el.innerHTML)-1);
				this.controlContainer.select('.active')[0].removeClassName('active');
				el.addClassName('active');
				return false;
			}.bind(this, el));
		}.bind(this));
	},
	
	setCaption: function() {
		if (this.titles[this.currentIndex] == null) {
			this.titles[this.currentIndex] = '';
		}
		this.captionContainer.innerHTML = '<h2 id="bannerTitle">' + this.titles[this.currentIndex] + '</h2><div>'+this.captions[this.currentIndex]+'</div>';
		//FLIR.replace( 'h2#bannerTitle' , new FLIRStyle({ cFont:'magnesium' }) );
	},
	setActiveControl: function() {
		active = this.controlContainer.select('.active');
		if (active.length) {
			active.each(function(el) {el.removeClassName('active')});
		}
		this.controlContainer.select('a')[this.currentIndex].addClassName('active');
	},
	setOptions: function(options) {
		for (var i in options) {
			this[i] = options[i];
		}
	}
});

Papercut.Menu = Class.create();
Papercut.Menu.defaultOptions = {
	displayStyle:'popup',
	click:function() {return true; },
	styleClass:'default',
	hideTime:1000,
	direction:'down',
	subPosition:'right',
	subAlign:'top',
	divider:false,
	dividerHTML:'',
	reverseTop:false,
	numLevels:-1,
	onlyShowActiveBranch:false
};

Papercut.Menu.hideTimer = null;
Papercut.Menu.currentZ = 1;
Papercut.Menu.menus = [];

var thisPage = getThisPage(location.href);
function getComparePage(page) {
	page = page.toLowerCase();
	if (page.charAt(page.length-1) == '/') {
		page = page.substr(0, page.length-1);
	}
	return page;
}
function getThisPage(page) {
	page = page.toLowerCase();
	page = page.replace(/#.*/, '');
	if (page.charAt(page.length-1) == '/') {
		page = page.substr(0, page.length-1);
	}
	return page;
}

Papercut.Menu.prototype = {
	version: 0.2,
	initialize: function(menuId) {
		this.menu = $(menuId);
		this.options = Object.extend(Object.clone(Papercut.Menu.defaultOptions), arguments[1] || {});
		if (this.menu != null) {
			this.apply();
		}
		Papercut.Menu.menus.push(this);
	},
	apply: function() {
		// hide the menu
		this.menu.style.visibility = 'hidden';
		this.menu.style.display = '';
		
		
		// apply the style
		this.menu.addClassName(this.options.styleClass);
		/*if (!this.menu.getStyle('height')) {
			this.menu.style.height = this.menu.offsetHeight + 'px';
		}
		*/
		switch(this.options.displayStyle) {
			case 'popup':
				this.initPopups();
			break;
			case 'tree':
				this.initTree();
			break;
			default:
				
			break;
		}
		
		this.reverseTop();
		
		// set active page
		anchors = this.menu.getElementsByTagName('a');
		for (i = 0; i < anchors.length; i++) {
			if (getComparePage(anchors[i].href) == thisPage) {
				$(anchors[i]).addClassName('active');
				if (this.options.displayStyle == 'tree') {
					subContainers = anchors[i].parentNode.getElementsByTagName('div');
					if (subContainers.length) {
						Element.show(subContainers[0]);
					}
				}
				for (j = this.getLevel(anchors[i].parentNode), parentAnchor = anchors[i]; j > 0; j--) {
					parentAnchor = $(parentAnchor.parentNode.parentNode.parentNode.parentNode.getElementsByTagName('a')[0]);
					parentAnchor.addClassName('active');
					
					if (this.options.displayStyle == 'tree') {
						subContainers = parentAnchor.parentNode.getElementsByTagName('div');
						if (subContainers.length) {
							Element.show(subContainers[0]);
						}
					}
				}
			}
		}
		
		// set last class names
		this.menu.select('ul:last-child').each(function(el){ el.addClassName('last'); });
		
		this.initDividers();
		this.showActiveBranch();
		
		// show the menu
		this.menu.style.visibility = 'visible';
	},
	
	showActiveBranch: function() {
		if (this.options.onlyShowActiveBranch) {
			actives = this.menu.select('.active');
			if (actives.length) {
				actives[0].hide();
				$('sidebarTitle').innerHTML = actives[0].innerHTML;
				$(actives[0].parentNode).siblings().each(function(el) {el.hide();});
			}
		}
	},
	
	reverseTop: function() {
		if (this.options.reverseTop) {
			var topEls = $(this.menu.childNodes[0]).childElements();
			var numTop = topEls.length;
			for (var i = 0; i < numTop-1; i++) {
				topEls[numTop-1].insert({after:topEls[i]});
			}
		}
	},
	
	initDividers: function() {
		if (this.options.divider) {
			// get top level lis
			var topLevels = $(this.menu.childNodes[0]).childElements();
			for (var i = 0; i < topLevels.length-1; i++) {
				topLevels[i].insert({after:'<li class="divider">'+this.options.dividerHTML+'</li>'});
			}
		}
	},
	
	initTree: function() {
		// set mouse click for each anchor
		var anchors = this.menu.getElementsByTagName('a');
		for (var i = 0; i < anchors.length; i++) {
			anchors[i].onclick = function(e, anchor, clickHandler) {
				if (anchor.href.match(/#$/)) {
					subLists = anchor.parentNode.getElementsByTagName('div');
					if (subLists.length) {
						Element.toggle(subLists[0]);
					}
					return false;
				}
				return clickHandler(anchor);
			}.bindAsEventListener(this, anchors[i], this.options.click);
		}
		
		// set mouseover for each li
		/*var liArray = this.menu.getElementsByTagName('li');
		for (var i = 0; i < liArray.length; i++) {
			liArray[i].onmouseover = function(e, hoveredLi) {
				this.setActiveLi(hoveredLi);
			}.bindAsEventListener(this, liArray[i]);
		}*/
	},
	
	positionSubList: function(subList) {
		var linkHeight = subList.parentNode.offsetHeight;
		if ($(subList.parentNode.parentNode.parentNode).hasClassName(this.options.styleClass)) {
			switch (this.options.direction) {
				case 'down':
					subList.style.top = linkHeight.toString() + 'px';
					subList.style.left = '0';
				break;
				case 'up':
					subList.style.visibility = 'hidden';
					subList.style.display = '';
					subList.style.top = 0 - parseInt(subList.offsetHeight) + 'px';
					subList.style.display = 'none';
					subList.style.visibility = 'visible';
					subList.style.left = '0';
				break;
				case 'right':
					subList.style.left = subList.parentNode.parentNode.offsetWidth + 'px';
					subList.style.top = '0';
				break;
				case 'left':
					subList.style.left = (0 - subList.parentNode.parentNode.offsetWidth) + 'px';
					subList.style.top = '0';
				break;
				
			}
		}
		else {
			switch (this.options.subPosition) {
				case 'right':
					subList.style.left = subList.parentNode.parentNode.offsetWidth + 'px';
				break;
				case 'left':
					subList.style.visibility = 'hidden';
					subList.style.display = '';
					subList.style.left = 0 - parseInt(subList.offsetWidth) + 'px';
					subList.style.display = 'none';
					subList.style.visibility = 'visible';
				break;
			}
			switch (this.options.subAlign) {
				case 'top':
					subList.style.top = '0';
				break;
				case 'bottom':
					subList.style.visibility = 'hidden';
					subList.style.display = '';
					subList.style.top = linkHeight - parseInt(subList.offsetHeight) + 'px';
					subList.style.display = 'none';
					subList.style.visibility = 'visible';
				break;
			}
		}
	},
	
	activeLis:[],
	zIndex:10000,
	
	getLevel: function(hoveredLi) {
		level = 0;
		while(!$(hoveredLi.parentNode.parentNode).hasClassName(this.options.styleClass)) {
			hoveredLi = hoveredLi.parentNode.parentNode.parentNode;
			level++;
		}
		return level;
	},
	
	showMenuTimer:null,
	
	showPopup: function(hoveredLi) {
		// check if li has a sublist
		subList = false;
		subLists = hoveredLi.getElementsByTagName('div');
		if (subLists.length) {
			subList = subLists[0];
			if (subList.style.display == 'none') {
				level = this.getLevel(hoveredLi);
				if (this.options.numLevels == -1 || level < this.options.numLevels) {
					this.positionSubList(subList);
					subList.style.zIndex = this.zIndex++;
					subList.style.position = 'absolute';
					Element.show(subList);
				}
			}
		}
	},
		
	showActives: function() {
		str = '';
		for (var i = 0; i < this.activeLis.length; i++) {
			str += this.activeLis[i].childNodes[0].innerHTML + ', ';
		}
		return str;
	},
	
	setActiveLi: function(hoveredLi) {
		hoveredLi.style.position = 'relative';
		level = this.getLevel(hoveredLi);
		
		// check for sublist to know whether or not to hide
		subLists = hoveredLi.getElementsByTagName('div');
		if (subLists.length) {
			subList = subLists[0];
			if (subList.style.display == 'none') {
				this.hideOtherPopups(level);
				this.activeLis[level] = hoveredLi;
			}
		}
		else {
			this.hideOtherPopups(level);
			this.activeLis[level] = hoveredLi;
		}
	},
	
	hideOtherPopups: function(level) {
		for (var i = this.activeLis.length-1; i >= level; i--) {
			subLists = this.activeLis[i].getElementsByTagName('div');
			if (subLists.length) {
				subList = subLists[0];
				Element.hide(subList);
			}
		}
		this.showActives();
	},
	
	hideMenuTimer:null,
	
	hideAll:function() {
		for (var i = 0; i < this.activeLis.length; i++) {
			subLists = this.activeLis[i].getElementsByTagName('div');
			if (subLists.length) {
				Element.hide(subLists[0]);
			}
		}
		this.activeLis = [];
	},
	
	initPopups: function() {
		// hide inner list so it doesn't take up space
		this.menu.childNodes[0].style.height = '1px';
		this.menu.childNodes[0].style.overflow = 'hidden';
		
		// set mouse click for each anchor
		var anchors = this.menu.getElementsByTagName('a');
		for (var i = 0; i < anchors.length; i++) {
			anchors[i].onclick = function(e, anchor, clickHandler) {
				return clickHandler(anchor);
			}.bindAsEventListener(this, anchors[i], this.options.click);
		}
		
		// set mouseover for each li
		var liArray = this.menu.getElementsByTagName('li');
		for (var i = 0; i < liArray.length; i++) {
			liArray[i].onmouseover = function(e, hoveredLi) {
				this.setActiveLi(hoveredLi);
				this.showPopup(hoveredLi);
				
				/*clearTimeout(this.showMenuTimer);
				this.showMenuTimer = setTimeout(function() {
					
				}.bind(this), 100);*/
			}.bindAsEventListener(this, liArray[i]);
		}
		
		this.menu.onmouseover = function() {
			clearTimeout(this.hideMenuTimer);
		}.bindAsEventListener(this);
		
		this.menu.onmouseout = function(a, b) {
			this.hideMenuTimer = setTimeout(function() {
				this.hideAll();
			}.bind(this), 1000);
		}.bindAsEventListener(this);
		
		this.menu.style.overflow = 'visible';
		
		// reset to a visible height
		this.menu.childNodes[0].style.height = 'auto';
		this.menu.childNodes[0].style.overflow = 'visible';
	}
};