jQuery.fn.bubble = function(options) {
	var defaultOptions = {
		target: $(this).prev(),
		position: 'below', // below, above, left, right
		arrowOffset: 0
	};
	options = jQuery.extend(defaultOptions, options);
	
	var left, top, right, bottom = null;
	if(options.position == 'below') {
		left = $(options.target).offset().left - options.arrowOffset + ($(options.target).outerWidth() / 2);
		top = $(options.target).offset().top + $(options.target).outerHeight();
	}
	
	var cssChanges = { };
	if(left != null)
		cssChanges['left'] = Math.round(left);
	if(top != null)
		cssChanges['top'] = Math.round(top);
	if(right != null)
		cssChanges['right'] = Math.round(right);
	if(bottom != null)
		cssChanges['bottom'] = Math.round(bottom);

	cssChanges['display'] = 'block';
	
	$(this).css(cssChanges);
	$(this).click(function(e) { e.stopPropagation(); });
	
	var bubble = this;
	$('#BubbleMask').remove();
	$('body').append('<div id="BubbleMask"></div>');
	$('#BubbleMask')
		.css({
			position: 'absolute',
			top: 0,
			left: 0,
			width: $(document).width(),
			height: $(document).height()
		})
		.click(function(e) {
			$(bubble).hide();
			$(this).hide();
		});
	$('#BubbleMask').show();

	if($(this).data('initialized') === undefined) {
		$(this)
			.css({ 'z-index': 100 })
			.find('.Close').click(function(e) {
				e.preventDefault();
				
				$('#BubbleMask').trigger('click');
			});
		
		$(this).data('initialized', true);
	}
};

