var cBaseXFader = {
	idWrapper: 'xFadeWrapper',
	wrapperStyle: null,
	timeFrame: 500,
    timeTransition: 250,
    images: null,
	idLoader: 'xFadeLoader',
	loaderImg: null,
	preloader: null
}

var cXFader = function() {
	// closure vars
	var selfRef = this;
	var preloader = null;
	var args = null;
	
	this.initXFader = function() {
		// generate a random id for the loader
		this.idLoader += getRandomInt(1000000000);
		
		$('#' + this.idWrapper)
			.empty()
			.queue(function(next) {
				for (var cssProp in selfRef.wrapperStyle) {
					$(this)
						.css(cssProp, selfRef.wrapperStyle[cssProp]);
				}
				next();
			})	
			.css('position', 'relative')
			.css('overflow', 'hidden')
			.html(
				$(document.createElement('div'))
					.attr('id', selfRef.idLoader)
					.css('margin-left', 'auto')
					.css('margin-right', 'auto')
					.css('text-align', 'center')
					.append(
						$(selfRef.loaderImg)
							.css('margin-left', 'auto')
							.css('margin-right', 'auto')
					)
					.queue(function(next) {
						$(this)
							.css('margin-top', 
								parseInt(
									($('#' + selfRef.idWrapper).height() / 2) - ($('#' + selfRef.idLoader).height() / 2)
								)  + 'px');	
						next();
					})
			);
		
		// measure point for timing
		var timeMP1 = 0;
			
		this.preloader = new cPreloader( {
			images: this.images,
			callbackImgLoaded: function(index, img) {
				// set css properties for all imgs
				$(img)										
					.css('top', '0px')
					.css('left', '0px')
					.css('position', 'absolute');                  
				// if first image was loaded fade it in
				if (index == 0) {
					// dtermine timing	
					var timeTransition = (selfRef.images[index]['timeTransition'] != null) ? selfRef.images[index].timeTransition : selfRef.timeTransition;			
					$('#' + selfRef.idWrapper)
						.empty()
						.html(
							$(img)
								//.hide()
								//.fadeIn(timeTransition)
                                .queue(function(next) {
                                    // if ie
                                    if ($.browser.msie) {
                                        $(this)
                                            .css('opacity', '0.0')
                                            .animate({
                                                opacity: '1.0'
                                            }, timeTransition);
                                    } else {
                                        $(this)
                                            .hide()
            					            .fadeIn(timeTransition);
                                    }
                                    next();
                                })								
						);
					// set measure point
					timeMP1 = (new Date()).getTime();
				}
			},
			callbackAllLoaded: function() {
				if (selfRef.images.length > 0) {
					// dtermine timing	
					var timeFrame = (selfRef.images[0]['timeFrame'] != null) ? selfRef.images[0].timeFrame : selfRef.timeFrame;
					var timeTransition = (selfRef.images[0]['timeTransition'] != null) ? selfRef.images[0].timeTransition : selfRef.timeTransition;							
					// wait for fade in and show time of first image
					// if preloading of all imgs is finished too early
					var timeElapsed = (new Date()).getTime() - timeMP1;
					var timeToWait = (timeFrame + timeTransition) - timeElapsed;
					timeToWait = (timeToWait < 0) ? 0 : timeToWait;
					// wait accordingly
					setTimeout(function(){
						selfRef.startAnimate();	
					}, timeToWait);					
				}				
			}
		});
	}
	
	this.startAnimate = function() {
		this.animate(1 % this.images.length);
	}
	
	this.animate = function(index) {
		// determine timing
		var timeFrame = (this.images[index]['timeFrame'] != null) ? this.images[index].timeFrame : this.timeFrame;		
		var timeTransition = (this.images[index]['timeTransition'] != null) ? this.images[index].timeTransition : this.timeTransition;
		// 		
		// animate
		$('#' + this.idWrapper)
			// index == 0 means we have to remove all but the last image
			// so we can fade in the first img over the last
			.find( (index == 0) ? 'img:not(img:last)' : 'nothing' )
			.remove()
			.end()
			.append(
				$(selfRef.images[index].img)
					//.hide()					
					//.fadeIn(timeTransition)                    
                    .queue(function(next) {
                        // if ie
                        if ($.browser.msie) {
                            $(this)
                                .css('opacity', '0.0')
                                .animate({
                                    opacity: '1.0'
                                }, timeTransition);
                        } else {
                            $(this)
                                .hide()
					            .fadeIn(timeTransition);
                        }
                        next();
                    })					
					.queue(function(next) {
						setTimeout(function() {
							selfRef.animate(++index % selfRef.images.length)
						}, timeFrame)
						next();
					})			
			);
	}
	
	// add args
	this.args = arguments[0];
	
	// bind arguments
    for (var n in arguments[0]) {
        this[n] = arguments[0][n];
    };
	
	// preload loader img & init xfader
	var prePreloadArgs = {
		loaderImg: {
			path: this.loaderImg
		}
	}
	this.preloader = new cPreloader( {
		images: [ 
			prePreloadArgs.loaderImg 
		],			
		callbackImgLoaded: null,
		callbackAllLoaded: function() {
			for (member in prePreloadArgs) {
				if (prePreloadArgs[member].img != null) {
					selfRef[member] = prePreloadArgs[member].img;
				}
			}
			selfRef.initXFader();
		}
	});
}
cXFader.prototype = cBaseXFader;

