///* http://gsgd.co.uk/sandbox/jquery/easing/ */
jQuery.easing.def = 'easeInOutCubic';
var carouselAnimationSpeed = 800;
jQuery.fx.interval = 13;

var twitterSettings = {
	slideExtraHeight: 26,
	slideHolderExtraHeight: 64,
	fadeAnimationLength: 750
};

var quoteSettings = {
	slideExtraHeight: 8,
	slideHolderExtraHeight: 46,
	fadeAnimationLength: 750,
	fadeSpanAnimationLength: 750
};

var carouselSettings = {
	fadeAnimationLength: 750
};

function removePlaceholders(carousel) {
	
	// In chrome and Safari, somehow empty placeholers are added, remove this because we don't want them..
	jQuery("li.jcarousel-item-placeholder-horizontal", carousel.container).remove();
	
}

function fadeOutPreloader(carousel) {
	jQuery(".preloader", carousel.container.parents(".sliderHolder").first()).fadeOut("slow");
	jQuery("div.slidesContainer", carousel.container.parents(".sliderHolder").first()).css('visibility','visible').hide().fadeIn('slow');

}

function flipImageSlideHover($slide) {
	$slide.find('.slideContentWrapper').stop().animate({marginTop:'400px'}, 600);
	$slide.find('.slideContentWrapper img').stop().fadeTo(600, 0.0);
}

function flipImageSlideHoverOut($slide) {
	$slide.find('.slideContentWrapper').stop().animate({marginTop:'0px'}, 600);
	$slide.find('.slideContentWrapper img').stop().fadeTo(600, 1);
}

function defaultSlideHover($slide) {
	
	var alreadyCufoned = false;
	var alreadyColoredPlus = false;
	
	$slide.find("div.slidebackground")
		.stop()
		.animate({
			top: "0"
		}, {
			duration: 500,
			
			step: function(currentTop){
				// Cut in the middle of the animation so we can refresh cufon at the right time 
				// (so the text-color won't be white on white)
				if (!alreadyCufoned && currentTop > -410) {
					alreadyCufoned = true;
					$slide.find('h1').css({color: "#E20000"});
					
					// Refresh cufon only for the current slider headings				
					var selector = "#"+$slide.parents(".sliderHolder").first().attr("id") + " div.slider_inhoud li h1.slideHeading";
					Cufon.refresh(selector);
				}
				
				// Animate the plus image							
				if (!alreadyColoredPlus && currentTop > -410) {
					alreadyColoredPlus = true;
					$slide.find("a.plusblack").stop().fadeTo(250, 1);
				}
				
			},
			
			complete: function(){
				// On animation complete
			}
		});
	
	$slide.addClass('hover');
	
	$slide.find('p').stop().animate({color: "#000000"});
	
	if ($slide.find('h1')) {
		if ($slide.find('h1 span.cat').length != 0) {
			$slide.find('h1 span.cat').css({
				color: "#000000"
			})
		}
	}
	
}

function defaultSlideHoverOut($slide) {
	
	var alreadyCufoned = false;
	$slide.find("a.plusblack").stop().fadeTo(250, 0.0);
	
	$slide.find("div.slidebackground")
		.stop()
		.animate({
			top: "-900px"
		}, {
			duration: 500,
			
			step: function(currentTop){
				// Cut in the middle of the animation so we can refresh cufon at the right time 
				// (so the text-color won't be white on white)
				if (currentTop < -410 && !alreadyCufoned) {
					alreadyCufoned = true;
					$slide.find('h1').css({color: "#FFFFFF"});
					
					// Refresh cufon only for the current slider headings
					var selector = "#"+$slide.parents(".sliderHolder").first().attr("id") + " div.slider_inhoud li h1.slideHeading";
					Cufon.refresh(selector);
				}
			},
			
			complete: function(){
				// On animation complete
			}
		});

	$slide.removeClass("hover");
	$slide.find('p').stop().animate({color: "#FFFFFF"});
	
	if ($slide.find('h1 span.cat').length != 0){
		$slide.find('h1 span.cat').css({color: "#E20000"})
	}
}

function animateSliderHeight(carousel, animationLength, slideExtraHeight, slideHolderExtraHeight, $slideWhichHeightIsBasedOn) {

	var $carouselContainer = carousel.container;
	var $sliderHolder = $carouselContainer.parents("div.sliderHolder").first();
	
	// Check if there's a given slide where the height can be taken from.
	// Otherwise, define the slide with the first visible one.
	if ($slideWhichHeightIsBasedOn == null) {
		// FIXME: :visible doesn't always returns the right slide, may need to fix this after functionality tests
		$slideWhichHeightIsBasedOn = jQuery("ul.slides li.jcarousel-item div.slideContent:visible", $sliderHolder);
	}
	
	if ($slideWhichHeightIsBasedOn != null && $slideWhichHeightIsBasedOn.height() > 0) {
		// If there's no extra height specified, set it to 0
		slideExtraHeight = slideExtraHeight == null ? 0 : slideExtraHeight;
		slideHolderExtraHeight = slideHolderExtraHeight == null ? 0 : slideHolderExtraHeight;
		
		var newSliderHeight = $slideWhichHeightIsBasedOn.height() + slideExtraHeight;
		var newSliderHolderHeight = newSliderHeight + slideHolderExtraHeight;
	}
	
	// Animate the height of the sliderHolder so the new slided in element will fit 
	$sliderHolder.stop().animate({'height': newSliderHolderHeight + 'px'}, animationLength);
}

function defaultPrevClickCallback(carousel, controlElement, animationFunction, slideInElementIndex, slideOutElementIndex) {
	
	if (slideInElementIndex == null) {
		var slideInElementIndex = carousel.last - 2;
	}
	if (slideOutElementIndex == null) {
		var slideOutElementIndex = carousel.first - 1;
	}

	var $carouselContainer = carousel.container;
	var $sliderHolder = $carouselContainer.parents("div.sliderHolder").first();
		
	// The slide element which is faded out (old active element)
	var $slideElementOut = jQuery("ul.slides li:eq("+slideOutElementIndex+")", $sliderHolder).find("div.slideContent");

	// The slide element which is faded in  (new active element)
	var $slideElementIn = jQuery("ul.slides li:eq("+slideInElementIndex+")", $sliderHolder).find("div.slideContent");
	
	if ($slideElementIn != null && $slideElementIn.length > 0) {
		// Unbind the next/prev buttons so the slider animation can't be interupted.
		carousel.unbindButtons();
		
		// Animate the slide to the left
		carousel.prev();
		
		// Add a nice specific fade animation for the quote slider
		animationFunction(carousel, $sliderHolder, $slideElementIn, $slideElementOut, false)
	}
}

function defaultNextClickCallback(carousel, controlElement, animationFunction, slideInElementIndex, slideOutElementIndex) {
	
	if (slideInElementIndex == null) {
		var slideInElementIndex = carousel.last;
	}
	if (slideOutElementIndex == null) {
		var slideOutElementIndex = carousel.first - 1;
	}
	
	var $carouselContainer = carousel.container;
	var $sliderHolder = $carouselContainer.parents("div.sliderHolder").first();
	
	// The slide element which is faded out (old active element)
	var $slideElementOut = jQuery("ul.slides li:eq("+slideOutElementIndex+")", $sliderHolder).find("div.slideContent"); 
	
	// The slide element which is faded in  (new active element)
	var $slideElementIn = jQuery("ul.slides li:eq("+slideInElementIndex+")", $sliderHolder).find("div.slideContent");
	
	if ($slideElementIn != null && $slideElementIn.length > 0) {
		// Unbind the next/prev buttons so the slider animation can't be interupted.
		carousel.unbindButtons();
		
		// Animate the slide to the right
		carousel.next();
		
		// Add a nice specific fade animation for the quote slider
		animationFunction(carousel, $sliderHolder, $slideElementIn, $slideElementOut, true);
	}
	
}

/*
 * Nicely Fade onchange of the carousel controls
 */
var defaultButtonChangeCallback = function(carousel, controlElement, isEnabled) {
	if (isEnabled) {
		jQuery(controlElement).hide().fadeIn(500);
	} else {
		jQuery(controlElement).removeClass("jcarousel-prev-disabled");
		jQuery(controlElement).removeClass("jcarousel-next-disabled");
		jQuery(controlElement).show().fadeOut(500);
	}
}
		

var quoteAnimation = function(carousel, $sliderHolder, $slideElementIn, $slideElementOut) {
	animateSliderHeight(carousel, 450, quoteSettings.slideExtraHeight, quoteSettings.slideHolderExtraHeight, $slideElementIn);
		
	jQuery("span", $slideElementIn).animate({
		backgroundColor: '#FFFFFF'
	}, quoteSettings.fadeSpanAnimationLength);
	
	$slideElementIn.fadeIn(quoteSettings.fadeAnimationLength);
	
	jQuery("span", $slideElementOut).animate({
		backgroundColor: '#000000'
	}, quoteSettings.fadeSpanAnimationLength);
	
	$slideElementOut.fadeOut(quoteSettings.fadeAnimationLength);

};

var twitterAnimation = function(carousel, $sliderHolder, $slideElementIn, $slideElementOut) {
	
//	TODO: Adjusting the slider height immediately doesn't work because the wrong height is returned somehow..
//	animateSliderHeight(carousel, 450, twitterSettings.slideExtraHeight, twitterSettings.slideHolderExtraHeight, $slideElementIn);
	
	// Fade in the new element
	$slideElementIn.fadeIn(twitterSettings.fadeAnimationLength);
	
	// Fade out the old element
	$slideElementOut.fadeOut(twitterSettings.fadeAnimationLength, function(){
		// After fading out, adjust the height of the slider
		animateSliderHeight(carousel, 450, twitterSettings.slideExtraHeight, twitterSettings.slideHolderExtraHeight, $slideElementIn);
	});
	
};

var carouselCounter = 0;
var carousels = new Array();

jQuery(document).ready(function() {
	
	/**
	 * Slider Quote
	*/
	jQuery('div#quote ul.slides').jcarousel({
		scroll: 1,
		animation: carouselAnimationSpeed,
		
		initCallback: function(carousel) {
			carousels[carouselCounter++] = carousel;
			animateSliderHeight(carousel, 0, 8, 46, null);
    	},
		
		setupCallback: function(carousel) {
			removePlaceholders(carousel);
		},
		
		buttonPrevElement: jQuery("div#quote ul.carousel_nav a.pijl_links"),
		buttonNextElement: jQuery("div#quote ul.carousel_nav a.pijl_rechts"),
	
		buttonPrevCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
		
		buttonNextCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
			
		buttonPrevClickCallback: function(carousel, controlElement) {
			defaultPrevClickCallback(carousel, controlElement, quoteAnimation);
		},
		
		buttonNextClickCallback: function(carousel, controlElement) {
			defaultNextClickCallback(carousel, controlElement, quoteAnimation);
		}
		
	});
	
	/**
	 * Slider Quote
	*/
	jQuery('div#twitter ul.slides').jcarousel({
		scroll: 1,
		animation: carouselAnimationSpeed,
		
		setupCallback: function(carousel) {
			removePlaceholders(carousel);
		},
		
		initCallback: function(carousel) {
			carousels[carouselCounter++] = carousel;
			animateSliderHeight(carousel, 0, twitterSettings.slideExtraHeight, twitterSettings.slideHolderExtraHeight, null);
    	},
		
		buttonPrevElement: jQuery("div#twitter ul.carousel_nav a.pijl_links"),
		buttonNextElement: jQuery("div#twitter ul.carousel_nav a.pijl_rechts"),
		
		buttonPrevCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
		
		buttonNextCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
		
		buttonPrevClickCallback: function(carousel, controlElement) {
			defaultPrevClickCallback(carousel, controlElement, twitterAnimation);
		},
		
		buttonNextClickCallback: function(carousel, controlElement) {
			defaultNextClickCallback(carousel, controlElement, twitterAnimation);
		}
		
	});
	
	/**
	 * Slider TagCloud
	*/
	jQuery('div#tagcloud ul.slides').jcarousel({
		scroll: 1,
		animation: carouselAnimationSpeed,
		
		setupCallback: function(carousel) {
			removePlaceholders(carousel);
		},
		
		initCallback: function(carousel) {
			carousels[carouselCounter++] = carousel;
			animateSliderHeight(carousel, 0, twitterSettings.slideExtraHeight, twitterSettings.slideHolderExtraHeight, null);
    	},
		
		buttonPrevElement: jQuery("div#tagcloud ul.carousel_nav a.pijl_links"),
		buttonNextElement: jQuery("div#tagcloud ul.carousel_nav a.pijl_rechts"),
		
		buttonPrevCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
		
		buttonNextCallback: function(carousel, controlElement, isEnabled) {
			defaultButtonChangeCallback(carousel, controlElement, isEnabled);
		},
		
		buttonPrevClickCallback: function(carousel, controlElement) {
			defaultPrevClickCallback(carousel, controlElement, twitterAnimation);
		},
		
		buttonNextClickCallback: function(carousel, controlElement) {
			defaultNextClickCallback(carousel, controlElement, twitterAnimation);
		}
		
	});
		
	jQuery('div.slider_inhoud li').hoverIntent({
		timeout: 1,
		over: function() {
			
			var $slide = jQuery(this);
			
			if (!$slide.hasClass("in_active")) {
			
				if (!$slide.hasClass("noHover") && !$slide.hasClass("flipimage")) {
					defaultSlideHover($slide);				
				}  else if ($slide.hasClass("flipimage")) {
					flipImageSlideHover($slide);
				}
				
			}
			
		},
		
		out: function() {

			var $slide = jQuery(this);
			
			if (!$slide.hasClass("in_active")) {
			
				if (!$slide.hasClass("noHover") && !$slide.hasClass("flipimage")) {
					defaultSlideHoverOut($slide);
				}  else if ($slide.hasClass("flipimage")) {
					flipImageSlideHoverOut($slide);
				}
				
			}
			
		}
		
	});
	
	if (jQuery.browser.msie && parseInt(jQuery.browser.version) == 8) {
	  // IE8 doesn't support visibility hidden with Cufonned text, 
	  // so we can't use the 'preload slider fades'..
	} else {
		fadeInElements();
	}

});

// Fade in the sliderElements onLoad of the page
var fadeCounter = 0;
function fadeInElements(){

	$elementToFadeIn = jQuery('ul.slides li:eq('+fadeCounter+')');
	
	if ($elementToFadeIn.length > 0) {
		
		fadeCounter++;
		$elementToFadeIn.css('visibility', 'visible').hide().fadeIn(1000);
		
		if ($elementToFadeIn.has(".slideContent:visible").length < 1) {
			// GOTO NEXT element
			fadeInElements();
			return;
		}

		setTimeout(function(){
			fadeInElements();
		}, 200);
			
	}

}

