/**
 *	The Bimhuis scripts
 */ 

/* Copyright (c) 2006 Mathias Bank (http://www.mathias-bank.de)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * Thanks to Hinnerk Ruemenapf - http://hinnerk.ruemenapf.de/ for bug reporting and fixing.
 */

var Garp = typeof Garp !='object' ? {} : Garp;
Garp.URLEncode = function(unencodedValue )
{
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var plaintext = unencodedValue;
	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i);
	    if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
			    throw( "Unicode Character '" 
                        + ch 
                        + "' cannot be encoded using standard URL encoding.\n" +
				          "(URL encoding only supports 8-bit characters.)\n" +
						  "A space (+) will be substituted." );
				encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return encoded;
};

/**
 * EXT JSON ported...
 */

var JSON = new (function(){
    var useHasOwn = {}.hasOwnProperty ? true : false;

    var pad = function(n) {
        return n < 10 ? "0" + n : n;
    };
    
    var m = {
        "\b": '\\b',
        "\t": '\\t',
        "\n": '\\n',
        "\f": '\\f',
        "\r": '\\r',
        '"' : '\\"',
        "\\": '\\\\'
    };

    var encodeString = function(s){
        if (/["\\\x00-\x1f]/.test(s)) {
            return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                var c = m[b];
                if(c){
                    return c;
                }
                c = b.charCodeAt();
                return "\\u00" +
                    Math.floor(c / 16).toString(16) +
                    (c % 16).toString(16);
            }) + '"';
        }
        return '"' + s + '"';
    };
    
    var encodeArray = function(o){
        var a = ["["], b, i, l = o.length, v;
            for (i = 0; i < l; i += 1) {
                v = o[i];
                switch (typeof v) {
                    case "undefined":
                    case "function":
                    case "unknown":
                        break;
                    default:
                        if (b) {
                            a.push(',');
                        }
                        a.push(v === null ? "null" :JSON.encode(v));
                        b = true;
                }
            }
            a.push("]");
            return a.join("");
    };
    
    var encodeDate = function(o){
        return '"' + o.getFullYear() + "-" +
                pad(o.getMonth() + 1) + "-" +
                pad(o.getDate()) + "T" +
                pad(o.getHours()) + ":" +
                pad(o.getMinutes()) + ":" +
                pad(o.getSeconds()) + '"';
    };
    
    /**
     * Encodes an Object, Array or other value
     * @param {Mixed} o The variable to encode
     * @return {String} The JSON string
     */
    this.encode = function(o){
        if(typeof o == "undefined" || o === null){
            return "null";
        }else if(o instanceof Array){
            return encodeArray(o);
        }else if(o instanceof Date){
            return encodeDate(o);
        }else if(typeof o == "string"){
            return encodeString(o);
        }else if(typeof o == "number"){
            return isFinite(o) ? String(o) : "null";
        }else if(typeof o == "boolean"){
            return String(o);
        }else {
            var a = ["{"], b, i, v;
            for (i in o) {
                if(!useHasOwn || o.hasOwnProperty(i)) {
                    v = o[i];
                    switch (typeof v) {
                    case "undefined":
                    case "function":
                    case "unknown":
                        break;
                    default:
                        if(b){
                            a.push(',');
                        }
                        a.push(this.encode(i), ":",
                                v === null ? "null" : this.encode(v));
                        b = true;
                    }
                }
            }
            a.push("}");
            return a.join("");
        }
    };
    
    /**
     * Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError.
     * @param {String} json The JSON string
     * @return {Object} The resulting object
     */
    this.decode = function(json){
        return eval("(" + json + ')');
    };
})();

/**
 * DATEX 
 */

function hideCalendar(){
	$('#calendar').empty();
}

var Garp = typeof Garp !='object' ? {} : Garp;
Garp.Datex = function(callback){

	var _base =  typeof calendarLink != 'undefined' ? calendarLink : '/programma';
	_base += '/date:';

	//var dayArr = ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'];
	//var monthArr = ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'];
	
	var getLastDayOfMonth = function(date){
		var year = date.getFullYear();
		var month = date.getMonth(date);
		var lastDay = 31;
		for (var t = 31; t >= 28; t--) {
			var d = new Date(Date.UTC(year, month, t));
			if (d.getUTCMonth() != month) {
				lastDay--;
			} else {
				break;
			}
		}
		return lastDay;
	};
	
	var getFirstDayOfMonth = function(date){
		return date.getDay();
	};
	
	var prettyPrintMonth = function(date){
		return monthArr[date.getMonth()];
	};
	
	var zeroPad = function(val,length){
		val = val + '';
		while(val.length!=length){
			val = '0'+val;
		}
		return val;
	};
		
	var mysqlTimeStamp=function(y,m,d){
		// be sure inputs are string:
		y=y+'';
		m=m+'';
		d=d+'';
		var str = y+zeroPad(m,2)+zeroPad(d,2)+'000000';
		return str;
	};
	
	var calendar = function(date){
		//var date = new Date('2011-02-01');
	
		var table = document.createElement('table');
		var thead = document.createElement('thead');
		var tbody = document.createElement('tbody');
		
		table.appendChild(thead);
		table.appendChild(tbody);
		table.id='datex';
		table.className='datex';
		
		var offset = 1;
		var mDate = new Date(date.getFullYear(), date.getMonth());
		//mDate = new Date(mDate.setDate(mDate.getDate()) + offset)
		var last = getLastDayOfMonth(mDate);
		var first = getFirstDayOfMonth(mDate) - offset;
		if(first < 0) first = (7 - first);
		
		var today = new Date();
		
		if (date.getMonth() == today.getMonth() && date.getFullYear() == today.getFullYear()) {
			var todayDay = today.getDate();
		}

		var max = last + first;
		if (max > 35) {
			max = 42
		} else if (max != 28) {
			max = 35;
		}
		
		var tr = document.createElement('tr');
		tbody.appendChild(tr);
		
		for (var c = 1, cc=1; c<= max; c++){
			var w = '';
			var s = false;
			if (c > first && c<= last+first) {
				w = cc;
				cc++;
				s = true;
			}
			
			var td = document.createElement('td');
			if (s) {
				var a = document.createElement('a');
				var txt = document.createTextNode(w);
				a.href = _base + (date.getFullYear() + '-' + zeroPad((date.getMonth() + 1), 2) + '-' + zeroPad(w, 2));
				a.className = 'ajaxHijack';
				a.appendChild(txt);
				td.appendChild(a);
			}
			tr.appendChild(td);
			
			if(s){
				td.className='active';
			} else {
				td.className='inactive';
			}
			if(todayDay && w == todayDay){
				td.className='today';
			}
			if(c%7 == 0){
				tr = document.createElement('tr');
				tbody.appendChild(tr);
			}
		}
		
		var header  = document.createElement('tr');
		header.className='header';
		
		$(header).click(function(target){
			
			var showMonthPicker = function(date){
				$('#calendar ol').remove();
				var months = $('<ol class="monthpicker"></ol>');
				var current = date.getMonth();
				for (var i in monthArr) {
					var selected = (i == current ? ' class="current" ' : '');
					var month = $('<li ' + selected + '><a href="#">' + monthArr[i] + '</a></li>');
					(function(i){
						$(month).click(function(){
							$(months).remove();
							date.setMonth(i);
							reload();
							return false;
						});
					})(i);
					$(months).append(month);
				}
				$('#calendar').append(months);
			};
	
			var showYearPicker = function(date){
				$('#calendar ol').remove();
				var years = $('<ol class="yearpicker"></ol>');
				var current = date.getFullYear();
				for(var y = current + 1; y >= 1973; y--){
					var selected = (y == current ? ' class="current" ' : '');
					var year = $('<li ' + selected + '><a href="#">' + y + '</a></li>');
					(function(y){
						$(year).click(function(){
							$(years).remove();
							date.setYear(y);
							reload();
							return false;
						});
					})(y);
					$(years).append(year);
				}
				$('#calendar').append(years);
			};
			
			if (!target) var target = window.event;
			if (target.target) target = target.target;
			else if (target.srcElement) target = target.srcElement;
			
			var action = target.className; //(target.originalTarget.className);
			switch(action){
				case 'year':
					showYearPicker(date);
					return false;
				break;
				case 'month':
					showMonthPicker(date);
					return false;
				break;
				//	callback(mysqlTimeStamp(date.getFullYear(),date.getMonth()+1,'0')); // month = 0 indexed
				//	return;
				case 'prev':
					date.setMonth(date.getMonth()-1);
				break;
				case 'next':
					date.setMonth(date.getMonth()+1);
				break;
			}
			reload();
			return false;
		});
		
		function reload(){
			var datex = new Garp.Datex(callback);
			//document.getElementById('calendar').replaceChild(datex.calendar(date),document.getElementById('datex'));
			hideCalendar();
			$('#calendar').append(datex.calendar(date));
			agendaHijack();
		}
		
		var vorige = document.createElement('th');
		var a = document.createElement('a');
		a.href = '#';
		var txt = document.createTextNode('\u00AB');
		vorige.className = 'prev';
		a.appendChild(txt);
		$(a).click(function(){
			date.setMonth(date.getMonth() - 1);
			reload();
			return false;
		});
		vorige.appendChild(a);
		vorige.colSpan = 2;

		var volgende = document.createElement('th');
		var a = document.createElement('a');
		a.href = '#';
		var txt = document.createTextNode('\u00BB');
		volgende.className = 'next';
		a.appendChild(txt);
		$(a).click(function(){
			date.setMonth(date.getMonth() + 1);
			reload();
			return false;
		});
		volgende.appendChild(a);
		volgende.colSpan=2;

		var maand = document.createElement('th');
		var a = document.createElement('a');
		a.setAttribute('class','month');
		a.setAttribute('className','month');
		maand.colSpan = 2;
		a.href = '#';
		var txt = document.createTextNode(prettyPrintMonth(date));
		a.appendChild(txt);
		maand.appendChild(a);
		
		var jaar = document.createElement('th');
		var a = document.createElement('a');
		a.setAttribute('class','year');
		a.setAttribute('className','year');
		a.href = '#';
		var txt = document.createTextNode(date.getFullYear());
		a.appendChild(txt);
		jaar.appendChild(a);
		

		header.appendChild(vorige);
		header.appendChild(maand);
		header.appendChild(jaar);
		header.appendChild(volgende);
		
		thead.appendChild(header);
		
		var days = document.createElement('tr');
		days.className = 'days';
		
		for (var s in dayArr) {
			var th = document.createElement('th');
			var txt = document.createTextNode(dayArr[s].substr(0,1));
			th.appendChild(txt);
			days.appendChild(th);
		}
		thead.appendChild(days);
		return table
	};
	
	return {
		getLastDayOfMonth: getLastDayOfMonth,	
		getFirstDayOfMonth: getFirstDayOfMonth,
		prettyPrintDate: prettyPrintMonth,
		calendar: calendar
	}
};

$('body').click(function(){
	hideCalendar();
});
$('#showCalendar').click(function(){
	if ($('#datex').length > 0) {
		hideCalendar();
	}
	var dx = new Garp.Datex(function(){
	});
	$('#calendar').append(dx.calendar(new Date()));
	agendaHijack();
	return false;
})

var t = null, currBusy;
$('#nav-info').mouseover(function() {
	if (t) {
		clearTimeout(t);
		t = null;
	}
	if (currBusy === this) {
		return true;
	}
	
	currBusy = this;
	
	var parent = $(this);
	$('div:not(#searchresult)', parent).fadeOut(1, function() {
		parent.addClass('hover');
		$('div', parent).fadeIn(300);
	});
	
}).mouseout(function() {
	var s = $(this);
	t = setTimeout(function() {
		$('div:not(#searchresult)', s).fadeOut(300,function(){
			s.removeClass('hover');
			currBusy = null;
		});
	}, 500);
});

var animateLoading = function(parent) {
	var l = jQuery('#loader')[0];
	if(!l) return;
	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++;
	}, 100);
};
var stopLoading = function() {
	var l = jQuery('#loader')[0];
	if (l && l.ai) {
		clearInterval(l.ai);
		l.ai = false;
	}
}

/**
 * Agenda paginator. Not a browsebox 'cause BB's not ready for inter-page-jumping
 */
function agendaHijack() {
	
	if(typeof calendarLink != 'undefined'){
		return true;
	}
	
	if (!$('#loader').length) {
		$('div.navbar.large').after('<div id="loader"/>');
	}
	$('#loader').hide();
	stopLoading();
	$('#agenda .navbar li a,.ajaxHijack').unbind().click(function(event) {
		$('#agenda .content').css({
			'overflow': 'hidden'
		});
		
		hideCalendar();
		$('#loader').fadeIn();
		animateLoading();			
		var self = $(this);
		$('#agenda .navbar li').addClass('disabled');
		var dir = $(this).parent().hasClass('next') ? 'next' : $(this).parent().hasClass('prev') ? 'prev' : 'date';
		
		$('#agenda').after('<div id="TEMP" style="visibility:hidden;position:absolute;top:0;left:0;z-index:-999"></div>');
		$('#TEMP').load(self.attr('href') + '/ajax:1', null, function(){
			var imgLoadedFlag = false;
			var imgs = $('#TEMP img').length;
			$('#TEMP img').each(function(){
				var s = $(this).attr('src');
				var i = new Image();
				
				$(this).attr('src','');
				function popNcheck(){
					imgs--;
					if (imgs === 0) {
						imgLoaded();
					}
				}
				$(i).bind('load',popNcheck).bind('error', popNcheck);
				$(this).attr('src',s); // Fix for Chrome!
				i.src = s;
				
			}); 	
			// in case there are no images (error result or no result)
			if(imgs === 0){
				imgLoaded();
			}
			
			function imgLoaded(){
				if(imgLoadedFlag) return;
				imgLoadedFlag = true;
				$('#agenda .navbar:eq(1)').replaceWith($('#TEMP .navbar')[1]);
				$('#agenda .navbar:eq(0)').replaceWith($('#TEMP .navbar')[0]);
				if ($('p.noknownconcerts').length > 0) {
					$('#agenda .content').replaceWith($('#TEMP .content'));
					makeAgendaBlockLinks();
				} else {
					var w = $('#TEMP ol').width();
					var h = $('#TEMP ol').height();
					$('#TEMP .content ol').clone().attr('id', 'content2').insertAfter($('#agenda .content ol'));
					
					$('#content2').css({
						'position': 'absolute',
						'left': (dir == 'next' ? w : dir == 'prev' ? 1 - w : 0),
						'top': dir == 'date' ? -h : 0
					});
					
					$('#agenda .content').width(w);
					$('#agenda .content').css({
						'position': 'relative'
					}).animate({
						'height': h,
						'width': w
					});
					
					$('#agenda .content ol:eq(0)').css({
						'position': 'absolute',
						'left': 0
					});
					$('#agenda .content ol:eq(0)').animate({
						'left': (dir == 'next' ? 1 - w : dir == 'prev' ? w : 0),
						'top': dir == 'date' ? h : 0
					});
				}
				$('#content2').animate({
					'left': 0,
					'top': 0
				}, {
					'complete': function(){
						$('#agenda .content ol:eq(0)').remove();
						$(this)[0].removeAttribute('id');
						$('#agenda .navbar li').removeClass('disabled');
						$('#loader').fadeOut();
						makeAgendaBlockLinks();
					}
				});
				agendaHijack();
				$('#TEMP').remove();
			}
		}
		);
		jQuery.history.load(self.attr('href'));
		return false;
	});
}
agendaHijack();

var sb = new Garp.SearchBox('#nav-searchbox', {
	afterComplete: function(parent) {
		parent.append('<i><b></b></i>');
	}
});

function historyLoad(hash){
	if (hash){ // && hash.indexOf(window.location.pathname) == -1) {
		$('#agenda').fadeOut();
		$('#agenda').load(hash + '/ajax:1', null, function(){
			$('#agenda').fadeIn();
			$('#loader').fadeOut();
			makeAgendaBlockLinks();
			agendaHijack();
		});
	}
}

/**
 * Make block links for "agenda" blocks
 */
function makeAgendaBlockLinks() {
	$('#agenda .content').css({
		'overflow': 'visible'
	});
	$('.programma li')
	.mouseover(function() {
		$(this).addClass('hover');
	})
	.mouseout(function() {
		$(this).removeClass('hover');
	})
	.click(function() {
		if ($('a.go', this).length) {
			window.location.href = $('a.go', this).attr('href');
		}
	});
}

makeAgendaBlockLinks();

if ($('#user_profile_form').length) {
	$('#user_profile_form .expandable legend').each(function() {
		$(this).html('<a href="#expand">'+$(this).text()+'</a>');
		$('a', this).click(function(e) {
			var expandable = $(this).parent().parent();
			if ($('div', expandable).css('display') == 'none') {
				$('div', expandable).show();
				$('#primary').height($('#primary').height() + expandable.height());
			} else {
				$('#primary').height($('#primary').height() - expandable.height());
				$('div', expandable).hide();
			}
			e.preventDefault();			
			return false;
		});
	});
	$('#user_profile_form .expandable div').hide();
}

/**
 * Ticket links & History onload
 */
$(document).ready(function(){
	$('.order-ticket').each(function() {
		if ($(this).hasClass('iframe')) {
			$(this).fancybox();
		}
	});
	
	var tooltip = $('#ticket-information p.tooltip');
	
	$('a.go.tickets').bind('mouseenter',function(){
		tooltip.fadeIn();
	}).bind('mouseout',function(){
		tooltip.fadeOut();
	});
	jQuery.history.init(historyLoad);
});

/**
 * Profile page trickery
 */

if ($('.profile-page').length) {
	// wait for window onload event, so all images are loaded first. This fixes a height issue.
	$(window).load(function() {
		var heights = [];
		var targets = [{
			'left': 0,
			'right': '-650px'
		}, {
			'left': '650px',
			'right': 0
		}];
		
		$('.profile-page .lego').each(function(i){
			$(this).css({
				position: 'absolute',
				top: 0,
				left: targets[i]['left']
			});
			heights[i] = this.offsetHeight;
		});
		$('.profile-page').css({
			position: 'relative',
			overflow: 'hidden',
			width: '650px',
			height: heights[0] + 'px',
			marginRight: '10px'
		});
		
		var switcheroo = function(){
			if (!this.goToTheRight) {
				$('.profile-page .lego').each(function(i){
					$(this).animate({
						left: targets[i]['right']
					}, 500, 'swing');
				});
				$('.profile-page').animate({
					height: heights[1] + 'px'
				}, 500, 'swing', function() {
					$('.profile input[type="text"]:first').focus();
				});
				this.goToTheRight = true;
			} else {
				$('.profile-page .lego').each(function(i){
					$(this).animate({
						left: targets[i]['left']
					}, 500, 'swing');
				});
				$('.profile-page').animate({
					height: heights[0] + 'px'
				}, 500, 'swing', function() {
					if ($('.favorites a:first').length) {
						$('.favorites a:first').focus();
					} else {
						$('#profile a').blur();
					}
				});
				this.goToTheRight = false;
			}
			return goToTheRight;
		};
		$('#profile a').click(function() {
			var editProfile = switcheroo();
			$(this).text(editProfile ? __('Toon favorieten') : __('Wijzig uw profiel'));			
			return false;
		});
		
		if (window.location.href.indexOf('?view=') !== -1) {
			var view = window.location.href.substr(window.location.href.indexOf('?view=')+6);
			if (view === 'profile') {
				$('#profile a').click();
			}
		}
	});
}

Garp.i18n.eng = {
	'Toon favorieten': 'Show favorites',
	'Wijzig uw profiel': 'Edit your profile',
	'Uw zoekopdracht is te kort...': 'Your search query is too short...',
	'%s is een verplicht veld.': '%s is a required field.',
	'Geen geldig bestandsformaat.': 'Invalid file type',
	'%s is geen geldig e-mailadres.': '%s is not a valid email address',
	'De wachtwoorden komen niet overeen.': 'The passwords are not equal.',
	'Als ### is ingevuld, is %s verplicht.': 'Because ### is filled out, %s is a required field.',
	'Als ### is aangevinkt, is %s verplicht.': 'Because ### is checked, %s is a required field.'
};