/* Create a name space for JavaScript used by the store. This way, we'll be less
 * likely to step on any other libraries and code. */

var STORE = {
	utils : {},
	cookie : {},
	ui : {},
	order : {},
	form : {},
	admin : {
		ordering : {},
		// NOTE: import is a reserved word in IE.
		importer : {}
	}
};


STORE.utils.getActiveStyle = function(obj)
{
	// Ensure that we have an object and not just the ID of an HTML element.
	
	obj = STORE.utils.getObject(obj);
	
	if (obj.currentStyle)
	{
		// Internet Explorer
		return obj.currentStyle;
	}
	else if (document.defaultView && document.defaultView.getComputedStyle)
	{
		// Mozilla/FireFox
		return document.defaultView.getComputedStyle(obj, null);
	}
	else
	{
		// Fall back to non-computed style.
		return obj.style;
	}
};

// Takes 1 argument which is either the ID or object reference of elements whose
// style display mode will be toggled.

STORE.utils.getObject = function(param)
{
	if (typeof(param) == "object")
	{
		return param;
	}
	else
	{
		return document.getElementById(param);
	}
};

STORE.utils.toggleDisplay = function()
{
	for ( var i = 0; i < arguments.length; i++ )
	{
		var obj = STORE.utils.getObject(arguments[i]);
		
		if (obj == null)
		{
			alert("Could not find object with ID " + arguments[i] + " in the page.");
		}
		
		var objStyle = STORE.utils.getActiveStyle(obj);
		
		// Since all elements are hidden with a value of "none", whereas each
		// element may have its own display value, we'll check for "none".
		
		if (objStyle.display == "none")
		{
			STORE.utils.show(obj);
		}
		else
		{
			STORE.utils.hide(obj);
		}
	}
};

STORE.utils.show = function(obj)
{
	// Make sure we have an object and not just the ID of the object.
	
	obj = STORE.utils.getObject(obj);
	
	obj.style.display = STORE.utils.getDefaultDisplay(obj);

	obj.style.visibility = "visible";
};


STORE.utils.hide = function(obj)
{
	// Make sure we have an object and not just the ID of the object.
	
	obj = STORE.utils.getObject(obj);
	
	obj.style.display = "none";
	
	obj.style.visibility = "hidden";
};

// Determines the default display value for the object's HTML element type. For
// instance, a DIV would have a default display of "block". This method should
// ensure that we use the correct display value for each browser.

STORE.utils.getDefaultDisplay = function(obj)
{
	// Make sure we have an object and not just the ID of the object.
	
	obj = STORE.utils.getObject(obj);
	
	var value = "";
	
	// Create a new element with a tag name that corresponds to the object.
	
	var objCopy = document.createElement(obj.tagName);
	
	// Unless we add the element to the document, we won't know the actual
	// display value. IE will return an empty string; Firefox, "block".
	
	// By setting the visibility to hidden, we ensure that the user will not
	// see any such changes.
	
	objCopy.visibility = "hidden";
	
	document.body.appendChild(objCopy);
	
	value = STORE.utils.getActiveStyle(objCopy).display;
	
	document.body.removeChild(objCopy);
	
	return value;
};

STORE.utils.fileInputCount = 0;

STORE.utils.appendFileInput = function(divId, name)
{
	var div = document.getElementById(divId);
	STORE.utils.fileInputCount += 1;
	
	var file = document.createElement("input");
	file.type = "file";
	file.maxlength = "255";
	file.name = name + "_" + STORE.utils.fileInputCount;
	file.className = "url";
	
	var caption = document.createElement("input");
	caption.type = "text";
	caption.name = name + "Caption_" + STORE.utils.fileInputCount;
	caption.className = "text";
	
	var br1 = document.createElement("br");
	
	var table = document.createElement("table");
	var tr1 = document.createElement("tr");
	var tr2 = document.createElement("tr");
	var td1 = document.createElement("td");
	var td2 = document.createElement("td");
	var td3 = document.createElement("td");
	var td4 = document.createElement("td");
	var tbody = document.createElement("tbody");
	
	td1.innerHTML = "File:";
	td2.appendChild(file);
					
	td3.innerHTML = "Caption:";
	td4.appendChild(caption);
	
	tr1.appendChild(td1);
	tr1.appendChild(td2);
	tbody.appendChild(tr1);
	
	tr2.appendChild(td3);
	tr2.appendChild(td4);
	tbody.appendChild(tr2);
	
	table.appendChild(tbody);
	
	div.appendChild(table);
	div.appendChild(br1);
};

// Returns the value of the cookie if the cookie exists. Otherwise, it returns
// null.
	
STORE.cookie.getCookie = function(cookieName)
{
	var cookies = document.cookie;
	
	var startOfName = cookies.indexOf(cookieName + '=');
	
	if (startOfName < 0)
	{
		return null;
	}
	
	var startOfValue = startOfName + cookieName.length + 1;
	
	var endOfValue = cookies.indexOf(";", startOfValue);
	
	if (endOfValue == -1)
	{
		endOfValue = cookies.length;
	}
	
	var value = cookies.substring(startOfValue, endOfValue);
	
	value = unescape(value);
	
	if (value == "")
	{
		return null;
	}
	
	return value;
};

STORE.cookie.setCookie = function(name, value, expires, domain, path, secure)
{
	// First, deal with the name/value pair. These are separated by an equals
	// sign.
	
	var cookie = name + "=" + escape(value);
	
	// Now, create a function which appends parameters to our cookie.
	
	var append = function(name, value)
	{
		cookie += ";" + name;
		
		// The check for an empty string is to address the path issue mentioned
		// below.
		
		if (value || value == "")
		{
			cookie += "=" + value;
		}
	}
	
	if (expires)
	{
		append("expires", expires.toGMTString());
	}
	
	if (domain)
	{
		append("domain", domain);
	}
	
	if (path)
	{
		append("path", path);
	}
	else if (path == "")
	{
		// If the path is an empty string, then we want to render it as path=
		// to match the behavior of ASP. Internet Explorer is picky about path
		// decarations. The absense of a path attribute is not the same as a
		// path=.
		
		append("path", "");
	}
	
	// The secure attribute doesn't have a value.
	
	if (secure)
	{
		append("secure");
	}
	
	document.cookie = cookie;
};

STORE.cookie.deleteCookie = function(name, domain, path)
{
	var expires = new Date();
	
	STORE.cookie.setCookie(name, "", expires, domain, path);
};

STORE.cookie.supportsCookies = function()
{
	var name = "ThisIsATesT";
	
	var value = "Yes";
	
	STORE.cookie.setCookie(name, value);
	
	var retrievedValue = STORE.cookie.getCookie(name);
	
	if (retrievedValue == value)
	{
		STORE.cookie.deleteCookie(name);
		
		return true;
	}
	else
	{
		return false;
	}
};

STORE.ui.setSelectedTab = function (id, index)
{
	var cookie = STORE.cookie.getCookie("selectedTab") || "";
	
	states = STORE.ui.parseTabStates(cookie);
	
	states[id] = index;
	
	var encodedStates = STORE.ui.encodeTabStates(states);
	
	STORE.cookie.setCookie("selectedTab", encodedStates);	
};

/* Takes a string in the following format:
 *   
 *   363412CF62B693DD578FA3285A4B6C78.2:2,40D96DFBEF7C82448A1B94FA0948CFFB.2:2
 *   
 * And converts into a hash table:
 *  
 *   {
 *     "363412CF62B693DD578FA3285A4B6C78.2" : "2",
 *     "40D96DFBEF7C82448A1B94FA0948CFFB.2" : "2"
 *   }
 */

STORE.ui.parseTabStates = function (encodedString)
{
	var states = {};
	
	// First, convert the string into an array of encoded states. That will give
	// us something that looks like this:
	// 
	//   ["363412CF62B693DD578FA3285A4B6C78.2:2", "40D96DFBEF7C82448A1B94FA0948CFFB.2:2"]
	
	var encodedStates = encodedString.split(",");
	
	for (var i in encodedStates)
	{
		// Each individual state pair will look something like this:
		//   
		//   363412CF62B693DD578FA3285A4B6C78.2:2
		
		var encodedStatePair = encodedStates[i];
		
		// Split the pair so that we can reference each half by index. That will
		// give us something like this:
		//   
		//   ["363412CF62B693DD578FA3285A4B6C78.2", "2"]
		
		var statePair = encodedStatePair.split(":");
		
		// The first element is the ID; the second, the selected tab index.
		
		var id = statePair[0];
		
		var index = statePair[1];
		
		// Add the state to our hash table.
		
		states[id] = index;	
	}
	
	return states;
};

STORE.ui.encodeTabStates = function (states)
{
	var encodedStates = [];
	
	for (var id in states)
	{
		var encodedState = id + ":" + states[id];
		
		encodedStates.push(encodedState);
	}
	
	var encodedStatesAsString = encodedStates.join(",");
	
	return encodedStatesAsString;
};

STORE.ui.panels = {};

STORE.ui.registerPanel = function(panelID, bodyID, linkID, url, panelOptions,
		callbackFunction)
{
	
	if (!panelOptions)
	{
		panelOptions = {
			"width" : "600px",
			"height" : "400px",
			"close" : true,
			"visible" : false,
			"fixedcenter" : true,
			"draggable" : false,
			"modal" : false,
			"constraintoviewport" : true,
			"effect" : {
				"effect" : YAHOO.widget.ContainerEffect.FADE,
				"duration" : 0.25
			}
		};
	}
	
	var panel = new YAHOO.widget.Panel(panelID, panelOptions);
	
	// Store a panel reference in case we need to hide the panel in the future.
	
	STORE.ui.panels[panelID] = panel;
	
	// NOTE: If the panels are not located directly under the body tag, errors
	// may occur in IE when calling this during the onload or domready events.
	// In which case, render should be called immediately before show().
	
	panel.render();
	
	if (url)
	{
		
		YAHOO.util.Event.addListener(
			linkID,
			"click",
			function(e)
			{
				var transaction = YAHOO.util.Connect.asyncRequest(
						"GET",
						url,
						{
							"success" : callbackFunction,
							"failure" : callbackFunction,
							"argument": {
								"id" : bodyID
							}
						}
				);
			}
		);
		
	}
	
	YAHOO.util.Event.addListener(
			linkID,
			"click",
			function(e)
			{
				panel.show(panel, true);
				// The panel is hidden by default to avoid scroll bars
				// in IE. We want to wait until the panel has been
				// positioned before displaying it.
				document.getElementById(panelID).style.display = "block";
				e.cancelBubble = true;
			}
	);
	
};

/*** Order ********************************************************************/

STORE.order.stateVisible = true;

STORE.order.handleCountrySelection = function(country, state, province)
{
	country = STORE.utils.getObject(country);
	
	state = STORE.utils.getObject(state);
	
	province = STORE.utils.getObject(province);
	
	var countryCode = country.options[country.selectedIndex].value;
	
	if (STORE.order.countryHasStates(countryCode))
	{
		
		STORE.order.populateStates(countryCode, state);
		
		STORE.order.showState(state, province);
		
	}
	else
	{
		STORE.order.showProvince(state, province);
	}
};

STORE.order.showState = function(state, province)
{
	STORE.utils.show(state);
	
	STORE.utils.hide(province);
	
	state.name = state.id;
	
	province.name = state.id & "-disabled";
	
	STORE.order.stateVisible = true;
};

STORE.order.showProvince = function(state, province)
{
	STORE.utils.show(province);
	
	STORE.utils.hide(state);

	state.name = state.id + "-disabled";
	
	province.name = state.id;

	STORE.order.stateVisible = false;
};


STORE.order.countries = {};

STORE.order.countryHasStates = function(country)
{
	if (STORE.order.countries[country])
	{
		return true;
	}
	else
	{
		return false;
	}
};

STORE.order.populateStates = function(countryCode, stateSelectList)
{
	STORE.form.clearSelectList(stateSelectList);
	
	var states = STORE.order.countries[countryCode];
	
	for (var i = 0; i < states.length; i++)
	{
		var state = states[i];
		
		var option = new Option(state.Name, state.Abbreviation);
		
		stateSelectList.options[i] = option;	
	}
};

STORE.order.setState = function(stateSelectList, provinceText, stateName)
{
	if (STORE.order.stateVisible)
	{
		stateSelectList = STORE.utils.getObject(stateSelectList);
		
		STORE.form.selectOption(stateSelectList, stateName);
	}
	else
	{
		provinceText = STORE.utils.getObject(provinceText);
		
		provinceText.value = stateName;	
	}
};

STORE.order.handleStateSelection = function(stateSelectList)
{
	stateSelectList = STORE.utils.getObject(stateSelectList);
	
	state = STORE.form.getValue(stateSelectList);
};

STORE.order.updateInput = function(id, value)
{
	var div = document.getElementById(id);
	
	div.value = value;
};


/*** Form *********************************************************************/

STORE.form.clearSelectList = function(selectList)
{
	for (var i = selectList.length - 1; i >= 0; i--)
	{
		selectList.options[i] = null;
	}
};


STORE.form.selectOption = function(selectList, optionValue)
{
	for (var i = 0; i < selectList.length; i++)
	{
		
		var option = selectList.options[i];
		
		if (option.value == optionValue)
		{
			option.selected = true;
		}
		
	}
};

STORE.form.getValue = function(element)
{
	element = STORE.utils.getObject(element);
	
	if (element.options)
	{
		return element.options[element.selectedIndex].value;
	}
	else
	{
		return element.value;
	}
};

/*** Admin - Ordering *********************************************************/

STORE.admin.ordering.creditCardTypeCount = 0;
STORE.admin.ordering.creditCardTypesId = "creditCardTypes";

STORE.admin.ordering.addCreditCardType = function()
{
	STORE.admin.ordering.creditCardTypeCount = STORE.admin.ordering.creditCardTypeCount + 1;
	
	var i = STORE.admin.ordering.creditCardTypeCount; // For convenience
	
	// Create the text box
	
	var inputText = document.createElement('input');
	inputText.setAttribute('type', 'text');
	inputText.setAttribute('name', 'newCreditCardType_' + i);
	
	// Create the "(Remove)" link
	
	var removeLink = document.createElement('a');
	removeLink.setAttribute('href', 'javascript:STORE.admin.ordering.removeNewCreditCardType(' + i + ')');
	removeLink.appendChild(document.createTextNode('(Remove)'));
	
	// Create the hidden form field
	
	var hidden = document.createElement('input');
	hidden.setAttribute('type', 'hidden');
	hidden.setAttribute('name', 'newCreditCardTypes');
	hidden.setAttribute('value', i);
	
	// Package the whole thing into a div
	
	var creditCardTypeDiv = document.createElement('div');
	creditCardTypeDiv.setAttribute('id', 'newCreditCardType_' + i);
	creditCardTypeDiv.appendChild(inputText);
	creditCardTypeDiv.appendChild(hidden);
	creditCardTypeDiv.appendChild(removeLink);
		
	// Add that div to the parent element
	
	var element = document.getElementById(STORE.admin.ordering.creditCardTypesId);
	element.appendChild(creditCardTypeDiv);
};

STORE.admin.ordering.removeCreditCardType = function(i)
{
	var creditCardTypeDiv = document.getElementById(STORE.admin.ordering.creditCardTypesId);
	var div = document.getElementById('creditCardTypeDiv_' + i);
	
	creditCardTypeDiv.removeChild(div);
};

STORE.admin.ordering.removeNewCreditCardType = function(i)
{
	var creditCardTypeDiv = document.getElementById(STORE.admin.ordering.creditCardTypesId);
	var div = document.getElementById('newCreditCardType_' + i);
	
	creditCardTypeDiv.removeChild(div);
};

/*** Admin - Import ***********************************************************/

STORE.admin.importer.toggleHelp = function(link)
{
	var help = STORE.admin.importer.getHelpForLink(link);
	
	if (help.style.display != "block")
	{
		help.style.display = "block";
	}
	else
	{
		help.style.display = "none";
	}
};

STORE.admin.importer.getHelpForLink = function(link)
{
	if (link.help)
	{
		return link.help;
	}
	
	var reason = link.getAttribute("store:help");
	
	var id = STORE.admin.importer.getHelpID(reason);
	
	var help = document.getElementById(id);
	
	if (!help)
	{
		help = STORE.admin.importer.getDefaultHelp();
	}
	
	link.help = STORE.admin.importer.copyHelp(help);
	
	link.parentNode.appendChild(link.help); 
	
	return link.help;
};

STORE.admin.importer.copyHelp = function(help)
{
	var clone = document.createElement("DIV");
	
	clone.className = help.className;
	
	clone.innerHTML = help.innerHTML;
	
	return clone;
};

STORE.admin.importer.getHelpID = function(reason)
{
	if (!reason)
	{
		return "import-help-unknown";
	}
	
	return "import-help-" + reason.toLowerCase();
};

STORE.admin.importer.CLASS_NAME = "itemHelp";

STORE.admin.importer.getDefaultHelp = function()
{
	var help = document.createElement("DIV");;
	
	help.className = STORE.admin.importer.CLASS_NAME;
	
	help.innerHTML = "<p>No help available for this item.</p>";
	
	return help;
};