/*
	Plugin Popup v1.0.0
	http://imperavi.com/
 
	Copyright 2010, Imperavi Ltd.
	Dual licensed under the MIT or GPL Version 2 licenses.
*/
(function($){
	
	// Initialization
	$.fn.popup = function(options)
	{
		return this.each(function() {
			var obj = new Construct(this, options);
			obj.init();
			
			// Global
			$.popupClose = function() {
				obj.close(false);
			};	
			
		});
	};	
	
	// Options and variables	
	function Construct(el, options) {

		this.opts = $.extend({
			id: 'imp_popup',
			className: 'imp_popup',
			event: 'click',
			effect: false,
			content: false,			
			url: false,		
			width: '200px',
			zIndex: 10000	
		}, options);	


		this.$el = $(el);
		
	};

	// Functionality
	Construct.prototype = {
		init: function()
		{	

			// handlers
			this.escHandler = function(e) { if( e.keyCode == 27) this.close(false); }.bind(this); 	
			this.closeHandler = function(e) { this.close(e); }.bind(this); 	
		
			this.popup = $('#' + this.opts.id);
			

			
			var self = this;
			
			this.$el.addClass('imp_popup_handler');
			
		
			this.$el.bind(this.opts.event, function(e){ self.show(e) });
			if (this.opts.event == 'mouseover') this.$el.bind('mouseout', function(e){ self.close(e, true) });


	
		},
		show: function(e)
		{
			if (typeof(this.opts.content) == 'object') this.content = this.opts.content.html();
			else if (typeof(this.opts.content) == 'string') this.content = this.opts.content;
			
			if (this.opts.url)
			{
				var self = this;
				$.ajax({
					url: this.opts.url,
					cache: false,
					success: function(content)
					{
						self._show(e, content);
					}
				});			
			}
			else this._show(e, this.content);
		},
		_show: function(e, content)
		{	

			var element = $(e.target);
			var pos = element.offset();
			var width = element.width();
			var height = element.height();			
			var right = $(document).width() - pos.left - width;
			var popup_width = this.normalize(this.opts.width);
		

			this.popup.removeClass().addClass(this.opts.className).css({ width: this.opts.width, zIndex: this.opts.zIndex }).html(content);
			
			if ($.browser.msie)
			{
				this.popup.css('border', '1px solid #ccc');
			}
			
			
			if (right < popup_width)
			{			

				var x = right;
				var y = pos.top + height;
				
				this.popup.css({ top: y + 'px', left: 'auto', right: x + 'px' });		

			}
		
			else
			{
				var x = pos.left;
				var y = pos.top + height;
				
				this.popup.css({ top: y + 'px', left: x + 'px', right: 'auto' });		
			}


		
			if (this.opts.effect === false) this.popup.show();	
			else if (this.opts.effect == 'slide') this.popup.slideDown();	
			else if (this.opts.effect == 'fade') this.popup.fadeIn();				
			
			$(document).keypress(this.escHandler);			
			$(document).click(this.closeHandler);	


				
				
		},
		close: function(e, link)
		{

			if (e !== false) 
			{
				if ($(e.target).hasClass('imp_popup_handler'))
				{
					if (link !== true) return false;				
				}
				
				if ($(e.target).attr('id') == this.opts.id) return false;
				else if ($(e.target).parents('#' + this.opts.id).size() != 0) return false;
			}
			
			
			if (this.opts.effect === false) this.popup.hide();	
			else if (this.opts.effect == 'slide') this.popup.slideUp();	
			else if (this.opts.effect == 'fade') this.popup.fadeOut();				
			
			$(document).unbind('keypress', this.escHandler);
			$(document).unbind('click', this.closeHandler);	
			
			
		},
		normalize: function(str)
		{
			return new Number(new String(str).replace('px',''));
		}			
	};
	
	// bind
	Function.prototype.bind = function(object)
	{
	    var method = this; var oldArguments = $.makeArray(arguments).slice(1);
	    return function (argument)
	    {
	        if (argument == new Object) { method = null; oldArguments = null; }
	        else if (method == null) throw "Attempt to invoke destructed method reference.";
	        else { var newArguments = $.makeArray(arguments); return method.apply(object, oldArguments.concat(newArguments)); }
	    };
	}		
	
})(jQuery);


