function delegate(scope, functionName) {
	if(arguments.length > 2) {
		var custom = new Array();
		for(var i = 2; i<arguments.length; i++) {
			custom.push(arguments[i]);
		}
		return function() {
			scope[functionName].apply(scope, custom);
		}
	}
	else {
		return function() {
			scope[functionName].apply(scope, arguments);
		}
	}
}

function dom_get(id){
	return document.getElementById(id);
}

function dom_every(element, className, callback) {
	if(element.getElementsByClassName) {
		var nodes = element.getElementsByClassName(className);
		for(var i = 0; i<nodes.length; i++) {
			callback(nodes[i]);
		}	
	}
	else {
		var pattern = new RegExp("(\\s|^)" + className + "(\\s|$)");
		var elements = element.getElementsByTagName("*");	
		for(var i = 0; i<elements.length; i++) {
			if(pattern.test(elements[i].className)) {
				callback(elements[i]);
			}
		}
	}
}

function dom_create(type, attributes){
    var element = document.createElement(type);
    for (var name in attributes) {
		element[name] = attributes[name];
    }
    return element;    
}

function dom_position(element) {
	var x = 0;
	var y = 0;
	while(element != null) {
		x += element.offsetLeft;
		y += element.offsetTop;
		element = element.offsetParent;
	}
	return {x:x, y:y};
}

function dom_opacity(element, value) {
	element.style.opacity = value;
	element.style.filter = "alpha(opacity=" + (value * 100) + ")";
}

function dom_set_class(element, className, condition){
	condition = condition == undefined ? true : condition;	
    var pattern = new RegExp("(\\s|^)" + className + "(\\s|$)");
    if (condition && !element.className.match(pattern)) {
        element.className += " " + className;
    }
    else if (!condition) {
		element.className = element.className.replace(pattern, " ");
	}
}
function dom_has_class(element, className) {
	return new RegExp("(\\s|^)" + className + "(\\s|$)").test(element.className);
}

function event_target(event) {
	var target;
	if(!event) {
		event = window.event;
	}
	if(event.target) {
		target = event.target;
	}
	if(event.srcElement) {
		target = event.srcElement;
	}
	if(target.nodeType == 3) {
		target = target.parentNode;
	}
	return target;
}

function event_mouseX(event) {
	if(event) {
		return event.pageX;
	}
	else {
		var d = document.documentElement;
		var b = document.body;
		return window.event.clientX + (d && d.scrollLeft || b && b.scrollLeft || 0) - (d && d.clientLeft || b && b.clientLeft || 0);
	}
	return 0;
}
function event_mouseY(event) {
	if(event) {
		return event.pageY;
	}
	else {
		var d = document.documentElement;
		var b = document.body;
		return window.event.clientY + (d && d.scrollTop || b && b.scrollTop || 0) - (d && d.clientTop || b && b.clientTop || 0);
	}
	return 0;	
}

function event_prevent(event) {
	if(event) {
		event.preventDefault();
	}
	else if(window.event) {
		window.event.returnValue = false;
	}
}

function URLLoader() {
	var scope = this;
	if(window.XMLHttpRequest) {
    	this.request = new XMLHttpRequest();
	}
	else if(window.ActiveXObject) {
		this.request = new ActiveXObject("Microsoft.XMLHTTP");
	}
    this.request.onreadystatechange = function() {
    	if(this.readyState == 4 && scope.onComplete) {
			scope.onComplete(this.responseText);
    	}
    }
	this.load = function(url, method, variables) {
		if(method && method.toUpperCase() == "POST") {
			if(!variables) variables = "";		
			this.request.open("POST", url, true);
			this.request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this.request.setRequestHeader("Content-length", variables.length);
			this.request.setRequestHeader("Connection", "close");
			this.request.send(variables);
		}
		else {
			this.request.open("GET", url, true);
			this.request.send();			
		}
	}	
	this.close = function() {
		this.request.abort();
	}
}

Timer = function(onUpdate, onComplete) {
	this.onUpdate = onUpdate;
	this.onComplete = onComplete;
	if(!Timer.intervalId) {
		Timer.items = [];
		Timer.time = new Date().getTime() / 1000;
		Timer.intervalId = setInterval(function() {
			Timer.time = new Date().getTime() / 1000;
			var i = Timer.items.length;
			while(i-- > 0) {
				if(!Timer.items[i].update()) {
					Timer.items.splice(i, 1);
				}
			}
		}, 13);
	}
	this.start = function(duration) {
		this.duration = duration;
		this.startTime = Timer.time;
		this.stopped = false;
		if(this.update()){
			Timer.items.push(this);
			//unshift?
		}
	}
	this.update = function() {
		if(this.stopped) {
			return false;
		}
		if(this.duration == null) {
			if(this.onUpdate) this.onUpdate(0);
			return true;
		}
		var time = Timer.time - this.startTime;
		if(time < this.duration) {
			if(this.onUpdate) this.onUpdate(time / this.duration);
			return true;
		}
		if(this.onUpdate) this.onUpdate(1);
		if(this.onComplete) this.onComplete();
		return false;
	}	
	this.stop = function() {
		this.stopped = true;
	}
}

function Tween(begin, end, ease) {
	this.begin = begin;
	this.end = end;
	this.ease = ease;
}
Tween.prototype.getValue = function(t) {
	if(this.ease) {
		return this.begin + (this.end - this.begin) * this.ease(t);
	}	
	return this.begin + (this.end - this.begin) * t;
}
Tween.easeIn = function(k) {
	return k * k * k;
}
Tween.easeOut = function(k) {
	return --k * k * k + 1;	
}
Tween.easeInOut = function(k) {
	if((k *= 2) < 1) return 0.5 * k * k * k;
	return 0.5 * ((k -= 2) * k * k + 2);		
}


/* slideshow */
Slide = function(element) {
	
	var slideshow = this;
	slideshow.element = element;
	slideshow.backgroundRatio = -1;
	
	slideshow.background = $(element).find('.slide_background').get(0);
	
	if(slideshow.background){			
		if(slideshow.background.width > 0) {
			slideshow.backgroundRatio = slideshow.background.width / slideshow.background.height;
		}
		else {
			slideshow.background.onload = delegate(slideshow, "backgroundLoaded");
		}		
	}	
}


Slide.prototype.move = function(x) {
	this.element.style.left = x + "px";
}			
Slide.prototype.show = function(value) {
	this.element.style.visibility = value ? "visible" : "hidden";
}				
Slide.prototype.backgroundLoaded = function() {
	this.backgroundRatio = this.background.width / this.background.height;
	this.layout();
}
Slide.prototype.layout = function() {
	
	var slideshow = this;
	
	if(slideshow.backgroundRatio > -1) {
		
		var containerWidth = slideshow.element.clientWidth;
		var containerHeight = slideshow.element.clientHeight;				
		
		var imageWidth;
		var imageHeight;
		
		if(slideshow.backgroundRatio < containerWidth / containerHeight) {
			imageWidth = containerWidth;
			imageHeight = containerWidth / slideshow.backgroundRatio;					
		}
		else {
			imageWidth = containerHeight * slideshow.backgroundRatio;
			imageHeight = containerHeight;				
		}
					
		slideshow.background.style.width = imageWidth + "px";
		slideshow.background.style.height = imageHeight + "px";
		slideshow.background.style.left = (containerWidth * 0.5 - imageWidth * 0.5) + "px";
		slideshow.background.style.top = (containerHeight * 0.5 - imageHeight * 0.5) + "px";
	}
}

Slideshow = function(id) {
	var slideshow = this;
	
	slideshow.slides = new Array();
	slideshow.element = document.getElementById(id);	
	$(slideshow.element).find('.slide').each(function(i, elm){
		slideshow.slides[i] = new Slide(elm);		
	});
	
	slideshow.currentIndex = 0;
	slideshow.setNavigation();
	
	if(typeof(slideshow.slides[0]) != 'undefined'){
		slideshow.slides[0].show(true);
		slideshow.timer = new Timer(delegate(slideshow, "timerUpdate"), delegate(slideshow, "timerComplete"));
	}
}

Slideshow.prototype.Start = function() {
	var slideshow = this;
	clearInterval(SSGoNext);
	SSGoNext = setInterval("slideshow.next()", 10000);
}

Slideshow.prototype.Stop = function() {
	clearInterval(SSGoNext);
}

Slideshow.prototype.timerUpdate = function(t) {
	var ease = Tween.easeInOut(t) * this.direction;
	var width = this.element.clientWidth;
	this.slides[this.currentIndex].move(width * this.direction + ease * -width);
	this.slides[this.previousIndex].move(ease * -width);
}

Slideshow.prototype.timerComplete = function() {
	this.slides[this.previousIndex].show(false);	
}

Slideshow.prototype.goto = function(index, direction) {

	if(this.currentIndex == index) {
		return;
	}
						
	if(direction == null) {
		this.direction = (this.currentIndex < index ? 1 : -1);
	}
	else {
		this.direction = direction;
	}
				

	if(this.previousIndex > -1) {
		this.slides[this.previousIndex].show(false);
	}
	
	this.previousIndex = this.currentIndex;
	this.currentIndex = index;
	
	this.slides[this.currentIndex].show(true);
	
	this.timer.start(0.8);
	
	if(typeof(this.navigation) == 'object'){
		this.navigation.find('li a').removeClass('active');
		this.navigation.find('li:eq('+slideshow.currentIndex+')').children('a.tab').addClass('active');
	}	
}

Slideshow.prototype.next = function() {
	if(this.currentIndex + 1 < this.slides.length) {
		this.goto(this.currentIndex + 1, 1);
	}
	else {
		this.goto(0, 1);
	}
	
	if(typeof(this.navigation) == 'object'){
		this.navigation.find('li a').removeClass('active');
		this.navigation.find('li:eq('+slideshow.currentIndex+')').children('a.tab').addClass('active');
	}	
}
Slideshow.prototype.prev = function() {
	if(this.currentIndex - 1 < 0) {
		this.goto(this.slides.length - 1, -1);
	}
	else {
		this.goto(this.currentIndex - 1, -1);
	}
	
	if(typeof(this.navigation) == 'object'){
		this.navigation.find('li a.active').removeClass('active');
		this.navigation.find('li:eq('+slideshow.currentIndex+')').children('a.tab').addClass('active');		
	}
}			
Slideshow.prototype.layout = function() {
	for(var i = 0; i<this.slides.length; i++) {
		this.slides[i].layout();
	}
}
Slideshow.prototype.setNavigation = function() {
	var slideshow = this;
	var tabSetSize = 10;
	var jumpTabLinkTpl = $('<a class="jump">...</a>');
	
	/* display a tabset starting with startIndex */ 
	var shiftTabSet = function(startIndex){
		var stopIndex = false;
		var startIndex = startIndex;
		
		tabs.filter(':eq('+startIndex+')').nextAll('li').each(function(){
			if($(this).find('a.jump').size() > 0){
				stopIndex = $(this).index();
				return false;
			}
		});
		
		if(!stopIndex){
			stopIndex = tabs.size();
		}
		
		tabs.hide();
		
		if(startIndex == 0){
			tabs.filter(':eq('+startIndex+')').show();		
		}
		
		tabs.filter(':gt('+startIndex+')').show();
		tabs.filter(':gt('+stopIndex+')').hide();			
	}
		
	if($(slideshow.element).siblings('.slideshow_navigation').size() > 0)
	{
		slideshow.navigation = $(slideshow.element).siblings('.slideshow_navigation');			
		var tabs = slideshow.navigation.find('li');
		var alias = getAlias();
		
		//Paginate
		if(tabs.size() > tabSetSize)
		{
			tabs.each(function(i, tab)
			{				
				$(tab).children('a').text(i+1);
				if((i+1)%tabSetSize == 0)
				{
					var jumpTabLink = jumpTabLinkTpl.clone();
					
					$(tab).addClass('jump');
					
					jumpTabLink
						.appendTo($(tab))
						.bind('click', function(){
							
							var startIndex = $(this).parent('li').index();
							shiftTabSet(startIndex);
							tabs.filter(':visible:first').find('a').trigger('click');
														
						});			
				}
			});
			
			shiftTabSet(0);
		}
		
		// center navigation
		slideshow.navigation.css({
			'margin-left'	:	'-'+slideshow.navigation.width()/2+'px',
			'visibility'	:	'visible'
		});
		
		tabs.find('a.tab').click(function(){
			var index = $(this).parent().index();			
			var nextSlide = tabs.filter(':eq('+index+')');
			var doShift = false;
			var startIndex = 0;
			
			tabs.filter(':eq('+index+')').prevAll('li').each(function(){
				if($(this).find('a.jump').size() > 0){
					startIndex = $(this).index();
					return false;
				}
			});
			
			doShift = nextSlide.is(':hidden');

			if(doShift){
				if(tabs.size() > tabSetSize) shiftTabSet(startIndex);
			}
			
			$(this).addClass('active').parent('li').siblings().children('a').removeClass('active');
			slideshow.goto(index);
			slideshow.Stop();
		});
		
		slideshow.navigation.find('a.next').click(function(){
			
			var nextSlide = tabs.filter(':eq('+(slideshow.currentIndex+1)+')');
			var doShift = false;
			var startIndex = 0;
			
			if(nextSlide.size() > 0){
				doShift = tabs.filter(':eq('+(slideshow.currentIndex+1)+')').is(':hidden');
				startIndex = tabs.filter(':visible:last').index();
			}
			else {
				doShift = true;	
			}
					
			if(doShift){
				if(tabs.size() > tabSetSize) shiftTabSet(startIndex);	
			}
						
			slideshow.next();			
			slideshow.Stop();
			$(this).slideShowNav({index : slideshow.currentIndex});
		});
		
		slideshow.navigation.find('a.prev').click(function(){
			var doShift = false;
			var startIndex = tabs.size() - (tabs.size()%tabSetSize) - 1;
			
			if(slideshow.currentIndex > 0){
				doShift = tabs.filter(':eq('+(slideshow.currentIndex-1)+')').is(':hidden');
				startIndex = tabs.filter(':visible:first').prev().index() - tabSetSize;
				if(startIndex < 0){
					startIndex = 0;
				}				
			}
			else {
				doShift = true;	
			}
			
			if(doShift){
				if(tabs.size() > tabSetSize) shiftTabSet(startIndex);	
			}
			
			slideshow.prev();
			slideshow.Stop();
			$(this).slideShowNav({index : slideshow.currentIndex});
		});	
		
		slideshow.navigation
			.find('li:eq('+slideshow.currentIndex+')')
			.children('a.tab')			
			.addClass('active');
	}
}

jQuery.fn.slideShowNav = function(params){
	
	var params = $.extend({},params);
	
	this.each(function(){
		$(this)
			.siblings('.wrapper')
			.find('a.tab:eq('+params.index+')')
			.addClass('active')
			.parent('li')
			.siblings()
			.children('a')
			.removeClass('active');	
	});
	
	return this;	
}








