(function($) /* Copyright (c) 2010, J v/d Wel */
{
	/*
		<div class="jrandom jrandom-name-blabla jrandom-interval-10 jrandom-beginfirst jrandom-uncomment">
			<img src="..."/>
			<img src="..."/>
			<img src="..."/>
			<img src="..."/>
			<img src="..."/>
			<div>
				<!-- <img src="..."/> -->
			</div>
		</div>
	*/
	var randoms = [];
	
	$(function() 
	{
		$('.jrandom').each(
		function()
		{
			var rand, jrandom, className, matches, name, interval, beginfirst, uncomment;
			
			jrandom = $(this);
			className = ' '+ jrandom.attr('class') +' ';
			
			matches = /\sjrandom-name-(\w+)\s/.exec(className);
			if (matches)
				name = matches[1];
			else
				name = 'default';
			
			beginfirst = /\sjrandom-beginfirst\s/.test(className);
			
			matches = /\sjrandom-interval-(\d+)\s/.exec(className);
			if (matches)
				interval = parseInt(matches[1], 10);
			else
				interval = 0;
			
			uncomment = /\sjrandom-uncomment\s/.test(className);
			
			randoms.push(rand = new JRandom(this, name, beginfirst, interval, uncomment));
		});
	});
	
	function JRandom(container, cookiename, beginfirst, interval, uncomment)
	{
		var self, a, index, jchildren;
		self = this;
		
		this.needsLoading = [];
		this.jcontainer = $(container);
		jchildren = this.jcontainer.children();
		this.cookiename = cookiename;
		this.beginfirst = beginfirst;
		this.interval = interval;
		this.uncomment = uncomment;
		
		this.lastIndex = parseInt(readCookie('jrandom-'+cookiename, -1), 10);
		
		jchildren.hide();
		if (this.interval)
		{
			this.display_timer = 
				setInterval(function()
				{
					self.displayTimer();
				}, Math.floor(this.interval * 1000));
		}
		
		if (jchildren.length < 1)
			return;
		
		if (this.beginfirst)
		{
			this.nextIndex = 0;
			this.nextNode = jchildren.get(0);
			this.show(false, false);
			this.findNext();
		}
		else
		{
			this.findNext();
			this.show(false);
			this.findNext();
		}
	}
	JRandom.prototype.show = show;
	JRandom.prototype.displayTimer = displayTimer;
	JRandom.prototype.findNext = findNext;
	JRandom.prototype.imageLoaded = imageLoaded;
	
	
	JRandom.prototype.jcontainer = null;
	JRandom.prototype.cookiename = '';
	JRandom.prototype.beginfirst = false;
	JRandom.prototype.interval = 0;
	JRandom.prototype.uncomment = false;
	JRandom.prototype.display_timer = 0;
	
	JRandom.prototype.previousIndex = -1;
	JRandom.prototype.nextIndex = -1;
	JRandom.prototype.previousNode = null;
	JRandom.prototype.nextNode = null;
	JRandom.prototype.needsLoading = null;
	JRandom.prototype.needsLoading_intervalover = null;
	
	function show(animated, setLastIndex) //todo: html comments
	{
		var jchildren, self;
		self = this;
		jchildren = this.jcontainer.children();
		if (setLastIndex === undefined)
			setLastIndex = true;
		
		
		if (this.previousNode == this.nextNode)
			return;
		
		this.needsLoading = [];
		this.jcontainer.find('img').unbind('load.jrandom');
		
		if (!animated)
		{
			jchildren.hide();
			if (this.nextNode)
			{
				$(this.nextNode).show();
				if (window.fullscreenimage_findFullscreenImage)
					window.fullscreenimage_findFullscreenImage();
			}
			this.previousIndex = this.nextIndex;
			this.previousNode = this.nextNode;
		}
		else
		{
			if (!this.previousNode)
			{
				if (this.nextNode)
				{
					$(this.nextNode).fadeIn(400);
					if (window.fullscreenimage_findFullscreenImage)
						window.fullscreenimage_findFullscreenImage();
				}
			}
			else
			{
				$(this.previousNode).fadeOut(400, function()
				{
					if (self.nextNode)
					{
						$(self.nextNode).fadeIn(400);
						if (window.fullscreenimage_findFullscreenImage)
							window.fullscreenimage_findFullscreenImage();
					}
				});
			}
			
			this.previousIndex = this.nextIndex;
			this.previousNode = this.nextNode;
		}
		
		if (setLastIndex)
			createCookie('jrandom-'+name, this.previousIndex, 0);
	}
	
	function findNext()
	{
		var jchildren, a, images, self;
		self = this;
		jchildren = this.jcontainer.children();
		
		if (jchildren.length < 1)
		{
			this.nextNode = null;
			this.nextIndex = -1;
		}
		else if (jchildren.length == 1)
		{
			this.nextIndex = 0;
			this.nextNode = jchildren.get(0);
		}
		else // > 1
		{
			a = 0;
			do
			{
				this.nextIndex = Math.floor(Math.random() * jchildren.length);
				a++;
			}
			while(this.nextIndex == this.lastIndex && a < 100);
			this.nextNode = jchildren.get(this.nextIndex);
		}
		if (!this.nextNode)
			return; // nothing more to do
		
		if (this.previousNode != this.nextNode)
			$(this.nextNode).hide();
		
		uncommentHTML(this.nextNode); // if any images were commented, start preloading
		
		this.needsLoading = [];
		images = this.nextNode.getElementsByTagName('img');
		for (a = 0; a < images.length; a++)
		{
			// triple =; this way it will not do anything if the browser has no support for HTMLImageElement.complete
			if (images[a].complete === false) // http://www.w3.org/TR/html5/embedded-content-1.html#dom-img-complete
			{
				this.needsLoading.push(images[a]);
				$(images[a]).bind('load.jrandom', function(e)
				{
					$(this).unbind('load.jrandom');
					self.imageLoaded(this);
				});
			} 
		}
		
	}
	
	function displayTimer()
	{
		if (this.needsLoading.length) // the next item has images that have not yet finished loading
		{
			this.needsLoading_intervalover = true;
			if (this.display_timer)
				clearInterval(this.display_timer);
			this.display_timer = 0;
			return;
		}
		this.show(true, true);
		this.findNext();
	}
	
	function imageLoaded(img)
	{
		var oldImages, a, self;
		self = this;
		oldImages = this.needsLoading;
		this.needsLoading = [];
		for (a = 0; a < oldImages.length; a++)
		{
			if (oldImages[a] != img)
				this.needsLoading.push(oldImages[a]);
		}
		
		if (!this.needsLoading.length && this.needsLoading_intervalover)
		{
			this.show(true, true);
			this.findNext();
			if (this.interval)
			{
				img = null;
				this.display_timer = 
					setInterval(function()
					{
						self.displayTimer();
					}, Math.floor(this.interval * 1000));
			}
		}
	}
	
	
	
	
	function uncommentHTML(container)
	{
		var node, nextSibling, div;
		node = container.firstChild;
		while (node)
		{
			nextSibling = node.nextSibling;
			if (node.nodeType == 8/*Node.COMMENT_NODE*/)
			{
				div = document.createElement('div');
				div.innerHTML = node.nodeValue;
				container.removeChild(node);
				while (div.firstChild)
					container.insertBefore(div.firstChild, nextSibling);
				div = null;
			}
			else if (node.nodeType == 1/*Node.ELEMENT_NODE*/)
			{
				uncommentHTML(node);
			}
			node = nextSibling;
		}
	}
	
	// http://www.quirksmode.org/js/cookies.html
	function createCookie(name,value,days) 
	{
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	};
	
	function readCookie(name, def) 
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		if (!def)
			def = null;
		
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return def;
	};
	
	function eraseCookie(name) 
	{
		createCookie(name,"",-1);
	};

})(jQuery);
