/**
 * Popup bubbles.
 *
 * @author Nikita Vershinin <me@endeveit.net>
 */
(function($) {
    $(document).ready(function() {
        $.fn.popup = function(options) {
            var
                hideDelayTimer = null,
                objectOut      = true,
                popupOut       = true,
                popupShown     = false,
                defaults       = {
                    hideDelay     : 200,
                    popupObject   : null,
                    duration      : 10,
                    mouseoverCb   : null,
                    mouseoutCb    : null,
                    animationOver : {
                        opacity : 'show'
                    },
                    animationOut  : {
                        opacity : 'hide'
                    }
                },
                checkTimer = function() {
                    if (hideDelayTimer) {
                        clearTimeout(hideDelayTimer);
                    }
                },
                setTimer = function() {
                    hideDelayTimer = setTimeout(timeoutCallback, opts.hideDelay);
                },
                timeoutCallback = function() {
                    if (objectOut && popupOut) {
                        hideDelayTimer = null;
                        $(opts.popupObject).animate(opts.animationOut, opts.duration, 'swing', function() {
                            popupShown = false;

                            if (opts.mouseoutCb) {
                                opts.mouseoutCb.call();
                            }
                        });
                    }
                };

            // Extend our default options with those provided
            var opts = $.extend(defaults, options);

            $(this).mouseover(function() {
                checkTimer();

                if (popupShown) {
                    // don't trigger the animation again
                    return false;
                } else {
                    // The cursor is over the object
                    objectOut = false;

                    $(opts.popupObject).animate(opts.animationOver, opts.duration, 'swing', function() {
                        popupShown = true;

                        if (opts.mouseoverCb) {
                            opts.mouseoverCb.call();
                        }
                    });
                }

                return false;
            }).mouseout(function() {
                checkTimer();
                objectOut = true;
                setTimer();

                return false;
            });

            $(opts.popupObject).mouseover(function() {
                // The cursor is over the info block
                popupOut = false;
            }).mouseout(function() {
                checkTimer();
                popupOut = true;
                setTimer();

                return false;
            });
        };
    });
})(jQuery);
