// 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);
		}
	});
})();


