(function($){
    $.fn.bubbleIndex = 0;
    $.fn.bubble = function(user_opts){
        var defaults = {
            data_src: "title",
            alone: true,
            once: false
        };
        if (typeof user_opts == "boolean") {
            var options = $.extend(defaults, {
                once: true
            });
        }
        else {
            var options = $.extend(defaults, user_opts);
        }
        
        function count(){
            return $.fn.bubbleIndex++;
        };
		
        return $(this).each(function(){
            if ($(this).data("bubble-loaded")) {
                return true;
            }
            else {
                $(this).data("bubble-loaded", true);
            }
            var index = count();
            var offset = $(this).offset(), boxPos = {}, content = new String();
            content = options.data_src && (typeof options.data_src == "string") ? this[options.data_src] : options.data_src.content;
            var box = $("<div />", {
                className: "bubble-box radius bubble-" + index,
                text: content,
            }).appendTo("body").hide();
            var arrow = $("<span />", {
                className: "fir bubble-arrow ",
            }).appendTo(box);
            this.title = "";
            box.css({
                left: offset.left - (box.outerWidth() - $(this).outerWidth()) * 0.5,
                top: offset.top - box.outerHeight() - 30
            });
            arrow.css({
                left: box.innerWidth() * 0.5 - 23,
                top: box.innerHeight()
            });
            if (options.once) {
                box.fadeIn(options.delay);
                var t = setTimeout(function(){
                    box.fadeOut(function(){
                        $(this).remove();
                    });
                }, 3000);
                box.click(function(){
                    $(this).remove();
                    clearTimeout(t);
                });
                $(this).data("bubble", index)
            }
            else {
                $(this).hover(function(){
                
                    box.hover(function(){
                        box.stop(true, true).show();
                    }, function(){
                        box.hide();
                    });
                }, function(){
                    box.hide();
                }).focus(function(){
                    if (options.alone) {
                        $(".bubble-box").hide();
                    }
                    box.fadeIn(options.delay);
                })
				.blur(function() {
					box.hide();
				})
				.data("bubble", index);
            }
            
        });
    };
    
    $.fn.showBubble = function(){
        return $(this).each(function(){
            $(this).mouseover();
        });
    };
    $.fn.clearBubble = function(){
        return $(this).each(function(){
            var index = $(this).data("bubble");
            if (index) {
                $(".bubble-" + index).remove();
            }
        });
    };
    $.bubble = function(selectors){
        if (selectors) {
            return $(selectors).each(function(){
                $(this).mouseover();
            });
        }
    };
})(jQuery);
