/**
 *	Dialog Controller
 *	---------------------------------------------
 *	(c) 2007 Lost Boys - http://www.lostboys.nl
 *	Requires:
 *		Utils.js
 *		EventListener.js
 *		ElementListener.js
 */

var DialogProperties = {
	ELEMENT_TITLE:		'h3',
	ELEMENT_BODY:		'p',

	DIALOG_OFFSET:		5,
	DIALOG_ORIENTATION:	'horizontal',
	DIALOG_MODAL:		false,

	OVERLAY_ACTIVE:		false,
	OVERLAY_ID:			'overlay'
}

/**
 *	DialogController
 *	--------------------------
 */

function DialogController() {
	this.dialogTypes = {};
	this.dialogs = {};

	if(/msie 6/i.test(navigator.userAgent)){
		this.createIEFrame();
	}

	EventListener.addEvent(document, 'click', this.scope(this.tryClose));
	LinkListener.register(/(^|\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;
			default:
				var element = document.getElementById('dialog-'+type);
				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) {
		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);
		dialog.toggle(true);
		this.toggleIEFrame(true, dialog.container);
		return dialog;
	},

	tryClose:function(e) {
		if(this.currentDialog) {
			var node = EventListener.getTarget(e);
			if(this.currentDialog.tryClose(node)) {
				this.toggleIEFrame(false);
			}
		}
	},

	toggleOverlay:function(toggle) {
		Overlay.toggle(toggle);
	},

	createIEFrame:function(){
		this.ieFrame = document.createElement("iframe");
		this.ieFrame.src = '../images/iata-logo.gif';
		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.src = '../images/iata-logo.gif';
				frm.left = Utils.calculateLeft(dialog, parent) + "px";
				frm.top = Utils.calculateTop(dialog, 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 = DialogProperties.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
 *	--------------------------
 */

function Dialog(element, controller, type) {
	this.container = element;
	this.controller = controller;
	this.type = type;

	this.modal = DialogProperties.DIALOG_MODAL;
	this.overlay = DialogProperties.OVERLAY_ACTIVE;
	this.orientation = DialogProperties.DIALOG_ORIENTATION;
	this.offset = DialogProperties.DIALOG_OFFSET;

	this.title = element.getElementsByTagName(DialogProperties.ELEMENT_TITLE)[0];
	this.body = element.getElementsByTagName(DialogProperties.ELEMENT_BODY)[0];
	this.vertical = /(^|\s)vertical(\s|$)/i;
	this.left = /(^|\s)left(\s|$)/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 = Utils.calculateLeft(origin);
		var y = Utils.calculateTop(origin);
		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 left = this.left.test(this.orientation);
			var offsetH = vertical? 0 : DialogProperties.DIALOG_OFFSET;
			var offsetV = vertical? DialogProperties.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) || left) 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]);
	},

	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();


/**
 *	custom: TooltipDialog
 *	--------------------------
 *	Origin nodevalue becomes title, 
 *	origin title attribute becomes body.
 */

TooltipDialog = dialogController.register('tooltip', Class.extend(
	Dialog,
	function() {
		this.offset = 5;
	},{
	activate:function() {
		var title = this.origin.innerHTML.replace(/<[^>]+>/g, '');
		var body = this.origin.getAttribute("title");
		this.write(title, body);
	}
}));


/**
 *	custom: LoginDialog
 *	--------------------------
 */

LoginDialog = dialogController.register('login', Class.extend(
	Dialog,
	function() {
		this.orientation = 'vertical left';
	},{

	confirm:function(toggle) {
		var form = this.container.getElementsByTagName("form")[0];
		var valid = true;
		for(var el,i=0; i<form.elements.length; i++) {
			el = form.elements[i];
			if(/text/i.test(el.type)) {
				valid &= el.value? true : false;
				el.style.border = el.value? '' : '1px solid red';
			}
		}

		if(valid) {
			form.submit();
		} else {
			dialogController.displayDialog(this.origin, 'dialog-login');
		}
	},

	position:function() {
		var x = Utils.calculateLeft(this.origin) - this.container.offsetWidth + this.origin.offsetWidth + 14;
		var y = Utils.calculateTop(this.origin) - 6;
		Dialog.prototype.position.apply(this, [x, y]);
	}
}));


/**
 *	custom: calendar dialog
 *	--------------------------
 */

CalendarDialog = dialogController.register('calendar', Class.extend(
	Dialog, 
	function(){
		if(window.Calendar) {
			this.calendar = new Calendar(this.container);
			this.calendar.setAction(this.scope(this.updateCalendar));
		}
	}, {

	activate:function(toggle) {
		if(toggle) {
			this.write(this.origin.getAttribute('title'), null);
			var rel = /(past|future)/i.exec(this.origin.getAttribute('rel'));
			var mode = rel? rel[1] : null;
			
			var selects = this.origin.parentNode.getElementsByTagName("select");
			this.calendar.copySelects(selects[2], selects[1]);
			var date = new Date(
				parseInt(selects[2].value, 10),
				parseInt(selects[1].value, 10)-1, 
				parseInt(selects[0].value, 10)
			);

			this.calendar.setMode(mode);
			this.calendar.setDate(date);
		}
	},
	
	updateCalendar:function(date) {
        function selectValue(select, value) {
        	for (var i=0; i<select.options.length; i++) {
				if(select.options[i].value == value) {
					select.selectedIndex = i;
					break;
				}
			}
		}
		
		var selects = this.origin.parentNode.getElementsByTagName("select");
        var s =  selects[0].id;
        var array = s.split('_');
        
		selectValue(selects[0], date.getDate());
		selectValue(selects[1], date.getMonth() + 1);
		selectValue(selects[2], date.getFullYear());
		
		try {
			// for strange selection bug in firefox
			var call = this.scope(function() { this.display(false); });
			setTimeout(call, 100);	
		} catch (e) {
			this.display(false);
		}
        changeDateNew(array[0]);
	}
}));