function isImageOk(img) {
    // During the onload event, IE correctly identifies any images
    // that weren't downloaded as not complete. Others should too.
    // Gecko-based browsers act like NS4 in that they report this
    // incorrectly: they always return true.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth
    // and naturalHeight. These give the true size of the image. If
    // it failed to load, either of these should be zero.
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
        return false;
    }

    // No other way of checking: assume it's ok.
    return true;
}

function setOpacity(elem, value) {
	elem.style.opacity = value/100;
	elem.style.filter = 'alpha(opacity=' + value*100 + ')';
}


function slideshow(container) {
	var jqContainer = $(container);
	var jqImageContainer = jqContainer.find('.image-square');
	var jqImage = jqImageContainer.find('img');
	var jqImageParent = jqImage.parent();	
	var jqControls = jqContainer.find('.controls');	
	
	var playing;
	var timer;
	var nextUrl;
	var loading = false;
	var desiredImage = null;
	
	function showLoader(show) {
		if (show != false) {
			if (jqImageContainer.find("span.loading").length == 0) {
				jqImageContainer.append('<span class="loading"> </span>');
			}
		} else {		
			jqImageContainer.find("span.loading").remove();
		}
	}
	
	// SimpleButton Class: Link with custom class and label, and enabled & disabled states
	var SimpleButton = function(labelText, className, href) {
	var SimpleButtonPub = new Object();
		if (!href) {
			href = '#';
		}
		var buttonEnabled = $("<li class='"+className+"'><a href='"+href+"'>"+labelText+"</a></li>");
		var buttonDisabled = $("<li class='"+className+"'><span>"+labelText+"</span></li>");
		var linkElement = buttonEnabled.find("a");
		
		var enabled = false;
		SimpleButtonPub.element = buttonDisabled;
		
		SimpleButtonPub.enable = function(functionRef) {
			if (!enabled) {
				SimpleButtonPub.element.after(buttonEnabled);
				SimpleButtonPub.element.remove();
				SimpleButtonPub.element = buttonEnabled;
				enabled = true;
			}
			if (functionRef) {
				linkElement.unbind("click");
				linkElement.click(functionRef);
			}			
		}
		
		SimpleButtonPub.disable = function() {
			if (enabled) {
				SimpleButtonPub.element.after(buttonDisabled);
				SimpleButtonPub.element.remove();
				SimpleButtonPub.element = buttonDisabled;	
				enabled = false;
			}			
		}
		SimpleButtonPub.setHref = function(newHref) {
			linkElement.attr('href', newHref);	
		}
		
	return SimpleButtonPub;
	}
	
	// ToggleButton Class: Combines multiple SimpleButtons, allowing toggling between them
	var ToggleButton = function(buttonArray) {
	var ToggleButtonPub = new Object();
		
		var current = 0;
		ToggleButtonPub.element = buttonArray[current].element;
		
		ToggleButtonPub.toggle = function(number) {
			if (number != undefined) {
				if (current != number) {
					buttonArray[current].element.after(buttonArray[number].element);
					buttonArray[current].element.remove();
					ToggleButtonPub.element = buttonArray[number].element;
					current = number;
				}
			} else {
				var newNumber = current + 1;
				if (newNumber > buttonArray.length-1) {
					newNumber = 0;
				}

				ToggleButtonPub.toggle(newNumber)
			}
		}
		
	return ToggleButtonPub;
	}	
	
	var prevButton = new SimpleButton(jqControls.find('.previous-button').text(), 'previous-button', jqControls.find('.previous-button').find('a').attr('href'));
	var nextButton = new SimpleButton(jqControls.find('.next-button').text(), 'next-button', jqControls.find('.next-button').find('a').attr('href'));
	var playButton = new SimpleButton('Play', 'play-button');
	var pauseButton = new SimpleButton('Pause', 'pause-button');
	var playPauseToggle = new ToggleButton([playButton, pauseButton]);
	
	jqControls.empty().append(playPauseToggle.element, prevButton.element, nextButton.element);

	function setImage(queueImage) {
		if (desiredImage == queueImage) {
			// Append new image after old one
			var jqOldImage = jqImageContainer.find("img");
			jqOldImage.after(queueImage.jqPreloadImage);

			// Remove throbber
			showLoader(false);
			
			function fade(element, direction, steps, interval, callback) {
				var fadeInterval;
				var i;
				var calc;
				var fadeInc = 100/steps;
				var stepCount = 0;
				
				function setFade() {
					i = i + calc;
					stepCount += 1;
					setOpacity(element, fadeInc * i);
					
					if (stepCount >= steps) {
						clearInterval(fadeInterval);
						
						callback()
					}
				}
				
				if (direction == "in") {
					setOpacity(element, 0);
					i = 0;
					calc = +1;
					fadeInterval = setInterval(setFade, interval);
				} else if (direction == "out") {
					setOpacity(element, 100);
					i = steps;
					calc = -1;
					fadeInterval = setInterval(setFade, interval);					
				}
			}
			
			// Fade out
			fade(jqImageParent[0], "out", 20, 20, function(){
				// Remove smooth object
				/*if (typeof(smoothScale) != undefined) {
					var oldSmoothObject = smoothScale.getSmoothObject(jqOldImage[0]);
					if (oldSmoothObject) {
						$(oldSmoothObject.element).remove();						
					}
				}*/
				// Remove old image
				jqOldImage.remove();

				// Set portrait/landscape class
				if (queueImage.portrait) {
					jqImageContainer.addClass('image-portrait');
					jqImageContainer.removeClass('image-landscape');			
				} else {
					jqImageContainer.addClass('image-landscape');
					jqImageContainer.removeClass('image-portrait');
				}

				// show new image
				queueImage.jqPreloadImage.removeAttr('style');
				// Smooth new image
				/*if (typeof(smoothScale) != undefined) {
					smoothScale.smoothImages(queueImage.jqPreloadImage[0]);				
				}*/
				
				// Set previous/next buttons and nextUrl for timer
				nextButton.setHref(queueImage.nextHref);
				prevButton.setHref(queueImage.prevHref);
				nextUrl = queueImage.nextHref;
				
				// Fade back in
				fade(jqImageParent[0], "in", 30, 20, function(){
					if (playing) {
						play();
					}					
				});
			});	
		} else {
			queueImage.jqPreloadImage.remove();
			queueImage = null;
		}
	}

	var QueueImage = function(url) {
	var QueueImagePub = new Object();	
		
		var imageSrc = null;
		var imageWidth = null;						
		var imageHeight = null;		
		QueueImagePub.nextHref = null;			
		QueueImagePub.prevHref = null;
		
		QueueImagePub.jqPreloadImage = $("<img />");
		QueueImagePub.portrait = null;
		var imageElement = QueueImagePub.jqPreloadImage[0];
		
		var hasLoaded = false;
		var displayWhenLoaded = false;
		
		var checkLoadInterval;
		
		QueueImagePub.showImage = function() {
			if (hasLoaded) {
				setImage(QueueImagePub);
			} else {
				showLoader();
				displayWhenLoaded = true;
			}
		}
		
		function checkLoaded() {
			if (isImageOk(imageElement)) {
				clearInterval(checkLoadInterval);
				hasLoaded = true;

				if (displayWhenLoaded) {
					QueueImagePub.showImage()
				}
			}
		}
		
		function loadImage() {
			QueueImagePub.jqPreloadImage.appendTo("body");
			QueueImagePub.jqPreloadImage.css("display", "none");
			QueueImagePub.jqPreloadImage.attr("src", imageSrc);
			QueueImagePub.jqPreloadImage.attr("width", imageWidth);
			QueueImagePub.jqPreloadImage.attr("height", imageHeight);
			if (imageWidth < imageHeight) {
				QueueImagePub.portrait = true;
			} else {
				QueueImagePub.portrait = false;
			}

			checkLoadInterval = setInterval(checkLoaded, 5000);
		}
		
		// Get image src and prev/next from URL		
		$.getJSON(url, {json: true}, function(json) {
			imageSrc = json['slideshowImage'];
			imageWidth = json['slideshowWidth'];						
			imageHeight = json['slideshowHeight'];
			QueueImagePub.nextHref = json['slideshowNextHref'];			
			QueueImagePub.prevHref = json['slideshowPrevHref'];
						
			loadImage();
		});
		
	return QueueImagePub;	
	}


	function changeImageUrl(url) {

	}
	function changeImageClick(evt) {
		// Stop autoplay
		clearTimeout(timer);		
		// Queue next image
		desiredImage = new QueueImage(evt.target.href);
		// Show immadetaly
		desiredImage.showImage();
				
		return false;
	}	

	function togglePlay() {
		if (playing) {
			// Pause it
			playPauseToggle.toggle(0);	
			playButton.enable(togglePlay);
			pause();
		} else {
			// Play it
			playPauseToggle.toggle(1);			
			pauseButton.enable(togglePlay);
			play();
		}

		return false;
	}
	
	function showQueued() {
		desiredImage.showImage();
	}
	function play() {
		// Queue next image
		desiredImage = new QueueImage(nextUrl);

		// Set timer
		clearTimeout(timer);
		timer = setTimeout(showQueued, 6000)
		
		playing = true;
	}
	
	function pause() {
		clearTimeout(timer);
		
		playing = false;
	}
	
	prevButton.enable(changeImageClick);
	nextButton.enable(changeImageClick);
	playButton.enable(togglePlay);
	pauseButton.enable(togglePlay);
	
	// Play
	var playing = true;	
	playPauseToggle.toggle(1);	
	nextUrl = jqControls.find('.next-button').find('a').attr('href');
	play();
}

$(document).ready(function(){
	slideshow('.slideshow')
})