/** 
 * @fileoverview Base Class for Client Side Widget System
 *
 * @author Gaaetan Lauff <glauff@plansoft.de>
 * @version $Id: class.dialog.js 286 2007-12-13 15:30:41Z glauff $
 */

function EKAT_RESIZE(w,h) {;}
function EKAT_CENTER_WINDOW() {;}

/**
 * Class Dialog
 *
 * @class Base Class for Client GUI System
 * This class handles the complete Client Side Widget System
 *
 * @constructor
 * @author	Gaetan Lauff	<glauff@plansoft.de>
 *
 * $Id: class.dialog.js 286 2007-12-13 15:30:41Z glauff $
 */
var Dialog = Class.create();

Dialog.prototype = 
{
	/**
	 * @var	string
	 */
	id: null,
	
	/**
	 * @var array
	 */
	widgets: [],
	
	/**
	 * @var integer
	 */
	width: 0,
	
	/**
	 * @var integer
	 */
	height: 0,
	
	/**
	 * @var array
	 */
	winRegistry: null,
	
	/**
	 * @var boolean
	 */
	initialized: false,
	
	popupsBlocked: false,
	
	/**
	 * Inititalizes the Client Side Widget System
	 *
	 * @private
	 */
	initialize: function() 
	{
		if(is.ie5_5up){
			try{
				document.execCommand("BackgroundImageCache", false, true);
			}catch(e){}
		}

		if (self != top) {
			try {
				top.dialog.enable();
			} catch( e ) {}
		} else {
			try {   
				if (self.opener) {
					var modal = Element.getAttributeValue( document.body, 'modal' );
				
					if (modal) {
						self.opener.dialog.winRegistry.startModalObserver( self.name );
					} else {
						self.opener.dialog.enable();
					}
				} else {
					//$('GUI_DISABLE').style.visibility = 'hidden';
					this.enable();
				}
			} catch( e ) {
				/**
				 * This is just used to detect if the opener
				 * is from same origin.
				 * to avoid JavaScript Errors
				 */
				//alert("Cross site opening !" + document.domain);
			}
		}
	
		Event.observe(document, "keydown", toggleEnterKey, true);
		if ( document.body.getAttribute('allowselect') != "true" )
			Event.observe(document, "selectstart", noSelect, true);
		
		this.id = document.body.id;
		this.winRegistry = new windowRegistry();
		
		Form.insertHidden('DLG_ID', this.id);

		Dialog.setWindowSize();
		
		if (is.ie5up)
			Event.observe( window, "unload", this.destroy.bindAsEventListener(this) );
			
		// Beim Submit wird der Dialog disabled um User Interaktion zu stoppen
		document.observe('form:eksubmit', function() {
			dialog.disable();
		});
	},
	
	/**
	 * Returns the Version Information
	 *
	 * @return	string
	 * @access	public
	 */
	getVersion: function()
	{
		alert( "Client Side System Properties \nEasyGUI: " + EasyGUI.Version + " " + EasyGUI.Build + "\nPrototype: " + Prototype.Version + "\nScriptaculous: " + Scriptaculous.Version );
	},
	
	/**
	 * Returns a message from a given Id
	 *
	 * @return	string
	 * @access	public
	 */
	getMessage: function( id )
	{
		var element = $(id);
		
		if ( element ) {
			return Element.getInnerText( element );
		}
		
		return id;
	},
	
	/**
	 * Registers all widgets of the current dialog.
	 * @access	public
	 * @throws	object	Error
	 * @private
	 */
	init: function()
	{
		//var allElements = document.getElementsByTagName('*');
		var tables 		= [];
		var widgetCons 	= [];
		var tabctrls 	= [];
		
		for (var i=0; i < widgets.length; i++) {
			var widget = widgets[i].split(':');
			var widgetName = '';
			
			for (var j=1; j < widget.length; j++ ) {
				widgetName += (widgetName == "" ) ? widget[j] : ":" + widget[j];
			}
			
			switch( widget[0] ) {
				case 'EasyGUI_table':
					tables[tables.length] = widgetName;
					break;
					
				case 'EasyGUI_TabCtrl':
					tabctrls[tabctrls.length] = widgetName;
					break;
					
				default:
					var widgetConstructor = widget[0] + '(\'' + widgetName + '\')';
					widgetCons[widgetCons.length] = widgetConstructor;
					break;
			}
		}
	
		for ( var i=0; i < tabctrls.length; i++ )
			this.registerWidget( new EasyGUI_TabCtrl( tabctrls[i] ) );
		
		for ( var i=0; i < widgetCons.length; i++ )
			this.registerWidget( eval( 'new ' + widgetCons[i] ) );
		
		for ( var i=0; i < tables.length; i++ ) {
			this.registerWidget( new EasyGUI_table( tables[i] ) );
		}
			
		this.renderWidgets();
		this.finalizeWidgets();
		
		this.initialized = true;
		
		// For nested iframes in iframes
		// very dangerous
		document.body.dialog = this;
	},
	
	/**
	 * builds all widgets according to the widgets array
	 * @private
	 */
	renderWidgets: function()
	{
		for (var i=0; i < this.widgets.length; i++) {
			var windowname = self.name;
			
			if ( DEBUGTIME ) {
				var timer = new JS_Timer();
				timer.startTimer();
			}
			
			this.widgets[i].render();
			
			if( DEBUGTIME )		
				GUITIME += this.widgets[i].id + ': ' + timer.stopTimer() + "s\r\n";
		}
	},
	
	/**
	 * Finalizes all widgets according to widgets array
	 * The Finalize function is for setup tasks that should be performed 
	 * after the widget is rendered !
	 * @private
	 */
	finalizeWidgets: function() 
	{
		for ( var i=0; i < this.widgets.length; i++ )
			this.widgets[i].finalize();
	},
	
	/**
	 * Destroys the Dialog object.
	 * Necessary for IE Memory Leaks
	 *
	 * @destructor
	 * @private
	 */
	destroy: function()
	{
		for (var i=0; i < this.widgets.length; i++) {
			this.widgets[i].destroy();
		}
	},
	
	/**
	 * Registers a widget in the widgets array
	 * @param	object	widget
	 * @returns	void
	 * @private
	 * @throws	object	Error
	 */
	registerWidget: function ( widget )
	{
		this[widget.id] = widget;
		this.widgets.push(widget);
	},
	
	/**
	 * Returns a specific widget of the widgets array.
	 * @param	string	id of widget
	 * @return	object	EasyGUI_Widget
	 * @access	public
	 * @throws	object	Error
	 */
	getWidget: function( id )
	{
		return (this[id]) ? this[id] : false;
		/*
		for (var i=0; i < this.widgets.length; i++) {
			if (id == this.widgets[i].id) {
				return this.widgets[i];
			}
		}
		
		return false;
		*/
	},
	
	/**
	 * Returns the whole widgets array.
	 *
	 * @returns	An array of EasyGUI Widgets.
	 * @access	public
	 */
	getWidgets: function()
	{
		return this.widgets;
	},
	
	/**
	 * Enables Dialog
	 * @returns	void
	 * @access	public
	 */
	enable: function()
	{
		// $() for IE
		if (this.disabler !== undefined )
			$(this.disabler).remove();
		//Element._hide('GUI_DISABLE');
	},
	
	/**
	 * Disables Dialog
	 * @returns	void
	 * @access	public
	 */
	disable: function ()
	{
		this.disabler = document.createElement('div');
		document.body.appendChild(this.disabler);
		var dialogSize = document.viewport.getDimensions();
		
		this.disabler.style.position = 'absolute';
		this.disabler.style.width = dialogSize.width + 'px';
		this.disabler.style.height = dialogSize.height + 'px';
		this.disabler.setAttribute('id', 'INPUT_DISABLE');
		this.disabler.className = 'disableInput';
		
		/*
		var disabler = $( 'GUI_DISABLE' ); 
		Element.setDimension( disabler, '100%', Dialog.getInnerHeight() );
		Element._show('GUI_DISABLE');
		*/
	}
};


/**
 * Sets window Size
 * @returns	void
 * @private
 */
Object.extend( Dialog, {
	/**
	 * @returns Inner Width of Document
	 */
	getInnerWidth: function()
	{
		if (self.innerWidth) {
			return self.innerWidth;
		} else if (document.documentElement && document.documentElement.clientWidth) {
			return document.documentElement.clientWidth;	
		} else if (document.body) {
			return document.body.clientWidth;	
		}
	},
	
	/**
	 * @returns Inner Height of document
	 */
	getInnerHeight: function() 
	{
		if (self.innerHeight) {
			return self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			return document.documentElement.clientHeight;
		} else if (document.body) {
			return document.body.clientHeight;
		}
	},
	
	/**
	 * @returns Page Y Offset (ScrollTop)
	 */
	getPageYOffset: function()
	{
		if (self.pageYOffset) {
			return self.pageYOffset;
		} else if (document.documentElement && document.documentElement.scrollTop) {
			return document.documentElement.scrollTop;
		} else if (document.body) {
			return document.body.scrollTop;
		}
	},
	
	/**
	 * @returns Page X Offset (scrollLeft)
	 */
	getPageXOffset: function()
	{
		if (self.pageXOffset) {
			return self.pageXOffset;
		} else if (document.documentElement && document.documentElement.scrollLeft) {
			return document.documentElement.scrollLeft;
		} else if (document.body) {
			return document.body.scrollLeft;
		}
	},
	
	/**
	 * @returns Page Height
	 */
	getPageHeight: function()
	{
		var test1 = document.body.scrollHeight;
		var test2 = document.body.offsetHeight;
		
		if (test1 > test2) {
			return document.body.scrollHeight;
		} else {
			return document.body.offsetHeight;
		}
	},
	
	/**
	 * @returns Page Width
	 */
	getPageWidth: function()
	{
		var test1 = document.body.scrollHeight;
		var test2 = document.body.offsetHeight;
		
		if (test1 > test2) {
			return document.body.scrollWidth;
		} else {
			return document.body.offsetWidth;
		}
	},
	
	/**
	 * Tries to set the correct windowsize
	 * Fails on IE 7 @investigate
	 *
	 * @private
	 */
	setWindowSize: function()
	{
		var appmode = ( document.forms[0].action.indexOf('easygui.plso') === -1 ) ? 'ek_internet' : 'ek_cdrom';
		
		var resizeDialog 	= Element.getAttributeValue( document.body, 'resizedialog');
		var centerDialog 	= Element.getAttributeValue( document.body, 'centerdialog' );
		
		var width 	= parseInt( Element.getAttributeValue( document.body, 'dialogwidth' ));
		var height 	= parseInt( Element.getAttributeValue( document.body, 'dialogheight' ));
	
		if (self == top && ( resizeDialog || appmode == 'ek_cdrom') ) {
			try {
				self.resizeTo(width + 10, height + 4);
				width += 4;
			    height +=4;
				var hrefCMD="javascript:void(EKAT_RESIZE("+width+","+height+"))";
				window.location.href=hrefCMD;
			} catch(e) {
				;
			}
		}
		
		if (self == top && centerDialog) {
			if ( appmode != 'ek_cdrom' ) {
				try {
					self.moveTo(((screen.width/2) - (width/2)), ((screen.height/2) - (height/2)));
					var hrefCMD="javascript:void(EKAT_CENTER_WINDOW())";
					window.location.href = hrefCMD;
				} catch(e) {
					;
				}
			}
		}
	},
	
	/**
	 * Shows a Message
	 * @param	msgId
	 * @returns	boolean
	 */
	showMessage: function( msgId ) {
		var msg = Element.getInnerText( msgId );
		alert( msg );
		return false;
	},
	
	/**
	 * Wrapper for ekSubmit Function
	 * Should be used when scripting in iframe
	 */
	submit: function( id, target, timeout ) 
	{
		ekSubmit( id, target, timeout );
	}
});

Dialog.Style = {
	/**
	 * Returns a specific shylesheet object from the document tree
	 *
	 * @param	{mixed}	sheetIdx	Can be a numeric or string value
	 * @returns The Style sheet from the Documents Style Sheet Collection
	 * @access	public
	 */
	getSheet: function( idx )
	{
		if (!idx) {
			var idx = 1;
		} else {
			if (typeof(idx) == 'string') {
				for (var i=0; i < document.styleSheets.length; i++) {
					if (document.styleSheets[i].title == idx) {
						var idx = i;
					}
				}
			}
		}
		
		return document.styleSheets[idx];
	},
	
	/**
	 * @param	{integer}	idx		Style Sheet Index
	 * @returns	All rules set in a specific stylesheet
	 * @access	public
	 */
	getRules: function( idx )
	{
		if (!document.styleSheets) {
			return false;
		}
		
		if (document.styleSheets[idx].cssRules) {
			return document.styleSheets[idx].cssRules;
		} else if (document.styleSheets[idx].rules) {
			return document.styleSheets[idx].rules;
		}
	},
	
	/**
	 * @param	mixed	idx		the stylesheet idx
	 * @returns	the current idx for stylesheet
	 * @access	public
	 */
	getIdx: function( idx )
	{
		if (idx == null) {
			var idx = 1;
		} else {
			if (typeof(idx) == 'string') {
				var sheets = document.styleSheets;
				for (var i=0; i < sheets.length; i++) {
					var id = sheets[i].ownerNode ? sheets[i].ownerNode.id : sheets[0].owningElement.id;
					if (id == idx) {
						//console.log( "Found Sheet: " + idx + " at idx: " + i );
						var idx = i;
					}
				}
			}
		}
				
		return idx;
	},
	
	/**
	 * Get a property Value from a linked Stylesheet
	 * @param	{string}	selector
	 * @param 	{string}	attribute
	 * @param	{mixed} 	idx
	 * @returns	The Property Value if one is found ! 
	 */
	getStyle: function (selector, attribute, idx)
	{
		if (!selector) {
			return false;
		}
		
		var idx 	= Dialog.Style.getIdx( idx );
		var rules 	= Dialog.Style.getRules( idx );
		
		for (var i=0; i < rules.length; i++) {
			if (rules[i].selectorText.indexOf("." + selector) != -1) {
				return rules[i].style[attribute];
			}
		}
				
		return Dialog.Style.getDefaultValue( selector, attribute );
	},
	
	/**
	 * Checks if a specific rule exists in the stylesheet
	 * @param	{string}	selector	the rule selector
	 * @param	{mixed}		idx			the style sheet idx
	 * @returns	TRUE if the rule exists in stylesheet, FALSE otherwise
	 * @access	public
	 */
	ruleExists: function( selector )
	{
		for (var i = (document.styleSheets.length - 1); i > 0; i--) {
			var rules = Dialog.Style.getRules( i );
		
			for (var j=0; j < rules.length; j++) {
				if (rules[j].selectorText.indexOf("." + selector) != -1) {
					return true;
				}
			}
		}
				
		return false;
	},
		
	/**
	 * Returns the Default Value defined in the easygui stylesheet
	 * @param	{string}	selector	The Selector text
	 * @param	{string}	attribute	The CSS Rule that should be extracted
	 * @returns The Property Value, FALSE otherwise.
	 */
	getDefaultValue: function( selector, attribute )
	{
		var idx = Dialog.Style.getIdx('easygui');
		var rules = Dialog.Style.getRules( idx );
		
		for (var i=0; i < rules.length; i++) {
			if ("." + selector == rules[i].selectorText) {
				return rules[i].style[attribute];
			}
		}
	
		return false;
	},
	
	/**
	 * Set a property in a given stylesheet
	 * @todo	implement
	 * @param	{string}	property
	 * @param	{mixed}		propertyValue
	 * @param	{object}	styleSheet
	 * @returns	void
	 * @access	public
	 * @todo	implement
	 */
	setProperty: function(property, propertyValue, styleSheet)
	{
		;
	}
};