/*******************************************************************************************************
 * shadower.js
 * Author: Erik Rasmussen
 * Email: erikwordpressplugins -at- gmail
 * Info: http://www.erik-rasmussen.com/blog/2006/12/04/the-shadower-realistic-drop-shadows-in-javascript/
 *******************************************************************************************************/
var Shadower =
{
	shadow: function(element)
	{
		element = $(element);
		var options = Object.extend(
		{
			distance: 8,
			angle: 130,
			opacity: 0.7,
			nestedShadows: 4,
			color: '#000000'
		}, arguments[1] || {});
		var positionStyle = Element.getStyle(element, 'position');
		var parent = element.parentNode;
		if (!element.shadowZIndex)
		{
			if (positionStyle != 'absolute' && positionStyle != 'fixed')
			{
				var placeHolder = this.idSafeClone(element);
				placeHolder.id = null;
				parent.insertBefore(placeHolder, element);
				Position.absolutize(element);
				Position.clone(placeHolder, element);
				element.style.margin = '0';
				placeHolder.style.visibility = 'hidden';
				positionStyle = 'absolute';
			}
			element.shadowZIndex = new Number(Element.getStyle(element, 'zIndex') ? Element.getStyle(element, 'zIndex') : 1);
			element.style.zIndex = element.shadowZIndex + options.nestedShadows;
		}
		if (arguments[2])  // force recreate
			this.deshadow(element);
		// create shadows
		if (!element.shadows)
		{
			element.shadows = new Array(options.nestedShadows);
			for (var i = 0; i < options.nestedShadows; i++)
			{
				var shadow = document.createElement('div');
				Element.hide(shadow);
				shadow.appendChild(document.createTextNode(' '));
				if (parent)
					parent.appendChild(shadow);
				shadow.style.position = positionStyle;
				shadow.style.backgroundColor = options.color;
				Element.setOpacity(shadow, options.opacity / options.nestedShadows);
				shadow.style.zIndex = element.shadowZIndex + i;
				element.shadows[i] = shadow;
			}
		}
		var legendHeight = this.getLegendHeight(element);
		// position shadows
		Position.prepare();
		var offsets = Position.positionedOffset(element);
		var topOffset = -Math.cos(-options.angle * Math.PI / 180) * options.distance;
		var leftOffset = -Math.sin(-options.angle * Math.PI / 180) * options.distance;
		element.shadows.each(function(shadow, i)
		{
			shadow.style.top = Math.ceil(offsets[1] + topOffset + i + (legendHeight / 2)) + 'px';
			shadow.style.left = (offsets[0] + leftOffset + i) + 'px';
			shadow.style.width = (element.offsetWidth - (2 * i)) + 'px';
			shadow.style.height = (element.offsetHeight - (2 * i) - (legendHeight / 2)) + 'px';
			Element.show(shadow);
		});
	},

	idSafeClone: function(node)
	{
		var clone = node.cloneNode(false);
		if (clone.hasAttribute && clone.hasAttribute('id'))
			clone.removeAttribute('id');
		var clonedChildren = $A(node.childNodes).collect(this.idSafeClone.bind(this));
		clonedChildren.each(function(child)
		{
			clone.appendChild(child);
		});
		return clone;
	},

	getLegendHeight: function(element)
	{
		if (element.nodeName.toLowerCase() == 'fieldset')
		{
			var legend;
			$A(element.childNodes).each(function(child)
			{
				if (child.nodeName.toLowerCase() == 'legend')
				{
					legend = child;
					throw $break;
				}
			});
			if (legend)
				return Element.getDimensions(legend).height;
		}
		return 0;
	},

	deshadow: function(element)
	{
		element = $(element);
		if (element.shadows)
		{
			element.shadows.each(Element.remove);
			element.shadows = null;
		}
	},

	shadowWithClass: function(cssClass, options)
	{
		$$('.' + cssClass).each(function(element)
		{
			this.shadow(element, options);
		}.bind(this));
	}
}

// check for prototype.js
if ((typeof Prototype == 'undefined') ||
    (typeof Element == 'undefined') ||
    (typeof Element.Methods == 'undefined') ||
    parseFloat(Prototype.Version.split(".")[0] + "." +
               Prototype.Version.split(".")[1]) < 1.5)
	throw("Shadower requires the Prototype JavaScript framework >= 1.5.0");

// the cross-browser opacity code below is borrowed from script.aculo.us
Element.getOpacity = function(element)
{
	var opacity;
	if (opacity = Element.getStyle(element, 'opacity'))
		return parseFloat(opacity);
	if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
		if (opacity[1]) return parseFloat(opacity[1]) / 100;
	return 1.0;
}

Element.setOpacity = function(element, value)
{
	element = $(element);
	if (value == 1)
	{
		Element.setStyle(element, { opacity:
				(/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
				0.999999 : null });
		if (/MSIE/.test(navigator.userAgent))
			Element.setStyle(element, {filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
	}
	else
	{
		if (value < 0.00001) value = 0;
		Element.setStyle(element, {opacity: value});
		if (/MSIE/.test(navigator.userAgent))
			Element.setStyle(element,
			{ filter: Element.getStyle(element, 'filter').replace(/alpha\([^\)]*\)/gi, '') +
			          'alpha(opacity=' + value * 100 + ')' });
	}
}
