/**
 * @author Igor Kucheinyk (igorok@igorok.com)
 * 
 * @fileoverview Slideshow
 * 
 * Example of usage
 * <pre>
 * 			var slideShow = new SS.slideShow({
 * 				target: document.getElementById("slideshowContainer"),   // Required. Target element  
 * 				images: [
 * 					'img1.jpg',
 * 					'img2.jpg',
 * 					'img3.jpg',
 * 					'img4.jpg',
 * 					'img5.jpg',
 * 					'img6.jpg',
 * 					'img7.jpg'
 * 				]
 * 			});		
 * </pre> 
 * 
 * 
 */

// initialize namespace
if (typeof SS == 'undefined') {
	SS = function() {};
}

/**
 * Constructor of the object
 * @constructor
 * @param objArgs {object} descr
 */
SS.slideShow = function(objArgs) {
	this.config = objArgs;
	var self = this;

	// register instance in objects array
	if(!SS.objects) SS.objects = [];
	this.objectId = SS.objects.length;
	SS.objects.push(this);
	// Check if Utils loaded
	if(!SS.Utils) {
		alert('Error while initializing slideshow, missing `utils/ss.js`');
		return;
	}	
	// Check image array
	if(!objArgs.images || !SS.Utils.isArray(objArgs.images)) {
		alert('Error wile initializing slideshow, `images` must be array of image strings');
		return;
	}
	// Check container
	if(!objArgs.container) {
		alert('Error while initializing slideshow, `container` invalid or missing');
		return;
	}
	this.delay = objArgs.delay ? objArgs.delay : 10000;
	this.container = objArgs.container;
	// Define appear container
	var containerOffset = SS.Utils.getElementOffset(this.container);
	if(objArgs.appearContainer) {
		this.appearContainer = objArgs.appearContainer;
	} else {
		var appearElement = document.createElement('DIV');
		if(this.container.nextSibling) {
			this.container.parentNode.insertBefore(appearElement, this.container.nextSibling)
		} else {
			this.container.parentNode.appendChild(appearElement);
		}
		this.appearContainer = appearElement;
	}
	this.container.style.backgroundPosition = 'center center';
	this.container.style.backgroundRepeat = 'no-repeat';
	this.appearContainer.style.position = 'absolute';
	this.appearContainer.style.top = containerOffset.top + 'px';
	this.appearContainer.style.left = containerOffset.left + 'px';
	this.appearContainer.style.backgroundPosition = 'center center';
	this.appearContainer.style.backgroundRepeat = 'no-repeat';
	this.appearContainer.style.width = containerOffset.width + 'px';
	this.appearContainer.style.height = containerOffset.height + 'px';
	this.imageUrls = objArgs.images;
	this.imageElems = [];
	this.imageComplete = [];
	// Define elements
	this.defineImageElements();
	// Preload images
	this.preloadOneByOne(0);
	this.start(0);
}


/**
 * Preload all images
 */
SS.slideShow.prototype.defineImageElements = function() {
	var self = this;
	var iImage, iImageLength;
	iImageLength = this.imageUrls.length;
	for (iImage=0; iImage<iImageLength; iImage++) {
		this.imageElems[iImage] = new Image(20,20);
	}
}

/**
 * Preloads the image
 * @param iImage {number} Id of image in the slideshow.imageElems array
 * @param onLoad {function} Callback function, will be called after image loaded
 */
SS.slideShow.prototype.preloadOneByOne = function(iImage) {
	if(!this.imageElems[iImage]) {
		return;
	}
	var self = this;
	var onLoad = function() {
		self.imageComplete[iImage] = true;
		self.preloadOneByOne(iImage+1);
	}
	var onError = function() {
		self.preloadOneByOne(iImage+1);
	}
	SS.Utils.addEvent(this.imageElems[iImage], 'load', onLoad, false);
	SS.Utils.addEvent(this.imageElems[iImage], 'error', onError, false);
	this.imageElems[iImage].src = this.imageUrls[iImage];
}

/**
 * Starts slideshow
 * @param iImage {number} Id of image in the slideshow.imageElems array
 */
SS.slideShow.prototype.start = function(iImage) {
	var self = this;
	if(this.imageElems[iImage]) {
		this.displayImage(iImage, function() {
			// Display next image in few seconds
			setTimeout(function() {
				if(self.imageElems.length > iImage+1) {
					self.start(iImage+1);
				} else {
					self.start(0);
				}
			}, self.delay);
		});
	}
}

/**
 * Preloads the image
 * @param iImage {number} Id of image in the slideshow.imageElems array
 */
SS.slideShow.prototype.displayImage = function(iImage, fImageDisplayed) {
	var containerOffset = SS.Utils.getElementOffset(this.container);
	this.appearContainer.style.top = containerOffset.top + 'px';
	this.appearContainer.style.left = containerOffset.left + 'px';

	var self = this;
	// If image already cached
	if(this.imageComplete[iImage]) {
		// Just display it
		//this.container.style.backgroundImage = 'url('+this.imageUrls[iImage]+')';
		// Display it softly
		var elContainer = this.container;
		var elChildContainer = this.appearContainer;

		// Hide appear container
		this.setElementOpacity(elChildContainer, 0);

		elChildContainer.style.backgroundImage = 'url('+this.imageUrls[iImage]+')';
		this.fadeIn(0, function() {
			elContainer.style.backgroundImage = 'url('+self.imageUrls[iImage]+')';
			self.setElementOpacity(elContainer, 1);
			elChildContainer.style.backgroundImage = 'none';
			self.setElementOpacity(elChildContainer, 0);

			if(fImageDisplayed) {
				fImageDisplayed(iImage);
			}
		});
	} else {
		var onLoad = function() {
			self.imageComplete[iImage] = true;
			self.displayImage(iImage, fImageDisplayed);
		}
		SS.Utils.addEvent(this.imageElems[iImage], 'load', onLoad, false);
		SS.Utils.addEvent(this.imageElems[iImage], 'error', onLoad, false);
	}
}

SS.slideShow.prototype.setElementOpacity = function(oElement, opacity) {
	if(SS.is_ie) {
		oElement.style.filter="alpha(opacity='" + (100 * opacity) + "')";
	} else {
		oElement.style.opacity = opacity;
	}
}

SS.slideShow.prototype.fadeIn = function(ii, callback) {
	var self = this;
	var container = this.container;
	var elChildContainer = this.appearContainer;
	this.setElementOpacity(container, 1 - (ii/10));
	this.setElementOpacity(elChildContainer, ii/10);
	if(ii>=10) {
		if(callback) {
			callback();
		}
		return;
	}
	// Next loop
	setTimeout(function() {
		self.fadeIn(ii+0.5, callback);
	}, 50)
}

