// External Box
// 
// Every <a rel="externalbox-something">content</a> will have its 
// content copied to <div id="something"></div> when clicked

(function($)
{
	var targetElements = {}; // targetElements['id'] = {...}

	var relRegexp = /\sexternalbox-(\S+)\s/;
	var openbydefaultRegexp = /\sexternalboxopenbydefault\s/;
	
	
	$.ExternalBox = {
		disabled: false,
		
		setDisabled: function(disabled)
		{
			var wasDisabled;
			wasDisabled = $.ExternalBox.disabled;
			$.ExternalBox.disabled = disabled;
			return wasDisabled;
		}
	};
	
	$(function()
	{
		var a, links;
		
		links = $('a[rel]').live('click', externalbox_click).get();
		
		for (a = 0; a < links.length; a++)
		{
			if (openbydefaultRegexp.test(' '+ links[a].getAttribute('rel') +' '))
				$(links[a]).click();
		}
	});
	
	function dissolveNode(node)
	{
		var parent;
		
		parent = node.parentNode;
		if (!parent) return;
		
		while (node.firstChild)
		{
			parent.insertBefore(node.firstChild, node);
		}
		
		parent.removeChild(node);
	};
	
	function img_load(e)
	{
		var a, len, target, elementQueue, links, rel;
		target = e.data.target;
		elementQueue = e.data.elementQueue;
		len = elementQueue.length;
		
		if (this.getAttribute('src') === 'about:blank') return; // wrong load event
		
		$(target).removeClass('externalbox-loading');
		if (!len) return;
		
		//remove any old elements in the target div
		while (target.childNodes.length)
		{
			target.removeChild(target.firstChild);
		}
		
		for (a = 0; a < len; a++)
		{
			target.appendChild(elementQueue[a]);
		}
		
		links = $('a[rel]', target).get();
		for (a = 0; a < links.length; a++)
		{
			rel = links[a].getAttribute('rel');
			if (!rel) continue;
			
			if (relRegexp.test(' '+rel+' '))
				dissolveNode(links[a]);
		}
		
		elementQueue.length = 0; //Empty the queue, incase this event is fired multiple times, it will be parsed only once
		
		if (window.supersleight) //png fix
			window.supersleight.run(target);
		
		if (window.fullscreenimage_findFullscreenImage)
			window.fullscreenimage_findFullscreenImage();
	}
	
	function externalbox_click(e)
	{
		var result, targetid, oldLink, oldSource, source, jsource, 
		    target, a, len, imgs, node, next, elementQueue, transplants; 

		if ($.ExternalBox.disabled || !this.hasAttribute('rel')) return true;
		
		result = relRegexp.exec(' '+this.getAttribute('rel')+' ');
		if (!result)
			return true;
		targetid = result[1];
		
		target = document.getElementById(targetid);
		if (!target) return;
		
		if (targetElements[targetid])
		{
			oldLink = targetElements[targetid].link;
			oldSource = targetElements[targetid].source;
			transplants = targetElements[targetid].transplants;
			
			// Put back elements we transplanted (moved) the last time (loop through it backwards so that it goes correctly when there are 2 transplanted elements after each other)
			for (a = transplants.length-1; a >= 0; a--)
			{
				transplants[a].parent.insertBefore(transplants[a].node, transplants[a].next);
			}
		}
		else
		{
			oldLink = null;
			oldSource = null;
		}
		source = this;
		
		jsource = $('.externalbox-source', source).eq(0);
		if (jsource.length)
		{
			source = jsource.get(0);
		}
		else
		{
			jsource = $(source).parents('.externalbox-source').eq(0);
			if (jsource.length)
			{
				source = jsource.get(0);
			}
			else
			{
				jsource = $(source);
			}
			
		}
		
		elementQueue = []; // When you click on an image, the external <div> is not filled until the image has finnished loading
		
		$(target).addClass('externalbox-loading');

		elementQueue.push(div('extraDiv0'));
		elementQueue.push(div('extraDiv1'));
		
		targetElements[targetid] = { link: this, 
		                             source: source,
		                             transplants: []
					   };
		
		transplants = targetElements[targetid].transplants; // loop backwards when rebuilding
		function clone(oldNode)
		{
			var newNode, node, next, a;
			
			if ($(oldNode).hasClass('externalbox-transplant')) // transplant the element so that any references remain intact (for editing with miracle for example)
			{
				transplants.push( { node   : oldNode, 
				                    parent : oldNode.parentNode,
				                    next   : oldNode.nextSibling
						  });
				return oldNode;
			}
			else
			{
				newNode = oldNode.cloneNode(false);
				
				if (newNode.nodeName.toUpperCase() === 'IMG')
					imgs.push(newNode);
			
				node = oldNode.firstChild;
				while(node)
				{
					next = node.nextSibling;
					newNode.appendChild(clone(node));
					node = next;
				}
			
				return newNode;
			}
		}
		
		imgs = [];
		//copy the content of this link
		node = source.firstChild;
	
		while (node)
		{
			next = node.nextSibling;
			elementQueue.push(clone(node));
			node = next;
		}
		
		function div(classname)
		{
			var node = document.createElement('div');
			node.setAttribute('class', classname);
			return node;
		}
		
		elementQueue.push(div('extraDiv2'));
		elementQueue.push(div('extraDiv3'));
		
		for(a = 0, len = imgs.length; a < len; a++)
		{
			node = imgs[a];
			node.removeAttribute('width');
			node.removeAttribute('height');
			
			node.setAttribute('src', 'about:blank');
			$(node).bind('load', {target: target, elementQueue: elementQueue}, img_load)
			       .bind('error', {target: target, elementQueue: elementQueue}, img_load);
			
			node.setAttribute('src', this.getAttribute('href'));
		}
		
		$(this).addClass('externalbox-open');
		jsource.addClass('externalbox-open');
		if (oldLink && oldLink !== this)
		{
			$(oldLink).removeClass('externalbox-open');	
		}
		
		if (oldSource && oldSource !== source)
		{
			$(oldSource).removeClass('externalbox-open');
		}
		
		return false;
	}
})(jQuery);
