/**
 * jquery.altsrc.js v1.0
 * 
 * @author Tiziano Treccani <treccani.tiziano@tiscali.it>
 * Copyright (c) 2009 Tiziano Treccani - released under MIT License
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:

 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

(function($){
	$.fn.altsrc = function(options){
		// selected elements
		var inputs = this;

		// default options
		var defaults = {
			altSrc: '',
			inlineAltSrc: false,
			useCache: true,
			uniqueCache: true
		}
		// merge options
		var options = jQuery.extend(defaults, options);
		
		// set passed selector. if selector is empty, i assumed to be the context		
		var selector = document;
		if(!options.uniqueCache){
			if(inputs.selector != ''){
				selector = inputs.selector;
			}
		}
		
		// local cache - there is a cache for each selector.
		var getCache = function(){
			var cache = jQuery(selector).data('altsrc_cache');
			if (cache == undefined){
				var cache = new Array();
				cache.getItem = function(cKey){
					return this[cKey];
				}
				cache.putItem = function(cKey, cValue){
					this[cKey] = cValue;
				}
				cache.hasItem = function(cKey){
					if (this[cKey] == undefined){
						return false;
					}
					return true;
				}
				jQuery(selector).data('altsrc_cache', cache);
			}
			return cache;
		}
		
		var isReachable = function(imgSrc){
			var reachable = true;
			jQuery.ajax({
				type: "GET",
				url: imgSrc,
				async: false,
				complete: function(xhr, statusText) {
					if (xhr.status != 200){
						reachable = false;
					}
				} 
			});
			return reachable;
		}
		
		var checkImage = function(img){
			var imgSrc = img.attr("src");
			var altSrc = options.inlineAltSrc ? img.attr("altsrc") : options.altSrc;
			
			if (altSrc != imgSrc){
				if(options.useCache){
					var cache = getCache();
					if(!cache.hasItem(imgSrc)){
						var reachable = isReachable(imgSrc);
						if(reachable){
							cache.putItem(imgSrc, imgSrc);
						}
						else {
							cache.putItem(imgSrc, altSrc);
						}
					}
					img.attr("src", cache.getItem(imgSrc));
				}
				else {
					var reachable = isReachable(imgSrc);
					if(!reachable){
						img.attr("src", altSrc);
					}
				}
			}
			
		}
		
		// startup jquery.altsrc for each selected input
		jQuery(inputs).each(function(){
			// if inputs are images
			if(this.nodeName == 'IMG'){
				checkImage(jQuery(this));
			}
			else {
				//if not, find all images
				jQuery(this).find('img').each(function(){
					checkImage(jQuery(this));
				});
			}
		});
		
		// return selected elements
		return inputs;
		
	};
})(jQuery);