/**
 * sliphover v2.0.2
 * require jquery 1.7+
 * wayou June 24, 2014,
 * MIT License
 * for more info pls visit :https://github.com/wayou/SlipHover
 */

;
(function($, window, document, undefined) {

    // Create the defaults once
    var pluginName = "sliphover",
        defaults = {
            target: 'img', //the element that the overlay will attach to
            caption: 'title', //the caption that will display when hover
            duration: 'fast', //specify how long the animation will lasts in milliseconds
            fontColor: '#fff',
            textAlign: 'center', //display the caption left, center or right
            verticalMiddle: true, //display the caption vertical middle or not
            backgroundColor: 'rgba(0,0,0,.7)', //specify the background color and opacity using rgba
            reverse: false, //reverse the direction
            height: '100%', //specify the height of the overlay
            withLink: true //if image is wraped with a link the overlay will be clickable, set false to disable click
        };

    function SlipHover(element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v2.0.3';
        this.init();
    }

    SlipHover.prototype = {
        init: function() {

            //disable on touch devices
            if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
                return;
            }

            var that = this,
                target = this.settings.target;

            //create the overlay container each time the mouse enters
            $(this.element).off('mouseenter.sliphover', target).on('mouseenter.sliphover', target, function(event) {
                //fix #9 https://github.com/wayou/SlipHover/issues/9
                //use this instead of event.target for sometimes the event.target is not retriving the right target we want
                //http://stackoverflow.com/questions/9838137/event-target-jquery-on-mousedown-up-is-not-giving-the-dom-specified-by-selecto
                var $element = $(this),
                    $overlayContainer = that.createContainer($element);

                $overlayContainer.off('mouseenter.sliphover mouseleave.sliphover').on('mouseenter.sliphover mouseleave.sliphover', function(event) {
                    //if (!$overlayContainer) return;
                    var direction = that.getDirection($(this), event);

                    //check if reverse option is on
                    direction = that.settings.reverse ? direction = (direction + 2) % 4 : direction;

                    if (event.type === 'mouseenter') {
                        //check if the previous overlay still exists before we create it
                        var $overlay = $overlayContainer.find('.sliphover-overlay');
                        if (!$overlay.length) {
                            $overlay = that.createOverlay(that, direction, $element);
                            //put the overlay into the container
                            $(this).html($overlay);
                        }
                        that.slideIn(that, $overlay);
                    } else {
                        //slide out based on the direction
                        that.removeOverlay(that, $(this), direction);
                    }
                });
            });
        },
        createContainer: function($element) {
            //get the properties of the target
            var top = $element.offset().top,
                left = $element.offset().left,
                //border = parseFloat($element.css("border-left-width")),
                width = $element.outerWidth(),
                height = $element.outerHeight();
            zIndex = $element.css("z-index");
            var $overlayContainer = $('<div>', {
                class: 'sliphover-container'
            }).css({
                width: width,
                height: height,
                position: 'absolute',
                overflow: 'hidden',
                top: top,
                left: left,
                borderRadius: $element.css('border-radius'), //in case the target has a round border, this will make the overlay more nicer
                zIndex: zIndex == +zIndex ? (zIndex + 1) : 999 // if the z-index of the target is not number then use 999
            });
            
            $overlayContainer.data('relatedElement', $element);
            //$element.closest('a').append($overlayContainer);
            $('body').append($overlayContainer);

            return $overlayContainer;
        },
        createOverlay: function(instance, direction, $element) {

            var bottom, left, $overlay, content, $targetAParent;

            switch (direction) {
                case 0:
                    //from top
                    left = 0;
                    bottom = '100%';
                    break;
                case 1:
                    //from right
                    left = '100%';
                    bottom = 0;
                    break;
                case 2:
                    //from bottom
                    left = 0;
                    bottom = '-100%';
                    break;
                case 3:
                    //from left
                    left = '-100%';
                    bottom = 0;
                    break;
                default:
                    window.console.error('error when get direction of the mouse');
            };

            //if we want to display content vertical middle, we need to wrap the content into a div and set the style with display table-cell
            if (instance.settings.verticalMiddle) {
                content = $('<div>').css({
                    display: 'table-cell',
                    verticalAlign: 'middle'
                }).html($element.attr(instance.settings.caption));
            } else {
                content = $element.attr(instance.settings.caption);
            }
            $targetAParent = $element.closest('a');
            if ($targetAParent.length && instance.settings.withLink) {
                var url = $targetAParent.attr('href');
                    classes = $targetAParent.attr('class');
                $overlay = $('<a>', {
                    'class': 'sliphover-overlay ' + classes,
                    'href': url || '#'
                }).css({
                    textDecoration: 'none'
                });
            } else {
                $overlay = $('<div>', {
                    class: 'sliphover-overlay'
                });
            }

            $overlay.css({
                width: '100%',
                height: instance.settings.height,
                position: 'absolute',
                left: left,
                bottom: bottom,
                display: instance.settings.verticalMiddle ? 'table' : 'inline',
                textAlign: instance.settings.textAlign,
                color: instance.settings.fontColor,
                backgroundColor: instance.settings.backgroundColor
            })
                .html(content);
            return $overlay;
        },
        slideIn: function(instance, $overlay) {
            $overlay.stop().animate({
                left: 0,
                bottom: 0
            }, instance.settings.duration);
        },
        removeOverlay: function(instance, $overlayContainer, direction) {
            var finalState,
                $overlay = $overlayContainer.find('.sliphover-overlay');

            switch (direction) {
                case 0: //to top
                    finalState = {
                        bottom: '100%',
                        left: 0
                    };
                    break;
                case 1: //to right
                    finalState = {
                        bottom: 0,
                        left: '100%'
                    };
                    break;
                case 2: //to bottom
                    finalState = {
                        bottom: '-100%',
                        left: 0
                    };
                    break;
                case 3: //to left
                    finalState = {
                        bottom: 0,
                        left: '-100%'
                    };
                    break;
                default:
                    window.console.error('error when get direction of the mouse');
            };

            //slide out
            $overlay.stop().animate(finalState, instance.settings.duration, function() {
                $overlayContainer.remove();
            });
        },
        getDirection: function($target, event) {
            //reference: http://stackoverflow.com/questions/3627042/jquery-animation-for-a-hover-with-mouse-direction
            var w = $target.width(),
                h = $target.height(),
                x = (event.pageX - $target.offset().left - (w / 2)) * (w > h ? (h / w) : 1),
                y = (event.pageY - $target.offset().top - (h / 2)) * (h > w ? (w / h) : 1),
                direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
            return direction;
        }
    };

    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new SlipHover(this, options));
            }
        });

        // chain jQuery functions
        return this;
    };

})(jQuery, window, document);