/*
 * jQuery css clip animation support -- Jim Palmer
 * version 0.1.1
 * idea spawned from jquery.color.js by John Resig
 * Released under the MIT license.
 */
(function(jQuery){
	jQuery.fx.step.clip = function(fx){
		if ( fx.state === 0 ) {
			var cRE = /rect\(([0-9]{1,3})(px|em) ([0-9]{1,3})(px|em) ([0-9]{1,3})(px|em) ([0-9]{1,3})(px|em)\)/;
			fx.start = cRE.exec( fx.elem.style.clip.replace(/,/g, '') );
			if (fx.end.replace) {
				fx.end = cRE.exec( fx.end.replace(/,/g, '') );
			}
		}
		var sarr = [], earr = [], spos = fx.start ? fx.start.length : 0 , epos = fx.end ? fx.end.length : 0,
			emOffset = fx.start[ss+1] == 'em' ? ( parseInt($(fx.elem).css('fontSize')) * 1.333 * parseInt(fx.start[ss]) ) : 1;
		for ( var ss = 1; ss < spos; ss+=2 ) { sarr.push( parseInt( emOffset * fx.start[ss] ) ); }
		for ( var es = 1; es < epos; es+=2 ) { earr.push( parseInt( emOffset * fx.end[es] ) ); }
		fx.elem.style.clip = 'rect(' + 
			parseInt( ( fx.pos * ( earr[0] - sarr[0] ) ) + sarr[0] ) + 'px ' + 
			parseInt( ( fx.pos * ( earr[1] - sarr[1] ) ) + sarr[1] ) + 'px ' +
			parseInt( ( fx.pos * ( earr[2] - sarr[2] ) ) + sarr[2] ) + 'px ' + 
			parseInt( ( fx.pos * ( earr[3] - sarr[3] ) ) + sarr[3] ) + 'px)';
	};
})(jQuery);

jQuery(document).ready(function() {
   /// do this stuff when the HTML is all ready

	// Load google map in about page //
	
	if (document.getElementById('map')){

		if (GBrowserIsCompatible()) {
				
				var map = new GMap2(document.getElementById("map"), {disableDefaultUI: true});
				map.setMapType(G_HYBRID_MAP);				
								
				map.setCenter(new GLatLng(52.363028, 4.891898), 14);								
				var point = new GLatLng(52.363028, 4.891898);
				map.addOverlay(new GMarker(point));
		        
      	}
	}

	// hide mailform and respond div's
	if(jQuery.url.attr("anchor") != 'mc_signup_form'){
		jQuery('.slider').hide();
	}

	// if mailinglist link is clicked, slide down mailform
	jQuery('a.mailinglist').click(function() {
		jQuery('.slider').slideToggle('normal');
		return false;
	});
	
	// mailinglist inline label behaviour
	var Garp = {};
	Garp.inlineLabels = {
		/**
		 * Find correct labels on the page and display 'em 'inline'
		 * @param Mixed $elements Optional elements, if none, "label.inline" will be used.
		 */
		init: function(elements) {
			var self = this;
			var $ = jQuery;
			elements = elements || 'label.inline';
			$(elements).each(function() {
				var thisLabel = $(this);
				var input = $('#'+thisLabel.attr('for'));
				input.focus(function() {
					self.focus.call(input, thisLabel);
				}).blur(function() {
					self.blur.call(input, thisLabel);
				});
				// 'cause browsers remember certain form values, there needs to be one manual check.
				setTimeout(function() {
					if ($(input).val()) {
						self.focus.call(input, thisLabel);
					}
				}, 1000);
			});
		},
		/**
		 * Focus event handler on inputs
		 */
		focus: function(theLabel) {
			theLabel.addClass('hidden');
		},
		/**
		 * Blur event handler on inputs
		 */
		blur: function(theLabel) {
			if (!this.val()) {
				theLabel.removeClass('hidden');
			}
		}
	};
	Garp.inlineLabels.init(jQuery('#mc_signup_form label'));
	
	// fancybox images on project pages
	jQuery('.project_images a.group').fancybox({
		imageScale: true,
		overlayShow: true
	});
		
	// "browseboxes" on home
	jQuery.each(['featuredProjects', 'projectsOverview'], function() {
		/**
		 * Make sure every item is equal in height for a smoother presentation
		 */
		var equalizeHeights = function(collection) {
			var tallest = 0;
			collection.each(function() {
				tallest = Math.max(tallest, this.offsetHeight);
			});
			collection.css('height', tallest+'px');
		};
				
		/**
		 * Animate blanket element within an .article
		 */
		var closeBlanket = function(element, fn) {
			if (!jQuery('.blanket', element).length) {
				jQuery(element).append('<div class="blanket"/>');
			}
			jQuery('.blanket', element).animate({
				height: '100%'
			}, 150, 'swing', typeof fn == 'function' ? fn : null);
		};
		
		var openBlanket = function(element, fn) {
			if (!jQuery('.blanket', element).length) {
				jQuery(element).append('<div class="blanket"/>');
			}
			jQuery('.blanket', element).animate({
				height: '0'
			}, 150, 'swing', function() {
				if (typeof fn === 'function') {
					fn();
				}
				// cleanup blanket after this
				jQuery(this).remove();
			});
		};
		
		var shuffle = function(o) {
			for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
			return o;
		};
		
		/**
		 * Replace old .article with new .article
		 */
		var switcheroo = function(elA, elB) {
			jQuery(elA).replaceWith(elB);
			openBlanket(elB);
		};
		
		/**
		 * Generate an array containing numbers in a certain range
		 */
		var range = function(min, max, step) {
			step = !step ? 1 : step;
			for (var i = min, a = []; i <= max; i += step) {
				a.push(i);
			}
			return a;
		};
		
		/**
		 * Show loading indicator
		 */
		var showLoading = function(parent) {
			jQuery('#'+parent).append('<div class="loader"></div>');
			animateLoading(parent);
		};
		
		/**
		 * Hide loading indicator
		 */
		var hideLoading = function(parent) {
			clearInterval(jQuery('#'+parent+' .loader')[0].ai);
			jQuery('#'+parent+' .loader').remove();
		};
		
		/**
		 * Animate loading indicator
		 */
		var animateLoading = function(parent) {
			var l = jQuery('#'+parent+' .loader')[0];
			l.ai = setInterval(function() {
				if (typeof l.i === 'undefined' || l.i === 12) {
					l.i = 1;
				}
				l.style.backgroundPosition = '0px -'+(l.i*40)+'px';
				l.i++;
			}, 66);
		};
		
		var target = this;
		equalizeHeights(jQuery('#'+target+' .article'));
		
		jQuery('#'+target+' a.older, #'+target+' a.newer').live('click', function(e) {
			e.preventDefault();
			if (!window.__BUSYBROWSEBOX__) {
				window.__BUSYBROWSEBOX__ = true;
				showLoading(target);
				var href = jQuery(this).attr('href');
				var mode = jQuery(this).hasClass('older') ? 'older' : 'newer';
				var theSection = jQuery('#'+target);
				jQuery.get(href, {}, function(data) {
					
					// unfortunately, I cannot select HTML from the fetched data directly, therefore I dump it in a temp. element
					jQuery('body').append('<div id="tmp_storage"/>');
					var tmpStorage = jQuery('#tmp_storage').css('display', 'none').html(data);
					// insert new navigation
					var nav = jQuery('.nav', tmpStorage);
					jQuery('.nav', theSection).replaceWith(nav);
					// find new .articles and replace the old ones with 'em
					var newArticles = jQuery('.article', tmpStorage);
					var oldArticles = jQuery('.article', theSection);
					// start the new ones with closed blankets
					closeBlanket(newArticles);
					var r = range(0, oldArticles.length-1);
					if (mode === 'newer') {
						r.reverse();
					}
					var i = 0;
					var curr = jQuery(oldArticles[r[i]]);

					// here's some anonymous recursive closure business goin' on
					(function initClosing(curr) {
						closeBlanket(curr, function() {						
							if (r[i] in newArticles) {
								switcheroo(curr, newArticles[r[i]]);
							} else {
								// curr.remove();
							}
						
							// remove tmpStorage if arrived at the last item
							if (i == r.length-1) {								
								// make sure they're equal in height
								equalizeHeights(newArticles);
								tmpStorage.remove();
								hideLoading(target);
								window.__BUSYBROWSEBOX__ = false;
							}
						
							// construct a chain of events; after every animation, 
							// trigger the next, if available
							if (r[++i] in oldArticles) {
								setTimeout(function() {
									initClosing(jQuery(oldArticles[r[i]]));
								}, 50);
							}
						});
					})(curr);
				});
			}
		});
	});
	
	// news needs a different transition
	jQuery('#news a.older, #news a.newer').live('click', function(e) {
		e.preventDefault();
		var href = jQuery(this).attr('href'),
			len  = jQuery('#news .article').length,
			i	 = 0,
			h	 = jQuery('#news').height();
		jQuery('body').append('<div id="tmp_storage"/>');
		var tmpStorage = jQuery('#tmp_storage').css('display', 'none');
		jQuery('#news').css('height', h+'px');
		tmpStorage.load(href, {}, function() {
			jQuery('#news .article').fadeOut(250, function() {
				i++;
				if (i === len) {
					// fade out new elements
					jQuery('.article', tmpStorage).css('display', 'block').fadeTo(250, 0.1, function() {
						jQuery('#news').html(tmpStorage.html());
						jQuery('#news .article').fadeTo(250, 1);
					});
					tmpStorage.remove();
				}
			});
		});
	});
	
	// scroll to top link in footer
	jQuery('a.top').click(function() {
		jQuery.scrollTo(0, 1000);
		return false;
	});
});
