/* 
 *	WhiteBox - Whitespace content overlay. 
 *		Richard Assar
 */	

/* WhiteBox */
var WhiteBox = Class.create({			
	state : { 
		active: false 
	},			
	
	options : {
		clickBackgroundToClose : true,
		corners : ["tl", "tr", "bl", "br"],
		bgColor : "#000",
		bgOpacity : 0.25,
		fadeDuration : 0.5,
		width : 400, 
		height : 400,
		minWidth : 200,
		minHeight : 200,
		maximised : false,
		maximisedMargin : 100,
		controls : {}
	},

	isset : function(variable) { return typeof(variable) != 'undefined'; },
	
	merge : function(obj1, obj2) {
		for(var p in obj2){
			if(obj2[p] !== undefined) {
				obj1[p] = obj2[p];
			}
		}
		
		return obj1;
	},
	
	insertControls : function(collection, extraClass) {						
		collection.each(function(i) {						
	    	var anchor = new Element('a', { "class" : i.anchor_class }).update(i.anchor).observe("click", i.callback);
	    	
	    	if(i.hasSpan == true) { 
	    		anchor.insert(new Element('span')); 	    		
    		}
	    	
	    	var li = new Element('li', { "class" : i.li_class }).insert(anchor)			    		
	    	
	    	if(extraClass !== undefined) { 
	    		li.addClassName(extraClass); 	    		
    		}
	    	
			this.controls.insert(li);		    		    
		}.bind(this));
	},

	initialize : function(options) {						    
		/* Init	*/		
		this.options = this.merge(this.options, options);		
		
		if(!this.isset(this.options.width) && !this.isset(this.options.height)) {			    	        	        		    		    
			this.options.maximised = true;
		}
		
		var dimensions = document.viewport.getDimensions();
		var scrollOffsets = document.viewport.getScrollOffsets();
										
		/* Create elements */
								
		// Background
		this.background = new Element('div', {
			id : "whitebox_bg",			
			style : "position:absolute; left:0; top:0; width:100%;"
		});
		
		this.background			
			.hide()				
			.setStyle({ background : this.options.bgColor });							
			
		if(this.options.clickBackgroundToClose) {			
			this.background.observe("click", function() {
				this.close();
			}.bind(this));
		}
	
		// Overlay
		this.overlay = new Element('div', {			
			id : "whitebox_overlay",
			style : "position:absolute; top:50%; left:50%; margin: -5px 0 0 -5px;"
		}).hide().setStyle({ 
			top : Prototype.Browser.IE ? (dimensions.height - this.options.height) / 2 + "px" : '50%',
			width : this.options.width + "px", 
			height : this.options.height + "px",
			margin : Prototype.Browser.IE ? "0 0 0 " + (-this.options.width / 2) + "px" : (-this.options.height / 2) + "px 0 0 " + (-this.options.width / 2) + "px"		   
		})
						
		// Overlay Content
		this.overlay_content = new Element('div', {
			id : "whitebox_overlay_content"
		});
			
		this.overlay.insert(this.overlay_content);
		
		// Insert controls				    
		this.controls = new Element('ul', {
		    id : "whitebox_controls"
	    });
	    
	    this.insertControls(this.options.controls);
		
	    this.overlay.insert(this.controls);
		
		// Spinner
		this.spinner = new Element('div', {
			id : 'whitebox_spinner'
		}).hide().insert(
			new Element('img', {			        
				src : 'images/whitebox-loader.gif'
			})			    
		);
		
		this.spinner.setStyle({
		    position : Prototype.Browser.IE ? "absolute" : "fixed", 
			top : "50%",
			left : "50%", 
			width : "32px",
			height : "32px",
			margin : "-16px 0 0 -16px",
			background : "#000"
		});
						
		// Insertion of main elements
		$(document.body).insert(this.spinner);				
		$(document.body).insert(this.background);		
		$(document.body).insert(this.overlay);						

		/* Corners */
		if(this.options.corners.length > 0) {
			this.options.corners.each(function(i) {			
				this.overlay.insert('<span class="corner ' + i + '"></span>');				
			}.bind(this));
		}
		
		/* Browser dependant onscroll & onresize handler */
		if(Prototype.Browser.IE) {								    			
			Event.observe(window, "scroll", function(event) {			
				var dimensions = document.viewport.getDimensions();			
				var scrollOffsets = document.viewport.getScrollOffsets();
									
				this.spinner.setStyle({ top : scrollOffsets.top + (dimensions.height - 32) / 2 + "px" });			
				
				this.background.setStyle({ top : scrollOffsets.top + "px"});			
				
				if(this.options.maximised) {
					this.overlay.setStyle({ top : (scrollOffsets.top + this.options.maximisedMargin / 2) + "px" });
				} else {
					this.overlay.setStyle({ top : (scrollOffsets.top + (dimensions.height - this.options.height) / 2) + "px" });
				}				
			}.bind(this));
						
			Event.observe(window, "resize", function() {
				var dimensions = document.viewport.getDimensions();
				var scrollOffsets = document.viewport.getScrollOffsets();
							
				this.background.setStyle({ top : scrollOffsets.top + "px", width : dimensions.width + "px", height : dimensions.height + "px" });		
				
				if(this.options.maximised) {
					this.overlay.setStyle({ top : (scrollOffsets.top + this.options.maximisedMargin / 2) + "px" });
				} else {
					this.overlay.setStyle({ top : (scrollOffsets.top + (dimensions.height - this.options.height) / 2) + "px" });
				}	
			}.bind(this));	
		
			this.background.setStyle({ top : scrollOffsets.top + "px", width : dimensions.width + "px", height : dimensions.height + "px" });		
		} else {
			this.background.setStyle({
				position : "fixed",
				height:"100%"				
			});
			
			this.overlay.setStyle({
				position : "fixed"
			});
		}						        				
		
		/* Onresize: resize to viewport if maximised. */
		Event.observe(document.onresize ? document : window, "resize", function() {
			if(this.options.maximised) {     
			   this.maximise();
			}
		}.bind(this));		
	},
	
	show : function() {
		/* Show */
		this.background.appear({ duration : this.options.fadeDuration, from : 0, to : this.options.bgOpacity });
		this.overlay.appear({ duration : this.options.fadeDuration, from : 0, to : 1 });				
	},
	
	maximise : function() {	    	    	    	    
		var dimensions = document.viewport.getDimensions();    		 		    
		
		if(dimensions.width - this.options.maximisedMargin < this.options.minWidth) {		    
			dimensions.width = this.options.minWidth + this.options.maximisedMargin; 
		}
		
		if(dimensions.height - this.options.maximisedMargin < this.options.minHeight) {		    
			dimensions.height = this.options.minHeight + this.options.maximisedMargin; 
		}
		
		this.resize({ width : dimensions.width - this.options.maximisedMargin, height : dimensions.height - this.options.maximisedMargin });    				    
	},
	
	minimise : function() {	           
		this.options.maximised = false;
		
		this.resize({ width : this.options.width, height : this.options.height });    				    
	},
	
	display : function(options) {	    						
		/* Check state */
		if(this.state.active)
			return;					
			
		this.state.active = true;			
		
		/* Set size if set in options */
		if(options.width !== undefined && options.height !== undefined) {
			this.setSize({ width : options.width, height : options.height });    				    
		}		
		
		/* If maximised, maximise */	    
		if(this.options.maximised) {
			this.maximise();
		} else {
			this.minimise();
		}
								
		if(options.extraControls !== undefined) {
			this.insertControls(options.extraControls, "extra");				
		}
		
		/* Add optional content class */
		if(options.overlayClass !== undefined) {
			this.overlay.addClassName(options.overlayClass);
		}
		
		/* Display modes */	
		switch(options.mode) {
			case "inline":
				// Insert content
				this.overlay_content.update(options.content);												
				
				// Show
				this.show();
				
				break;
				
			case "element":				
				if(options.inheritSize && !this.options.maximised) {
					this.overlay.setStyle({
						width : "auto",
						height : "auto"
					});
				}
				
				// Insert content							
				if(options.clone) {	
					this.overlay_content.update(options.element.cloneNode(true));
				} else {
					this.overlay_content.update(options.element);
				}
								
				// Inherit size
				if(options.inheritSize && !this.options.maximised) {			        			        
					var dimensions = this.overlay.getDimensions();			        			    
					
					this.resize({ width : dimensions.width, height : dimensions.height });    				  
				}
				
				// Show
				this.show();
				
				break;
				
			case "iframe":										 					
				this.overlay_content.update(
					new Element('iframe', {
						src : options.url,
						width : "100%",
						height : "100%"
					})
				);				
				
				// Show
				this.show();			  		
				
				break;
			
			case "ajax":										    		        
				//this.spinner.appear({ duration : 1, from : 0, to : 1 });
				this.spinner.show();
				
				new Effect.Pulsate(this.spinner, {
					pulses : 5,
					from : 0.5,
					duration : 10
				});

				new Ajax.Request(options.url, {					
					method : options.method,
					parameters : options.parameters,
					onSuccess: function(transport) {			      					      					      					      				      					      			
						// Remove spinner
						this.spinner.hide();
						
						// Insert content			    		
						this.overlay_content.update(transport.responseText);
						
						// Show
						this.show();			  		
						
					}.bind(this)
				});
				
				break;				
				
			default:				
				// Invalid mode.
								
				return;
		}																			
		
		/* On Add */
		if(this.options.onAddContent) {
			this.options.onAddContent();
		}
		
		if(options.onDisplay !== undefined) {
			options.onDisplay();
		}
	},	
	
	close : function (callback) {
		/* Close whitebox */
		if(!this.state.active) {
			return; 
		}
		
		this.state.active = false;
		
		this.background.fade({ duration : this.options.fadeDuration });
		
		this.overlay.fade({
			duration : this.options.fadeDuration, 
			afterFinish : function() {
				/* Remove content class */
				this.overlay.setAttribute('class', '');
				
				/* Remove extra controls */
				var extraControls = this.controls.select(".extra");
								
				if(extraControls !== undefined) {
					extraControls .each(function(i) {
						i.remove();
					});
				}				
				
				/* Fire callback */
				if(callback !== undefined) {
					callback();								
				}
			}.bind(this)			
		});										
	},
	
	setSize : function(options) {				
		this.resize(options);
		
		this.options.width = options.width;
		this.options.height = options.height;		
	},
	
	resize : function(options) {			    
		this.overlay.setStyle({ 
			width : options.width + "px", 
			height : options.height + "px",
			margin : Prototype.Browser.IE ? "0 0 0 " + (-options.width / 2) + "px" : (-options.height / 2) + "px 0 0 " + (-options.width / 2) + "px"
		});			
		
		/* Set top in IE */
		if(Prototype.Browser.IE) {		
			var dimensions = document.viewport.getDimensions();			
			var scrollOffsets = document.viewport.getScrollOffsets();
								
			if(this.options.maximised) {
				this.overlay.setStyle({ top : (scrollOffsets.top + this.options.maximisedMargin / 2) + "px" });
			} else {
				this.overlay.setStyle({ top : (scrollOffsets.top + (dimensions.height - this.options.height) / 2) + "px" });
			}	
		}										
	}
});