/**
* Required HTML-elements:
*
* Optional HTML-elements:
*/

/**
* identifier: 			string that uniquely identifies the image shifter on the page
* transitionEffect:		- 'off' if not used
*						- 'none' to use simple skip
*						- 'fade' to fade
* imageDisplayTime: 	How long the image will be displayed after it is completely faded in. In seconds. 0 if not used.
* fadeInterval: 		How long between each change in opacity. In seconds. 0 if not used.
* opacityChange: 		How much to change the opacity with every time it is changed. An int representing percent. 2 is a good nr.
* pauseImage: 			Path to image to use as pause icon.
* playImage: 			Path to image to use as play icon.
*/

			
/**
* Too complex to use default values both here and in the php-code and since the
* php-code needs to know the values more than the js-code does, I have moved
* the default values to the php-code.
*/
/**
if(this.fadeInterval == false) {
	this.fadeInterval = 25; // Default value
} else {
	this.fadeInterval = this.fadeInterval * 1000; // Recalculate to miliseconds
}

if(this.imageDisplayTime == false) {
	this.imageDisplayTime = 10000; // Default value
} else {
	this.imageDisplayTime = this.imageDisplayTime * 1000; // Recalculate to milisconds)
}
*/
function imageShifter(identifier, transitionEffect, imageDisplayTime, fadeInterval, opacityChange, pauseImage, playImage) {
	
	var thisObj = this;
	this.identifier = identifier;
	this.transitionEffect = transitionEffect;
	this.imageDisplayTime = imageDisplayTime * 1000; // Recalculate to miliseconds
	this.fadeInterval = fadeInterval * 1000; // Recalculate to miliseconds
	this.opacityChange = opacityChange / 100; // Recalculate from percent
	this.totalNrOfImages = 0;
	this.currentImageIndex = 0;
	this.nextImageIndex = false;
	this.timeoutId = false;
	this.fadingInImageNr = 2;
	this.fadingOutImageNr = 1;
	this.fadingInImageObj = false;
	this.fadingOutImageObj = false;
	this.pauseImage = pauseImage;
	this.playImage = playImage;
	this.isPlaying = true;
	this.autoTransitionActivated = false;
	this.images = new Array();
	this.linkElement;
	
	this.start = function() {
		
		this.linkElement = document.getElementById('imageShifterLink_' + identifier);
		
		// Is there a transition effect
		if(this.transitionEffect != 'off') {
			
			// If the browser can not handle fading, fall back to none
			if(this.transitionEffect == 'fade' && !this.browserCanHandleFade()) {
				this.transitionEffect = 'none';
			}
			
			this.autoTransitionActivated = true;
			
			// Always start at 0
			this.currentImageIndex = 0;
			this.nextImageIndex = this.getNextImageIndex();
			
			// Write the image to the document
			this.writeImageToDoc(this.fadingOutImageNr, this.currentImageIndex);
			this.writeLinkToDoc(this.currentImageIndex);
			
			// Only use second image if we want to fade
			if(this.transitionEffect == 'fade') {

				this.fadingOutImageObj = document.getElementById('imageShifterImage' + this.fadingOutImageNr + '_' + this.identifier);
				this.fadingInImageObj = document.getElementById('imageShifterImage' + this.fadingInImageNr + '_' + this.identifier);
				
				// Set start opacity
				//this.setElementOpacity(this.fadingOutImageObj, 1);
				//this.setElementOpacity(this.fadingInImageObj, 0);
				this.fadingOutImageObj.myOpacity = 1;
				this.fadingInImageObj.myOpacity = 0;
				
				//this.fadingInImageObj.style.display = 'block';
				
				this.writeImageToDoc(this.fadingInImageNr, this.nextImageIndex);
				
				// Start the fading!
				this.timeoutId = setTimeout(function() { thisObj.autoFadeToNextImage(); }, this.imageDisplayTime);
				

			} else {
				
				this.timeoutId = setTimeout(function() { thisObj.autoSkipToNextImage(); }, this.imageDisplayTime);
				
			}
			
		}
		
	}
	
	/**
	* No effect, just skip.
	*/
	this.autoSkipToNextImage = function() {
		
		this.goToNextImage('autoSkip');
		this.timeoutId = setTimeout(function() { thisObj.autoSkipToNextImage(); }, this.imageDisplayTime);
		
	}
	
	/**
	* Fade effect.
	*/
	this.autoFadeToNextImage = function() {
		
		// Set new opacity values
		fadingOutImageNewOpacity = this.fadingOutImageObj.myOpacity - this.opacityChange;
		fadingInImageNewOpacity = this.fadingInImageObj.myOpacity + this.opacityChange;
		
		// Set the opacity on the image
		this.setElementOpacity(this.fadingOutImageObj, fadingOutImageNewOpacity);
		this.setElementOpacity(this.fadingInImageObj, fadingInImageNewOpacity);
		
		// If the fading out image is completely transparent
		if(fadingOutImageNewOpacity <= 0) {
			
			// Lets move one step forward
			this.setNextImageIndex();
			
			this.writeLinkToDoc(this.currentImageIndex);
			
			// Change the source of the faded out image to the one that is gonna fade in
			this.writeImageToDoc(this.fadingOutImageNr, this.getNextImageIndex());
			this.writeImageCounterToDoc(this.currentImageIndex+1);
			
			// Swap the fading in and out image nrs
			tempFadingOutImageNr = this.fadingOutImageNr;
			this.fadingOutImageNr = this.fadingInImageNr;
			this.fadingInImageNr = tempFadingOutImageNr;
			
			// Change the objects
			this.fadingOutImageObj = document.getElementById('imageShifterImage' + this.fadingOutImageNr + '_' + this.identifier);
			this.fadingInImageObj = document.getElementById('imageShifterImage' + this.fadingInImageNr + '_' + this.identifier);
			
			// Set correct opacities
			this.setElementOpacity(this.fadingOutImageObj, 1);
			this.setElementOpacity(this.fadingInImageObj, 0);
			
			// Set display to block since it has been set to none previously.
			this.fadingInImageObj.style.display = 'block';
			
			// Call this function again after displaying the image for a set amount of time
			this.timeoutId = setTimeout(function() { thisObj.autoFadeToNextImage(); }, this.imageDisplayTime);
			
		} else {
			
			// Call this function again after the set interval has passed
			this.timeoutId = setTimeout(function() { thisObj.autoFadeToNextImage(); }, this.fadeInterval);
			
		}
		
	}
	
	/**
	* Set a new opacity value to the given obejct
	*
	* @param HtmlObject obj the given object.
	* @param int opacity the new opacity value.
	*/
	this.setElementOpacity = function(obj, opacity) {
		
		// Lets round to two decimals
		opacity = (Math.round(opacity*100)/100);
		
		// Change display here to avoid opacity bug in FF
		this.fadingInImageObj.style.display = 'block';
		
		if(opacity < 0) {
			
			// Set it to 0 exactly
			opacity = 0;
			
			// Hide the image
			obj.style.display = 'none';
		}
		
		
		//set the style opacity for the object for different browsers
		obj.myOpacity = opacity; // Internal use
		obj.style.opacity = obj.myOpacity;
		obj.style.MozOpacity = obj.myOpacity;
		obj.KhtmlOpacity = obj.myOpacity;
		obj.style.filter = "alpha(opacity=" + (obj.myOpacity*100) + ")";
	}
	
	/**
	* Add image to the ones to shift between
	*/
	this.addImage = function(imageShifterImage) {
		
		this.images[this.images.length] = imageShifterImage;
		this.totalNrOfImages++;
		
	}
	
	/**
	*
	*/
	this.goToNextImage = function(caller) {

		this.setNextImageIndex();
		this.writeSkipToDoc(caller);
		
	}
	
	/**
	*
	*/
	this.goToPrevImage = function(caller) {
		
		this.setPreviousImageIndex();
		this.writeSkipToDoc(caller);		
		
	}
	
	/**
	*
	*/
	this.playPause = function(caller) {
		
		if(this.isPlaying) {
			this.pause(caller);
		} else {
			this.play(caller);
		}
		
	}

	/**
	*
	*/
	this.pause = function(caller) {
		
		if(this.timeoutId != false) {
			clearTimeout(this.timeoutId);
		}
		
		this.isPlaying = false;
		
		// Change the play/pause image
		//document.getElementById('playPauseButton_' + this.identifier).src = this.playImage;
		
	}
	
	/**
	*
	*/
	this.play = function(caller) {
		
		this.isPlaying = true;
		this.restartAutoTransition(caller, true);
		
		//document.getElementById('playPauseButton_' + this.identifier).src = this.pauseImage;
		
	}
	
	/**
	*
	*/
	this.restartAutoTransition = function(caller, instantPlay) {
		
		if(this.timeoutId != false) {
			clearTimeout(this.timeoutId);
		}
		
		// If we ant to play immediately
		if(instantPlay) {
			
			wait = 200; // Wait a short while for a nice user experience
			
		} else {
			
			wait = this.imageDisplayTime; // Wait the set amount of time
			
		}
		
		if(caller == 'user') {
					
			switch (this.transitionEffect) {
				
				case 'none' : 
					this.timeoutId = setTimeout(function() { thisObj.autoSkipToNextImage(); }, wait);
					break;
					
				case 'fade' :
					this.timeoutId = setTimeout(function() { thisObj.autoFadeToNextImage(); }, wait);
					break;
				
			}
			
		}
		
	}	
	
	/**
	*
	*/
	this.setNextImageIndex = function() {
		
		// If we will end up outside the array when we add 1
		if(this.currentImageIndex == (this.totalNrOfImages-1)) {
			
			// Go back to start
			this.currentImageIndex = 0;
			
		} else {
			
			// Go to next
			this.currentImageIndex++;
		}
		
	}
	
	/**
	*
	*/
	this.setPreviousImageIndex = function() {
		
		// If we will reach 0 when decreasing the current nr by 1
		if(this.currentImageIndex == 0) {
			
			// Go to the last image in the array
			this.currentImageIndex = (this.totalNrOfImages-1);
			
		} else {
			
			// Go back one step
			this.currentImageIndex--;
		}
		
	}
	
	
	/**
	*
	*/
	this.getNextImageIndex = function() {
		
		var index = this.currentImageIndex + 1;
		
		// If adding one to current image index leaves us
		// outside the array
		if(index >= this.images.length) {
			
			index = 0;
			
		}
		
		return index;
		
	}
	
	/**
	*
	*/
	this.getPreviousImageIndex = function() {
		
		var index = this.currentImageIndex - 1;
		
		// If we will reach 0 when decreasing the current nr by 1
		if(index < 0) {
			
			// Go to the last image in the array
			index = (this.totalNrOfImages-1);
			
		}
		
		return index;
		
	}	

	/**
	*
	*/
	this.writeSkipToDoc = function(caller) {
		
		this.writeImageToDoc(this.fadingOutImageNr, this.currentImageIndex);
		this.writeLinkToDoc(this.currentImageIndex);
		this.writeImageCounterToDoc((this.currentImageIndex+1));
		
		switch(this.transitionEffect) {
			
			case 'fade' :
			
				clearTimeout(this.timeoutId);

				// We are writing to the image that we are fading out so make sure that it is fully visible
				// and that the one fading in is hidden.
				this.setElementOpacity(this.fadingOutImageObj, 1);
				this.setElementOpacity(this.fadingInImageObj, 0);
				
				// Change the fading in image to the next image
				this.writeImageToDoc(this.fadingInImageNr, this.getNextImageIndex());
				
				// Set display to block since it has been set to none previously.
				this.fadingInImageObj.style.display = 'block';
				this.fadingOutImageObj.style.display = 'block';			
			
				break;
			
		}	
		
		// If autotransition is activated
		if(this.autoTransitionActivated && this.isPlaying) {
			
			this.restartAutoTransition(caller, false);
			
		}
		
	}
	
	/**
	*
	*/
	this.writeImageToDoc = function(imageNr, arrayIndex) {
		
		var imageToShiftTo = this.images[arrayIndex];	
		
		document.getElementById('imageShifterImage' + imageNr + '_' + this.identifier).src = imageToShiftTo.src;
		document.getElementById('imageShifterImage' + imageNr + '_' + this.identifier).width = imageToShiftTo.width;
		document.getElementById('imageShifterImage' + imageNr + '_' + this.identifier).height = imageToShiftTo.height;
		document.getElementById('imageShifterImage' + imageNr + '_' + this.identifier).alt = imageToShiftTo.alt;
		
	}
	
	/**
	*
	*/
	this.writeLinkToDoc = function(arrayIndex) {
		
		// Make sure that we have a link to write to
		if(this.linkElement != null) {
		
			// If the image has a link
			if(this.images[arrayIndex].href != '') {
				
				if(this.images[arrayIndex].linkTarget == '') {
				
					this.images[arrayIndex].linkTarget = '_self';
				
				}
				
				// Set values to link
				this.linkElement.href = this.images[arrayIndex].href;
				this.linkElement.target = this.images[arrayIndex].linkTarget;
				this.linkElement.onclick = '';
				
				try{
					this.linkElement.style.cursor = "pointer";
				} catch(eOldIEVersion){
					this.linkElement.style.cursor = "hand";
				}

			} else {
				
				// Set values on the link element to fake hiding the link
				this.linkElement.href ='';
				this.linkElement.onclick = function() { return false; };
				this.linkElement.style.cursor = 'default';
				this.linkElement.target = '_self';
				
			}
			
		}
		
	}
	
	/**
	*
	*/
	this.writeImageCounterToDoc = function(val) {
		
		if(document.getElementById('imageShifterCurrentImageNr_' + this.identifier)) {		
			
			document.getElementById('imageShifterCurrentImageNr_' + this.identifier).innerHTML = val;
			
		}
		
	}
	
	/**
	* Check if the used browser can handle fading.
	*/
	this.browserCanHandleFade = function (){
		
		//specify the none fade compatable browser ids
		var noneCompatableBrowsers = new Array('MSIE 5.0', 'MSIE 5.5');
		
		//get the current browser version string
		navString = navigator.appVersion;
		
		//loop through the none compatable browsers
		for(i=0; i < noneCompatableBrowsers.length; i++){
		
			//if the current browser match any of the none compatable ones
			if(navString.indexOf( noneCompatableBrowsers[i] ) != -1 ){
				
				return false;
			}
		}
		
		return true;
	}	
	
}


/**
*
**/
function imageShifterImage(src, alt, width, height, href, linkTarget) {
	
	this.preload = new Image;
	this.preload.src = src;
	
	this.src = src;
	
	this.alt = alt;
	
	this.href = href;
	
	this.linkTarget = linkTarget;
	
	this.width = width;
	
	this.height = height;
	
	this.myOpacity = 1;

}