﻿(function ($) {
    $.fn.tooltip = function (options) {
        var lastOpened = null;

        options = $.extend({
            boxClass: "tooltip-box",
            contentClass: "tooltip-content",
            closeClass: "tooltip-close",
            overClass: "tooltip-above",
            underClass: "tooltip-under",
            yoffset: 10,
            xoffset: 10,
            openOn: 'click',
            closeOn: '',
            animationSpeed: 100,
            closeOnDocumentClick: true,
            followMouse: false
        }, options);

        var fixPosition = function (tip) {
            if (tip.offset().top > ($(document).scrollTop() + $(window).height() / 2)) {
                tip.css("top", (tip._tooltip.trigger.offset().top - options.yoffset - tip.height()) + "px");
                tip.removeClass(options.underClass).addClass(options.overClass);
            }
        }

        // Close tooltip when clicked outside?
        if (options.closeOnDocumentClick) {
            $(document).click(function () {
                if (lastOpened != null && lastOpened.is(":visible")) {
                    var temp = lastOpened;
                    lastOpened.animate({ opacity: 0 }, { duration: options.animationSpeed, complete: function () { temp.hide(); } });
                    lastOpened = null;
                }
            });
        }

        if (window.tooltips == undefined)
            window.tooltips = {};


        return this.each(function (idx, item) {
            var jqItem = $(item);
            if (typeof (jqItem[options.openOn]) == 'function') {
                var box = window.tooltips['tooltip' + jqItem.attr('rel')];
                jqItem[options.openOn](function (e) {
                    e.preventDefault();
                    e.stopPropagation();

                    var pos = $(this).offset();

                    // Close other tooltip, if any opened
                    if (lastOpened != null) {
                        var temp = lastOpened;
                        if (lastOpened != box) lastOpened.animate({ opacity: 0 }, { duration: options.animationSpeed, complete: function () { temp.hide(); } });
                        else return;
                    }

                    // Create wrapper box if needed
                    if (!box) {
                        box = $('<div class="' + options.boxClass + '"></div>').css({
                            position: 'absolute',
                            zindex: 99,
                            opacity: 0,
                            left: pos.left + "px"
                        }).appendTo($('body'));

                        box._tooltip = {}
                        box._tooltip.mouseMove = function (e) {
                            box.css('left', (e.pageX - (box.width() / 2) + options.xoffset) + 'px');
                            if (box.offset().top > ($(document).scrollTop() + $(window).height() / 2))
                                box.css('top', (e.pageY - box.height() - 2 - options.yoffset) + 'px').removeClass(options.underClass).addClass(options.overClass);
                            else
                                box.css('top', (e.pageY + 2 + options.yoffset) + 'px');
                        };
                        box._tooltip.trigger = jqItem;

                        var content = $("#" + jqItem.attr("rel")).show().appendTo(box);

                        $("." + options.closeClass, content).click(function () {
                            box.animate({ opacity: 0 }, { duration: options.animationSpeed, complete: function () { box.hide(); } });
                            lastOpened = null;
                            $(document).unbind('mousemove', box._tooltip.mouseMove);
                        });

                        window.tooltips['tooltip' + jqItem.attr('rel')] = box;
                    }

                    box.addClass(options.underClass).removeClass(options.overClass);
                    box.css("top", pos.top + jqItem.height() + options.yoffset + "px");
                    box.css("left", (pos.left + (jqItem.width() /* / 2 */) + options.xoffset) + "px");

                    if (options.followMouse)
                        $(document).mousemove(box._tooltip.mouseMove);
                    else
                        fixPosition(box);

                    box.show().animate({ opacity: 1 }, options.animationSpeed);
                    lastOpened = box;
                });


            }
            // Any close trigger?
            if (typeof (jqItem[options.closeOn]) == 'function') {
                jqItem[options.closeOn](function () {
                    box.animate({ opacity: 0 }, { duration: options.animationSpeed, complete: function () { box.hide(); } });
                    $(document).unbind('mousemove', lastOpened._tooltip.mouseMove);
                    lastOpened = null;
                });
            }
        });
    };
})(jQuery); 
