/**
 * Class wrapping DOM elements with div elements to 
 * create a visual box with background images
 *
 * @package picnic
 * @version 1.0.1 2006-12-20
 * @author Joel Arvidsson <joel@above.se>
 */

var Boxify = 
{
	//The type of the created wrapper elements
	tagName:		'div', 
	
	//Predefined sets of classes, use with Boxify.combine(set1, set2, ...)
	BORDERS:		['top', 'right', 'bottom', 'left'], 
	CORNERS:		['top-right', 'bottom-right', 'bottom-left', 'top-left'], 
	TOP_CORNERS:	['top-left', 'top-right'], 
	BOTTOM_CORNERS:	['bottom-left', 'bottom-right'], 
	RIGHT_CORNERS:	['top-right', 'bottom-right'], 
	LEFT_CORNERS:	['top-left', 'bottom-left'], 
	
	//Combine multiple arrays to a single
	combine: function () 
	{
		var classNames = new Array();
		for (var arg, j, i = 0; i < arguments.length; i++)
		{
			arg = arguments[i];
			if (typeof arg == 'string')
			{
				classNames.push(arg);
				continue;
			}
			for (j = 0; j < arg.length; j++)
			{
				classNames.push(arg[j]);
			}
		}
		return classNames;
	}, 
	
	/**
	 * Create wrappers for whatever, takes n arguments
	 * Usage: Boxify.init(
	 *    Boxify.combine(Boxify.CORNERS, Boxify.BORDERS), 
	 *    'first-element', 
	 *    ['second-element', 'third-element'],
	 *    document.getElementsByClassName('box')
	 * );
	 */
	init: function (classNames)
	{
		if (!classNames || !classNames.length)
		{
			//If we don't have any wrappers to create, take a break
			return;
		}
		for (var method, arg, i = 1; i < arguments.length; i++)
		{
			arg = arguments[i];
			switch (typeof arg)
			{
				case 'string': 
				{
					//Let's assume it's an ID
					arg = $(arg);
					method = this._initSingle;
					break;
				}
				case 'array': 
				{
					//This is plenty of something, probably elements or ID's
					method = this._initMultiple;
					break;
				}
				case 'function': 
				{
					if (arg.length)
					{
						//This is probably a DOMNodeList
						method = this._initMultiple;
						break;
					}
					continue;
				}
				case 'object': 
				{
					if (arg.tagName)
					{
						//This is most likely a DOMElement
						method = this._initSingle;
					}
					else if (arg.length)
					{
						//This is probably a DOMNodeList
						method = this._initMultiple;
					}
					else
					{
						//Some strange object that we can't do anything with
						continue;
					}
					break;
				}
				default:
				{
					//Something really strange like an integer or something, pass it on
					continue;
				}
			}
			//Wow, we actually know what to do with it
			method.bind(this)(arg, classNames);
		}
	},
	
	//Create wrappers for a single element, private method
	_initSingle: function (element, classNames)
	{
		//document.createElement is not application/xml+xhtml safe, but that wont happen
		//any time soon so lets be lazy and cheat =)
		var	lastWrapper = firstWrapper = document.createElement(this.tagName);
		Element.addClassName(lastWrapper, classNames[0]);
		
		//Create the wrappers and give them classes
		for (var tmp, i = 1; i < classNames.length; i++)
		{
			tmp = document.createElement(this.tagName);
			lastWrapper = lastWrapper.appendChild(tmp);
			Element.addClassName(lastWrapper, classNames[i]);
		}
		
		//Move the children of the original element to the new wrapper
		while (element.firstChild != null)
		{
			tmp = element.firstChild;
			element.removeChild(tmp);
			lastWrapper.appendChild(tmp);
		}
		element.appendChild(firstWrapper);
	}, 
	
	//Create wrappers for a multiple elements in arrays/iteratable lists, private method
	_initMultiple: function (elements, classNames)
	{
		for (var i = 0; i < elements.length; i++)
		{
			this._initSingle(elements[i], classNames);
		}
	}
};

