var Papercut = {
	version:'0.1.2'
};

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.SlideShow = Class.create({
	version: 0.1,
	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.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';
			if (i) {
				this.items[i].style.display = 'none';
			}
		}
		
		if (this.totalItems) {
			this.items[0].show();
			if (this.container.getStyle('height') == '0px') {
				this.container.style.height = this.items[0].offsetHeight + 'px';
			}
			if (this.totalItems > 1) {
				this.start();
			}
		}
	},
	
	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);
		}
	},
	
	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;
					}.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;
				}.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;
				}.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}$/);
	},
	
	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'
};

Papercut.Menu.hideTimer = null;
Papercut.Menu.currentZ = 1;
Papercut.Menu.menus = [];
Event.observe(window, 'load', function() {
	
});

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.1,
	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;
		}
		
		// 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]);
						}
					}
				}
			}
		}
		
		// show the menu
		this.menu.style.visibility = 'visible';
	},
	
	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.className == 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.className != 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);
				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';
	}
};
