(function($){
	$.rollover = function(options){
		var opts = $.extend({}, $.rollover.defaults, options);
		var selector = opts.selector || '.' + opts.classAtt;
		$(selector).each(function(i){
			$.rollover.saveOverOut(this, opts);
			$(this).hover(function(){$.rollover.imgSrcObj.set(this, $(this).attr(opts.overAtt));},
			function(){$.rollover.imgSrcObj.set(this, $(this).attr(opts.outAtt));});
		});
		if(opts.buttonClass){
			$.rollover.makeButtons(opts);
		}				
	};
	
	$.rollover.saveOverOut = function(obj, options){
		var imgSrc = $.rollover.imgSrcObj.get(obj, $.rollover.getImgAttr(obj));
		var imgOver = $.rollover.overPath(imgSrc, options.overSuffix);
		$.rollover.preloadImg(imgOver);
		$(obj).attr(options.overAtt, imgOver).attr(options.outAtt, imgSrc);		
	};
	
	$.rollover.makeButtons = function(options){
		opts = $.extend({}, $.rollover.defaults, options);
		var selector = opts.buttonSelector || '.' + opts.buttonClass;
		$(selector).each(function(i){
			$thisbutton = $(this);
			$thisbutton.css('cursor', 'pointer');			
			$thisbutton.hover(function(){
				$(this).find('*').removeClass(opts.buttonTextOutClass).addClass(opts.buttonTextOverClass);			
			},function(){
				$(this).find('*').removeClass(opts.buttonTextOverClass).addClass(opts.buttonTextOutClass);
			});
			$('*', this).each(function(j){
				var q = $.rollover.defaults.count;
				$.rollover.elemsArray[q]={};
				$.rollover.elemsArray[q].obj=this;
				$.rollover.saveOverOut(this, opts);				
				if($(this).attr(opts.overAtt)){
					$thisbutton.hover(function(){
						//alert($.rollover.elemsArray[q].over);
						$.rollover.imgSrcObj.set($.rollover.elemsArray[q].obj, $($.rollover.elemsArray[q].obj).attr(opts.overAtt));
					}, function(){
						$.rollover.imgSrcObj.set($.rollover.elemsArray[q].obj, $($.rollover.elemsArray[q].obj).attr(opts.outAtt));
					});
				}
				$.rollover.defaults.count++;
			}
			);	
		});
	}
	
	$.renameEvent = function (jObj, oldType, newType){
		var events = $.data(jObj[0], "events");
		if(events && events[oldType]){
			for(var handler in events[oldType]){
				$.event.add(jObj[0], newType, events[oldType][handler], events[oldType][handler].data);
			}
			$.event.remove(jObj[0], oldType);			
		}
	};	
	
	$.toggleHover = function(obj, groupid){
		if(obj){		
			var $obj=$(obj);
			groupid = groupid || 'default';
			$.toggleHover.ActiveObj[groupid] = $.toggleHover.ActiveObj[groupid] || {};
			if(typeof $.toggleHover.ActiveObj[groupid].obj != "undefined"){
				$.renameEvent($($.toggleHover.ActiveObj[groupid].obj), 'mouseout_hidden', 'mouseout');
				$($.toggleHover.ActiveObj[groupid].obj).mouseout();
				delete $.toggleHover.ActiveObj[groupid].obj;
			}
			$.toggleHover.ActiveObj[groupid].obj = obj;
			$.renameEvent($obj, 'mouseout', 'mouseout_hidden');
			$obj.mouseover();
		}
	};
	
	$.toggleHover.ActiveObj = {};
	
	$.rollover.imgSrcObj = {
		get: function(obj, attr){
					var ret='';
					try{
					if(obj && attr){
						if(attr != 'style'){ //style has different form
							ret = $(obj).attr(attr);					
						}
						else{
							ret = $(obj).css('background');
						}
					}
					}catch(e){}
					return ret;	
				},
		set:function(obj,val){
					var ret;
					var attr = $.rollover.getImgAttr(obj);
					try{
					if(attr != 'style'){ //style has different form
						ret = $(obj).attr(attr, val);
					}
					else{
						ret = $(obj).css('background', val);
					}
					}catch(e){}
				}		
	};
	
	$.preloadImages = function(){
		$('*').each(function(i){
		var src = $.rollover.imgSrcObj.get(this,$.rollover.getImgAttr(this));
		if(src){
			$.rollover.preloadImg(src);
		}
		});	
	};
	$.rollover.getImgAttr = function(obj){
		var ret = '';
		if(obj && typeof obj == 'object'){
			switch(obj.tagName){
			case 'IMG':
				ret='src';
				break;
			case 'INPUT':
				if(obj.type == 'image'){
					ret='src';
				}
				else{
					ret='style';
				}
				break;
			case 'TD':
				ret='background';
				break;
			default:
				ret='style';
			}

		}
		return ret;
	};
	
	$.rollover.elemsArray=[];
	$.rollover.imgPreload=[];
	
	$.rollover.preloadImg = function(src){
		if(!$.rollover.imgPreload[src])
		{
			$.rollover.imgPreload[src] = new Image();
			$.rollover.imgPreload[src].src = src;
		}
		return $.rollover.imgPreload[src].src;
	};
	
	$.rollover.overPath = function(path, suffix){
		if(path != undefined){			
			var lastIndexOf = path.lastIndexOf('.');
			if(lastIndexOf !=-1){
				var oldsuffix = path.substring(lastIndexOf);
				return path.substring(0,lastIndexOf) + suffix + oldsuffix;
			}
		}
		else{
			return suffix;
		}		
	};
	
	$.rollover.defaults ={
	classAtt: 'rollover',
	outAtt: 'outImg',
	overAtt: 'overImg',
	overSuffix: '_on',
	buttonClass: '',
	buttonTextOverClass: 'buttonover',
	buttonTextOutClass:'button',
	count:0,
	selector: null
	};
	
	$.fn.rollover = function(options){
		options = options || {};
		options.selector = this;
		$.rollover(options);
	};
	
	$.fn.makeButtons = function(options){
		options = options || {};
		options.buttonSelector = this;
		$.rollover.makeButtons(options);	
	};
	
	$.fn.toggleHover = function(groupid){
		$.toggleHover(this[0], groupid);
	};
}(jQuery));
