/* $Id: imgflip.jquery.js,v 1.1.2.1 2008/07/10 23:07:49 gburns Exp $

Unobtrusive Accessible jQuery 1.2.1 image flips.

Supports:
	- Parent objects triggering flips on images (first child img or input[type='image'] found
	- Focus flips (for accessibility/tabbing)

Usage:
	Name your images with the proper scheme: <name>_off for "regular" state, <name>_on for "over" state.
	In your JavaScript use the syntax $('.rollOverName').imgflip();

Authors:
	bcurtis, gburns

TODO:
	Support "down" state.
	"active" state?
*/

jQuery.fn.imgflip = function() {
	var img_obj, src_parts, hasRolls, $trigger;

	var reg_match = /^(.*?)([^\/]+)_(on|off|down|active|selected)\.(\w{3,4})$/;

	var self = this;

	return jQuery(this).each(function() {
		// if the element has a src, use it
		// TODO: make sure these are img or input[type='image'] as opposed to something else with a src property?
		if ( this.src ) {
			img_obj = this;
		// otherwise find the first image or input[type='image'] found within the element
		// TODO: make it possible for the flip to not be the first image?
		} else {
			jQuery('img, input[type=\'image\']', this).each(function() {
				if ( this.src.match(reg_match) ) {
					img_obj = this;
					return;
				}
			});
		}

		if (!img_obj) return;

		src_parts = img_obj.src.match(reg_match);

		hasRolls = false;

		if ( src_parts ) {
			// Load images/image paths into object
			if ( !this[src_parts[1] + src_parts[2]] ) this[src_parts[1] + src_parts[2]] = [];

			this[src_parts[1] + src_parts[2]]['default'] = new Image();
			this[src_parts[1] + src_parts[2]]['default'].src = img_obj.src;

			this[src_parts[1] + src_parts[2]]['on'] = new Image();
			this[src_parts[1] + src_parts[2]]['on'].src = src_parts[1] + src_parts[2] + '_on.' + src_parts[4];

			// If the parent is an anchor tag, use that for the mouseover/focus trigger rather than the object itself
			if ( jQuery(this).attr('type') == 'image' || this.parentNode.nodeName != 'A' ) {
				$trigger = jQuery(this);
			} else {
				$trigger = jQuery(this).parent()
			}

			$trigger
				.mouseover(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['on'].src))
				// Make sure we don't fire "out" functions too many times if they are clicking
				.mousedown(function(img_obj) {
					return function() {
						img_obj['mouseisdown'] = true;
					}
				}(img_obj))
				.click(function(img_obj) {
					return function() {
						img_obj['mouseisdown'] = false;
					}
				}(img_obj))
				.focus(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['on'].src));
			hasRolls = true;
		}

		// TODO: maybe reexamine the logic here
		if ( hasRolls ) {
			if ( jQuery(this).attr('type') == 'image' ) {
				$trigger = jQuery(this);
			} else {
				$trigger = jQuery(this).parent()
			}

			$trigger
				.mouseout(function(img_obj, flip_name) {
					return function() {
						img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['default'].src))
				.blur(function(img_obj, flip_name) {
					return function() {
						if ( img_obj['mouseisdown'] == false ) img_obj.src = flip_name;
					}
				}(img_obj, this[src_parts[1] + src_parts[2]]['default'].src));
		}

		this['mouseisdown'] = false;
	});
}