(function ($) {
    $.fn.crossfade = function (startOptions, endOptions) {
        var defaults = {
            'start' : {
                'type' : 'mouseenter',
                'delay' : 400,
                'callback' : null,
                'condition' : function () { return true; }
            },
            
            'end' : {
                'type' : 'mouseleave',
                'delay' : 1000,
                'callback' : null,
                'condition' : function () { return true; }
            }
        };
        
        if (typeof options == 'number') {
            options = {
                'start' : { 'delay' : options },
                'end' : { 'delay' : options }
            };
        }
        
        var settings = {};
        settings.start = $.extend({}, defaults.start, startOptions);
        settings.end = $.extend({}, defaults.end, endOptions);

        // return this;
        return this.each(function (i) { 
            var $$ = $(this);
            var targetImage = $$.attr('rel');
			var targetId = $$.attr('id') + "_over";
			if (targetImage == null) {
				targetImage = $$.attr('src');
			}
            var hiddenImage = $$.wrap('<span style="position: relative;"></span>')
                .parent()
                .prepend('<img>')
                .find(':first-child')
				.attr('id', targetId)
                .attr('src', targetImage)
				.attr('border', '0')
				.attr('class', 'appover');
                
            // CSS tweaks to position the starting image correctly
            if ($.browser.mozilla) {
                $$.css({
                    'position' : 'absolute', 
                    'left' : 0,
                    'background' : '',
                    'top' : this.offsetTop
                });
			} else if ($.browser.msie) {
                $$.css({
                    'position' : 'absolute', 
                    'left' : 0,
                    'background' : '',
                    'top' : $(this).offsetTop
                });
            } else if ($.browser.opera && $.browser.version < 9.5) {
                // opera < 9.5 has a render bug - so this is required to get around it
                // we can't apply the 'top' : 0 separately because Mozilla strips
                // the style set originally somehow...
                $$.css({
                    'position' : 'absolute', 
                    'left' : 0,
                    'background' : '',
                    'top' : "0"
                });
            } else {
                $$.css({
                    'position' : 'absolute', 
                    'left' : 0,
                    'background' : ''
                });
            }
            
            if (settings.start.type) {
                $$.bind(settings.start.type, function () {
                    if (settings.start.condition.call(this)) {
						$(this).stop().animate({
                            opacity: 0
                        }, settings.start.delay);
						var newid = '#' + $(this).attr('id') + '_over'; 
						$(newid).stop().animate({
							opacity: 1
						}, settings.start.delay);
                    }
                    if (settings.start.callback) return settings.start.callback.call(this);
                });
            }
            
            if (settings.end.type) {
                $$.bind(settings.end.type, function () {
                    if (settings.end.condition.call(this)) {
                        $(this).stop().animate({
                            opacity: 1
                        }, settings.end.delay);
						var newid = '#' + $(this).attr('id') + '_over'; 
						$(newid).stop().animate({
							opacity: 0
						}, settings.end.delay);

                    }
                    if (settings.end.callback) return settings.end.callback.call(this);
                });
            }
        });
    };
    
})(jQuery);
