/*
Sky.Window 
copyright by MySign AG (http://www.mysign.ch), Christian Troller
depencies: Prototype 1.6.0.2
           script.aculo.us 1.8.1 effects
           script.aculo.us 1.8.1 dragdrop
		   Sky.PrototypeExtensions
*/

// creating namespace
var Sky;
if ( !Sky ) Sky = {};

Sky.Window = Class.create();

Sky.Window.instanceCounter = 0;
Sky.Window.instances = new Array();

Sky.Window.EVENT_WINDOW_CLOSING = "Sky.Window:closing";
Sky.Window.EVENT_WINDOW_CLOSED = "Sky.Window:closed";
Sky.Window.EVENT_OVERLAY_CLOSED = "Sky.Window:overlayclosed";
Sky.Window.EVENT_CONTENT_LOADED = "Sky.Window:contentloaded";

Sky.Window.POSITION_CENTER = 1;
Sky.Window.POSITION_TOP = 2;
Sky.Window.POSITION_BOTTOM = 3;

Sky.Window._requirementsChecked = false;
Sky.Window._cssClassesAdded = false;
Sky.Window._REQUIRED_PROTOTYPE = '1.6.0.2';
Sky.Window._REQUIRED_SCRIPTACULOUS_EFFECTS = '1.8.1';
Sky.Window._REQUIRED_SCRIPTACULOUS_DRAGDROP = '1.8.1';

Sky.Window._CSS_LOADING = 'skyWindowDefaultLoading';
Sky.Window._CSS_CLOSE = 'skyWindowDefaultClose';
Sky.Window._CSS_OVERLAY = 'skyWindowDefaultOverlay';
Sky.Window._CSS_WINDOW = 'skyWindowDefaultWindow';
Sky.Window._CSS_FRAME = 'skyWindowDefaultFrame';
Sky.Window._CSS_HEADER = 'skyWindowDefaultHeader';
Sky.Window._CSS_FOOTER = 'skyWindowDefaultFooter';
Sky.Window._CSS_CONTENTHOLDER = 'skyWindowDefaultContentHolder';
Sky.Window._CSS_CONTENT = 'skyWindowDefaultContent';
Sky.Window._CSS_DRAGGER = 'skyWindowDefaultDragger';

Sky.Window.CLOSEFUNCTION_BLINDUP = 1;
Sky.Window.CLOSEFUNCTION_FADE = 2;

Sky.Window._checkRequirements = function ()
{
	if( !Sky.Window._requirementsChecked )
	{
		// checking Sky.PrototypeExtensions
		if( Object.isUndefined( Sky.PrototypeExtensions ) )
		{
			throw( "Sky.Window requires the Sky.PrototypeExtensions JavaScript framework" );
		}
		// checking Prototype
		if( !Sky.PrototypeExtensions.isPrototypeLoaded( Sky.Window._REQUIRED_PROTOTYPE ) )
		{
			throw( "Sky.Window requires the Prototype JavaScript framework >= " + Sky.Window._REQUIRED_PROTOTYPE );
		}
		// checking script.aculo.us effects
		if( !Sky.PrototypeExtensions.isScriptaculousEffectsLoaded( Sky.Window._REQUIRED_SCRIPTACULOUS_EFFECTS ) )
		{
			throw( "Sky.Window requires the script.aculo.us effects JavaScript framework >= " + Sky.Window._REQUIRED_SCRIPTACULOUS_EFFECTS );
		}
		// checking script.aculo.us dragdrop
		if( !Sky.PrototypeExtensions.isScriptaculousDragDropLoaded( Sky.Window._REQUIRED_SCRIPTACULOUS_DRAGDROP ) )
		{
			throw( "Sky.Window requires the script.aculo.us dragdrop JavaScript framework >= " + Sky.Window._REQUIRED_SCRIPTACULOUS_DRAGDROP );
		}
		
		Sky.Window._requirementsChecked = true;
	}
}


Sky.Window.prototype =
{
	initialize: function( opts )
	{
		// checking requirements
		Sky.Window._checkRequirements();
		
		if ( !Sky.Window._cssClassesAdded )
		{
			var cssTagText = '';
			cssTagText += '.' + Sky.Window._CSS_LOADING + ' {';
			cssTagText += 'text-align: center;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_CLOSE + ' {';
			cssTagText += 'cursor: pointer;';
			cssTagText += 'float: right;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_OVERLAY + ' {';
			cssTagText += 'position: absolute;';
			cssTagText += 'margin: auto;';
			cssTagText += 'top: 0;';
			cssTagText += 'left: 0;';
			cssTagText += 'width: 100%;';
			cssTagText += 'height: 100%;';
			cssTagText += 'background-color: #000!important;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_OVERLAY + '[id] {';
			cssTagText += 'position: fixed;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_WINDOW + ' {';
			cssTagText += 'position: absolute;';
			cssTagText += 'top: 0;';
			cssTagText += 'left: 0;';
			cssTagText += 'border: 0;';
			cssTagText += 'text-align: left;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_WINDOW + '[id] {';
			cssTagText += 'position: fixed!important;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_FRAME + ' {';
			cssTagText += 'position: relative;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_HEADER + ' {';
			cssTagText += 'margin: 0;';
			cssTagText += 'padding: 0;';
			cssTagText += 'height: 20px;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_FOOTER + ' {';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_CONTENTHOLDER + ' {';
			cssTagText += 'background-color: #EFEFEF;';
			cssTagText += '}';
			
			cssTagText += '.' + Sky.Window._CSS_CONTENT + ' {}';
			
			cssTagText += '.' + Sky.Window._CSS_DRAGGER + ' {';
			cssTagText += 'cursor: move;';
			cssTagText += 'float:left;';
			cssTagText += '}';
			
			if( Prototype.Browser.IE )
			{
				document.createStyleSheet();
				document.styleSheets[document.styleSheets.length-1].cssText = cssTagText;
			}
			else
			{
				var cssTag = new Element( 'style', { type: 'text/css' } ).insert( cssTagText );
				$$("head")[0].appendChild( cssTag );
			}
			
			Sky.Window._cssClassesAdded = true;
		}
		
		this.options = {
			contentCode:			null,
			contentObj:				null,
			contentURL:				null,
			ajaxParams: 			{},									// Default AJAX Parameters
			ajaxMethod: 			"get",  							// Default Ajax request method
			
			addToContent:			{ width: 0, height: 0 },
			
			dynamicAdjustment:		true, 								// Defines if the Sky.Window should resize itself automatically to fit the content.
			maxWindowHeight:		650,								// Default maximal height of the window
			minWindowHeight:		100,								// Defualt minimal height of the window
			maxWindowWidth:			900,
			minWindowWidth:			150,
			width:					150, 	 							// Default width in px
			height:					100, 	 							// Default height in px
			
			draggable: 				true,  								// Define if the Sky.Window is draggable.
			dragCustom:				false,
			dragPosX:				0, 									// Defines the x position where the draggable layer should be placed 
			dragPosY:				0, 									// Defines the y position where the draggable layer should be placed
			dragWidth:				"100%",								// Defines the width of the draggable layer.
			dragHeight:				"100%",								// Defines the height of the draggable layer
			
			closeCode:				'',									// Default code attribute for close Sky.Window link
			onBeforeClose:			null,								// Callback function on before close Sky.Window
			closeVisible: 			true,  								// Close button visible?
			closeVisibleAfterLoad:	false,								// Hide the close button until the content is loaded
			
			footerCode:				null,
			
			loadingCode: 			'',									// Default loading code
			
			windowId:				null,
			
			overlayClose:			false,	 							// Close Sky.Window by clicking on overlay
			overlayOpacity:			.65, 	 							// Default overlay opacity
			overlayDuration:		.25, 	 							// Default overlay fade in/out duration in seconds
			
			slideDownDuration:		.5, 	 							// Default Sky.Window appear slide down effect in seconds
			slideUpDuration:		.5, 	 							// Default Sky.Window hiding slide up effect in seconds
			resizeDuration:			.75, 	 							// Default resize duration seconds
			
			closeFunction:			Sky.Window.CLOSEFUNCTION_BLINDUP,	// Default Sky.Window hiding function
			closeFunctionDuration:	.5,									// Default Sky.Window hiding duration
			
			fadeDuration:			.75, 	 							// Default Appear/Fade duration
			inactiveFade: 			true,	 							// Fades Sky.Window on inactive state
			
			transitions: 			true, 								// Toggles transition effects. Transitions are enabled by default
			
			autoFocusing:			true,  								// Toggles auto-focusing for form elements. Disable for long text pages.
			
			autoShow:				true,								// Show Sky.Window after init.
			
			windowPosition:			Sky.Window.POSITION_CENTER,  		// Window position.
			
			modal:					true,  								// Flag to set if the window should be modal (no other actions behind it allowed) or not.
			//customLayout:			false,								// TODO: implement this flag
			
			cssClassContentHolder:	Sky.Window._CSS_CONTENTHOLDER,
			cssClassContent:		Sky.Window._CSS_CONTENT,
			cssClassLoading:		Sky.Window._CSS_LOADING,
			cssClassHeader:			Sky.Window._CSS_HEADER,
			cssClassFooter:			Sky.Window._CSS_FOOTER,
			cssClassDragger:		Sky.Window._CSS_DRAGGER,
			cssClassClose:			Sky.Window._CSS_CLOSE,
			cssClassWindow:			Sky.Window._CSS_WINDOW,
			cssClassFrame:			Sky.Window._CSS_FRAME,
			cssClassOverlay:		Sky.Window._CSS_OVERLAY,
			
			contentOverflow:		true								// if the window_content element should get overflow: auto
		};
		
		Sky.Window.instances.push( this );
		Sky.Window.instanceCounter++;
		this.instanceId = Sky.Window.instanceCounter;
		
		this.resizeCounter = 0;
		
		this.defaultDocWindowSize = { width: this._getDocumentWidth(), height: this._getDocumentHeight() };
		
		this._contentSize = { width: 0, height: 0 };
		this.content = null;
		
		Object.extend( this.options, opts || {} );
		
		this.active = false;
		this.focusableElements = new Array();
		this.currFocused = false;
		this.newWindow = true;
		this.window_closeClickObserved = false;
		this.window_overlayClickObserved = false;
		
		this.windowId = this.options.windowId;
		if( this.windowId == null || Object.isUndefined( this.windowId ) )
		{
			this.windowId = 'skyWindow' + this.instanceId;
		}
		
		this._setupElements();
		
		//Adding event observers
		this.setWidthAndPositionHandler = this._setWidthAndPosition.bindAsEventListener(this);
		this.prepareIEHandler = this._prepareIE.bindAsEventListener(this);
		this.hideObserver = this._hide.bindAsEventListener(this);
		this.kbdObserver = this._kbdHandler.bindAsEventListener(this);
		this._initObservers();
		
		this.initialized = true; // Mark as initialized
		
		if( this.options.autoShow )
		{
			this.show();
		}
		
		this._activate();
	},
	
	_setupElements: function()
	{
		var newZIndex = 10000;
		newZIndex += ( this.instanceId * 10 );
		
		if( this.options.modal )
		{
			//Create the overlay
			this.window_overlay = new Element("div", { id: "SkyWindow_overlay" + this.instanceId }).setOpacity( 0 );
			this.window_overlay.addClassName( this.options.cssClassOverlay );
			this.window_overlay.setStyle( {
					zIndex: newZIndex
			} );
		}
		
		newZIndex++;
		
		//Create DOM for the window
		this.window = new Element("div", {id: this.windowId, style: 'display: none;' }).update(
			this.window_frame = new Element("div", {id: "SkyWindow_frame" + this.instanceId}).update(
				this.window_header = new Element("div", {id: "SkyWindow_header" + this.instanceId, style: 'width: ' + this.options.width + 'px' }).addClassName( this.options.cssClassHeader )
			).addClassName( this.options.cssClassFrame )
		).addClassName( this.options.cssClassWindow );
		
		this.window.setStyle( {
			zIndex: newZIndex
		} );
		
		this.window_contentholder = new Element( "div", { id: "SkyWindow_contentholder" + this.instanceId } ).update(
			this.window_content = new Element("div", {id: "SkyWindow_content" + this.instanceId }).update(
				this.window_loading = new Element("div", {id: "SkyWindow_loading" + this.instanceId}).addClassName( this.options.cssClassLoading ).update( this.options.loadingCode )
			).addClassName( this.options.cssClassContent )
		).addClassName( this.options.cssClassContentHolder );
		
		this.window_frame.insert({'bottom':this.window_contentholder});
		
		if ( this.options.footerCode !== null )
		{
			this.window_footer = new Element("div", {id: "SkyWindow_footer" + this.instanceId }).addClassName( this.options.cssClassFooter );
			this.window_footer.insert( this.options.footerCode );
			this.window_frame.insert({'bottom':this.window_footer});
		}
		else
		{
			this.window_footer = null;
		}
		
		// Inserting into DOM.
		$(document.body).insert({'top': this.window});
		if( this.options.modal )
		{
			$(document.body).insert({'top': this.window_overlay});
		}
		
		if( this.options.contentOverflow )
		{
			this.window_content.setStyle({overflow: 'auto'});
		}
		
		if( this.options.draggable )
		{
			this.window_dragger = new Element( "div", { id: "SkyWindow_dragger" + this.instanceId } ).addClassName( this.options.cssClassDragger );
			if( this.options.dragCustom )
			{
				this.window.insert( { "top": this.window_dragger } );
			}
			else
			{
				this.window_header.insert( { "top": this.window_dragger } );
			}
			
			this.window_dragger.setStyle( {
				width: this.options.dragWidth,
				top: this.options.dragPosY + "px",
				left: this.options.dragPosX + "px",
				cursor: "move"
			} );
			
			if( this.options.dragCustom )
			{
				this.window_dragger.setStyle( {
					zIndex: newZIndex
				} );
			}
			
			var z = newZIndex++;
			new Draggable( this.window, { zindex: z, starteffect: null, endeffect: null, handle: this.window_dragger } );
		}
		
		if( this.options.closeVisible )
		{
			newZIndex++;
			
			this.window_close = new Element( "div", { id: "SkyWindow_close" + this.instanceId } ).update( this.options.closeCode ).addClassName( this.options.cssClassClose );
			
			if( this.options.closeVisibleAfterLoad )
			{
				this.window_close.hide();
			}
			
			this.window_close.setStyle( {
				zIndex: newZIndex
			} );
			
			if( this.options.draggable )
			{
				if( this.options.dragCustom )
				{
					this.window_header.insert({'bottom': this.window_close});
				}
				else
				{
					this.window_dragger.insert({'bottom': this.window_close});
				}
			}
			else
			{
				this.window_header.insert({'bottom': this.window_close});
			}
		}
		
		this.window_header.insert( { 'bottom': new Element( "div", { "class": "clear" } ) } );
	},
	
	isActive: function() 
	{
		return this.active;
	},
	
	show: function() 
	{
		if(this.window.style.display == "none") 
		{ // First Sky.Window appearing
			if( Sky.Window.instances.length > 1 )
			{
				Sky.Window.instances[Sky.Window.instances.length-2]._deactivate();
			}
			this._appear();
			this.event("onShow");
		}
	},
	
	hide: function() 
	{ // External hide method to use from external HTML and JS
		if( this.initialized ) 
		{
			// Passing beforeHide callback
			this.event("beforeHide");
			this.window.fire( Sky.Window.EVENT_WINDOW_CLOSING, this );
			if(this.options.transitions)
			{
				var closeWindowAfterFinish = this._deinit.bind( this );
				switch( this.options.closeFunction )
				{
					case Sky.Window.CLOSEFUNCTION_FADE:
						Effect.Fade( this.window, { duration: this.options.closeFunctionDuration, afterFinish: closeWindowAfterFinish } );
						break;
					default:
						Effect.BlindUp( this.window, { duration: this.options.slideUpDuration, transition: Effect.Transitions.sinoidal, afterFinish: closeWindowAfterFinish } );
						break;
				};
			}
			else
			{
				this.window.hide();
				this._deinit();
			}
		}
		else 
		{ 
			throw("Sky.Window is not initialized.");
		}
	},
	
	swapContent: function ( opts )
	{
		var swapOptions = {
			contentCode:			this.options.contentCode,
			contentObj:				this.options.contentObj,
			contentURL:				this.options.contentURL,
			ajaxParams: 			this.options.ajaxParams,
			ajaxMethod: 			this.options.ajaxMethod
		}
		Object.extend( swapOptions, opts || {} );
		Object.extend( this.options, swapOptions );
		
		this._update();
		this.event("onUpdate"); // Passing onUpdate callback
	},
	
	_hide: function(event)
	{ // Internal hide method to use with overlay and close link
		if ( !Object.isUndefined( event ) )
		{
			event.stop(); // Stop event propaganation for link elements
			
			// Then clicked on overlay we'll check the option and in case of overlayClose == false we'll break hiding execution [Fix for #139]
			if(!this.options.overlayClose && event.element().id === 'SkyWindow_overlay' + this.instanceId)
			{
				return false;
			}
		}
		
		var callBackFunction = false;
		if ( !Object.isUndefined ( this.options.onBeforeClose ) && this.options.onBeforeClose !== null )
		{
			callBackFunction = this.options.onBeforeClose( this );
		}
		else
		{
			callBackFunction = true;
		}
		
		if ( callBackFunction )
		{
			this.hide();
		}
	},
	
	_prepareIE: function ()
	{
		var documentHeight = this._getDocumentHeight();
		var documentWidth = this._getDocumentWidth();
		var dOffsets = document.viewport.getScrollOffsets();
		
		if( this.options.modal )
		{
			this.window_overlay.setStyle( { 
				height: documentHeight + 'px',
				width: documentWidth + 'px',
				top: dOffsets.top + 'px',
				left: dOffsets.left + 'px'
			} );
		}
	},
	
	_appear: function()
	{ // First appearing of Sky.Window
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up) 
		{ // Preparing IE 6 for showing Sky.Window
			var instanceId = '';
			if( Sky.Window.instances.length > 1 )
			{
				instanceId = '#' + Sky.Window.instances[Sky.Window.instances.length-2].windowId + ' ';
			}
			$$(instanceId + 'select').invoke('setStyle', {'visibility': 'hidden'}); // Toggle visibility for all selects in the common document
			
			this._prepareIE();
		}
		
		var overlayOpacity = 0;
		if( Object.isFunction( this.options.overlayOpacity ) )
		{
			overlayOpacity = this.options.overlayOpacity();
		}
		else
		{
			overlayOpacity = this.options.overlayOpacity;
		}
		this.window.setStyle( {width: this.options.width + 'px', height: this.options.height + 'px'} );
		this._setPosition();
		
		if(this.options.transitions) 
		{
			if( this.options.modal )
			{
				this.window_overlay.setOpacity( 0 );
				
				new Effect.Fade(this.window_overlay, {
					from: 0,
					to: overlayOpacity,
					duration: this.options.overlayDuration,
					afterFinish: function() 
					{
						new Effect.BlindDown( this.window, { 
							duration: this.options.slideDownDuration,
							afterFinish: function( fx )
											{
												this._loadContent();
											}.bind( this )
						} );
					}.bind(this)
				});
			}
			else
			{
				new Effect.BlindDown( this.window, { 
					duration: this.options.slideDownDuration,
					afterFinish: function( fx )
									{
										this._loadContent();
									}.bind( this )
				} );
			}
		}
		else
		{
			if( this.options.modal )
			{
				this.window_overlay.setStyle({opacity: overlayOpacity});
			}
			
			this.window.show();
			this._loadContent();
		}
		
		if( this.options.closeVisible && !this.window_closeClickObserved )
		{
			this.window_close.observe( 'click', this.hideObserver );
			this.window_closeClickObserved = true;
		}
	},

	
	_update: function() 
	{ // Updating Sky.Window in case of wizards
		this.window_content.update(this.window_loading);
		this._loadContent();
	},
	
	_loadContent: function () 
	{
		if(this.event("beforeLoad")) 
		{ // If callback passed false, skip loading of the content
			if( this.options.contentCode != null )
			{
				this._insertContent( this.options.contentCode );
			}
			else if ( this.options.contentObj != null )
			{
				this._insertContent( this.options.contentObj );
			}
			else if ( this.options.contentURL != null )
			{
				new Ajax.Request( this.options.contentURL, {
						method: this.options.ajaxMethod.toLowerCase(), 
						parameters: this.options.ajaxParams,
						onSuccess: function(transport) 
									{
										var responseText = transport.responseText;
										var response = new String(responseText);
										this._insertContent( responseText );
									}.bind(this),
						onException: function(instance, exception)
						{
							alert( exception.message );
							this.hide();
						}.bind( this )
					});
			}
			else
			{
				this.hide();
				throw('Sky.Window Parameters Error: Please specify correct URL or HTML element (plain HTML or object)');
			}
		}
	},
	
	_insertContent: function(tmpContent, callback)
	{
		// remove old script
		if ( this.scriptTag != null && !Object.isUndefined( this.scriptTag ) )
		{
			this.scriptTag.remove();
			this.scriptTag = null;
		}
		
		var h = this.window_contentholder.getHeight();
		this.window_content.update( "" ).setStyle( { height: h + "px" } );
		var forPositioning, used, _htmlObj, posElement;
		if(typeof tmpContent == 'string') 
		{ // Plain HTML is given
			posElement = new Element( "div" ).update(tmpContent.stripScripts()).hide();
			this.window.insert( { "before": posElement } );
			if( !this.options.contentOverflow )
			{
				// somehow the posElement is 2 pixels too high
				posElement.setStyle( { height: ( posElement.getHeight() - 2 ) + "px" } );
				this.window_content.setStyle({overflow: 'hidden'});
			}
			forPositioning = posElement;
			used = 1;
		} 
		else if (typeof tmpContent == 'object') 
		{ // HTML Object is given
			_htmlObj = tmpContent.cloneNode(true); // If node already a part of DOM we'll clone it
			forPositioning = _htmlObj;
			// If clonable element has ID attribute defined, modifying it to prevent duplicates
			if(tmpContent.id) tmpContent.id = "SkyWindow_" + tmpContent.id + this.instanceId;
			/* Add prefix for IDs on all elements inside the DOM node */
			$(tmpContent).select('*[id]').each(function(el){ el.id = "skyWindow_" + el.id; });
			
			used = 2;
		}
		
		if( this.options.dynamicAdjustment && forPositioning )
		{
			this._contentSize.width = forPositioning.getWidth() + this.options.addToContent.width;
			this._contentSize.height = forPositioning.getHeight() + this.options.addToContent.height;
		}
		else
		{
			this._contentSize.width = this.options.width;
			this._contentSize.height = this.options.height - this.window_header.getHeight();
			if ( this.window_footer !== null )
			{
				this._contentSize.height -= this.window_footer.getHeight();
			}
		}
		
		if( posElement ) 
		{
			posElement.remove();
		}
		
		var dim = this._getDim();
		var width = dim.width;
		var contentHeight = dim.contentHeight;
		var windowHeight = dim.windowHeight;
		var windowTooHigh = dim.windowTooHigh;
		
		if( !this.options.contentOverflow && Prototype.Browser.IE && !Prototype.Browser.IE7up )
		{
			contentHeight -= 2;
		}
		
		var dimForPos = this._getDimForPositioning( width, windowHeight );
		
		this._myResize(
					width,
					windowHeight,
					contentHeight,
					dimForPos,
					windowTooHigh,
					function()
					{
						if( this.options.closeVisibleAfterLoad )
						{
							this.window_close.show();
						}
						
						if( used == 1 )
						{
							if( this.options.transitions )
							{
								var myUpdate = this.window_content.setOpacity(0).myUpdate( { contentCode: tmpContent } );
								this.scriptTag = myUpdate.script;
								new Effect.Appear( $(myUpdate.element), { duration: this.options.fadeDuration } );
							}
							else
							{
								var myUpdate = this.window_content.myUpdate( { contentCode: tmpContent } );
								this.scriptTag = myUpdate.script;
							}
						}
						else if( used == 2 )
						{
							this.window_content.update( _htmlObj ).down( 'div' ).show();
							if(Prototype.Browser.IE)
							{ // Toggling back visibility for hidden selects in IE
								$$("." + this.options.cssClassContent + " select").invoke('setStyle', {'visibility': ''});
							}
						}
						setTimeout(function()
						{ // MSIE fix
							this._putContent(callback);
						}.bind(this),1);
					}.bind( this )
				);
	},
	
	_getDimForPositioning: function( x, y )
	{
		var newX = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( x / 2 ) );
		var newY = ( Math.floor( this._getDocumentHeight() / 2 ) - Math.floor( y / 2 ) );
		
		if( this.options.windowPosition == Sky.Window.POSITION_TOP )
		{
			newY = 0;
		}
		
		if( this.options.windowPosition == Sky.Window.POSITION_BOTTOM )
		{
			newY = ( this._getDocumentHeight() - y );
		}
		
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
		{
			var dOffset = document.viewport.getScrollOffsets();
			newX += dOffset.left;
			newY += dOffset.top;
		}
		
		return { x: newX, y: newY };
	},
	
	_putContent: function(callback)
	{
		this.window_content.show();
		this.focusableElements = this._findFocusableElements();
		this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button)
		if(callback != undefined)
		{
			callback(); // Executing internal JS from loaded content
		}
		
		if( this.options.draggable )
		{
			if( this.options.dragCustom )
			{
				this.window_dragger.setStyle( {
					height: this.options.dragHeight
				} );
			}
			else
			{
				this.window_dragger.setStyle( {
					height: this.window_header.getHeight() + 'px'
				} );
			}
		}
		
		if( !this.isActive() && Prototype.Browser.IE && !Prototype.Browser.IE7up )
		{
			$$('#' + this.windowId + ' select').invoke('setStyle', {'visibility': 'hidden'}); // Toggle visibility for all selects in the common document
		}
		
		this.window.fire( Sky.Window.EVENT_CONTENT_LOADED, this );
		this.event("afterLoad"); // Passing callback
	},
	
	_activate: function()
	{
		if( !this.active )
		{
			this.active = true;
			
			if( this.options.closeVisible && !this.window_closeClickObserved )
			{
				this.window_close.observe( 'click', this.hideObserver );
				this.window_closeClickObserved = true;
			}
			
			if( this.options.overlayClose && this.options.modal && !this.window_overlayClickObserved )
			{
				this.window_overlay.observe('click', this.hideObserver);
				this.window_overlayClickObserved = true;
			}
			
			if( this.options.transitions && this.options.inactiveFade )
			{
				new Effect.Appear(this.window, {duration: this.options.fadeDuration});
			}
		}
	},
	
	_deactivate: function() 
	{
		if( this.active )
		{
			this.active = false;
			
			if( this.options.closeVisible && this.options.modal && this.window_closeClickObserved )
			{
				this.window_close.stopObserving('click', this.hideObserver);
				this.window_closeClickObserved = false;
			}
			
			if(this.options.overlayClose && this.options.modal &&  this.window_overlayClickObserved )
			{
				this.window_overlay.stopObserving('click', this.hideObserver);
				this.window_overlayClickObserved = false;
			}
			
			if(this.options.transitions && this.options.inactiveFade)
			{
				new Effect.Fade(this.window, {duration: this.options.fadeDuration, to: .5});
			}
		}
	},
	
	_initObservers: function()
	{        	
		if(this.options.overlayClose && this.options.modal && !this.window_overlayClickObserved )
		{
			this.window_overlay.observe('click', this.hideObserver);
			this.window_overlayClickObserved = true;
		}
		
		if( this.options.closeVisible && !this.window_closeClickObserved )
		{
			this.window_close.observe( 'click', this.hideObserver );
			this.window_closeClickObserved = true;
		}
		
		if(Prototype.Browser.Gecko)
		{
			Event.observe(document, "keypress", this.kbdObserver); // Gecko is moving focus a way too fast
		}
		else
		{
			Event.observe(document, "keydown", this.kbdObserver); // All other browsers are okay with keydown
		}
		
		Event.observe( window, "resize", this.setWidthAndPositionHandler );
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
		{
			Event.observe( window, "scroll", this.prepareIEHandler );
			Event.observe( window, "scroll", this.setWidthAndPositionHandler );
		}
	},
	
	_activateLastWindow: function()
	{
		var lastInstance = Sky.Window.instances.last();
		if ( !Object.isUndefined( lastInstance ) )
		{
			lastInstance._activate();
		}
	},
	
	_removeObservers: function()
	{        	
		if(this.options.overlayClose && this.options.modal && this.window_overlayClickObserved )
		{
			this.window_overlay.stopObserving('click', this.hideObserver);
			this.window_overlayClickObserved = false;
		}
		
		if( this.options.closeVisible && this.window_closeClickObserved )
		{
			this.window_close.stopObserving( 'click', this.hideObserver );
			this.window_closeClickObserved = false;
		}
		
		if(Prototype.Browser.Gecko)
		{
			Event.stopObserving(document, "keypress", this.kbdObserver);
		}
		else
		{
			Event.stopObserving(document, "keydown", this.kbdObserver);
		}
		
		Event.stopObserving( window, "resize", this.setWidthAndPositionHandler );
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
		{
			Event.stopObserving( window, "scroll", this.prepareIEHandler );
			Event.stopObserving( window, "scroll", this.setWidthAndPositionHandler );
		}
	},
	
	_setFocus: function()
	{
		/* Setting focus to the first 'focusable' element which is one with tabindex = 1 or the first in the form loaded. */
		if ( this.options.autoFocusing )
		{
			if( this.focusableElements.length > 0 ) 
			{
				var firstEl = this.focusableElements.find(function (el)
															{
																return el.tabIndex == 1;
															}) || this.focusableElements.first();
				this.currFocused = this.focusableElements.toArray().indexOf(firstEl);
				if ( this.initialized )
				{
					firstEl.focus(); // Focus on first focusable element except close button
				}
			}
		}
		else if( this.options.closeVisible )
		{
			if ( this.initialized )
			{
				this.window_close.focus();
			}
		}
	},
	
	_findFocusableElements: function()
	{ // Collect form elements or links from content
		var focusElements = this.window_content.select('input:not([type~=hidden]), select, textarea, button');
		if( !Object.isUndefined( focusElements ) )
		{
			focusElements.invoke('addClassName', 'SkyWindow_focusable');
		}
		
		return this.window_content.select('.SkyWindow_focusable');
	},
	
	_kbdHandler: function(event) 
	{
		if( !Object.isUndefined( Sky.Window.instances.last() ) && this.instanceId == Sky.Window.instances.last().instanceId )
		{
			var node = event.element();
			
			switch(event.keyCode)
			{
				case Event.KEY_TAB:
					event.stop();
					
					/* Switching currFocused to the element which was focused by mouse instead of TAB-key. Fix for #134 */
					if(node != this.focusableElements[this.currFocused])
					{
						this.currFocused = this.focusableElements.toArray().indexOf(node);
					}
					
					if(!event.shiftKey) 
					{ //Focusing in direct order
						if(this.currFocused == this.focusableElements.length - 1) 
						{
							this.focusableElements.first().focus();
							this.currFocused = 0;
						}
						else
						{
							this.currFocused++;
							this.focusableElements[this.currFocused].focus();
						}
					}
					else
					{ // Shift key is pressed. Focusing in reverse order
						if(this.currFocused == 0) 
						{
							this.focusableElements.last().focus();
							this.currFocused = this.focusableElements.length - 1;
						}
						else
						{
							this.currFocused--;
							this.focusableElements[this.currFocused].focus();
						}
					}
					break;
				case Event.KEY_ESC:
					if(this.options.overlayClose)
					{
						this._hide(event);
					}
					break;
				case 32:
					this._preventScroll(event);
					break;
				case 0: // For Gecko browsers compatibility
					if(event.which == 32)
					{
						this._preventScroll(event);
					}
					break;
				case Event.KEY_UP:
				case Event.KEY_DOWN:
				case Event.KEY_PAGEDOWN:
				case Event.KEY_PAGEUP:
				case Event.KEY_HOME:
				case Event.KEY_END:
					// Safari operates in slightly different way. This realization is still buggy in Safari.
					if(Prototype.Browser.WebKit && !["textarea", "select"].include(node.tagName.toLowerCase()))
					{
						event.stop();
					}
					else if( (node.tagName.toLowerCase() == "input" && ["submit", "button"].include(node.type)) || (node.tagName.toLowerCase() == "a") )
					{
						event.stop();
					}
					break;
			}
		}
	},
	
	_preventScroll: function(event) 
	{ // Disabling scrolling by "space" key
		if(!["input", "textarea", "select", "button"].include(event.element().tagName.toLowerCase()))
		{
			event.stop();
		}
	},
	
	_deinit: function()
	{
		this.window.fire( Sky.Window.EVENT_WINDOW_CLOSED, this );
		this._removeObservers();
		
		if(this.options.transitions) 
		{
			if( this.options.modal )
			{
				new Effect.Fade( this.window_overlay, { 
					to: 0,
					duration: this.options.overlayDuration,
					afterFinish: this._deinitHandler.bind(this) });
			}
			else
			{
				this._deinitHandler();
			}
		}
		else
		{
			if( this.options.modal )
			{
				this.window_overlay.hide();
			}
			
			this._removeElements();
		}
	},
	
	_deinitHandler: function()
	{
		this._removeElements();
	},
	
	_removeElements: function () 
	{
		/* Initialized will be set to false */
		this.initialized = false;
		this.event("afterHide"); // Passing afterHide callback
		if( this.options.modal )
		{
			this.window_overlay.fire( Sky.Window.EVENT_OVERLAY_CLOSED, this );
		}
		
		for ( var i = 0; i < Sky.Window.instances.length; i++ )
		{
			var skyWindow = Sky.Window.instances[i];
			if ( skyWindow.instanceId === this.instanceId )
			{
				Sky.Window.instances.splice( i, 1 );
				break;
			}
		}
		
		this._activateLastWindow();
		
		if ( this.scriptTag != null && !Object.isUndefined( this.scriptTag ) )
		{
			this.scriptTag.remove();
			this.scriptTag = null;
		}
		
		if ( this.options.modal && Element.myIsExisting( this.window_overlay.id ) )
			this.window_overlay.remove();
		if ( Element.myIsExisting( this.window.id ) )
			this.window.remove();
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
		{
			var instanceId = '';
			if( Sky.Window.instances.length > 0 )
			{
				instanceId = '#' + Sky.Window.instances.last().windowId + ' ';
			}
			$$(instanceId + 'select').invoke('setStyle', {'visibility': 'visible'}); // Toggle visibility for all selects in the common document
		}
		
		/* Replacing prefixes 'SkyWindow_' in IDs for the original content */
		if( this.options.contentObj != null ) 
		{
			if(this.options.contentObj.id && this.options.contentObj.id.match(/SkyWindow_/)) 
			{
				this.options.contentObj.id = this.options.contentObj.id.replace(/SkyWindow_/, "");
			}
			this.options.contentObj.select('*[id]').each(function(el){ el.id = el.id.replace(/skyWindow_/, ""); });
		}
	},
	
	_getDocumentHeight: function()
	{
		return (window.innerHeight ||  document.documentElement.clientHeight || document.body.clientHeight || 0);
	},
	
	_getDocumentWidth: function()
	{
		return (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0);
	},
	
	_setPosition: function ()
	{
		var myTop;
		var myLeft;
		
		if( this.options.dynamicAdjustment )
		{
			if( this.options.windowPosition == Sky.Window.POSITION_CENTER )
			{
				myTop = ( Math.floor( this._getDocumentHeight() / 2 ) - Math.floor( this.window.getHeight() / 2 ) );
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.window.getWidth() / 2 ) );
			}
			else if( this.options.windowPosition == Sky.Window.POSITION_TOP )
			{
				myTop = 0;
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.window.getWidth() / 2 ) );
			}
			else if( this.options.windowPosition == Sky.Window.POSITION_BOTTOM )
			{
				myTop = ( this._getDocumentHeight() - this.window.getHeight() );
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.window.getWidth() / 2 ) );
			}
		}
		else
		{
			if( this.options.windowPosition == Sky.Window.POSITION_CENTER )
			{
				myTop = ( Math.floor( this._getDocumentHeight() / 2 ) - Math.floor( this.options.height / 2 ) );
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.options.width / 2 ) );

			}
			else if( this.options.windowPosition == Sky.Window.POSITION_TOP )
			{
				myTop = 0;
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.options.width / 2 ) );
			}
			else if( this.options.windowPosition == Sky.Window.POSITION_BOTTOM )
			{
				myTop = ( this._getDocumentHeight() - this.options.height );
				myLeft = ( Math.floor( this._getDocumentWidth() / 2 ) - Math.floor( this.options.width / 2 ) );
			}
		}
		
		if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
		{
			var dOffset = document.viewport.getScrollOffsets();
			myTop += dOffset.top
			myLeft += dOffset.left
		}
		
		this.window.setStyle( {
			top: myTop + "px",
			left: myLeft + "px"
		} );
	},
	
	_getDim: function ()
	{
		var returnValue = { width: 0, contentHeight: 0, windowHeight: 0, windowTooHigh: false };
		
		var width = this._contentSize.width;
		var contentHeight = this._contentSize.height;
		var windowHeight = 0;
		if ( this.options.dynamicAdjustment )
		{
			windowHeight = contentHeight;
			if ( this.window_header !== null )
			{
				windowHeight += this.window_header.getHeight();
			}
			if ( this.window_footer !== null )
			{
				windowHeight += this.window_footer.getHeight();
			}
		}
		else
		{
			windowHeight = this.options.height;
		}
		var windowTooHigh = false;
		
		if( windowHeight > this.options.maxWindowHeight )
		{
			contentHeight -= ( windowHeight - this.options.maxWindowHeight );
			windowHeight = this.options.maxWindowHeight;
			windowTooHigh = true;
		}
		else if( windowHeight < this.options.minWindowHeight )
		{
			contentHeight += ( this.options.minWindowHeight - windowHeight );
			windowHeight = this.options.minWindowHeight;
		}
		
		if( width > this.options.maxWindowWidth )
		{
			width = this.options.maxWindowWidth;
		}
		else if ( width < this.options.minWindowWidth )
		{
			width = this.options.minWindowWidth;
		}
		
		var documentHeight = this._getDocumentHeight();
		if( windowHeight > documentHeight )
		{
			contentHeight -= ( windowHeight - ( documentHeight ) );
			windowHeight = documentHeight;
			windowTooHigh = true;
		}
		var documentWidth = this._getDocumentWidth();
		if( width > documentWidth )
		{
			width = documentWidth;
		}
		
		returnValue.width = width;
		returnValue.contentHeight = contentHeight;
		returnValue.windowHeight = windowHeight;
		returnValue.windowTooHigh = windowTooHigh;
		
		return returnValue;
	},
	
	_setWidthAndPosition: function () 
	{
		var currentWindowSize = { width: this._getDocumentWidth(), height: this._getDocumentHeight() };
		if( this.defaultDocWindowSize.width != currentWindowSize.width || this.defaultDocWindowSize.height != currentWindowSize.height )
		{
			this.defaultDocWindowSize = currentWindowSize;
			if(Prototype.Browser.IE && !Prototype.Browser.IE7up)
			{
				this._prepareIE();
			}
			
			var dim = this._getDim();
			var width = dim.width;
			var contentHeight = dim.contentHeight;
			var windowHeight = dim.windowHeight;
			var windowTooHigh = dim.windowTooHigh;
			
			var dimForPos = this._getDimForPositioning( width, windowHeight );
			
			if( this.options.dynamicAdjustment )
			{
				var addToWindowWidth = 0;
				if ( windowTooHigh )
				{
					addToWindowWidth = 16;
				}
				
				if( this.options.transitions )
				{
					new Effect.Parallel( [
						new Effect.Morph( this.window, {
							style: {
								height: windowHeight + "px",
								width: width + "px"
							},
							sync: true
						}),
						new Effect.Morph( this.window_frame, {
							style: {
								width: width + "px"
							},
							sync: true
						}),
						new Effect.Morph( this.window_header, {
							style: {
								width: width + "px"
							},
							sync: true
						} ),
						new Effect.Morph( this.window_contentholder, {
							style: {
								height: ( contentHeight - this.options.addToContent.height ) + "px",
								width: ( width - this.options.addToContent.width ) + "px"
							},
							sync: true
						}),
						new Effect.Morph( this.window_content, {
							style: {
								height: ( contentHeight - this.options.addToContent.height ) + "px",
								width: ( (width+addToWindowWidth) - this.options.addToContent.width ) + "px"
							},
							sync: true
						}),
						new Effect.Move( this.window, {
							x: dimForPos.x,
							y: dimForPos.y,
							mode: 'absolute',
							sync: true
						})
					],{
						duration: this.options.resizeDuration
					});
				}
				else
				{
					this.window.setStyle( { height: windowHeight + "px", width: width + "px" } );
					this.window_frame.setStyle( { width: width + "px" } );
					this.window_header.setStyle( { width: width + "px" } );
					this.window_contentholder.setStyle( { height: ( contentHeight - this.options.addToContent.height ) + "px", width: ( width - this.options.addToContent.width ) + "px" } );
					this.window_content.setStyle( { height: ( contentHeight - this.options.addToContent.height ) + "px", width: ( (width+addToWindowWidth) - this.options.addToContent.width ) + "px" } );
					this.window.setStyle( { left: dimForPos.x, top: dimForPos.y } );
				}
			}
			else
			{
				if( this.options.transitions )
				{
					new Effect.Parallel( [
						new Effect.Move( this.window, {
							x: dimForPos.x,
							y: dimForPos.y,
							mode: 'absolute',
							sync: true
						})
					],{
						duration: this.options.resizeDuration
					});
				}
				else
				{
					this.window.setStyle( { x: dimForPos.x, y: dimForPos.y } );
				}
			}
		}
	},
	
	event: function(eventName) 
	{
		if(this.options[eventName]) 
		{
			var returnValue = this.options[eventName](); // Executing callback
			this.options[eventName] = null; // Removing callback after execution
			if(returnValue != undefined)
			{
				return returnValue;
			}
			else
			{
				return true;
			}
		}
		return true;
	},
	
	_myResize: function( newWindowWidth, newWindowHeight, newContentHeight, dim, windowTooHigh, callback )
	{
		var wWidth = this.window.getWidth();

		var wHeight = this.window_content.getHeight();
		
		if( !callback )
		{
			callback = function(){ return false; };
		}
		
		if( newContentHeight != wHeight )
		{
			if( this.options.transitions )
			{
				new Effect.Parallel( [
						new Effect.Morph( this.window, {
							style: {
								height: newWindowHeight + "px"
							},
							sync: true
						}),
						new Effect.Morph( this.window_contentholder, {
							style: {
								height: ( newContentHeight - this.options.addToContent.height ) + "px"
							},
							sync: true
						}),
						new Effect.Morph( this.window_content, {
							style: {
								height: ( newContentHeight - this.options.addToContent.height ) + "px"
							},
							sync: true
						}),
						new Effect.Move( this.window, {
							x: this.window.getStyle( "left" ) != null ? this.window.getStyle( "left" ).replace( /px/, "" ) : 0,
							y: dim.y,
							mode: 'absolute',
							sync: true
						})
					], {
					duration: this.options.resizeDuration,
					afterFinish: ( ( newWindowWidth != wWidth || windowTooHigh ) ? function( fx )
													{
														this._myResizeWidth( newWindowWidth, windowTooHigh, dim, callback );
													}.bind( this ) : callback.bind( this ) )
				} );
			}
			else
			{
				this.window.setStyle( {
					height: newWindowHeight + "px"
				} );
				
				this.window_contentholder.setStyle( {
					height: ( newContentHeight - this.options.addToContent.height ) + "px"
				} );
				
				this.window_content.setStyle( {
					height: ( newContentHeight - this.options.addToContent.height ) + "px"
				} );
				
				this.window.setStyle( {
					left: this.window.getStyle( "left" ) != null ? this.window.getStyle( "left" ).replace( /px/, "" ) : 0,
					top: dim.y	
				} );
				
				if( newWindowWidth != wWidth || windowTooHigh )
				{
					this._myResizeWidth( newWindowWidth, windowTooHigh, dim, callback );
				}
				else
				{
					callback();
				}
			}
		}
		else if( newWindowWidth != wWidth )
		{
			this._myResizeWidth( newWindowWidth, windowTooHigh, dim, callback );
		}
		else
		{
			callback();
		}
	},
	
	_myResizeWidth: function( newWindowWidth, windowTooHigh, dim, callback )
	{
		if( Object.isUndefined( callback ) )
		{
			callback = function(){ return false; };
		}
		
		var addToContentWidth = 0;
		if ( windowTooHigh )
		{
			addToContentWidth = 16;
		}
		this.window_content.setStyle( { width: this.window_content.getWidth() + 'px' } );
		if( this.options.transitions )
		{
			new Effect.Parallel( [
				new Effect.Morph( this.window_contentholder, {
					style: {
						width: ( newWindowWidth - this.options.addToContent.width ) + "px"
					},
					sync: true
				}),
				new Effect.Morph( this.window_content, {
					style: {
						width: ( (newWindowWidth+addToContentWidth) - this.options.addToContent.width ) + "px"
					},
					sync: true
				}),
				new Effect.Morph( this.window, {
					style: {
						width: newWindowWidth + "px"
					},
					sync: true
				}),
				new Effect.Morph( this.window_frame, {
					style: {
						width: newWindowWidth + "px"
					},
					sync: true
				}),
				new Effect.Morph( this.window_header, {
					style: {
						width: newWindowWidth + "px"
					},
					sync: true
				} ),
				new Effect.Move( this.window, {
					x: dim.x,
					y: this.window.getStyle( "top" ) != null ? this.window.getStyle( "top" ).replace( /px/, "" ) : 0,
					mode: 'absolute',
					sync: true
				})
			], {
				duration: this.options.resizeDuration,
				afterFinish: callback.bind( this )
			} );
		}
		else
		{
			this.window.setStyle( {
				width: newWindowWidth + "px"
			} );
			
			this.window_header.setStyle( {
				width: newWindowWidth + "px"
			} );
			
			this.window_frame.setStyle( {
				width: newWindowWidth + "px"
			} );
			
			this.window_contentholder.setStyle( {
				width: ( newWindowWidth - this.options.addToContent.width ) + "px"
			} );
			
			this.window_content.setStyle( {
				width: ( (newWindowWidth+addToContentWidth) - this.options.addToContent.width ) + "px"
			} );
			
			this.window.setStyle( {
				left: dim.x,
				top: this.window.getStyle( "top" ) != null ? this.window.getStyle( "top" ).replace( /px/, "" ) : 0
			} );
			
			callback();
		}
	}
};

Sky.Window.PopUp = Class.create();

Sky.Window.PopUp.CONTENTTYPE_URI = 1;
Sky.Window.PopUp.CONTENTTYPE_CODE = 2;

Sky.Window.PopUp.prototype =
{
	initialize: function( className, opts )
	{
		// checking requirements
		Sky.Window._checkRequirements();
		
		this.className = className;
		
		this.options = {
			skyWindowOpts:		{},
			linkTag:			'a',
			contentGetTag:		'href',
			contentType:		Sky.Window.PopUp.CONTENTTYPE_URI
		};
		Object.extend( this.options, opts || {} );
		
		$$(this.options.linkTag + '.' + className).each( function ( link ) {
				link.observe( 'click', this._handleOnClick.bind( this ) );
		}.bind( this ) );
	},
	
	_handleOnClick: function ( event )
	{
		Event.stop( event );
		
		var link = event.element();
		
		if ( link.tagName.toLowerCase() != this.options.linkTag )
		{
			link = link.up( this.options.linkTag );	
		}
		
		var opts = this.options.skyWindowOpts;
		
		var contentCode = null;
		var contentURI = null;
		switch ( this.options.contentType )
		{
			case Sky.Window.PopUp.CONTENTTYPE_CODE:
				contentCode = $(link.getAttribute( this.options.contentGetTag )).innerHTML;
				break;
			default:
				contentURI = link.getAttribute( this.options.contentGetTag );
				break;
		}
		
		Object.extend( opts, { 'contentURL': contentURI, 'contentCode': contentCode } );
		
		new Sky.Window( opts );
		
		return false;
	}
};


// For compatibility reasons
var My;
if( !My ) My = {};
My.Window = Sky.Window;