/** 
 * @file jquery.ds.popabove.js
 * @ver 0.1
 *
 * Copyright (c) 2010 Dániel Sólyom (DS)
 *
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * 2010-04-01
 */

(function($) {
	$.fn.popAbove = function(request) 
	{
		var me = $(this);
		var onSuccess;
		
		if (me[0].popAboveStarted) {
			return;
		}

		me[0].popAboveStarted = true;

		if (me[0] == document) {
			onSuccess = me.popAboveFade;
		} else {
			onSuccess = me.popAboveLoaded;
		}
		
		if (request.type == 'image') {
			onSuccess('<img src="' + request.url + '" alt=" + request.url + "/>');
			return true;
		}
		
		$.ajax({ url: request.url, 
                      cache: false, context: this,
                      data: request,
                      success: onSuccess
        });
	}
	
	$.fn.popAboveFade = function()
	{
		bg = $('<div></div>').attr('Id', 'pop-above-bg')
							 .css('background-color', '#000000')
							 .css('position', 'absolute')
							 .css('z-index', 99999)
							 .css('width', $(document).width())
							 .css('height', $(document).height())
							 .css('top', 0)
							 .css('left', 0)
							 .fadeTo(1,0);
		$('body').append(bg);
		
		html = arguments[0];
		
		bg.ready(function() {
			bg.fadeTo('', 0.75, function() { $(document).popAboveLoaded(html) });
		});
	}
	
	$.fn.popAboveLoaded = function()
	{
		var me = $(this);

		var target,
			targetWidth,
			targetHeight,
			targetOffset,
			left,
			top;

		if (me[0] == document) {
			target = $(window);
		
			targetOffset = { 'left': target.scrollLeft(), 'top': target.scrollTop() };

			left = (targetWidth = target.width()) / 2 + targetOffset.left;
			top = (targetHeight = target.height()) / 2 + targetOffset.top;
		} else {
			targetOffset = me.offset();
			left = (targetWidth = me.width()) / 2 + targetOffset.left;
			top = (targetHeight = me.height()) / 2 + targetOffset.top;
		}

		var container = $('<div></div>').attr('Id', 'pop-above-container')
										.css('position', 'absolute')
										.css('left', '-10000px')
										.css('top', top + 'px')
										.css('z-index', 100000)
										.css('overflow', 'hidden');
		
		var content;
		
		if (typeof( content = arguments[0] ) != 'object') {
			content = $('<div></div>').attr('Id', 'pop-above-content')
									  .attr('innerHTML', arguments[0]);
		}
		
		if (me[0] == document) {
			$('body').append(content);
		} else {
			me.after(content);
		}
		content.wrap(container);

		container = $('#pop-above-container');
		container[0].target = me;

		content.ready(function() {
			var contentWidth = container.width();
			var contentHeight = container.height();
			
			content.width(contentWidth);

			container.css('left', left + 'px')
				     .width(0)
				     .height(0);

			if (me[0] == document) {
				content.css('position', 'absolute')
					   .css('left', (targetWidth - contentWidth) / 2)
				       .css('top', (targetHeight - contentHeight) / 2);
				container.animate({ 'left' : targetOffset.left, 'top': targetOffset.top, 
									'width': targetWidth, 'height': targetHeight }, 500, me.popAboveFinish);
			} else {
				content.css('position', 'absolute')
					   .css('left', 0)
					   .css('top', 0);
				me.css('overflow', 'hidden')
				  .animate({ 'width': (contentWidth),
							 'height': (contentHeight)
				});
				
				var windowTopPos = targetOffset.top;
				
				if (contentHeight < (wHeight = $(window).height())) {
					windowTopPos -= wHeight - contentHeight;
				}
				if (windowTopPos < 0) {
					windowTopPos = 1;
				}
				
				$(window).scrollTop( windowTopPos );
				container.animate({ 'left' : targetOffset.left, 'top': targetOffset.top, 
									'width': contentWidth, 'height': contentHeight }, 500, me.popAboveFinish);
			}
		});
	}
	
	$.fn.popAboveFinish = function() 
	{
		me = $(this);

		if (this.target[0] == document) {
			target = $(window);
			target.scroll(function() {
				me.css('left', target.scrollLeft())
				  .css('top', target.scrollTop());
				
				return false;
			});
		} else {
			this.target.hide();
			me.css('position', 'relative')
			  .css('left', 0)
			  .css('top', 0)
			  .css('z-index', 0);
		}
		this.target[0].popAboveStarted = false;
	}
})(jQuery);
