/**
 * Basis functionaliteit.
 */
var CB = 
{
	/**
	 * Dient bij het laden van de pagina aan te worden geroepen.
	 */
	run: function()
	{
		// wijziging in adres locatie
		$.address.change(function(event) {
			CB.onAddressChange(event);
		});
		
		// alles wordt dynamisch ingeladen vanaf nu
		$('#wrapper').empty();
		
		// bij een rechtstreekse aanroep
		if (document.location.pathname.length > 1) {
			$.address.value(document.location.pathname);
		}
		
		// bij esc -> venster sluiten
		$(document).keydown(function(e) {
			var which = e ? e.which : event.keyCode;
			if (which == 27) {
				CB.Window.Manager.closeActiveWindow();
			}
		});
	
		// supersize opties definieren
		$.fn.supersized.options = {  
			startwidth: 640,  
			startheight: 400,			//let goed op deze verhouding, dit blijft de verhouding
			vertical_center: 1,
			slideshow: 0
		};
		
		this.applyBehaviour();
	},
	
	/**
	 * Past de standaard javascript functionaliteit toe.
	 * 
	 * @param {Element} parent  Wanneer niet opgegeven wordt de body gebruikt
	 */
	applyBehaviour: function(parent)
	{
		if (parent) {
			if (!parent.jquery) {
				parent = $(parent);
			}
		} else {
			parent = $(document.body);
		}
		for (var selector in CB.behaviour) {
			parent.find(selector).each(function() {
				CB.behaviour[selector](this);
			});
		}
	},
	
	/**
	 * Wordt uitgevoerd wanneer er een andere locatie aan wordt gevraagd.
	 * 
	 * @param {Object} event
	 */
	onAddressChange: function(event)
	{
		if (event.value == '' || event.value == '/') {
			CB.Window.Manager.closeAllWindows();
			return;
		}
		
		pageTracker._trackPageview(event.value);
		
		var address = event.value + '?format=html';

		var module = event.pathNames.length ? event.pathNames[0] : null;
		switch (module) {
				
			case 'cb':
				CB.Window.Manager.create(address, address, CB.EditorWindow);
				break;
				
			case 'projecten':
				
				if (event.pathNames.length < 2 || event.pathNames[2] != 'details') {
					CB.Window.Manager.create(address, address, CB.ProjectsWindow);
				} else {
					CB.Window.Manager.create(address, address, CB.ProjectWindow);
				}
				break;
				
			case 'afbeeldingen':
				CB.Window.Manager.create(address, address, CB.DesktopimageWindow);
				break;
				
			case 'contact':
				CB.Window.Manager.create(address, address, CB.ContactWindow);
				break;
				
			case 'closeWindow':
				CB.Window.Manager.closeWindow(event.pathNames[1], true);
				break;
			
			default:
			case 'teksten':
				CB.Window.Manager.create(address, address, CB.ContentWindow);
				break;
		}
	},
	
	/**
	 * Toont of verbergt de tweets.
	 */
	showhideTwitter: function()
	{
		var tsidebar = $('#twitter_sidebar');
		
		tsidebar.stop();
		
		if (CB.twitterHidden) {
			if ($.browser.msie) {
				tsidebar.addClass('hidden');
			} else {
				tsidebar.animate({opacity: 1});
			}
			CB.twitterHidden = false;
		} else {
			if ($.browser.msie) {
				tsidebar.removeClass('hidden');
			} else {
				tsidebar.animate({opacity: 0});
			}
			CB.twitterHidden = true;
		}
		$.cookie('twitterHidden', CB.twitterHidden ? '1' : '0');
	},
	
	/**
	 * Een object met alle standaard javascript functionaliteit.
	 */
	behaviour: 
	{
		'#clock': function(element)
		{
			element = $(element);
			var previousMinutes;
			setInterval((function() {

				var now = new Date();
				var minutes = now.getMinutes().toString();
				
				if (previousMinutes && previousMinutes == minutes) {
					return;
				} else {
					previousMinutes = minutes;
				}
				
				if (minutes.length == 1) {
					minutes = '0' + minutes;
				}
				
				var day = now.getDay();
				var dayStr;
				switch (day) {
					case 0: dayStr = 'Zon'; break;
					case 1: dayStr = 'Maa'; break;
					case 2: dayStr = 'Din'; break;
					case 3: dayStr = 'Woe'; break;
					case 4: dayStr = 'Don'; break;
					case 5: dayStr = 'Vri'; break;
					case 6: dayStr = 'Zat'; break;
				}
				
				element.text(dayStr + ' ' + now.getHours() + ':' + minutes);
				
				return arguments.callee;
				
			})(), 1000);
		},
		
		'#closeAll': function(element)
		{
			element = $(element);
			
			element.click(function() {
				while (CB.Window.Manager.activeWindow) {
					CB.Window.Manager.closeActiveWindow(true);
				}
				return false;
			});
		},
		
		'a:not(.nofollow)': function(element) 
		{
			element = $(element);
			
			var href = element.attr('href');
			
			// absolute links die naar een lokale locatie verwijzen omzetten naar lokale links
			href = href.replace(new RegExp('^https?:\\/\\/' + window.location.host), '');
			
			if (/^mailto:/.test(href)) {
				return;
			}
			
			// externe links negeren
			if (/^https?:\/\//.test(href)) {
				return;
			}
			
			element.click(function() {
				$.address.value(href);
				return false;
			});

			// A IMG HOVERS
			// HOVER
			var hoverStateButtonsAnimating = false;
			element.find('img:not(.picture_big a img)').mouseover(function() {		
				if (!hoverStateButtonsAnimating) {
					$(this).fadeTo(100, 0.75); 		//SET
					hoverStateButtonsAnimating = true;
				}
			});	

			// UNHOVER
			element.find('a img').mouseleave(function() {			
				$(this).fadeTo(100, 1.00).queue(function() { 	//RESET
					hoverStateButtonsAnimating = false;
					$(this).dequeue(); 	
				});	
			}); 
		},
		
		'#supersize': function(element) 
		{
			$(element).supersized();
		},
		
		'#swapTwitter': function(element) 
		{

			if ($.cookie('twitterHidden') && $.cookie('twitterHidden') != '0') {
				$('#twitter_sidebar').css('opacity', 0);
				CB.twitterHidden = true;
			}
			
		    $(element).click(function() {
		    	CB.showhideTwitter();
		    	return false;
		    });
		}
	}
};

/**
 * De window class.
 */
CB.Window = Class.extend({
	
	currentUrl: null,
	
	initialize: function(options)
	{
		var self = this;
		
		this.options = $.extend({
			x: null,
			y: null,
			content: null
		}, options || {});
		
		this.dom = {
			container: $('<div />')
		};
		
		this.dom.container
			.addClass('window')
			.hide()
			.mousedown(function() {
				self.onContainerMouseDown();
			});
		
		if (this.options.x) {
			this.setX(this.options.x);
		}
		if (this.options.y) {
			this.setY(this.options.y);
		}
		if (this.options.content) {
			this.setContent(this.options.content);
		}
		
		$('body').append(this.dom.container);
	},

	/**
	 * Vernietigt het venster.
	 */
	destroy: function()
	{
		this.dom.container.fadeOut(250);
	},
	
	/**
	 * Zet de content van het venster.
	 * 
	 * @param {String} html
	 */
	setContent: function(html)
	{
		this.dom.container.html(html);
		this.onWindowContentLoaded();
	},

	/**
	 * Ze de x-locatie van het venster.
	 */
	setX: function(x)
	{
		this.dom.container.css('left', x);
	},

	/**
	 * Ze de y-locatie van het venster.
	 */
	setY: function(y)
	{
		this.dom.container.css('top', y);
	},

	/**
	 * Verkrijgt de z-index van het venster.
	 */
	getZIndex: function()
	{
		return this.dom.container.css('z-index');
	},

	/**
	 * Wordt uitgevoerd wanneer er op de venster is geklikt.
	 */
	onContainerMouseDown: function()
	{
		CB.Window.Manager.bringToFront(this);
	},
	
	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		var self = this;
		
		CB.applyBehaviour(this.dom.container);
	
		this.dom.container
			.find('a.btn_exit')
				.click(function() {
					self.onBtnCloseClick();
					return false;
				});

		this.dom.container.draggable({
			handle: this.dom.container.find('.move').css('cursor', 'move')
		});
		
		this.dom.container.show();
	},
	
	/**
	 * Wordt uitgevoerd waneer er op de sluitknop is gedrukt.
	 */
	onBtnCloseClick: function()
	{
		this.destroy();
	}
});

/**
 * Ajax window.
 */
CB.AjaxWindow = Class.extend(CB.Window, {

	initialize: function(url, options)
	{
		this.parent(options);

		this.loadUrl(url);
	},
	
	/**
	 * Laadt de content van het venster.
	 * 
	 * @param {String} url
	 */
	loadUrl: function(url)
	{
		var self = this;
		
		this.dom.container
			.load(url, function() {
				self.onWindowContentLoaded();
			});
	
		this.currentUrl = url;
	},

	
	/**
	 * Wordt uitgevoerd waneer er op de sluitknop is gedrukt.
	 */
	onBtnCloseClick: function()
	{
		$.address.value('/closeWindow/' + this.getZIndex());
	}
});

/**
 * De projecten window class.
 */
CB.ProjectsWindow = Class.extend(CB.AjaxWindow, {

	currentFilter: null,
	
	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		var self = this;

		this.parent();
		
		this.dom.tableWrap = this.dom.container.find('.container .inner');
		this.dom.filter = this.dom.container.find('input.input_search');
		
		this.dom.filter
			.focus()
			.bind('keyup change', function() {
				var value = $(this).val();
				if (!this.previousFilter && !value) {
					return;
				}
				if (this.previousFilter != value) {
					self.onFilterValueChange(value);
					this.previousFilter = value;
				}
			});
		
		this.onTableLoaded();
	},
	
	/**
	 * Wordt uitgevoerd wanneer de tabel geladen is.
	 */
	onTableLoaded: function()
	{
		var self = this;

		this.dom.container
			.find('a.customer')
				.click(function() {
					var customer = $(this).text();
					self.dom.filter.val(customer).focus();
					self.filter(customer);
					return false;
				})
			.end()
			.find('tbody tr:odd')
				.addClass('odd')
			.end()
			.find('tbody tr:even')
				.addClass('even')
			.end();
//			.find('a')
//				.click(function() {
//					//alert(':)');
////					$.address.value($(this).attr('href'));
////					return false;
//				});
	},
	
	/**
	 * Wordt uitgevoerd wanneer de waarde van het filter input element wijzigt.
	 * 
	 * @param {String} value
	 */
	onFilterValueChange: function(value)
	{
		var self = this;
		
		clearTimeout(this.filterTimeout);
		this.filterTimeout = setTimeout(function() {
			self.filter(value);
		}, 500);
	},
	
	/**
	 * Past een filter toe.
	 * 
	 * @param {String} value
	 */
	filter: function(value)
	{
		if (this.currentFilter == value) {
			return;
		}
		
		this.currentFilter = value;
		this.reloadTable();
	},
	
	/**
	 * Herlaadt de table.
	 */
	reloadTable: function()
	{
		var self = this;
		
		var url = this.currentUrl + '&tableonly=1&filter=' + escape(this.currentFilter);
		
		this.dom.tableWrap.load(url, function() {
			self.onTableLoaded();
			CB.applyBehaviour(this);
		});
	}
});

/**
 * De contact window class.
 */
CB.ContactWindow = Class.extend(CB.AjaxWindow, {

	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		this.parent();
		
		var self = this;
		
		this.dom.form = this.dom.container.find('form');
		this.dom.formElements = this.dom.form.find('input[type=text], textarea');
		
		this.dom.form.find('input.defaultText').defaultText();
		
		this.dom.container.find('a.submit').click(function() {
			self.dom.form.submit();
			return false;
		});
		this.dom.container.find('[name=onderwerp]').focus();
		this.dom.form.ajaxForm({
			url: '/contact/index/verstuur/format/json',
			dataType: 'json',
			beforeSubmit: function() {
			
				self.dom.formElements
					.addClass('disabled')
					.attr('disabled', 'disabled');
			},
			success: function(response) {
				
				self.dom.formElements
					.removeClass('disabled')
					.attr('disabled', null);
				
				self.onFormSubmitted(response);
			}
		});
	},
	
	/**
	 * Wordt uitgevoerd als er een response terug is gekomen vanaf de server.
	 * 
	 * @param {Object} response
	 */
	onFormSubmitted: function(response)
	{
		CB.Window.Manager.dialog(response.response);
		
		if (response.valid) {
			CB.Window.Manager.closeWindow(this);
		}
	}
});

/**
 * De content window class.
 */
CB.ContentWindow = Class.extend(CB.AjaxWindow, {

	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		this.parent();
		
		var self = this;
		
		if (this.dom.container.find('div.image li').length > 1) {
			var imageCycler = this.dom.container.find('div.image ul');
			this.dom.imageCycler = imageCycler;
			this.initializeImageCycler(this.dom.imageCycler, {
				timeout: 0,
				prev: this.dom.container.find('.btn_left'),
				next: this.dom.container.find('.btn_right')
			});
		}
	},
	
	/**
	 * Initialiseert een image cycler.
	 */
	initializeImageCycler: function(element, options)
	{
		element.cycle($.extend({
			fx: 'scrollHorz'
		}, options || {}));
	}
});

/**
 * De project window class.
 */
CB.ProjectWindow = Class.extend(CB.ContentWindow, {

});

/**
 * De editor window class.
 */
CB.EditorWindow = Class.extend(CB.ContentWindow, {
	
	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		var self = this;
		
		this.parent();
		
		this.dom.textarea = this.dom.container.find('textarea');
		this.dom.textarea
			.focus()
			.autoResize()
			.change(function() {
				self.onContentChanged($(this));
			})
			.change();
	},
	
	/**
	 * Wordt uitgevoerd wanneer de content van de editor aan is gepast.
	 * 
	 * @param {Element} editor
	 */
	onContentChanged: function(editor)
	{
		this.saveContent();
	},
	
	/**
	 * Slaat de content op van de editor.
	 */
	saveContent: function()
	{
		$.cookie('editorContent', this.dom.textarea.val(), {expires: 100, path: '/'});
	},
	
	/**
	 * Vernietigt het venster.
	 */
	destroy: function()
	{
		this.saveContent();
		this.parent();
	}
});

/**
 * De achtergrond afbeelding window class.
 */
CB.DesktopimageWindow = Class.extend(CB.ContentWindow, {

	/**
	 * Wordt uitgevoerd wanneer de content van het venster in is geladen.
	 */
	onWindowContentLoaded: function()
	{
		var self = this;
		
		this.parent();
		
		this.dom.container.find('input[name=dekstopImage]').click(function() {
			self.onImageChanged($(this));
		});
	},
	
	/**
	 * Wordt uitgevoerd wanneer er een andere achtergrond afbeelding wordt geselecteerd.
	 * 
	 * @param {Element} imageInput
	 */
	onImageChanged: function(imageInput)
	{
		var imgData = imageInput.val().split('|');
		
		$('#supersize img').attr('src', imgData[1]);
		$('#supersize').resizenow();
		$.cookie('desktopImage', imgData[0], {expires: 100, path: '/'});
	}
});

/**
 * De window handler.
 */
CB.Window.Manager = 
{
	x: 40,
	y: 40,
	zIndex: 60,
	windows: {},
	currentDialog: null,
	activeWindow: null,
	
	/**
	 * Toont een dialogvenster.
	 */
	dialog: function(content)
	{
		var dialog = new CB.Window({
			content: content
		});
		
		var contentContainer = dialog.dom.container.find('.container');
		
		dialog.setX(($(window).width() / 2) - (contentContainer.width() / 2));
		dialog.setY(($(window).height() / 2) - (contentContainer.height() / 2));
		
		this.bringToFront(dialog);
		
		this.currentDialog = dialog;
	},
	
	/**
	 * Maakt een nieuw venster aan.
	 */
	create: function(url, windowId, windowClass) 
	{
		if (!this.windows[windowId]) {
			
			if (!windowClass) {
				windowClass = CB.AjaxWindow;
			}
			
			this.x = (this.x + 30) % 150;
			this.y = (this.y + 30) % 150;
			
			this.windows[windowId] = new windowClass(url, {
				x: this.x,
				y: this.y
			});
			this.windows[windowId].windowId = windowId;
			
		} else {
			if (this.windows[windowId].currentUrl != url) {
				this.windows[windowId].loadUrl(url);
			}
		}
		this.bringToFront(this.windows[windowId]);
	},

	/**
	 * Sluit alle open vensters.
	 */
	closeAllWindows: function()
	{
		for (var windowId in this.windows) {
			this.windows[windowId].destroy();
			delete this.windows[windowId];
		}
	},
	
	/**
	 * Sluit de opgegeven window.
	 */
	closeWindow: function(window, ignoreHistory)
	{
		if (!ignoreHistory) {
			$.address.value('/closeWindow/' + window.getZIndex());
		} else {
			
			if (typeof window != 'object') {
				for (var windowId in this.windows) {
					if (window == this.windows[windowId].getZIndex()) {
						window = this.windows[windowId];
						break;
					}
				}
			}
			
			if (typeof window != 'object') {
				return;
			}
			
			window.destroy();
			delete this.windows[window.windowId];
			
			// als we het actieve venster hebben gesloten
			if (window == this.activeWindow) {
				
				// door alle vensters lopen om de hierna hoogste op te zoeken
				var nextWindow;
				for (var windowId in this.windows) {
					if (!nextWindow || this.windows[windowId].getZIndex() > nextWindow.getZIndex()) {
						nextWindow = this.windows[windowId];
					}
				}
				this.activeWindow = nextWindow;
			}
		}
	},
	
	/**
	 * Sluit het huidige venster.
	 */
	closeActiveWindow: function(ignoreHistory)
	{
		if (this.activeWindow) {
			this.closeWindow(this.activeWindow, ignoreHistory);
		}
	},
	
	/**
	 * Brengt het opgegeven venster naar voren.
	 */
	bringToFront: function(w)
	{
		if (typeof w != 'object') {
			w = this.windows[w];
		}
		if (w && this.activeWindow != w) {
			w.dom.container.css('z-index', this.zIndex++);
			this.activeWindow = w;
			
			if (this.currentDialog && w != this.currentDialog) {
				this.currentDialog.destroy();
				this.currentDialog = null;
			}
		}
	}	
};
