Control.WindowExtended = Class.create(Control.Window,{
    open: function(event){
            if(this.isOpen){
                    this.bringToFront();
                    return false;
            }
            if(this.notify('beforeOpen') === false)
                    return false;
            //closeOnClick
            if(this.options.closeOnClick){
                    if(this.options.closeOnClick === true)
                            this.closeOnClickContainer = $(document.body);
                    else if(this.options.closeOnClick == 'container')
                            this.closeOnClickContainer = this.container;
                    else if (this.options.closeOnClick == 'overlay'){
                            Control.Overlay.load();
                            this.closeOnClickContainer = Control.Overlay.container;
                    }else
                            this.closeOnClickContainer = $(this.options.closeOnClick);
                    this.closeOnClickContainer.observe('click',this.closeHandler);
            }
            if(this.href && !this.options.iframe && !this.remoteContentLoaded){
                    //link to image
                    this.remoteContentLoaded = true;
                    if(this.href.match(/\.(jpe?g|gif|png|tiff?)$/i)){
                            var img = new Element('img');
                            img.observe('load',function(img){
                                    this.getRemoteContentInsertionTarget().insert(img);
                                    this.position();
                                    if(this.notify('onRemoteContentLoaded') !== false){
                                            if(this.options.indicator)
                                                    this.hideIndicator();
                                            this.finishOpen();
                                    }
                            }.bind(this,img));
                            img.writeAttribute('src',this.href);
                    }else{
                            //if this is an ajax window it will only open if the request is successful
                            if(!this.ajaxRequest){
                                    if(this.options.indicator)
                                            this.showIndicator();
                                    this.ajaxRequest = new Ajax.Request(this.href,{
                                            method: 'post',
                                            parameters: this.options.parameters,
                                            onComplete: function(request){
                                                    this.notify('onComplete',request);
                                                    this.ajaxRequest = false;
                                            }.bind(this),
                                            onSuccess: function(request){
                                                    this.getRemoteContentInsertionTarget().update(request.responseText);
                                                    this.notify('onSuccess',request);
                                                    if(this.notify('onRemoteContentLoaded') !== false){
                                                            if(this.options.indicator)
                                                                    this.hideIndicator();
                                                            this.finishOpen();
                                                    }
                                                    this.remoteContentLoaded = false;
                                            }.bind(this),
                                            onFailure: function(request){
                                                    this.notify('onFailure',request);
                                                    if(this.options.indicator)
                                                            this.hideIndicator();
                                            }.bind(this),
                                            onException: function(request,e){
                                                    this.notify('onException',request,e);
                                                    if(this.options.indicator)
                                                            this.hideIndicator();
                                            }.bind(this)
                                    });
                            }
                    }
                    return true;
            }else if(this.options.iframe && !this.remoteContentLoaded){
                    //iframe
                    this.remoteContentLoaded = true;
                    if(this.options.indicator)
                            this.showIndicator();
                    this.getRemoteContentInsertionTarget().insert(Control.Window.iframeTemplate.evaluate({
                            href: this.href
                    }));
                    var iframe = this.container.down('iframe');
                    iframe.onload = function(){
                            this.notify('onRemoteContentLoaded');
                            if(this.options.indicator)
                                    this.hideIndicator();
                            iframe.onload = null;
                    }.bind(this);
            }
            this.finishOpen(event);
            return true
    }    
});

Control.ModalExtended = Class.create(Control.WindowExtended,{
	initialize: function($super,container,options){
		Control.ModalExtended.InstanceMethods.beforeInitialize.bind(this)();
		$super(container,Object.extend(Control.ModalExtended.defaultOptions,options || {}));
	}
});
Object.extend(Control.ModalExtended,{
	defaultOptions: {
		overlayOpacity: 0.5,
		closeOnClick: 'overlay'
	},
	current: false,
	open: function(container,options){
		var modal = new Control.ModalExtended(container,options);
		modal.open();
		return modal;
	},
	close: function(){
		if(Control.ModalExtended.current)
			Control.ModalExtended.current.close();
	},
	InstanceMethods: {
		beforeInitialize: function(){
			Control.Overlay.load();
			this.overlayFinishedOpening = false;
			this.observe('beforeOpen',Control.ModalExtended.Observers.beforeOpen.bind(this));
			this.observe('afterOpen',Control.ModalExtended.Observers.afterOpen.bind(this));
			this.observe('afterClose',Control.ModalExtended.Observers.afterClose.bind(this));
		}
	},
	Observers: {
		beforeOpen: function(){
			if(!this.overlayFinishedOpening){
				Control.Overlay.observeOnce('afterShow',function(){
					this.overlayFinishedOpening = true;
					this.open();
				}.bind(this));
				Control.Overlay.show(this.options.overlayOpacity,this.options.fade ? this.options.fadeDuration : false);
				throw $break;
			}else
			Control.Window.windows.without(this).invoke('close');
		},
		afterOpen: function(){
			Control.ModalExtended.current = this;
		},
		afterClose: function(){
			Control.Overlay.hide(this.options.fade ? this.options.fadeDuration : false);
			Control.ModalExtended.current = false;
			this.overlayFinishedOpening = false;
		}
	}
});

Control.LightBox = Class.create(Control.Window,{
	initialize: function($super,container,options){
		this.allImagesLoaded = false;
		if(options.modal){
			var options = Object.extend(Control.LightBox.defaultOptions,options || {});
			options = Object.extend(Control.ModalExtended.defaultOptions,options);
			options = Control.ModalExtended.InstanceMethods.beforeInitialize.bind(this)(options);
			$super(container,options);
		}else
			$super(container,Object.extend(Control.LightBox.defaultOptions,options || {}));
		this.hasRemoteContent = this.href && !this.options.iframe;
		if(this.hasRemoteContent)
			this.observe('onRemoteContentLoaded',Control.LightBox.Observers.onRemoteContentLoaded.bind(this));
		else
			this.applyImageObservers();
		this.observe('beforeOpen',Control.LightBox.Observers.beforeOpen.bind(this));
	},
	applyImageObservers:function(){
		var images = this.getImages();
		this.numberImagesToLoad = images.length;
		this.numberofImagesLoaded = 0;
		images.each(function(image){
			image.observe('load',function(image){
				++this.numberofImagesLoaded;
				if(this.numberImagesToLoad == this.numberofImagesLoaded){
					this.allImagesLoaded = true;
					this.onAllImagesLoaded();
				}
			}.bind(this,image));
			image.hide();
		}.bind(this));
	},
	onAllImagesLoaded: function(){
		this.getImages().each(function(image){
			this.showImage(image);
		}.bind(this));
		if(this.hasRemoteContent){
			if(this.options.indicator)
				this.hideIndicator();
			this.finishOpen();
		}else
			this.open();
	},
	getImages: function(){
		return this.container.select(Control.LightBox.imageSelector);
	},
	showImage: function(image){
		image.show();
	}
});
Object.extend(Control.LightBox,{
	imageSelector: 'img',
	defaultOptions: {},
	Observers: {
		beforeOpen: function(){
			if(!this.hasRemoteContent && !this.allImagesLoaded)
				throw $break;
		},
		onRemoteContentLoaded: function(){
			this.applyImageObservers();
			if(!this.allImagesLoaded)
				throw $break;
		}
	}
});