// protoHover
// a simple hover implementation for prototype.js
// Sasha Sklar and David Still

(function() {
        // copied from jquery
        var withinElement = function(evt, el) {
                // Check if mouse(over|out) are still within the same parent element
                var parent = evt.relatedTarget;

                // Traverse up the tree
                while (parent && parent != el) {
                        try {
                                parent = parent.parentNode;
                        } catch (error) {
                                parent = el;
                        }
                }
                // Return true if we actually just moused on to a sub-element
                return parent == el;
        };

        // Extend event with mouseEnter and mouseLeave
        Object.extend(Event, {
                mouseEnter: function(element, f, options) {
                        element = $(element);

                        // curry the delay into f
                        var fc = (options && options.enterDelay)?(function(){window.setTimeout(f, options.enterDelay);}):(f);

                        if (Prototype.Browser.IE) {
                                element.observe('mouseenter', fc);
                        } else {
                                element.hovered = false;

                                element.observe('mouseover', function(evt) {
                                        // conditions to fire the mouseover
                                        // mouseover is simple, the only change to default behavior is we don't want hover fireing multiple times on one element
                                        if (!element.hovered) {
                                                // set hovered to true
                                                element.hovered = true;

                                                // fire the mouseover function
                                                fc(evt);
                                        }
                                });
                        }
                },
                mouseLeave: function(element, f, options) {
                        element = $(element);

                        // curry the delay into f
                        var fc = (options && options.leaveDelay)?(function(){window.setTimeout(f, options.leaveDelay);}):(f);

                        if (Prototype.Browser.IE) {
                                element.observe('mouseleave', fc);
                        } else {
                                element.observe('mouseout', function(evt) {
                                        // get the element that fired the event
                                        // use the old syntax to maintain compatibility w/ prototype 1.5x
                                        var target = Event.element(evt);

                                        // conditions to fire the mouseout
                                        // if we leave the element we're observing
                                        if (!withinElement(evt, element)) {
                                                // fire the mouseover function
                                                fc(evt);

                                                // set hovered to false
                                                element.hovered = false;
                                        }
                                });
                        }
                }
        });


        // add method to Prototype extended element
        Element.addMethods({
                'hover': function(element, mouseEnterFunc, mouseLeaveFunc, options) {
                        options = Object.extend({}, options) || {};
                        Event.mouseEnter(element, mouseEnterFunc, options);
                        Event.mouseLeave(element, mouseLeaveFunc, options);
                }
        });
})();
