﻿(function ($) {
    $.fn.extend({
        hoverIntent: function (f, g) {
            var ops = $.extend({ timeout: 300 }, g ? { over: f, out: g} : f);
            this.each(function () {
                var timerId;
                $(this).bind('mouseenter', function () {
                    var self = this;
                    timerId = window.setTimeout(function () {
                        window.clearTimeout(timerId);
                        timerId = undefined;
                        if ($.isFunction(ops.over)) ops.over.apply(self);
                    }, ops.timeout);
                }).bind('mouseleave', function () {
                    if (timerId) {
                        window.clearTimeout(timerId);
                        timerId = undefined;
                    }
                    else if ($.isFunction(ops.out)) ops.out.apply(this);
                });
            });
            return this;
        },
        hasScrollbar: function () { return this.get(0).scrollHeight > this.outerHeight(false); },
        hitBottom: function (f) {
            var ops = $.extend({ repeat: false, distance: 0 }, $.isFunction(f) ? { onTouch: f} : f);
            this.each(function () {
                var lastScrollHeight = -1;
                $(this).bind('scroll', function () {
                    var scrollHeight = this.scrollHeight;
                    var diff = $(this).outerHeight(false) - scrollHeight + $(this).scrollTop() + ops.distance;
                    //$('#debug').html($(this).outerHeight(false) + '  ' + scrollHeight + '  ' + lastScrollHeight + '  ' + $(this).scrollTop() + '  ' + diff);
                    if (diff >= 0) {
                        if (scrollHeight != lastScrollHeight) {
                            if (!ops.repeat) $(this).unbind('scroll');
                            else lastScrollHeight = scrollHeight;
                            ops.onTouch.apply(this);
                        }
                    }
                });
            });
            return this;
        }
    });
})($);
