var openedWindows = {};

// Code to handle DHTML layers

// Shortcut way to get objects by string ID. If already an object then return it unchanged.
// If strict is true then an error is thrown when the object isn't found. Defaults to true.
function obj(ref, strict)
{
	var isStrict = strict || typeof strict == 'undefined';
	if (isString(ref)) {
		var o = document.getElementById(ref);
		if (isStrict && !o) throw new Error("No element with id '" + ref + "' found");
		return o;
	} else {
		if (isStrict && !ref) throw new Error("Null passed to obj()");
		return ref;
	}
}

// Dynamically change CSS class
function setClass(ref, newClass)
{
	obj(ref).className = newClass;
}

// Dynamically change contents
function setText(ref,text)
{
	obj(ref).innerHTML = text;
}

/*
 * cssjs
 * written by Christian Heilmann (http://icant.co.uk)
 * eases the dynamic application of CSS classes via DOM
 * parameters: action a, object or name o and class names c1 and c2 (c2 optional)
 * actions: swap exchanges c1 and c2 in object o
 *			add adds class c1 to object o
 *			remove removes class c1 from object o
 *			toggle turns class c1 off if it is currently on and vice-versa
 *			check tests if class c1 is applied to object o
 * example:	cssjs('swap',document.getElementById('foo'),'bar','baz');
 */

function cssjs(a,ref,c1,c2)
{
	var o = obj(ref, true);
	if (o) {
		switch (a){
			case 'swap':
				o.className=!cssjs('check',o,c1)?o.className.replace(c2,c1):o.className.replace(c1,c2);
				break;
			case 'add':
				if(!cssjs('check',o,c1)){o.className+=o.className?' '+c1:c1;}
				break;
			case 'del': case 'remove':
				var rep=o.className.match(' '+c1)?' '+c1:c1;
				o.className=o.className.replace(rep,'');
				break;
			case 'toggle':
				cssjs('check',ref,c1) ? cssjs('remove',ref,c1) : cssjs('add',ref,c1);
				break;		
			case 'check':
				return new RegExp('\\b'+c1+'\\b').test(o.className);
		}
	}
}
function showImage(ref) 
{
	var img = obj(ref);
	cssjs('remove',img,'hidden');
	img.src = img.src; // reload
}

function hideImage(ref) 
{
	cssjs('add',ref,'hidden');
}

/* call this to continue image loading when interrupted by a javascript action */
function reloadImages() {
	var images = document.getElementsByTagName('IMG');
	for (var i=0;i<images.length;i++){
		images[i].src = images[i].src;
	}
}

function showLayer(ref) 
{
	cssjs('remove',ref,'hidden');
}

function hideLayer(ref) 
{
	cssjs('add',ref,'hidden');
}

function deleteLayer(ref) {
	var node = obj(ref);
	node.parentNode.removeChild(node);
}

/* Show next hidden layer in a sequence (up to a maximum) */
function showNextLayer(ref, max) 
{
	if (!isNumber(max)) max = 999;
	for (var i=1; i<max; i=i+1) {
		var el = obj(ref + '_' + i);
		if (el) {
			if (cssjs('check',el,'hidden')) {
				// found next hidden element in sequence
				showLayer(el);
				break;
			}
		} else {
			// no more elements
			break;
		}
	}
	// reached max
}

// Show a CSS layer popup
function showPopup(ref) 
{
	window.scroll(0,0);
	showLayer(ref + '_popup');
}

// Hide a CSS layer popup
function hidePopup(ref) 
{
	hideLayer(ref + '_popup');
}

// Show URL in a new window called <name>
function showWindow(name, url, width, height, options) 
{
	var name = name || 'unnamed';
	var url = url || '/' + name;
	var width = width || 400;
	var height = height || 500;
	var options = options || "scrollbars=1,resizable=yes";

	// default common window settings
	switch(name) {
		case 'my_planner': width = 900; height = 700; break;
		case 'my_messages': width = 600; height = 700; break;
		case 'shopping_cart': width = 800; height = 700; break;
		case 'my_wishlist': width = 600; height = 700; break;
		case 'shipping': width = 600; height = 600; break;
		case 'terms': width = 600; height = 600; break;
	}
	try {
		targetwindow = window.open(url, name, options + ',width='+width+',height='+height);
		openedWindows[name] = targetwindow;
		targetwindow.focus();
	} catch(e) {
		warning("Popup couldn't open, please disable your popup blocker.");
	}
}

// Focus a window if it's already opened
function focusWindow(name) {
	if (openedWindows[name]) openedWindows[name].focus();
}

// Refresh a window if it's already opened
function refreshWindow(name) {
	if (openedWindows[name]) {
		openedWindows[name].location.reload();
	}
}

// Redirect Parent (opener) window
function redirectParent(url) {
	if (window.opener) window.opener.location = url;
}

// writes or changes a general message
function message(text, className)
{
	try {
		// We write the message into the page if the class has 'inline', otherwise it's a popup message
		// eg, msg("Display in page", "popup warning")
		className = className || '';
		var is_popup = new RegExp('\\bpopup\\b').test(className);
		// Add the message text as a list item
		var message_ul = obj( is_popup ? 'popup_messages_list' : 'inline_messages_list' );
		message_ul.innerHTML += '<li class="'+className+'">' + text;
		// Set visual style based on class
		if (is_popup && obj('messages')) {
			showPopup('messages');
		} else {
			showLayer('inline_messages');
		}
		window.scroll(0,0);
	} catch(e) {
		//window.alert(text); // fallback to basic alert
	}
}

// writes or changes a warning message
function warning(text, className)
{
	className = className || '';
	message(text, className + ' warning');
}

// writes or changes an error message
function error(text, className)
{
	className = className || '';
	message(text, className + ' error');
}

// Clear any messages already written
function clearMessages()
{
	var pml = obj('popup_messages_list',false);
	var iml = obj('inline_messages_list',false);
	if (pml) pml.innerHTML = '';
	if (iml) iml.innerHTML = '';
}

// Clear any messages already written
function hideMessages()
{
	if (obj('popup_messages',false)) hidePopup('messages');
	if (obj('inline_messages',false)) hideLayer('inline_messages');
	clearMessages();
}

// Shortcuts (backwards-compat)
msg = message;
warn = warning;
err = error;

/* Get element offset from document top */
function getElementPos( el ) {
	var pos = new Object;
	pos.x = 0; pos.y = 0;
	el = obj( el );
	do {
		pos.x += el.offsetLeft;
		pos.y += el.offsetTop;
	} while (el = el.offsetParent);
	return pos;
}

/* Test wether a point overlaps a rect. The rect is defined using CSS ordering */
function pointInRect(px,py,rt,rr,rb,rl) {
	return px>=rl && px<=rr && py>=rt && py<=rb;
}

/*
	Cross-browser getElementsByClassName. Falls back to slower implementations when native support is missing
	Developed by Robert Nyman, http://www.robertnyman.com
	Code: http://code.google.com/p/getelementsbyclassname/
	License: MIT License (open-source)
*/
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};

