// Link switcher script by Antti Kupila
// Version: 0.2
// Email: akupila [at] gmail [dot] com
// WWW: http://www.anttikupila.com

// This is release under a Creative Commons license.
// More information can be found here:
// http://creativecommons.org/licenses/by-sa/2.5/

// Easing function by Robert Penner
// http://www.robertpenner.com

strongEaseOut = function(t,b,c,d){ return c*((t=t/d-1)*t*t*t*t + 1) + b }

// -------[ SETTINGS ]-------------------------------------------------

var inDelay = 750; // milliseconds
var outDelay = 750; // milliseconds
var easeFunction = strongEaseOut;

// ---------------------------------------------------------------------------

function addEffects() {
	var links = getElementsByClass("switch", document, "a");
	for (var i=0;i<links.length;i++) {
		links[i].parentNode.style.height = "18px";
		links[i].innerHTML = "<span class='switchHover' style='position: absolute; top: -100%'>" + links[i].innerHTML + "</span>" + links[i].innerHTML;
		links[i].style.position = "absolute";
		links[i].parentNode.style.overflow = "hidden";	
		links[i].parentNode.style.position = "relative";
		links[i].effect = new animation(links[i]);
		links[i].onmouseover = function () {	this.effect.tween(100, inDelay, easeFunction )	}
		links[i].onmouseout = function () { this.effect.tween(0, outDelay, easeFunction )	}
	}
}

function animation(link, to) {
	this.el = link;
	this.from = 0;
	this.to = 100;
};

animation.prototype = {
	tween: function(targetPos, duration, easeFunc) {
		this.duration = duration;
		this.from = this.now || 0;
		this.to = targetPos;
		this.ease = easeFunc;
		this.go();
	},
	
	go: function() {
		clearInterval(this.timer);
		this.startTime = (new Date).getTime();
		this.timer = setInterval (this.step.bind(this), 10);
	},
	
	step: function() {
		var time	= (new Date).getTime();
		if (time >= this.duration+this.startTime) {
			this.now = this.to;
			clearInterval(this.timer);
			this.now = this.to;
		}
		else {
			var Tpos = (time - this.startTime) / (this.duration);
			this.now = Math.round(this.ease(Tpos, this.from, this.to-this.from, 1));
		}
		this.el.style.top = this.now + "%";
	}
}

// --------------------------------------- //

// Snippets by other people (thanks!!)

// Parts from prototype.js
// http://prototype.conio.net/

Function.prototype.bind = function() {
	var __method = this, args = $A(arguments), object = args.shift();
	return function() {
		return __method.apply(object, args.concat($A(arguments)));
	}
}

var $A = Array.from = function(iterable) {
	if (!iterable) return [];
	if (iterable.toArray) {
		return iterable.toArray();
	} else {
		var results = [];
		for (var i = 0; i < iterable.length; i++)
			results.push(iterable[i]);
		return results;
	}
}

// Get elements by class script by Dustin Diaz
// http://www.dustindiaz.com/getelementsbyclass/

function getElementsByClass(searchClass,node,tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {	
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

// Add Event function by Scott Andrew
// http://www.scottandrew.com/weblog/articles/cbs-events

function addEvent(obj, evType, fn){
	if (obj.addEventListener){
		obj.addEventListener(evType, fn, true);
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
} 

addEvent(window, 'load', addEffects);