/**
 * pDialog
 * 
 * This is a wrapper plugin for jQuery UI dialog
 * p is for 'peppered'
 * 
 * Requires:
 * 		jQuery (1.3.2)
 * 		jQuery UI dialog (developed on 1.8) (derived from 1.7.2, may possibly still work on that)
 * 		$.log function in global namespace
 *		$.url (for when doing parentRefresh (special cases only))
 *		swfobject (for type == 'swf')
 * 
 * @author AK | Peppered
 * @version 1.3.0
 * 
 */
;(function($) {

var dialogs = {};	// object to keep track of created dialogs

$.pDialog = function(options){
	if ($.isPlainObject(options)) {
		// init (new) pDialog
	}
	else if (typeof options == 'string') {		
		if (arguments[1] == 'option') {
			// option setter
			// ... @todo
		}
		return;
	}
	
	var dialogId = null;
	
	/*
	 * Options
	 * All default UI Dialog options (including option events) will be passed through
	 * The same defaults are valid as the default dialog (http://jqueryui.com/demos/dialog/#options),
	 * with the following exceptions:
	 * 	modal: true		(pdialog will mostly be used this way)
	 *  autoOpen: false	(though pdialog opens itself after invoking, stuff like centering happens before the actual dialog open)
	 *  bgiframe: true
	 * 
	 */
	
	// specific pDialog options
	var pDialogOptions = {
		debug: true,
		
		id: '',								// each pdialog should have an unique id (used to respawn the dialog after a close for instance) 
											//   a HTML id attribute is assigned to the content <div/> as: {idPrefix}{id}
											// 
		type: null,							// dialog type, must be specified:
											//   message | confirmation | iframe | tabs | page | swf
											// 	
		extraClass: null,					// extra class to assign to dialog widget (format: ui-pdialog-TYPE-dialogClass)
											//   currently only implemented for type='iframe'
		idPrefix: 'uiDialog-',				// id-prefix
		autoResize: true,					// @todo (autoresize when window is resized)
		tabs: null,							// object defining the tabs (when type == 'tabs')
		useTabsAsHeader: false,				// instead of using default header displaying 'title', use the tabs as header (when type == 'tabs')	
		closeOnOutsideclick: false,			// not yet implemented, only works if modal == true
		bringInFocusOnOutsideclick: true,	// centers the dialog, and highlights it. Only works if modal == true
		keepInDom: true,					// if true, a dialog close just hides the dialog, keeping it in the DOM (default behaviour)
											//   if false, the whole HTML structure will be removed, forcing a new generation of the dialog
											// 
		iframe_header: null,				// snippet of HTML to put before the iframe (type==iframe)
		iframe_footer: null,				// snippet of HTML to put after the iframe (type==iframe)
		iframe_header: null					// snippet of HTML to use as header (instead of title) (type==iframe)
	};
	
	// extend options
	options = $.extend({		
		modal: true,
		autoOpen: false,
		bgiframe: true						// deprecated?
	}, pDialogOptions, options);
	
	// strip options from custom pdialog options, so we keep an object with purely UI dialog options
	var uiDialogOptions = $.extend({}, options);	// make a copy	
	for (var key in pDialogOptions) {
		delete uiDialogOptions[key];
	};
	
	var buttonExtras = {}; //@todo (be able to define different types/roles of buttons)
	
	return spawnDialog(options.type);
	
	
	/**
	 * spawnDialog()
	 * 
	 */
	function spawnDialog(type) {
		
		var $uiWidget = {};		
		dialogId = options.idPrefix + options.id;
		
		/**
		 * addWidgetClasses();
		 */
		function addWidgetClasses(){
			$uiWidget.addClass('ui-pdialog ui-pdialog-' + options.type + (options.extraClass != null ? ' ui-pdialog-'+options.type+'-'+options.extraClass : ''));
		};
				
		
		// Once, generate base HTML structure and append to body:
				
		if (!dialogs[options.id]) {
							
			// buttons
			uiDialogOptions.buttons = generateButtons();
			
			switch (options.type) {
				case 'tabs':
					createDialogWithTabs(dialogId);
					dialogs[options.id] = true;			// remember it has been created	
					break;
					
				case 'confirmation':
					var $dialog = $('<div id="' + dialogId + '">' + options.content + '</div>');
					$('body').append($dialog.hide());					
					$dialog.dialog(uiDialogOptions);	// create the dialog
					
					$uiWidget = $dialog.parent();
					addWidgetClasses();										
					
					$uiWidget.find('button').addClass('button'); /*@todo/wip*/
					
					dialogs[options.id] = true;
					break;
					
				case 'message':
					var $dialog = $('<div id="' + dialogId + '">' + options.content + '</div>');
					$('body').append($dialog.hide());
					$dialog.dialog(uiDialogOptions);
					
					$uiWidget = $dialog.parent();
					addWidgetClasses();
					
					dialogs[options.id] = true;
					break;
					
				case 'page':
					var $dialog = $('<div id="' + dialogId + '"></div>');
					$('body').append($dialog.hide().addClass('ui-dialog-content-loading'));
					
					$dialog.dialog(uiDialogOptions);

					$dialog.load( options.load, null, function(responseText, textStatus, XMLHttpRequest){  // gets cached in IE
						debug(XMLHttpRequest);
						$theDialogContent.removeClass('ui-dialog-content-loading');
					});
					
					$uiWidget = $dialog.parent();
					addWidgetClasses();
									
					dialogs[options.id] = true;
					break;
					
				case 'swf':
					if (typeof swfobject == 'undefined') {
						return false;
					}
					
					var $dialog = $('<div id="' + dialogId + '"><div id="swfPlaceholder">REPLACE</div></div>');
									
					$('body').append($dialog.hide());
					
					var flashvars = {};
		            var params = {
						wmode: 'opaque',
						allowFullScreen: 'true',
						allowscriptaccess: 'always'
					};
		            var attributes = {};
					var callback = function(){};
					//var callback = function(){ $('#uiDialog-youtube').removeClass('ui-dialog-content-loading') };
					
					swfobject.embedSWF(options.load, 'swfPlaceholder', '476', '300', '9.0.0', false, flashvars, params, attributes, callback);
										
					$dialog.dialog(uiDialogOptions);
					
					$uiWidget = $dialog.parent();
					addWidgetClasses();
										
					dialogs[options.id] = true;					
					break;
					
				case 'iframe':
					var $dialog = $('<div id="' + dialogId + '">' + options.iframe_header + '<iframe scrolling="auto" frameborder="0" src="' + options.load + '" />' + options.iframe_footer + '</div>');
					$('body').append($dialog.hide());
					$dialog.dialog(uiDialogOptions);
					
					$uiWidget = $dialog.parent();
					$uiWidget.addClass('ui-pdialog ui-pdialog-iframe' + (options.extraClass != null ? ' ui-pdialog-iframe-'+options.extraClass : ''));
					
					$uiWidget.find('.ui-dialog-titlebar-close').addClass('button'); // custom
								
					// custom title/header
					if (options.custom_header !== null) {
						$dialog.dialog('option', 'draggable', false);
						var $box = $('<div class="customHeader dragHandle"/>').append(options.custom_header);
						$uiWidget.find('.ui-dialog-titlebar .ui-dialog-title').replaceWith($box);
						$uiWidget
							.draggable({ handle: '.ui-dialog-titlebar .dragHandle', containment: 'document' })
						;						
					}
					
					dialogs[options.id] = true;
					break;
					
				default:
					debug('Aborting: Invalid dialog type');
					return false;
					
			}
			
			// Bind default events, and store options
			$dialog
				.bind('dialogopen',  function(e, ui) {
					debug(' default dialogopen event triggered');
					
					$theDialogContent = $(this);
									
					if (type == 'tabs' && options.useTabsAsHeader) {
						//fn_useTabsAsHeader($(this), e, ui);
					}
					if (options.bringInFocusOnOutsideclick) {
						fn_bringInFocusOnOutsideclick($(this), e, ui);
					}
					if (type == 'iframe') {
						$theDialogContent.addClass('ui-dialog-content-loading');
						$('body').addClass('ui-busy');
						$uiWidget.find('iframe').load(function(){
							$theDialogContent.removeClass('ui-dialog-content-loading');
							$('body').removeClass('ui-busy');
						});
						$uiWidget.find('iframe').error(function(){
							$theDialogContent.removeClass('ui-dialog-content-loading');
							$('body').removeClass('ui-busy');
						});
					}
					else if (type == 'swf') {
						$theDialogContent.addClass('ui-dialog-content-loading');
						$('html').addClass('ui-modalActive-swf');
					}
					
					$('html').addClass('ui-modalActive');
				})
							
				.bind('beforeclose',  function(e, ui) {
					debug('default beforeclose event triggered');
					if ($(this).dialog('option', '_parentRefresh') !== false) {
						if (options.parentRefresh) {
							$('body').addClass('ui-wait');
							e.preventDefault();
							// 'reload' parent (no location.reload() <> possible form submits)
							window.location = $.url.set(window.location.href, {fragment: ''});
						}
					}
				})
				
				.bind('dialogclose',  function(e, ui) {
					debug('default dialogclose event triggered');
					debug(options.width);
					$('html').removeClass('ui-modalActive ui-modalActive-swf');
					if (options.keepInDom === false) {
						// remove from DOM
						debug('remove from DOM')
						$dialog = $('#'+dialogId);
						$dialog.dialog('destroy').remove();
						dialogs[options.id] = false;	
					}
				})
				
				.data('pdialog', {options: options})
			;	
		}
		else {
			$dialog = $('#'+dialogId);
		}
		
		// open/show the dialog
		// always center (if existing dialog has been opened after moved & closed)
		
		return $dialog
			.dialog('option', 'position', 'center')
			.dialog('open')
		;
	
	}; /* /spawnDialog() */
	
	
	/**
	 * fn_bringInFocusOnOutsideclick()
	 */
	function fn_bringInFocusOnOutsideclick($theDialogContent, e, ui) {
		var $dialog = $theDialogContent.parent();
		var $overlay = $dialog.prev('.ui-widget-overlay');		
		$overlay.click(function(){
			debug('event: ui-widget-overlay clicked');
			//debug($theDialogContent);
			$dialog.effect('highlight');
			$theDialogContent.dialog('option', 'position', 'center');
		});
	};
	
	
	/**
	 * generateButtons()
	 */
	function generateButtons() {
		var buttons = {};
		var i = 0;
		$.each(options.buttons, function(key, val) {
			i++;
			buttonExtras[i] = {role: this.role }
			
			switch (this.action) {
				case 'cancel':
					buttons[key] = function() {
						var $this = $(this);
						$this.dialog('close');
					}
					break;
				case 'submit':
					buttons[key] = function() {
						debug('OK pressed, submit the form: ');
					}
					break;
				default:
					if (typeof this.action == 'function') {
						buttons[key] = this.action;
					}
					break;
			}
			
		});
		//debug(buttonExtras);
		return buttons;
	};
	
	
	/**
	 * createDialogWithTabs()
	 * 
	 * Available options per tab:
	 *    type		{String ('iframe')}		defaults to loading via Ajax
	 *    title		
	 *    load		{String}				the URL to load in tab
	 *    
	 * 
	 */
	function createDialogWithTabs(dialogId) {
		
		var tabsHTML, tabListItemsHTML = '', tabContentsHTML = '', tabId;
			
		$.each(options.tabs, function(i, val){
			tabId = this.tabId = 'dialog-tab' + i;
			tabListItemsHTML += '<li><a href="#' + tabId + '">' + this.title + '</a></li>';	
			tabContentsHTML  += '<div id="' + tabId + '"></div>'	
		});
		
		
		// Generate tabs HTML
		// This first needs to be appended to body, else the Tabs plugin can't/won't work correctly
		tabsHTML = '<div class="tabs" id="' + dialogId + '"><ul>'
			+ tabListItemsHTML
			+ '</ul><div class="richtext" id="tabDivsContainer">'
			+ tabContentsHTML
			+ '</div></div>'
		;
		
		// Append to body & hide
		$('body').append($(tabsHTML).hide());
		
		// Create the tabs and dialog
		var $dialog = $('#'+dialogId).tabs().dialog(uiDialogOptions);
		var $uiWidget = $dialog.parent();
		$uiWidget.addClass('ui-pdialog-dialogtabs');
		
		if (options.useTabsAsHeader) {
			var $uiTabsNav = $uiWidget.find('.ui-tabs-nav');			
			$dialog.dialog('option', 'draggable', false);			
			$uiWidget.find('.ui-dialog-titlebar').replaceWith($uiTabsNav);			
			$uiTabsNav
				.wrap('<div class="ui-tabs ui-dialog-titlebar"/>')
			;
			$uiWidget
				.draggable({ handle: '.ui-tabs-nav', cancel: '.ui-tabs-nav li', containment: 'document' })
			;
		}
		
		// load Ajax content
		$.each(options.tabs, function(i, val) {
			if (this.type == 'iframe') {
				var html = '<iframe src="'+this.load+'" frameborder="0"></iframe>';
				$('#' + this.tabId).addClass('pdialog-tab-iframe').html(html);
			}
			else {
				$('#' + this.tabId).load( this.load, null, function(responseText, textStatus, XMLHttpRequest){
					debug(responseText);
				} ); // gets cached in IE
			}
		});
	
	};
	
	/**
	 * Debugging
	 * private
	 */
	function debug($obj) {
		function formatMsg($obj){
			if (typeof $obj == 'string') {
				return 'pDialog' + (typeof dialogId != 'undefined' ? ' ['+dialogId+'] ' : ' ') + $obj;
			}
			else {
				return $obj;
			}
		};
				
		if (options.debug) {
			if (window.console && window.console.debug) {
				console.debug(formatMsg($obj));
			}
			else if (window.console && window.console.log) {
				console.log(formatMsg($obj));
			}
		}
	};


}; /* end of $.pDialog */


/**
 * public showNotice()
 * Shortcut function to use for (short) system messages/notices
 * 
 * @param {String} id				The unique id for pDialog
 * @param {String} notice_text		Plain-text String
 */
$.pDialog.showNotice = function(id, notice_text) {
	$.pDialog({
		id: id,			
		type: 'message',
		title: 'Let op!',
		content: '<div class="richtext"><p>' + notice_text+ '.</p><p>Klik op OK om door te gaan.</p></div>',
		bringInFocusOnOutsideclick: true,
		modal: true,
		buttons: {
			'OK': {
				action: 'cancel'
			}
		}
	});
};

	
})(jQuery); /* end of $.pDialog closure */
