function normalize(val, max) {
	return val < 0 ? max + val % max : val % max;
}
function createObject(id, type, data, width, height, params, fallbackContent, createElementFunc) {
	var createElementFunc = createElementFunc || createElement;
	var obj = createElementFunc('object', {
		'type': type,
		'data': data,
		'width': width,
		'height': height,
		'id' : id
	});
	if(id)
		obj.setAttribute('id', id);
	if(params)
		for(var i = 0, pair; pair = params[i]; i++)
			obj.appendChild(createElementFunc('param', {
				'name': pair[0],
				'value': pair[1]
			}));
	if(fallbackContent)
		obj.appendChild(fallbackContent);
	return obj;
}
function setFlash(target, id, data, width, height, params, fallback) {
	var FLASH_MEDIA_TYPE = 'application/x-shockwave-flash';
	var targetNode = $(target);
	// DOM manipulation and styling of OBJECT tags is not available in IE
	if(Browser.ie) {
		if(typeof fallback != 'string')
			fallback = fallback.innerHTML;
		targetNode.innerHTML = createObject(id, FLASH_MEDIA_TYPE, data, width, height, params, fallback, createElementStr);
	} else {
		if(typeof fallback == 'string')
			fallback = document.createTextNode(fallback);
		removeChildren(targetNode);
		targetNode.appendChild(createObject(id, FLASH_MEDIA_TYPE, data, width, height, params, fallback));
	}
	return targetNode.firstChild;
}

function updatePagedControls(index, container, nodeName, activeClass, reverse) {
	if(index == null)
		return;
	var controls = getChildElementsByTagName(container, nodeName);
	for(var i = 0; i < controls.length; i++)
		controls[i].className = '';
	controls[reverse ? controls.length - index - 1 : index].className = activeClass;
}
function updatePagedIncrementalControls(index, container, nodeName, activeClass, disabledClass, reverse) {
	if(index == null)
		return false;
	var controls = getChildElementsByTagName($(container), nodeName);
	var control = controls[reverse ? controls.length - index - 2 : index + 1];
	var prevControl = reverse ? controls[controls.length - 1] : controls[0];
	var nextControl = reverse ? controls[0] : controls[controls.length - 1];
	if(control.className != activeClass) {
		for(var i = 1; i < controls.length - 1; i++)
			controls[i].className = '';
		control.className = activeClass;
		prevControl.className = '';
		nextControl.className = '';
		if(index == 0)
			prevControl.className = disabledClass;
		else if(index == controls.length - 3)
			nextControl.className = disabledClass;
		return true;
	}
	return false;
}

function hideFormField(field) {
	hide(field);
	$(field).disabled = true;
}

function showFormField(field) {
	$(field).disabled = false;
	show(field);
}

function clearCheckedFields(element) {
	var inputs = $(element).getElementsByTagName('input');

	for(var i = 0, input; input = inputs[i]; i++)
		if(input.checked)
			input.checked = false;
}

function setIntOptions(select, max) {
	select = $(select);
	removeChildren(select);
	for(var i = 1; i <= max; i++) {
		var opt = createElement('option', {'value':i});
		opt.appendChild(document.createTextNode(i));
		select.appendChild(opt);
	}
}

function showPagedContentMulti(container, pageTagName, pageIndices, detectionFunc, activationFunc, deactivationFunc) {
	var detectionFunc = detectionFunc || visible;
	var activationFunc = activationFunc || show;
	var deactivationFunc = deactivationFunc || hide;
	var pages = getChildElementsByTagName($(container), pageTagName);

	var j = 0;

	for(var i = 0; i < pages.length; i++) {
		if(indexOf(pageIndices, i) == -1)
			deactivationFunc(pages[i]);
		else
			activationFunc(pages[i]);
	}
	return null;
}

// Be sure the parameter rxhtml is asserted when making AJAX requests to force XHTML to be returned when HTML normally would be
var Store = {
	CART_ACTION_PATH : 'data/cart.xml',
	SPLASH_CONTENT_CONTAINER_ID : 'splashContent',
	QTY_INPUT_THRESHOLD : 30,
	showProductPage : function(controlSets, container, page, relative) {
		var doScroll = false;
		var pageIndex = showPagedContent(container, 'div', page, relative);
		if(pageIndex == null)
			return;
		//if($(this.SPLASH_CONTENT_CONTAINER_ID))
		//	(pageIndex == 0 ? show : hide)(this.SPLASH_CONTENT_CONTAINER_ID);
		for(var i = 0; i < controlSets.length; i++)
			doScroll |= updatePagedIncrementalControls(pageIndex, controlSets[i], 'a', 'current', 'disabled', true);
		if(doScroll) {
			window.location = "#p" + (pageIndex + 1);
			window.scroll(0, 0);
		}
	},
	showFirstPage : function(pageControlIds, container) {
		if(!window.location.hash)
			return;
		var matches = window.location.hash.match(/^#p([0-9]+)$/);
		if(matches && matches.length > 1)
			Store.showProductPage(pageControlIds, container, matches[1] - 1);
	},
	showItemInfo : function(control, page) {
		updatePagedControls(showPagedContent(control.parentNode, 'div', page), control.parentNode, 'a', 'info-hit');
	},
	setItemAvailability : function(select) {
		var idSuffix = select.form.name;
		if(select.form.productid.value == '') {
			hideFormField('quantity' + idSuffix);
			hideFormField('quantitySelect' + idSuffix);
			show('soldOut' + idSuffix);
			$('add' + idSuffix).className = 'add-button-disabled';
		} else {
			 $('add' + idSuffix).className = 'add-button';
			 hide('soldOut' + idSuffix);
			 if(maxItemQty[idSuffix][select.selectedIndex] <= Store.QTY_INPUT_THRESHOLD) {
				setIntOptions('quantitySelect' + idSuffix, maxItemQty[idSuffix][select.selectedIndex]);
				hideFormField('quantity' + idSuffix);
				showFormField('quantitySelect' + idSuffix);
			} else {
				$('quantity' + idSuffix).value = 1;
				hideFormField('quantitySelect' + idSuffix);
				showFormField('quantity' + idSuffix);
			}
		}
	},
	addToCartForm : function(target) {
		while(target.nodeName.toLowerCase() != 'form')
			target = target.parentNode;

		if(target.productid.value != '') {
			var quantity = 0;
			var fields = target.elements;

			for(var field, i = 0; field = fields[i]; i++) {
				if(field.name == 'quantity' && !field.disabled) {
					quantity = field.value;
					break;
				}
			}

			Store._cartAction('add', target.productid.value, quantity, target.gift && target.gift.checked);
			window.scroll(0, 0);
		}
	},
	removeFromCart : function(productId, gift, context) {
		Store._cartAction('remove', productId, null, gift, context);
	},
	updateCart : function(context, container) {
		var url = HTTP.setURLParams({
			'rxhtml':'true',
			'action':'update',
			'context':encodeURIComponent(context)
		}, jsRoot + this.CART_ACTION_PATH + '?' + HTTP.encodeForm(container));

		Sarissa.updateContentConditionally(url, $('shoppingcart'), null, ampFix, Store.checkoutRefresh, true);
	},
	updateQueue: function(queueStrings, optionalTime){
		
		if(optionalTime == null){
			optionalTime = 12700;
		}
			
		var preventCache = new Date();
		
		$j("#updatingText").show();
		
		$j.ajax({
			type: "GET",
			url: '/store/cashier-line.xml?rhtml=false&requestType=updateQueue&noCache=' + preventCache.getTime(),
			async: true,
			dataType: "xml",
			success: function(msg){

				try{
					$j("#updatingText").fadeOut('slow');
					
					var pageXML = $j(msg).find("queueUpdate");			
					var doneWaiting = ($j(pageXML).children().attr("done-waiting")*1 == 1) ? true : false;
					var etaVal = $j(pageXML).children().attr("eta")*1;							
					var positionInQueue = $j(pageXML).children().attr("position");
					var isSoldOut = ($j(pageXML).children().attr("all-sold-out") == null) ? false : true;
					
					if(isSoldOut){
						//show sold out message
						$j("#soldOut").show();
						$j("#queueLine").hide();
					}
					if(doneWaiting){
						
						try{
							window.newwin.document.getElementById("queueholder").innerHTML = '<div id="queue"><div><h1>#0</h1><h2>- -</h2></div></div>';
						}catch(e){}
						
						if(!isSoldOut){
							$j("#endOfLine").show();							
							var redirectTimeout = setTimeout(function() {  window.location = "/store/co/cor.xml" }, 10000); //take to checkout
						}
						
						$j("#queueLine").hide();
					}else{
						if(etaVal > 60){
								if(etaVal < 120){
									$j("#timeRemaining")[0].innerHTML = (Math.floor(etaVal / 60)) + " " + queueStrings.hour;
								}else{
									$j("#timeRemaining")[0].innerHTML = (Math.floor(etaVal / 60)) + " " + queueStrings.hours;
								}
						}else{
							if(etaVal < 2){
								$j("#timeRemaining")[0].innerHTML = queueStrings.underMinute;
							}else{
								$j("#timeRemaining")[0].innerHTML = etaVal + " " + queueStrings.minutes;
							}
						}
						$j("#positionInQueue")[0].innerHTML = positionInQueue;
						
						try{
							window.newwin.document.getElementById("queueholder").innerHTML = '<div id="queue"><div><h1>#'+positionInQueue+'</h1><h2>'+$j("#timeRemaining")[0].innerHTML+'</h2></div></div>';
						}catch(e){}
						
						var itemsArr = $j(pageXML).children().children().children();						
						
						if((itemsArr.length - 1) != $j(".stock-bar-wrap").length){
							window.location.reload();
						}
						
						$j(itemsArr).each(function(i){
							//skip first one							
							if(i != 0){
								//store item id
								var itemId = $j(this).attr("itemid");								
								var stockLeft = $j(this).attr("stock-left")*1;
								var itemQuantity = $j(this).attr("quantity");
								
								//set to px height because ie6 wasnt recognizing % height
								$j("#stock-bar_" + itemId).attr("style","height: "+ ((stockLeft * 60) / 100) +"px"); 
								$j("#quantity_" + itemId)[0].innerHTML = itemQuantity;
								
								if($j(this).attr("availability") == 'unavailable'){
									$j("#itemInfo_" + itemId).addClass("trans-50");
									$j("#itemInfo_" + itemId).parent().addClass("ie7fade");
									$j("#soldOutTxt_" + itemId).show();
									$j("#soldOutTxt_" + itemId)[0].innerHTML = queueStrings.itemSoldOut_line1 + "<br />" + queueStrings.itemSoldOut_line2;
									$j("#stockLeft_" + itemId).hide();
								}else{				
									//update qty
									$j("#stockLeftQty_" + itemId)[0].innerHTML = $j(this).attr("stock-left");
								}
								
								//show low qty message
								if($j(this).attr("low-quantity") != null){
									$j("#lowQty_" + itemId).show();
								}else{
									$j("#lowQty_" + itemId).hide();
								}
							}
						});	
						
						var queueTimeout = setTimeout(function() { Store.updateQueue(queueStrings) }, optionalTime);
							



						
					
						

					}
				}catch(e){
					//alert(e.message);
					window.location.reload();
				}
				
			},
			error: function(msg){		
				//alert("ajax error: " + msg);
				window.location.reload();
			}
		});		
	},
	toggleCartEditable : function(container, elementName, className1, className2, controlContainer, controlElementName) {
		var nodes = container.getElementsByTagName(elementName);
		for(var i = 0, node; node = nodes[i]; i++)
			if(node.className == className1 || node.className == className2)
				toggle(node);
		var controls = controlContainer.getElementsByTagName(controlElementName);
		for(var i = 0, node; node = controls[i++]; toggle(node));
	},
	changeShippingAddress : function(paymentIndex, addressIndex) {
		var CREDIT_CARD_SECURITY_INPUT_ID = 'cvvcheck';
		var SHIPPING_ADDRESS_CONTAINER_ID = 'shippingMethods';
		var ERROR_CONTAINER_ID = 'cannotShipError';
		var SERVER_ERROR_CONTAINER_ID = 'serverAddressError';
		var PAGE_TAG_NAME = 'label';

		showPagedContent('addressList', 'div', addressIndex);
		hide(SERVER_ERROR_CONTAINER_ID);

		if(paymentIndex != null)
			((paymentMethods[paymentIndex][0] || shippingMethods[addressIndex][1]) ? show : hide)(CREDIT_CARD_SECURITY_INPUT_ID);

		if(!$(SHIPPING_ADDRESS_CONTAINER_ID)) // not present if products are all digital
			return;

		clearCheckedFields(SHIPPING_ADDRESS_CONTAINER_ID);
		showPagedContentMulti(SHIPPING_ADDRESS_CONTAINER_ID, PAGE_TAG_NAME, shippingMethods[addressIndex][0]);
		var pages = getChildElementsByTagName($(SHIPPING_ADDRESS_CONTAINER_ID), PAGE_TAG_NAME);

		for(page in pages) {
			if(visible(pages[page])) {
				var inputs = pages[page].getElementsByTagName('input');
				for(input in inputs) {
					if(inputs[input].type == 'radio') {
						inputs[input].checked = true;
						hide(ERROR_CONTAINER_ID);
						return;
					}
				}
			}
		}

		show(ERROR_CONTAINER_ID);
	},
	changePaymentMethod : function(paymentIndex, addressIndex) {
		var CREDIT_CARD_SECURITY_INPUT_ID = 'cvvcheck';
		var EXPIRED_ERROR_CONTAINER_ID = 'expiredPaymentError';

		((paymentMethods[paymentIndex][0] || (addressIndex > -1 && shippingMethods[addressIndex][1])) ? show : hide)(CREDIT_CARD_SECURITY_INPUT_ID);
		(paymentMethods[paymentIndex][1] ? show : hide)(EXPIRED_ERROR_CONTAINER_ID);

		showPagedContent('paymentList', 'div', paymentIndex);
	},
	checkoutRefresh : function() {
		$('CheckoutForm').elements['action'].value = 'update';
		$('CheckoutForm').submit();
	},
	addPaymentSuccessCallback : function() {
		$('CheckoutForm').submit();
	},
	_cartAction : function(action, productId, quantity, gift, context) {
		var url = jsRoot + this.CART_ACTION_PATH + '?action=' + action  + '&productId=' + productId;
		if(quantity != null)
			url += '&quantity=' + quantity;
		if(gift && gift != '')
			url += '&gift=true';
		if(context)
			url += '&context=' + context;
		Sarissa.updateContentConditionally(HTTP.setURLParams({'rxhtml':'true'}, url), $('shoppingcart'), null, ampFix, Store.checkoutRefresh, true);
	}
}


function enableTOUCheck(checkbox, text, reset) {
	var deactiveClass = 'tou-deactive';

	if($(checkbox)) {
		$(checkbox).disabled = (reset) ? true : false;
		if(reset) $(checkbox).checked = false;
	}
	if($(text)) $(text).className = (reset) ? deactiveClass : '';
}

function hasScrolledToBottom(target) {
	return target.scrollTop >= (target.scrollHeight - target.offsetHeight);
}