/**
 *	Dialog Controller for jQuery
 *	---------------------------------------------
 *	(c) 2008 Lost Boys - http://www.lostboys.nl
 *	Requires:
 *		jquery.js
 *		jquery.lb.utils.js
 */

(function($){

/**
 *	Settings
 *	--------------------------
 */

var ELEMENT_TITLE = 'h2',
	ELEMENT_BODY = 'p',

	DIALOG_OFFSET = 5,
	DIALOG_ORIENTATION = 'vertical',
	DIALOG_MODAL = false,

	OVERLAY_ACTIVE = true,
	OVERLAY_ID = 'overlay';

/**
 *	DialogController
 *	--------------------------
 */

function DialogController() {
	this.dialogTypes = {};
	this.dialogs = {};

	if(/msie 6/i.test(navigator.userAgent)){
		this.createIEFrame();
	}

	$(document).click(this.scope(this.tryClose));
	$(document).addRelation(/(^|\s)dialog-/i, this.displayDialog, this);
}

DialogController.prototype = {
	register:function(type, constructor) {
		this.dialogTypes[type] = constructor;
		return constructor;
	},

	displayDialog:function(link, dialogRel) {
	
		if(this.currentDialog) {
			this.currentDialog.display(false);
			this.toggleOverlay(false);
			this.toggleIEFrame(false);
		}
		var type = /dialog-([a-z0-9_-]+)/i.exec(dialogRel)[1];
		switch (type) {
			case 'close': break;
			case 'confirm': this.currentDialog.confirm(true); return true; break;
			case 'cancel': this.currentDialog.confirm(false); return true; break;
			case 'http_large' :
				var element = document.getElementById('dialog-http');
				return this.createDialog(element, link, 'http', true);
			break;
			default:
				//quick fix script, rel can have multiple values and this script does not handle that. We use only the additional nofollow
				//can be more generic.
				if (dialogRel.indexOf('nofollow') !=-1) {
					dialogRel = 'dialog-http';
					
				}				
				var element = document.getElementById(dialogRel);
				return this.createDialog(element, link, type);
			break;
		}
		this.currentDialog = null;
		return true;
	},

	display:function(type, origin, title, body, action) {
		this.displayDialog(origin || document.body, 'dialog-' + type);
		this.currentDialog.write(title, body);
		this.setAction(action);
	},

	createDialog:function(element, link, type) {
		createDialog(element, link, type, false);
	},
	createDialog:function(element, link, type, fullscreen) {
		if(!element) return;
		var dialog = this.dialogs[type];
		if(!dialog) {
			var DialogClass = this.dialogTypes[type] || Dialog;
			dialog = new DialogClass(element, this, type);
		}
		this.currentDialog = this.dialogs[type] = dialog;
		dialog.setOrigin(link);
		if(fullscreen) {
			dialog.fullScreen();
		}
		dialog.toggle(true);
		this.toggleIEFrame(true, dialog.container);
		return dialog;
	},

	tryClose:function(e) {
		if(this.currentDialog) {
			var node = e.target;
			if(this.currentDialog.tryClose(node)) {
				this.toggleIEFrame(false);
			}
		}
	},

	toggleOverlay:function(toggle) {
		Overlay.toggle(toggle);
	},

	createIEFrame:function(){
		this.ieFrame = document.createElement("iframe");
		this.ieFrame.src = "javascript:false;";
		this.ieFrame.className = "cover-frame";
		this.ieFrame.frameBorder = 0;
	},

	toggleIEFrame:function(toggle, dialog) {
		if(this.ieFrame){
			var frm = this.ieFrame.style;
			if(toggle) {
				var parent = dialog.parentNode;
				parent.appendChild(this.ieFrame);
				frm.left = $(dialog).calculateLeft(parent) + "px";
				frm.top = $(dialog).calculateTop(parent) + "px";
				frm.width = dialog.offsetWidth + "px";
				frm.height = dialog.offsetHeight + "px";
				frm.display = "block";
			} else {
				frm.display = "none";
			}
		}
	},

	scope:function(method) {
		var scope = this;
		return function() {
			return method.apply(scope, arguments);
		}
	}
}

/*
 *	Overlay
 *	-------------------------
 */

var Overlay = {
	init:function() {
		var overlay = document.createElement('div');
		overlay.id = OVERLAY_ID;
		this.container = document.body.appendChild(overlay);
	},

	setHeight:function() {
		var height = document.documentElement.scrollHeight || document.body.scrollHeight;
		var winHeight = window.innerHeight || document.documentElement.clientHeight;
		if(height < winHeight) {
			height = winHeight;
		}
		this.container.style.height = height + 'px';
	},

	toggle:function(toggle) {
		if(!this.container) this.init();
		this.setHeight();
		this.container.style.display = toggle? 'block' : 'none';
	}
}

/**
 *	Default Dialog
 *	--------------------------
 */

$.Dialog = function(element, controller, type) {
	this.container = element;
	this.controller = controller;
	this.type = type;

	this.modal = DIALOG_MODAL;
	this.overlay = OVERLAY_ACTIVE;
	this.orientation = DIALOG_ORIENTATION;
	this.offset = DIALOG_OFFSET;

	this.title = element.getElementsByTagName(ELEMENT_TITLE)[0];
	this.body = element.getElementsByTagName(ELEMENT_BODY)[0];
	this.vertical = /^vertical$/i;
}

$.Dialog.prototype = {
	setAction:function(action) { this.action = action; },
	setOrigin:function(origin) { this.origin = origin; },
	action:function() {},
	activate:function() {},

	toggle:function(toggle) {
		if(this.overlay || this.modal)
			this.controller.toggleOverlay(toggle);
		this.activate(toggle);
		this.display(toggle);
	},

	display:function(toggle) {
		var dialog = this.container;
		var origin = this.origin;
		var x = $(origin).calculateLeft();
		var y = $(origin).calculateTop();
		var css = dialog.style;

		css.display = toggle? 'block':'none';

		if(origin != document.body) {
			var w = dialog.offsetWidth;
			var h = dialog.offsetHeight;
			var ow = origin.offsetWidth;
			var oh = origin.offsetHeight;

			var vertical = this.vertical.test(this.orientation);
			var offsetH = vertical? 0 : DIALOG_OFFSET;
			var offsetV = vertical? DIALOG_OFFSET : 0;

			var availWidth = window.innerWidth || document.documentElement.clientWidth;
			var availHeight = window.innerHeight || document.documentElement.clientHeight;
			var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
			var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

			var tx = (vertical? x : (x + ow)) + offsetH;
			var ty = (vertical? (y + oh) : y) + offsetV;
			if((tx + w) > (availWidth + scrollLeft)) tx = (vertical? (x + ow - w) : (x - w)) - offsetH;
			if((ty + h) > (availHeight + scrollTop)) ty = (vertical? (y - h) : (y + oh -h)) - offsetV;

			this.position(tx, ty);
		} else {
			this.center();
		}

		dialog.style.visibility = toggle? 'visible':'hidden';
	},

	position:function(x, y) {
		var css = this.container.style;
		css.left = x + 'px';
		css.top = y +'px';
	},

	center:function() {
		var x = ((window.innerWidth || document.documentElement.clientWidth) - this.container.offsetWidth)/2;
		var y = (window.pageYOffset || document.documentElement.scrollTop) + ((window.innerHeight || document.documentElement.clientHeight) - this.container.offsetHeight)/2;
		$.Dialog.prototype.position.apply(this, [x, y]);
	},
	fullScreen: function() {
		var css = this.container.style;
		css.width = 'auto';
		css.height = 'auto';
		css.left = '20px';
		css.top = '20px';
		//css.right = '20px';
		//css.bottom = '20px';
	},

	tryClose:function(node) {
		if(this.modal) return;
		while(node) {
			if(node == this.container || node == this.origin) return false;
			node = node.parentNode;
		}

		this.toggle(false);
		return true;
	},

	write:function(title, body) {
		if(title) this.title.innerHTML = title;
		if(body) this.body.innerHTML = body;
	},

	confirm:function(confirm) {
		if(this.action) this.action(confirm);
	},

	scope:function(method) {
		var scope = this;
		return function() {
			return method.apply(scope, arguments);
		}
	}
}

/**
 *	Initialise
 *	--------------------------
 */

var dialogController = new DialogController();

$.extend($, {
	displayDialog:function(type) {
		return dialogController.displayDialog(document.body, type);
	},

	registerDialog:function(type, dialog) {
		return dialogController.register(type, dialog);
	}
});

$.extend($.fn, {
	displayDialog:function(type){
		dialogController.displayDialog(this[0], type);
		return this;
	}
});

/**
 *	End and init
 *	--------------------------
 */

})(jQuery);

/**
 * custom
 */

HttpDialog = $.registerDialog('http', Class.extend(
	$.Dialog,
	function() {
	},{

	toggle:function(toggle, uri) {
		if (toggle) {
			var that = this;
			var href = uri || this.origin.href;
			$("#dialog_container").load(
				href + " #product_options", // complete document; remove id if fragment is returned
				function (responseText) {
					$("#dialog_container").html(responseText) ;
					$.Dialog.prototype.toggle.call(that, true);
					BLOKKER.button.replace($('#dialog-http input[type=submit]'));
					BLOKKER.sifr.write({ selector : ".dialog .sifr"});
					var config = $("#dialog-http form"), base = BLOKKER.order.form;
					if (document.getElementById('order_frame')) {
						config.bind(
							'submit',
							function () {
								var configData = BLOKKER.form.data(config.get(0)).object;
								var baseData = BLOKKER.form.data(base).object;
								for (var i in configData) {
									if (configData.hasOwnProperty(i)) {
										if (base.elements[i]) {
											base.elements[i].value = configData[i];
										} else {
											$(base).append(
												$('<input type="hidden" name="' + i + '" value="' + configData[i] + '"></input>)')
											);
										}
									}
								}
								$.Dialog.prototype.toggle.call(that, false);
								BLOKKER.order.update();
								return false;
							}
						);
					}
					
					/*
					$("div.dialog form").bind(
						'submit',
						function (e) {
							// this should be generic
							var data = {
								size   : $('#PD_size').val(),
								color  : $('#PD_number').val(),
								number : $('#PD_number').val(),
								add    : $('#add').val()
							};
							$.Dialog.prototype.toggle.call(that, false);
							if (document.getElementById('order_frame')) {
								BLOKKER.order.update(data);
							} else {
								var str = '';
								for (i in data) {
									if (data.hasOwnProperty(i)) {
										str += i + '=' + data[i] + '&';
									}
								}
								data = str.substr(0, (str.length - 1));
								BLOKKER.basket.update(data);
								BLOKKER.basket.show();
								window.setTimeout(
									BLOKKER.basket.hide,
									1500
								);
							}
							return false;
						}
					);
					*/
				}
			);
		} else {
			$.Dialog.prototype.toggle.call(this, false);
		}
	},
	position:function() {
		this.center();
	}

}));


