/**
 * Utilities
 */

window.extend({
		getCenter : function()
		{
			var windowSize = Window.getSize();
			
			return {
					x : windowSize.scroll.x + windowSize.size.x / 2,
					y : windowSize.scroll.y + windowSize.size.y / 2
				}
		}
	});
	
Element.extend({
		getZIndex : function()
		{
			var zIndex = 'auto';
			
			for (var node = this; node; node = $(node.parentNode))
			{
				if (!node.getStyle)
				{
					break;
				}
				
				zIndex = node.getStyle('z-index');
				
				if (zIndex != 'auto')
				{
					break;
				}
			}
			
			return zIndex;
		}
	});
	
/**
 * Lightbox
 */

var Lightbox = {
		zIndex : 1000,
		util : {}
	};

Lightbox.util.create = function()
{
	var actions = new Element('div', {
			'class' : 'lightbox-actions'
		})
		.adopt(new Element('span', {
				'class' : 'action-close',
				'events' : {
						'click' : function()
							{
								Lightbox.close(this);
							}
					}
			})
			.setText('Close'));
			
	return new Element('div', {
			'class' : 'lightbox lightbox-loading',
			'styles' : {
					'z-index' : ++Lightbox.zIndex
				}
		})
		.adopt(new Element('div', {
				'class' : 'wrapper1'
			})
			.adopt(new Element('div', {
					'class' : 'wrapper2'
				})
				.adopt(new Element('div', {
						'class' : 'wrapper3'
					})
					.adopt(new Element('div', {
							'class' : 'wrapper4'
						})
						.adopt(new Element('div', {
								'class' : 'content'
							}))
						.adopt(actions)))));
}

Lightbox.util.handleWindowMovement = function()
{
	if (Lightbox._scrollTimer)
	{
		clearTimeout(Lightbox._scrollTimer);
	}
	
	Lightbox._scrollTimer = Lightbox.util.moveMiddle.delay(500, window, [ $$('.lightbox')[0], true ]);
}

window.addEvent('scroll', Lightbox.util.handleWindowMovement);
window.addEvent('resize', Lightbox.util.handleWindowMovement);

Lightbox.util.moveMiddle = function(elem, animate, width)
{
	if (!elem)
	{
		return;
	}
	
	if (typeof animate === 'undefined')
	{
		animate = true;
	}
	
	var mid = window.getCenter();
	
	var size = elem.getSize().size;
	
	var styles = {};
	
	if (width)
	{
		styles.width = width;
		
		size.x = width;
	}
	
	styles.left = mid.x - size.x / 2;
	styles.top = mid.y - size.y / 2;
		
	if (animate)
	{
		new Fx.Styles(elem, {
				duration: 500,
				transition: Fx.Transitions.Expo.easeInOut
			})
			.start(styles);
	}
	else
	{
		elem.setStyles(styles);
	}	
}

Lightbox.util.setContent = function(box, content, move)
{
	box = $(box);
	
	var container = box.getElement('.content');
	
	if ($type(content) == 'element')
	{
		container.adopt(content);
		
		content.setStyle('display', 'block');
	}
	else
	{
		container.setHTML(content);
	}
	
	if (move)
	{
		var oldWidth = box.getSize().size.x;
		
		box.removeClass('lightbox-loading');
		
		var newWidth = box.getSize().size.x;
		
		box.setStyle('width', oldWidth);
		
		//console.log(oldWidth, newWidth);
		
		Lightbox.util.moveMiddle(box, true, newWidth);
	}
	else
	{
		box.removeClass('lightbox-loading');
	}
}

Lightbox.display = function(content)
{
	var box = Lightbox.util.create();
	
	box.injectTop(document.body);
	
	box.setStyles({
			'position' : 'absolute',
			'display' : 'block',
			'opacity' : 0
		});
	
	// Hide select boxes as they will 'peek' through the image in IE
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
			selects[i].style.visibility = "hidden";
	}
		
	if (content)
	{
		var contentElement = $(content);
		
		if (contentElement)
		{
			content = contentElement.clone();
		}
		
		Lightbox.util.setContent(box, content, false);
	}
	
	Lightbox.util.moveMiddle(box, false, null);
		
	box._viewportBlocker = Lightbox.viewport.hide(box);
	
	return box;
}

Lightbox.close = function(box)
{
	for (box = $(box); box; box = $(box.parentNode))
	{
		if (box.hasClass('lightbox'))
		{
			break;
		}
	}
	
	if (box)
	{
		var blocker = box._viewportBlocker;
		
		// make select boxes visible
		selects = document.getElementsByTagName("select");
		for (i = 0; i != selects.length; i++) {
			selects[i].style.visibility = "visible";
		}
		
		new Fx.Elements([ box, blocker], {
				duration : 500,
				transition : Fx.Transitions.Expo.easeOut
			})
			.start({
					'0' : {
							'opacity' : 0
						},
					'1' : {
							'opacity' : 0
						}
				})
				.chain(function()
					{
						box.remove();
						
						blocker.remove();
						
						Lightbox.util.handleWindowMovement();
					});
	}
	
	return box;
}

Lightbox._remoteCache = {};

Lightbox.remote = function(url, options)
{	
	options = options || {};
	
	if (!options.method)
	{
		options.method = 'get';
	}
	
	var hash = url + '|' + Object.toQueryString(options);
	
	if (options.cache && Lightbox._remoteCache[hash])
	{
		Lightbox.display(Lightbox._remoteCache[hash]);
		
		return;
	}
	
	var box = Lightbox.display();
	
	var req = new Ajax(url, options);
	
	req.addEvent('onComplete', function(text)
		{
			Lightbox.util.setContent(box, text, true);
			
			if (options.cache)
			{
				Lightbox._remoteCache[hash] = text;
			}
		})
		
	req.request();
}

Lightbox.viewport = {};

Lightbox.viewport.hide = function(box)
{
	var blocker = new Element('div', { 'class' : 'viewport-blocker'});
	
	blocker.injectTop(document.body);
	
	var windowSize = Window.getSize();
	
	var viewport = windowSize.size;
	
	var fullSize = windowSize.scrollSize;
	
	blocker.setStyles({
			'z-index' : Lightbox.zIndex++,
			'background-color' : '#000000',
			'overflow' : 'hidden',
			'position' : 'absolute',
			'left' : 0,
			'top' : 0,
			'width' : '100%',
			'height' : fullSize.y,
			'opacity' : 0,
			'display' : 'block'
		});
		
	new Fx.Elements([ box, blocker], {
			duration : 500,
			transition : Fx.Transitions.Expo.easeOut
		})
		.start({
				'0' : {
						'opacity' : [ 0, 1 ]
					},
				'1' : {
						'opacity' : [ 0, 0.8 ]
					}
			});
		
	return blocker;
}

/**
 * Tooltip.js
 */

var Tooltip = {
		util : {},
		active : []
	};

Tooltip.util.init = function()
{
	document.getElements('.tippable[title]').each(function(elem)
		{
			elem.addEvent('mouseover', function(e)
				{
					Tooltip.display(this.title, this, Tooltip.Position.CenterTop);
				
					new Event(e).preventDefault();
				});
		})
}

window.addEvent('domready', Tooltip.util.init);

Tooltip.util.clean = function(e)
{
	var pos = new Event(e).page;
	
	Tooltip.active.each(function(contextNode)
		{
			if (!Tooltip.util.isPositionWithinArea(pos, contextNode.getCoordinates())
				&& !Tooltip.util.isPositionWithinArea(pos, contextNode._tooltip.getCoordinates()))
			{
				if (!contextNode._tooltipHideTimer)
				{
					contextNode._tooltipHideTimer = Tooltip.hide.delay(500, null, contextNode);
				}
			}
			else
			{
				if (contextNode._tooltipHideTimer)
				{
					$clear(contextNode._tooltipHideTimer);
					
					delete contextNode._tooltipHideTimer;
				}
			}
		});
}

document.addEvent('mousemove', Tooltip.util.clean.bindAsEventListener());

Tooltip.util.create = function()
{
	return new Element('div', {
			'class' : 'tooltip tooltip-loading'
		})
		.adopt(new Element('div', {
				'class' : 'wrapper1'
			})
			.adopt(new Element('div', {
					'class' : 'wrapper2'
				})
				.adopt(new Element('div', {
						'class' : 'wrapper3'
					})
					.adopt(new Element('div', {
							'class' : 'wrapper4'
						})
						.adopt(new Element('div', {
								'class' : 'content'
							}))))));
}

Tooltip.util.setContent = function(tooltip, contextNode, content, position)
{
	tooltip = $(tooltip);
	
	var container = tooltip.getElement('.content');
	
	if ($type(content) == 'element')
	{
		container.adopt(content);
		
		content.setStyle('display', 'block');
	}
	else
	{
		container.setHTML(content);
	}
	
	if (position)
	{
		var oldSize = tooltip.getSize().size;
		
		tooltip.removeClass('tooltip-loading');
		
		var newSize = tooltip.getSize().size;
		
		tooltip.setStyles({
				'width' : oldSize.width,
				'height' : oldSize.height
			});
		
		Tooltip.util.moveToPosition(tooltip, contextNode, position, true, newSize);
	}
	else
	{
		tooltip.removeClass('tooltip-loading');
	}
}

Tooltip.util.moveToPosition = function(tooltip, contextNode, position, animate, toSize)
{
	var size = tooltip.getSize().size;
	
	var coords = contextNode.getCoordinates();
	
	var styles = {};
	
	if (toSize && toSize.width)
	{
		size.x = styles.width = toSize.width;
	}
	
	if (toSize && toSize.height)
	{
		size.y = styles.height = toSize.height;
	}
	
	styles.left = coords.left + coords.width * position.x + size.x * (position.x - 1);
	styles.top = coords.top + coords.height * position.y + size.y * (position.y - 1);
	
	if (animate)
	{
		new Fx.Styles(tooltip, {
				duration: 500,
				transition: Fx.Transitions.Expo.easeInOut
			})
			.start(styles);
	}
	else
	{
		tooltip.setStyles(styles);
	}
		
	tooltip._currentPosition = position;
		
	return tooltip;
}

Tooltip.util.isPositionWithinArea = function(position, area)
{
	return position.x > area.left && position.x < area.right
		&& position.y > area.top && position.y < area.bottom;
}

Tooltip.display = function(content, contextNode, position)
{	
	contextNode = $(contextNode);
	
	if (contextNode._tooltip)
	{
		return contextNode._tooltip;
	}
	
	var tooltip = Tooltip.util.create();
	
	contextNode._tooltip = tooltip;
	
	Tooltip.active.push(contextNode);
	
	var zIndex = contextNode.getZIndex();
	
	if (!isNaN(zIndex))
	{
		++zIndex;
	}
	
	tooltip.setStyles({
			'position' : 'absolute',
			'display' : 'block',
			'margin-top' : 20,
			'opacity' : 0,
			'z-index' : zIndex
		});
	
	tooltip.injectTop(document.body);
	
	if (content)
	{
		var contentElement = $(content);
		
		if (contentElement)
		{
			content = contentElement.clone();
		}
		
		Tooltip.util.setContent(tooltip, contextNode, content, null);
	}
	
	Tooltip.util.moveToPosition(tooltip, contextNode, position, false);
	
	contextNode._tooltipFadeIn = new Fx.Styles(tooltip, {
			duration: 750,
			transition : Fx.Transitions.Cubic.easeInOut
		})
		.start({
				'margin-top' : 0,
				'opacity' : 1
			});
			
	return tooltip;
}

Tooltip._remoteCache = {};

Tooltip.remote = function(url, contextNode, position, options)
{	
	options = options || {};
	
	if (!options.method)
	{
		options.method = 'get';
	}
	
	var hash = url + '|' + Object.toQueryString(options);
	
	if (options.cache && Tooltip._remoteCache[hash])
	{
		Tooltip.display(Tooltip._remoteCache[hash], contextNode, position);
		
		return;
	}
	
	var tooltip = Tooltip.display(null, contextNode, position);
	
	var req = new Ajax(url, options);
	
	req.addEvent('onComplete', function(text)
		{
			Tooltip.util.setContent(tooltip, contextNode, text, position);
			
			if (options.cache)
			{
				Tooltip._remoteCache[hash] = text;
			}
		})
		
	req.request();
}

Tooltip.hide = function(contextNode)
{
	if (!contextNode._tooltip)
	{
		return;
	}
	
	var tooltip = contextNode._tooltip;
	
	if (contextNode._tooltipFadeIn)
	{
		contextNode._tooltipFadeIn.stop();
		
		delete contextNode._tooltipFadeIn;
	}
	
	new Fx.Styles(tooltip, {
			duration: 1000,
			transition : Fx.Transitions.Expo.easeIn
		})
		.start({
				'margin-top' : -20,
				'opacity' : 0
			})
			.chain(function()
				{
					try
					{
						tooltip.remove();
					}
					catch(e) {}
					
					delete contextNode._tooltip;
					
					Tooltip.active.remove(contextNode);
				});
}

Tooltip.Position = {
		LeftTop : { x : 0, y : 0 },
		LeftMiddle : { x : 0, y : 0.5 },
		LeftBottom : { x : 0, y : 1 },
		CenterTop : { x : 0.5, y : 0 },
		CenterMiddle : { x : 0.5, y : 0.5 },
		CenterBottom : { x : 0.5, y : 1 },
		RightTop : { x : 1, y : 0 },
		RightMiddle : { x : 1, y : 0.5 },
		RightBottom : { x : 1, y : 1 }
	};