/**
 * Model dialog class for showing a nice looking dialog to the user and 
 * disabeling the rest of the browser window.
 * 
 * oOptions takes an object with the following structure
 * {
 *	iWidth		: 450,
 *	iHeight		: 480,
 *	sMessage	: The dialog message, can be html code!
 *	sContent	: 'innerHTML content, overwrites sMessage',
 *  oContent	: The custom dialog div inside, in the form of an object, this overwrites sContent
 *  sDialogDivClass : defaults to dialogDIV
 * }
 * 
 * @author Remco Verton 
 * @author Christian Höntsch-Rode
 * 
 * @param {Object} aOptions
 */
jQuery.fn.ModelDialog = function( oOptions ){
	var oVeilDiv;
	var oButtonNames = {
		0 : 'yes',
		1 : 'no',
		2 : 'ok',
		3 : 'cancel',
		4 : 'close'
	};
	
	var oScripts;
	var oIframe;		// The iframe that disables select boxes in internet explorer
	var oIcon;			// The small icon we display for questions and information dialogs
	var oContentDiv;	
	var oContentElement;
	var oDialogDiv;
	var oDialogTable;	// The table that surrounds any dialog, and shows nice borders
	
	var aPageDimensions = jQuery().getPageDimensions();
	var aScrollingPosition = jQuery().getScrollingPosition();
	var aViewportSize = jQuery().getViewportSize();
	var oBody = $('body');
	
	var oSettings = {
		'iWidth'        	: 450,
		'iHeight'       	: 480,
		'sDialogDivClass'	: 'dialogDIV'
	};
	// Merge the options and settings
	if ( oOptions ) {
		jQuery.extend( oSettings, oOptions );
	}
	
	/**
	 * Create the confirm Dialog
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.confirmDialog = function( oCallbackOk ){
		createDialogButtons( { 'ok' : oCallbackOk  } );
		createDialogIcon( 'info' );
		centerContentDiv();
		stealFocus();
	} // func
	
	/**
	 * Create the information dialog with no callback function possible
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.informationDialog = function( ){
		createDialogButtons( { 'ok' : jQuery().disposeDialog , 'close' : '' } );
		createDialogIcon( 'info' );
		centerContentDiv();
		stealFocus();
	} // func
	
	/**
	 * Create the custom dialog with a personal layout
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.customDialog = function( ){
		centerContentDiv();
		stealFocus();
	} // func
		
	/**
	 * Create the ok cancel dialog
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.okCancelDialog = function( oCallbackOk, oCallbackCancel ){
		createDialogButtons( { 'ok' : oCallbackOk , 'cancel' :oCallbackCancel , 'close' : oCallbackCancel } );
		createDialogIcon( 'question' );
		centerContentDiv();
		stealFocus();
	} // func
		
	/**
	 * Create the yes no dialog
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.yesNoDialog = function( oCallbackYes, oCallbackNo ){
		createDialogButtons( { 'yes' : oCallbackYes , 'no' :oCallbackNo, 'close' : oCallbackNo } );
		createDialogIcon( 'question' );
		centerContentDiv();
		stealFocus();
	} // func
	
	/**
	 * Create the yes no dialog cancel
	 *
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	this.yesNoCancelDialog = function( oCallbackYes, oCallbackNo , oCallbackCancel ){
		createDialogButtons( { 'yes' : oCallbackYes , 'no' : oCallbackNo , 'cancel' : oCallbackCancel , 'close' : oCallbackCancel} );
		createDialogIcon( 'question' );
		centerContentDiv();
		stealFocus();
	} // func
	
	/**
	 * You need to call this function when ever you destroy an instance of the model dialog.
	 * It removes all divs and iframes from the DOM
	 * 
	 * @author Remco Verton 
	 * @access public
	 * 
	 * @return void
	 */
	this.remove = function(){
		oVeilDiv.remove();
		oContentDiv.remove();
		if( $.browser.msie ){ 
			oIframe.remove();
		}
		removeEventListeners();
	} // func
	
	/**
	 * public wrapper function for the build function
	 * 
	 * @author Remco Verton
	 * @author Christian Höntsch-Rode
	 * 
	 * @access public
	 * @return void
	 */
	this.build = function(){
		buildDialog();
	} // func
	
	/**
	 * Builds the entire model dialog window
	 * 
	 * @author Remco Verton
	 * @author Christian Höntsch-Rode
	 * 
	 * @access private
	 * @return void
	 */
	function buildDialog(){
		buildVeilDiv();
		
		buildIframe();
		buildContentDiv();
		buildDialogBaseLayout();
		addEventListeners();
	} // func
	
	/**
	 * Builds the div that disables the window
	 * 
	 * @author Remco Verton
	 * @author Christian Höntsch-Rode
	 * 
	 * @access private
	 * @return void
	 */
	function buildVeilDiv(){
		var width = aPageDimensions[0];
		var height = aPageDimensions[1];
		if( aViewportSize[1] > height) height = aViewportSize[1];
		
		oVeilDiv = $( document.createElement( 'div' ) );
		oVeilDiv.css({ // all non dynamic css is defined in main.css for SDLG
			'width'		:width + 'px',
			'height'	:height + 'px'
		});
		oVeilDiv.attr({
			"id"	:'modDialogVeil'
		});

		oBody.append( oVeilDiv );
	} // func
	
	/**
	 * Builds the div that contains the content
	 * 
	 * @author Remco Verton
	 * @author Christian Höntsch-Rode
	 * 
	 * @access private
	 * @return void
	 */
	function buildContentDiv(){
		oContentElement = document.createElement( 'div' );
		oContentDiv = $( oContentElement );
		oContentDiv.attr({ 'id'		:'dialogContentDiv' });
		// For some reason we need to add a timeout to fix a bug in ie6 ( images not showing the first time you see a standard dialog )
		if( jQuery.browser.msie && jQuery.browser.version.split( '.' ).shift() == '6'){
			setTimeout( function(){oBody.append( oContentDiv );},100);				// Append the body
		}
		else{
			oBody.append( oContentDiv );
		}
	} // func
	
	function stealFocus(){
		// Build the element that will steal the focus and then dissapear
		var oContentFocusThiefElement = document.createElement( 'input' );
		var oContentFocusThief = $( oContentFocusThiefElement );
		oContentFocusThief.attr({
			'type':'text',
			'id':'dialogContentFocusThiefElement'
		});
		oContentDiv.append( oContentFocusThief );
		// Take the focus away from all other input fields, then remove our focused element from the DOM
		oContentFocusThiefElement.focus();
		oContentElement.removeChild( oContentFocusThiefElement );
	}
	
	/**
	 * Builds the i frame needed for internet explorer 6, this iframe will only be build if the browser type is 
	 * miscrosoft internet explorer.
	 * 
	 * Returns true if an iframe was created, false if not
	 * 
	 * @author Remco Verton
	 * @author Christian Höntsch-Rode
	 * 
	 * @access public
	 * @return bool
	 */
	function buildIframe(  ){
		// Iframe hack fix for IE
		if( $.browser.msie ){
			var width = aPageDimensions[0];
			var height = aPageDimensions[1];
			if( aViewportSize[1] > height) height = aViewportSize[1];
			
			oIframe = $( document.createElement( 'iframe' ) );
			oIframe.css( { // All non dynamic css can be found in the main.css file for SDLG
				'width'		:width + 'px',
				'height'	:height + 'px'
			} );
			
			oIframe.attr( { 
				'scrolling' 		: 'no',
				'frameborder'		: 'no',
				'allowtransparency'	: 'yes',
				'id'				: 'modDialogVeilIframe'
			} );
			oBody.append(oIframe);
			return true;
		}
		else{
			// For other browsers we do not need the iframe fix!
			return false;
		}
	} // func
	
	/**
	 * Create the basic laout for any dialog div, in witch the template can be added
	 *
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return bool
	 */
	function buildDialogBaseLayout(){
		oDialogDiv = $( document.createElement( 'div' ) );
		
		oDialogDiv.attr({ 'class'		: oSettings.sDialogDivClass });
		
		// Our new content object interface, to fill the idalogDiv
		if( oOptions['oContent'] != undefined ){
			buildDialogTable( );
			oScripts = oOptions['oContent'].find( 'script' ); 		// Copy all script tags from the dom object
			oOptions['oContent'].find( 'script' ).remove(); 		// Remove all script tags from the dom object
			oDialogDiv.append( oOptions['oContent'] );
		}
		else if( oOptions['sContent'] != undefined ){
			// We still provide the sContent innerHTML for smart login and other modules using the custom
			// dialog interface
			buildDialogTable( );
			oOptions['oContent'] = $( '<div>' + oOptions['sContent'] + '</div>');			
			oScripts = oOptions['oContent'].find( 'script' ); 		// Copy all script tags from the dom object
			oOptions['oContent'].find( 'script' ).remove(); 		// Remove all script tags from the dom object
			oDialogDiv.append( oOptions['oContent'] );
		}
		else{ // standard dialog interface
			var oHeading = $( document.createElement( 'h1' ) );
			var oHeadingText = $( document.createTextNode( oSettings['sTitle'] ) );
			oHeading.append( oHeadingText );
			
			
			// If we have a message append it as an html block		
			var oMessage = $( document.createElement( 'div' ) );
			oMessage.css({ 'textAlign:' :'center'	});
			oMessage.attr({
				'innerHTML' : oSettings['sMessage'],
				'id'		: 'dialogMessage'
			});
			oDialogDiv.append( oMessage );
			buildDialogTable( oHeading );
		}
		
		oContentDiv.append( oDialogTable );
		oContentDiv.append( oScripts );	// Append the scripts, they execute now!
	} // func
	
	/**
	 * Build the table that makes the dialog window 100% flexible
	 * 
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return void
	 */
	function buildDialogTable( oHeading ){
		oDialogTableTest = document.createElement( 'table' );
		oDialogTable = $( oDialogTableTest );
		
		if( oSettings['iWidth'] != undefined &&  parseInt( oSettings['iWidth'] ) > 0 ){
			oDialogTable.css({
				'width'	: oSettings['iWidth'] + 'px' 
			});
		}
		oDialogTable.attr({
			'id' 			: 'dialogTable',
			'cellspacing'	: '0',
			'cellpadding'	: '0',
			'border'		: '0'
		});

		// Ie 6 hack, it does not seem to listen to the above jquery code!
		oDialogTableTest.cellSpacing="0";
		oDialogTableTest.cellPadding="0";
		// Build row 1
		var oDialogTableTr1 = $( document.createElement( 'tr' ) );
		var oDialogTableTr1Td1 = $( document.createElement( 'td' ) );
		var oDialogTableTr1Td2 = $( document.createElement( 'td' ) );
		var oDialogTableTr1Td3 = $( document.createElement( 'td' ) );
		oDialogTableTr1Td1.attr({ 'id': 'dialogTableTr1Td1' });
		oDialogTableTr1Td2.attr({ 'id': 'dialogTableTr1Td2' });
		oDialogTableTr1Td3.attr({ 'id': 'dialogTableTr1Td3' });			
		oDialogTableTr1.append( oDialogTableTr1Td1 );
		oDialogTableTr1.append( oDialogTableTr1Td2 );
		oDialogTableTr1.append( oDialogTableTr1Td3 );
		oDialogTable.append( oDialogTableTr1 );
		// Build row 2
		var oDialogTableTr2 = $( document.createElement( 'tr' ) );
		var oDialogTableTr2Td1 = $( document.createElement( 'td' ) );
		var oDialogTableTr2Td2 = $( document.createElement( 'td' ) );
		var oDialogTableTr2Td3 = $( document.createElement( 'td' ) );
		oDialogTableTr2Td1.attr({ 'id': 'dialogTableTr2Td1' });
		oDialogTableTr2Td2.attr({ 'id': 'dialogTableTr2Td2' });
		oDialogTableTr2Td3.attr({ 'id': 'dialogTableTr2Td3' });
		oDialogTableTr2.append( oDialogTableTr2Td1 );
		oDialogTableTr2.append( oDialogTableTr2Td2 );
		oDialogTableTr2.append( oDialogTableTr2Td3 );
		oDialogTable.append( oDialogTableTr2 );
		// Build row 3
		var oDialogTableTr3 = $( document.createElement( 'tr' ) );
		var oDialogTableTr3Td1 = $( document.createElement( 'td' ) );
		var oDialogTableTr3Td2 = $( document.createElement( 'td' ) );
		var oDialogTableTr3Td3 = $( document.createElement( 'td' ) );
		oDialogTableTr3Td1.attr({ 'id': 'dialogTableTr3Td1' });
		oDialogTableTr3Td2.attr({ 'id': 'dialogTableTr3Td2' });
		oDialogTableTr3Td3.attr({ 'id': 'dialogTableTr3Td3' });
		oDialogTableTr3.append( oDialogTableTr3Td1 );
		oDialogTableTr3.append( oDialogTableTr3Td2 );
		oDialogTableTr3.append( oDialogTableTr3Td3 );
		oDialogTable.append( oDialogTableTr3 );
		
		if( oHeading != undefined ){
			oDialogTableTr1Td2.append( oHeading );
		}
		oDialogTableTr2Td2.append( oDialogDiv );
	} // func
	
	/**
	 * Show the buttons defined by the calling function, this function is meant to be private!
	 *
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return bool
	 */
	function createDialogButtons( aImageCallbacks ){
		// Loop through the array of defined images, to get the proper image order
		for( var i in oButtonNames ){
			if ( aImageCallbacks[oButtonNames[i]] != undefined ) {
			 	var oButtonLink = $( document.createElement( 'a' ) );
				oButtonLink.attr({ 'href': 'javascript:void(0);' });		
				var oButton = $( document.createElement( 'img' ) );
				oButton.attr({ 
					'src'	: oCruxStrings.getString( 'SDLG', 'simple_dialog_'+ oButtonNames[i] +'_button_url' ),
					'class' : 'DialogButton'				
				});
				if( oButtonNames[i] == 'close' ){
					oButton.attr({ 'class'	: 'switch'	});
				}
				oButton.bind( 'click' , {'callback': aImageCallbacks[oButtonNames[i]] } , function(event){
					// Switch the type of the callback function , it can be a real function or an string
					switch( typeof event.data.callback ){
						case 'string':
							// We trust the source se we can eval the javascript string!
							eval( event.data.callback );							
						break;
						case 'function':
							// It is a function execute it
							event.data.callback();
						break;
						default:
							// be silent
						break;
					}
					jQuery().disposeDialog();
				});
				oButtonLink.append(oButton);
				oDialogDiv.append( oButtonLink );
			}
		}
	} // func
	
	/**
	 * Adds the nice looking icons to the standard dialogs
	 * 
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	function createDialogIcon( sIconName ){
		oIcon = $(document.createElement( 'img' ) );
		oIcon.attr({
			'src' 	: oCruxStrings.getString( 'SDLG', 'simple_dialog_'+ sIconName +'_icon_url' ),
			'class' : 'SimpleDialogIcon',
			'id'	: 'testIcon'
		});
		oDialogDiv.append( oIcon );
	} // func
	
	/**
	 * Adds event listeners needed for the model dialog
	 * 
	 * @author Remco Verton 
	 * 
	 * @access public
	 * @return void
	 */
	function addEventListeners(){
		// Add an onresize event that returns false, i do not know why but
		// this makes the disabeling window the same size as the viewport after resizing the browser window
		$(window).resize( function(){
			resize();
			centerContentDiv();
			return false;
		});
		$(window).scroll( function( ){
			centerContentDiv( 'scrolling' );
		});
	} // func
	
	/**
	 * Remove event listeners needed for the model dialog
	 * 
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return bool
	 */
	function removeEventListeners(){
		// Add an onresize event that returns false, i do not know why but
		// this makes the disabeling window the same size as the viewport after resizing the browser window
		$(window).unbind( 'resize' );
		$(window).unbind( 'scroll' );
	} // func
	
	/**
	 * Window resize handler, resize and reposition the divs needed for the model dialog when ever the window is resized
	 * 
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return void
	 */
	function resize( ){
		// Make the veil very small, then get the page dimentions, else it veil can determine the page dimentions
		oVeilDiv.css( {'width':'1px'} );		
		oVeilDiv.css( {'height':'1px'} );
		if( $.browser.msie ){
			oIframe.css( {'width':'1px'} );
			oIframe.css( {'height':'1px'} );
		}
		
		
		aPageDimensions = jQuery().getPageDimensions();
		aViewportSize = jQuery().getViewportSize();
		
		var width = aPageDimensions[0];
		var height = aPageDimensions[1];
		if( aViewportSize[1] > height) height = aViewportSize[1];
		
		
		oVeilDiv.css( {'width'	:width + 'px'} );
		oVeilDiv.css( {'height'	:height + 'px'} );

		if( $.browser.msie ){
			oIframe.css( {'width'	:width + 'px'} );
			oIframe.css( {'height'	:height + 'px'} );
		}
	} // func
	
	/**
	 * Center the dialog content div
	 * 
	 * @author Remco Verton 
	 * 
	 * @access private
	 * @return void
	 */
	function centerContentDiv( scrolling ){
	
		aScrollingPosition = jQuery().getScrollingPosition();
		aViewportSize = jQuery().getViewportSize();
		if( parseInt(aViewportSize[1]) <  oContentElement.offsetHeight ){
			iTop = 30;
			if( scrolling != 'scrolling' ){
				oContentDiv.css({ 'top'		:iTop+'px' });
				window.scrollTo( 0 , 30 );
			}
			
		}
		else{
			var iTop  = (aScrollingPosition[1] + (parseInt(aViewportSize[1] / 2))) - (parseInt(oContentElement.offsetHeight / 2));
			if ( iTop < 0 ){
				iTop = 30;
			}
			oContentDiv.css({'top'		:iTop+'px' });
		}
		
		var iLeft = aScrollingPosition[0] + parseInt(aViewportSize[0] / 2) - parseInt(oContentElement.offsetWidth / 2);
		oContentDiv.css({ 'left'		:iLeft+'px'	});
		
	} // func
}

var modelDialogWindow;

/**
 * Show an custom dialog with no callbacks, you can fill the floating div with all the html code you want
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sContent'		: '<div>The dialog content!</div>'
 * 'oContent'		: The custom dialog div inside, in the form of an object, this overwrites sContent
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @return bool
 */
jQuery.fn.showDialog = function( aOptions ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.customDialog(  );
		return true;
	}
	return false;
} // func

/**
 * Show an alert dialog, with only an ok, this ok button disposes the dialog
 * 
 * sMessage		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {string} sMessage 
 * @return bool
 */
jQuery.fn.alertDialog = function( sMessage ) {
	if ( !modelDialogWindow ){
		var oOptions = {
			'sTitle' 	: oCruxStrings.getString( 'SDLG', 'simple_dialog_alert_title' ),
			'sMessage'	: sMessage
		};
		modelDialogWindow = new jQuery.fn.ModelDialog( oOptions );
		modelDialogWindow.build();
		modelDialogWindow.informationDialog( );
		return true;
	}
	return false;
} // func

/**
 * Show an information dialog, with only an ok, this ok button disposes the dialog
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sTitle'			: 'The dialog title'
 * 'sMessage'		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @return bool
 */
jQuery.fn.informationDialog = function( aOptions  ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.informationDialog(  );
		return true;
	}
	return false;
} // func

/**
 * Show a confirm dialog, with only an ok button, this button can have an optional callback function
 * Each button will have by default the callback to dispose the dialog
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sTitle'			: 'The dialog title'
 * 'sMessage'		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @param {object} oCallbackOk the ok button callback function. Needs to be a reference!
 * @return bool
 */
jQuery.fn.confirmDialog = function( aOptions , oCallbackOk ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.confirmDialog( oCallbackOk );
		return true;
	}
	return false;
} // func

/**
 * Show an ok cancel dialog, with an ok and cancel button, both buttons can have an optional callback function
 * Each button will have by default the callback to dispose the dialog
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sTitle'			: 'The dialog title'
 * 'sMessage'		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @param {object} oCallbackOk the ok button callback function. Needs to be a reference!
 * @param {object} oCallbackCancel the cancel button callback function. Needs to be a reference!
 * @return bool
 */
jQuery.fn.okCancelDialog = function( aOptions, oCallbackOk, oCallbackCancel ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.okCancelDialog( oCallbackOk , oCallbackCancel );
		return true;
	}
	return false;
} // func

/**
 * Show an yes no dialog, with a yes and no button, both buttons can have an optional callback function
 * Each button will have by default the callback to dispose the dialog
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sTitle'			: 'The dialog title'
 * 'sMessage'		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @param {object} oCallbackYes the yes button callback function. Needs to be a reference!
 * @param {object} oCallbackNo the no button callback function. Needs to be a reference!
 * @return bool
 */
jQuery.fn.yesNoDialog = function( aOptions , oCallbackYes, oCallbackNo ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.yesNoDialog( oCallbackYes, oCallbackNo  );
		return true;
	}
	return false;
} // func

/**
 * Show an yes no cancel dialog, with a yes no and cancel button, each button can have an optional callback function
 * Each button will have by default the callback to dispose the dialog
 * 
 * aOptions ( all optional )accepts the following attributes 
 * 'iWidth'         : 400
 * 'iHeight'        : 480
 * 'sTitle'			: 'The dialog title'
 * 'sMessage'		: 'The message to be displayed to the user'
 *
 * @author Remco Verton 
 * 
 * @param {object} aOptions 
 * @param {object} oCallbackYes the yes button callback function. Needs to be a reference!
 * @param {object} oCallbackNo the no button callback function. Needs to be a reference!
 * @param {object} oCallbackCancel the cancel button callback function. Needs to be a reference!
 * @return bool
 */
jQuery.fn.yesNoCancelDialog = function( aOptions , oCallbackYes, oCallbackNo , oCallbackCancel ) {
	if ( !modelDialogWindow ){
		modelDialogWindow = new jQuery.fn.ModelDialog( aOptions );
		modelDialogWindow.build();
		modelDialogWindow.yesNoCancelDialog( oCallbackYes, oCallbackNo , oCallbackCancel );
		return true;
	}
	return false;
} // func

/**
 * Remove the currently displayed dialog window
 * 
 * @author Remco Verton 
 * 
 * @return false
 */
jQuery.fn.disposeDialog = function(){
	if ( modelDialogWindow ){
		modelDialogWindow.remove();
		modelDialogWindow = null;
		return true;
	}
	return false;
} // func

/**
 * Returns the viewport size width, height
 * 
 * @author Remco Verton 
 * 
 * @return {array} viewport size array(width, height)
 */
jQuery.fn.getViewportSize = function() {
	var aViewportSize = [0, 0];
	if ( typeof window.innerWidth != "undefined" ) {
		aViewportSize = [ window.innerWidth, window.innerHeight ];
	} else if (
		typeof document.documentElement != "undefined" &&
		typeof document.documentElement.clientWidth != "undefined" &&
		document.documentElement.clientWidth > 0 ) {
		aViewportSize = [document.documentElement.clientWidth, document.documentElement.clientHeight];
	} else {
		var oElement = document.getElementsByTagName('body')[0];
		aViewportSize = [ oElement.clientWidth, oElement.clientHeight ];
	}
	return aViewportSize;
} // func

jQuery.fn.getPageDimensions = function() {
	var oBody             = document.getElementsByTagName('body')[0];
	var iBodyOffsetWidth  = 0;
	var iBodyOffsetHeight = 0;
	var iBodyScrollWidth  = 0;
	var iBodyScrollHeight = 0;
	var aPageDimensions   = [0, 0];

	if ( typeof document.documentElement != "undefined" && typeof document.documentElement.scrollWidth != "undefined" ) {
		aPageDimensions[0] = document.documentElement.scrollWidth;
		aPageDimensions[1] = document.documentElement.scrollHeight;
	}

	iBodyOffsetWidth = oBody.offsetWidth;
	iBodyOffsetHeight = oBody.offsetHeight;
	iBodyScrollWidth = oBody.scrollWidth;
	iBodyScrollHeight = oBody.scrollHeight;
	
	aPageDimensions[0] = Math.max( Math.max( iBodyOffsetWidth,  aPageDimensions[0] ), iBodyScrollWidth);
	aPageDimensions[1] = Math.max( Math.max( iBodyOffsetHeight, aPageDimensions[1] ), iBodyScrollHeight);
	return aPageDimensions;
} // func

jQuery.fn.getScrollingPosition = function() {
	var aPosition = [0, 0];

	// Supported by some browsers directly
	if ( typeof window.pageYOffset != "undefined" ) {
		aPosition = [ window.pageXOffset, window.pageYOffset ];
	}

	if ( typeof document.documentElement.scrollTop != "undefined" && document.documentElement.scrollTop>0 ) {
		aPosition = [ document.documentElement.scrollLeft, document.documentElement.scrollTop ];
	} else if ( typeof document.body.scrollTop != 'undefined' ) {
		aPositon =   [ document.body.scrollLeft, document.body.scrollTop ];
	}
	return aPosition;
} // func

jQuery.fn.maxZ = function() {
	iMaxZ = 0;
	$("body *").each( function() {
		iMaxZ = Math.max( iMaxZ, this.style.zIndex );
	})
	return iMaxZ;
} // func