
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	jQuery Simple Overlay

*/

(function($){


	$.fn.SimpleOverlay = function(options){	//-------------------------------------------------------------------------------	Start - Simple Overlay
		
		
		var o = $.extend({
			
			showByDefault: true,
			
			preventDefault: true,
			
			//Fallback ---------------------------------------------------
			fallbackId: 'fallback',							//id for the fallback
			fallbackStyle: {},								//Style for fallback - Object literal with style properties or function which returns object literal with style properties							
			
			fallbackAnimateInStyle: {opacity: 0.8},			//START - fallback animation properties
			fallbackAnimateOutStyle: {opacity: 0},			
			fallbackEffect: 'swing',						
			fallbackEffectDuration: 150,					//END	- fallback animation properties					
			fallbackClick: true,							//Flag for indicating whether fallback click is enabled
			
			//Overlay ----------------------------------------------------
			overlayRef: '#overlay',							//reference for overlay - 
			overlayStyle: {},								//Style for overlay - Object literal with style properties or function which returns object literal with style properties	
			overlayTop: null,								//Integer with top position of overlay on page
			overlayContent: null,							//Content for overlay inserted with the 'html()' function
			
			overlayEffect: 'swing',							//START	- overlay animation properties				
			overlayEffectDuration: 200,						//END	- overlay animation properties
			
			//Close button -----------------------------------------------
			hasCloseBtn: true,
			closeBtnClass: 'close',
			closeBtnText: 'close',
			closeBtnStyle: {},
			
			//Utility ----------------------------------------------------
			before: function(){}, 							//Executed before adding the overlay to the page
			after: function(){},							//Executed after displaying the overlay
			beforeHide: function(){},						//Executed before hiding the overlay		
			afterHide: function(){}						//Executed after hiding the overlay
				
		},options);
		
		//--------------------------------------------------------------------------------------	Start	-
		//--------------------------------------------------------------------------------------	End		-
		
		
		
		//--------------------------------------------------------------------------------------	Start	- Properties
		
			var $thisObj = this;
			
			var fallback = null;
			
			var overlay = null;
		
		
		//--------------------------------------------------------------------------------------	End		- Properties
		
		
		
		
		//--------------------------------------------------------------------------------------	Start	- Fallback
		
			function createFallback()
			{
				var fallbackStyle = (typeof o.fallbackStyle == 'function') ? o.fallbackStyle.call(this) : o.fallbackStyle;//Get style
				
				fallbackStyle = $.extend(fallbackStyle,{//Set up default style
					display: 'none',
					position: 'absolute',
					top: 0,
					left: 0,
					opacity: 0,
					width: $(document.body).width(),
					height: $(document).height()
						
				});
				
				fallback =  $('<div></div>')//Create fallback
					.css(fallbackStyle)
					.attr({
						id: o.fallbackId	
					})
					.click(function($e){
						if(o.fallbackClick)hide();	
					})
					.appendTo(document.body);
				
			}
			
			
			
			function refreshFallback()
			{
				setTimeout(function(){
					fallback.css({
						width: $(document.body).width(),
						height: $(document).height()	
					});	
				},100);
			}
			
			
		
		//--------------------------------------------------------------------------------------	End		- Fallback
		
		
		//--------------------------------------------------------------------------------------	Start	- Overlay
			
			function createOverlay()
			{
				var overlayRef = (typeof o.overlayRef == 'function') ? o.overlayRef.call(this) : o.overlayRef;//Get reference to overlay
				
				var overlayStyle = (typeof o.overlayStyle == 'function') ? o.overlayStyle.call(this) : o.overlayStyle;//Check if there is styling for close button
				
				overlayStyle = $.extend({//Set close button style
					display: 'none',
					opacity: 0,
					position: 'absolute',
					'z-index':999
				},overlayStyle);
				
				overlay = $(overlayRef).css(overlayStyle)//Set up overlay
				
			}
			
			function getOverlay()
			{
				if(o.overlayContent)
				{
					var overlayContent = (typeof o.overlayContent == 'function') ? o.overlayContent.call(this) : o.overlayContent;//Get reference to overlay
					overlay.html(overlayContent);//if there is content to be inserted, insert it
				}
				if(o.hasCloseBtn)createCloseBtn.call(this);//If the close button is enabled, add it
				refreshOverlay();//Refresh position of overlay after content has been populated into it
				overlay
					.css({
						display:'block',
						opacity: 0
					})
					.animate({opacity: 1},o.overlayEffectDuration,o.overlayEffect,function(){//Display overlay
						$(window).bind('resize',refreshOverlay);//Attach refreshOverlay to window resize event in order to monitor its position
						o.after();//After overlay has been loaded call the after function
					});
			}
			
			function setOverlayContent(str)
			{
				overlay.html(str);
				if(o.hasCloseBtn)createCloseBtn.call(this);
			}
			
			
			function getOverlayTrimming()
			{
				return {
					horizontal: (overlay.outerWidth() - overlay.width()),
					vertical: (overlay.outerHeight() - overlay.height())
				}
			}
			
			function getOverlayDimensions()
			{
				return{
					width: overlay.width(),
					height: overlay.height()	
				}
			}
			
			function refreshOverlay()
			{
				
				if(o.overlayTop)//If top position has been specified
				{
					var top = Math.round($(window).scrollTop() + o.overlayTop);	
				} else {//If top position has not been spcified
					if(overlay.outerHeight() > $(window).height())//If overlay is taller than window
					{
						var top = Math.round($(window).scrollTop() + o.overlayTop);	//Move to 50 pixels below top
					} else {
						var top = Math.round(($(window).scrollTop() + ($(window).height() / 2)) - (overlay.outerHeight() / 2));	//Center it accordingly
					}
				}
				
				overlay.css({
					top: top,
					left: Math.round(($(window).width() / 2) - (overlay.outerWidth() / 2))	
				});
				
				refreshFallback();	//Refresh fallback in order to prevent overlay from overflowing content area
					
			}
			
			function resize(settings)
			{
				
				var trimming = getOverlayTrimming();
				var childHeight = settings.height;
				var childWidth = settings.width;
				
				
				var overlayFinalHeight = trimming.vertical + childHeight;
				var overlayFinalWidth = trimming.horizontal + childWidth;
				
				if(o.overlayTop || (overlayFinalHeight > $(window).height()))//If top position has been specified
				{
					var top = Math.round($(window).scrollTop() + o.overlayTop);	
				} else {//If top position has not been spcified
					var top = Math.round(($(window).scrollTop() + ($(window).height() / 2)) - (overlayFinalHeight / 2));	//Center it accordingly
				}
				
				overlay.animate({
					height: childHeight,
					width: childWidth,
					top: top,
					left: Math.round(($(window).width() / 2) - (overlayFinalWidth / 2))
				},o.overlayEffectDuration,o.overlayEffect,function(){//Display overlay
					refreshFallback();	
					if(settings.after)settings.after();
				});
				
				
					
			}
		
		
		
		//--------------------------------------------------------------------------------------	End		- Overlay
		
		
		//--------------------------------------------------------------------------------------	Start	- closeBtn
		
		
			function createCloseBtn()
			{
				var closeBtnStyle = (typeof o.closeBtnStyle == 'function') ? o.closeBtnStyle.call(this) : o.closeBtnStyle;//Check if there is styling for close button
				
				closeBtnStyle = $.extend({//Set close button style
					display: 'block',
					position: 'absolute',
					top: 0,
					right: 0
				},closeBtnStyle);
				
				$('<a></a>')
					.attr({
						href: '#'	
					})
					.addClass(o.closeBtnClass)
					.text(o.closeBtnText)
					.click(function($e){
						$e.preventDefault();
						hide();	
					})
					.appendTo(overlay);	
			}
		
		
		
		//--------------------------------------------------------------------------------------	End		- closeBtn
		
		
		
		//--------------------------------------------------------------------------------------	Start	- hide()
		
			function show()
			{
				var fallbackAnimateInStyle = (typeof o.fallbackAnimateInStyle == 'function') ? o.fallbackAnimateInStyle.call(this) : o.fallbackAnimateInStyle;//Get fallback animation
				fallback.css({opacity:0,display:'block'}).animate(fallbackAnimateInStyle,o.fallbackEffectDuration,o.fallbackEffect,function(){//Display fallback
					$(window).bind('resize',refreshFallback);//Attach refreshFallback to windw resize listener in order to track monitor its size
					getOverlay.call(this);//Display overlay
				});
			}
		
			function hide()//Hides the overlay
			{
				o.beforeHide();//Execute before hiding the overlay
				
				if(fallback)
				{
					var fallbackAnimateOutStyle = (typeof o.fallbackAnimateOutStyle == 'function') ? o.fallbackAnimateOutStyle.call(this) : o.fallbackAnimateOutStyle;	
					fallback.stop().animate(fallbackAnimateOutStyle,o.fallbackEffectDuration,o.fallbackEffect,function(){
						fallback.css({
							opacity: 0,
							display: 'none'	
						});
					});
				}
				
				if(overlay)
				{
					overlay.stop().animate({opacity:0},o.overlayEffectDuration,o.overlayEffect,function(){
						$(window).unbind('resize',refreshOverlay);
						overlay.css({
							display: 'none'	
						});
						o.afterHide();//Execute after hiding the overlay	
					});	
				}
				
			}
		
		//--------------------------------------------------------------------------------------	End		- hide()
		
		
		//--------------------------------------------------------------------------------------	Start	- API
		
		this.hide = function(){hide();};//Hides the overlay
		
		this.getOverlayTrimmings = function(){
			return getOverlayTrimming.call(this);
		};
		
		this.getOverlayDimensions = function(){
			return getOverlayDimensions.call(this);
		};
		
		this.setContent = function(str){
			setOverlayContent.call(this,str);
		};
		
		this.resize = function(settings){
			var s = $.extend({
				width: overlay.innerWidth(),
				height: overlay.innerHeight()
			},settings);
			resize.call(this,s);
		}
		
		this.show = function(){
			show.call(this);
		};
		
		this.refreshFallback = function(){
			refreshFallback.call(this);	
		};
		
		//--------------------------------------------------------------------------------------	End		- API
		
		//--------------------------------------------------------------------------------------	Start	- Init
		
		createOverlay.call(this);
		createFallback.call(this);
		
		return this.each(function(){
			
			var overlayRef = (typeof o.overlayRef == 'function') ? o.overlayRef.call(this) : o.overlayRef;//Get reference to this anchor's overlay
			$(overlayRef).css({display:'none'});//Hide this anchor's overlay
			$(this).click(function($e){//Attach click event to anchor
				
				var e = this;//Keep reference to this anchor
				
				if(o.preventDefault)$e.preventDefault();//If default action is to be prevented
				
				if(!o.showByDefault)return;
				
				o.before();//Call this function before loading overlay
				show.call($thisObj);
				
			});
			
		});	
		
		//--------------------------------------------------------------------------------------	End		- Init
		
	}; //---------------------------------------------------------------------------------------------------------------------	End - Simple Overlay

	
	
	
})(jQuery);
