// GLOBAL VARIABLES
var availability = {};

/* UTILITY FUNCTIONS */
function selectItem(id, location) {
	$(location).each(function(i, item){
		$(item).toggleClass('selected', i == id);
	});
}
function selectItemByTrigger($trigger, location) {
	$(location).each(function(i, item){
		$(item).removeClass('selected');
	});	
	$trigger.addClass('selected');
}
function getUrlVars() {
	var vars = {},
		tmp = [],
		hash,
		hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
	
	for(var i = 0; i < hashes.length; i++){
		hash = hashes[i].split('=');
		if(typeof(vars[hash[0]]) != 'undefined'){
			tmp = [];
			tmp.push(vars[hash[0]]);
			tmp.push(hash[1]);
			vars[hash[0]] = tmp;
		}else{
			vars[hash[0]]=hash[1];
		}
	}
	return vars;
}
Array.prototype.dedup = function() {
	var newArray = [],
		seen = {};
	
	for ( var i = 0; i < this.length; i++ ) {
		if ( seen[ this[i] ] ){
			continue;
		}
		newArray.push( this[i] );
		seen[ this[i] ] = 1;
	}
	return newArray;
};
function jumpToAnchor(anchorId){
	var $anchor = $('#'+ anchorId);
		if ($anchor.length != 0){
			var new_position = $anchor.offset();
			window.scrollTo(new_position.left,new_position.top);
		}
	}
/* SWATCHES AND THUMBS*/
function swatchOver($trigger) {
	
	$('.swatch-details').remove();
	
	var swatchId = $trigger.attr('data-id'),
		colorize = (productSwatches[swatchId].colorize != undefined)?productSwatches[swatchId].colorize:'',
		details = (productSwatches[swatchId].details != undefined)?productSwatches[swatchId].details:'',
		requestable= (productSwatches[swatchId].requestable != undefined)?productSwatches[swatchId].requestable:'',
		relatedAttributeId= (productSwatches[swatchId].relatedAttributeId != undefined)?productSwatches[swatchId].relatedAttributeId:'',
		swatchPage = '/catalog/product/includes/swatch-details.jsp?selected='+swatchId+'&colorize='+colorize+'&requestable='+requestable+"&relatedAttributeId="+relatedAttributeId,
		$swatchOverlay = $('<div class="swatch-details"></div>'),
		$triggerParent = $trigger.parent(),
		triggerPosition = $trigger.offset(),
		swatchGroupPosition = $('#product-swatches').offset(),
		getImgParam = $trigger.attr('src'),
		showAlign = 'left',
		thisWidth = $trigger.width(),
		thisHeight = $trigger.height();

		getImgParam = getImgParam.split('?$');
		getImgParam = getImgParam[1].split('$');
			
		if ((triggerPosition.left - swatchGroupPosition.left) > 270) {
			showAlign = 'right';
		} else {
			showAlign = 'left';
		}
	
		if(showAlign == 'left'){
			$swatchOverlay.css({left:0}).css({bottom:thisHeight+9});
		}else if(showAlign == 'right'){
			$swatchOverlay.css({left:thisWidth - 288}).css({bottom:thisHeight+9});
		}
		
		$swatchOverlay.appendTo($triggerParent).fadeIn(300);
		$swatchOverlay.load(swatchPage);
		
		if(details == 'true'){
			$swatchOverlay.oneTime(1600, 'growBox', function(){
				$(this).animate({
					width: '585px'
				},800);
			});
		}
}
function swatchOut($trigger) {
	var $hoverBox = $trigger.parent().find('.swatch-details');
	$hoverBox.stopTime('growBox').fadeOut(300, function() {
		$hoverBox.remove();
	});
}
function swatchSelect($trigger, productContainer){
	var swatchId = $trigger.attr('data-id');
		attributes = (productSwatches[swatchId].attributes != undefined)?productSwatches[swatchId].attributes:'';
		colorize = (productSwatches[swatchId].colorize != undefined)?productSwatches[swatchId].colorize:'',
		imgUrl= (productSwatches[swatchId].imgurl != undefined)?productSwatches[swatchId].imgurl:'';
		zoomUrl = '',
		swatchRE = /&swatchId=[0-9a-zA-Z]+$/;
	if(colorize == 'true'){
		$('#alt-photo0').attr('src',imgUrl);
		switchMainImage(0);
		selectItemByTrigger($trigger,'#product-swatches .swatch-group img');
		zoomUrl = $('#zoom-link').attr('href');
		if (zoomUrl.indexOf('&swatchId') > 0 ){
			zoomUrl = zoomUrl.replace(swatchRE,'&swatchId=' + swatchId)
		}else{
			zoomUrl += '&swatchId=' + swatchId;
		}
		$('#zoom-link').attr('href', zoomUrl);
		selectItem(-1,'#product-photo-thumbs li');
	}
	window[productContainer].selectSwatchAttributes(swatchId, attributes); // TODO: DO NOT HARD CODE PRODUCT CONTAINER
}

/* MAIN IMAGE */
function switchMainImage(thumb) {
	
	var zoomUrl = $('#zoom-link').attr('href'),
		frameRE = /&initialframe=[0-9]+$/;
	
	try{cmCreatePageviewTag(cmProduct + ' (image-' + thumb + ')', null, 'Additional Images');}catch(e){}
	
	if($('#default-photo').is(':visible')){
		$('#default-photo').fadeOut('slow');
		$('#alt-photo'+thumb).fadeIn('slow');
	}else{
		$('.alternate-photo').each(
			function(i,item){
				if(i != thumb){
					$(item).fadeOut('slow');
				}else{
					$(item).fadeIn('slow');
				}
			}
		);
		
	}
	if(thumb != 0){
		if (zoomUrl.indexOf('&initialframe=') > 0 ){
			zoomUrl = zoomUrl.replace(frameRE,'&initialframe=' + thumb);
		}else{
			zoomUrl += '&initialframe=' + thumb;
		}
	}
	
	if(thumb == 0){
		zoomUrl = zoomUrl.replace(frameRE,'');
	}
	$('#zoom-link').attr('href', zoomUrl);
	selectItem(thumb,'#product-photo-thumbs li');
	selectItem(-1,'#product-swatches .swatch-group img');
}

function resetMainImage() {
	var zoomUrl = '',
	frameRE = /&initialframe=[0-9]+$/,
	swatchRE = /&swatchId=[0-9a-zA-Z]+$/;
	
	if(!$('#default-photo').is(':visible')){
		zoomUrl = $('#zoom-link').attr('href');
		$('.alternate-photo').fadeOut('slow');
		$('#default-photo').fadeIn('slow');
		zoomUrl = zoomUrl.replace(frameRE,'');
		zoomUrl = zoomUrl.replace(swatchRE,'');
		$('#zoom-link').attr('href', zoomUrl);
		selectItem(0,'#product-photo-thumbs li');
		selectItem(-1,'#product-swatches .swatch-group img');
		$('#product-photo-controls').show();
	}
}


// MODAL FUNCTIONS
function removeOverlay() {
	$('#modal-product-actions').overlay().close();
}

function showOverlay() {
	$('#modal-product-actions').addClass('loading').overlay().load();
}

function loadModalContents(data) {
	
	var $modal = $(this.modal),
		$contentWrap = $modal.find(this.contentWrap),
		$contentContainer,
		myHeight = 0,
		utilityHeight = 0,
		padding = 0,
		viewportHeight = window.innerHeight ? window.innerHeight : $(window).height(),
		monogramAjaxOptions = { 
			clearForm: false,
			dataType: 'html', 
			success: handleResponse,
			beforeSerialize: updateMonogramFormFields,
			productContainer: this.productContainer,
			closeModal:false,
			error: handleError
		};
	
	$contentWrap.html(data);
	myHeight = $contentWrap.height();
		
	$contentContainer = $contentWrap.find('#mod-scroll');
		
	if(myHeight > viewportHeight ){
		myHeight = viewportHeight * 0.8;
		$('.static' ,$contentWrap).each(function(i,item){
			utilityHeight += $(item).outerHeight();
		});
		padding = $contentContainer.outerHeight() - $contentContainer.height();
		$contentContainer.height(myHeight - utilityHeight - padding);
	}
	
	if (this.modalType == 'monogram') {
		$('#monogramForm').ajaxForm(monogramAjaxOptions);
	}
	
	$modal.animate({height:myHeight}, 200, function(){
		$(this).removeClass('loading');
	});
}

//AJAX FORM FUNCTIONS
function updateFormFields($form, options) {

	var form = $form[0],
		productContainer = window[options.productContainer],
		prodForms = productContainer.lineItems,
		prodLength = form['/atg/commerce/order/purchase/CartModifierFormHandler.addItemCount'].value,
		postalCodeField = '/atg/commerce/order/purchase/CartModifierFormHandler.postalCode',
		quantityField = '',
		personalizeField = '',
		fontAttributeIdField = '',
		threadColorAttrIdField = '',
		catalogRefIdField = '',
		giftCertToId = '',
		giftCertFromId = '',
		toValue = '',
		fromValue = '',
		comLength = 0,
		quantity = 0,
		postalCodeFound = false,
		catalogRefId = '',
		data = '';
			
	$('.postal-code').each(function(){
		if (this.value != ''){
			postalCodeFound = true;
			form[postalCodeField].value = this.value;
		}
	});
	if(postalCodeFound == true){
		var hidd = document.createElement("input");
		hidd.setAttribute( "type", "hidden");
		hidd.setAttribute( "name", '/atg/commerce/order/purchase/CartModifierFormHandler.changePostalCode');
		hidd.setAttribute( "value", "Enter");
		hidd.setAttribute( "id", "postalSubmit");
		form.appendChild(hidd);
	}
	
	for(var x = 0; x < prodLength; x++){
		catalogRefIdField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].catalogRefId';
		quantityField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].quantity';
		quantity = prodForms[x].$qtyInput.val();
		data = prodForms[x].data;
		catalogRefId = prodForms[x].catalogRefId;
		
		if(!quantity){quantity = 0;}

		if( quantity > 0 ){
			if(!catalogRefId) {
				$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Missing required options. Please review your selections and try again.</div></div></div>');
				window.scrollTo(0,productContainer.$errorZone.offset().top-10);
				return false;
			}			
			if(availability[catalogRefId].inventoryCode == '9999' && !postalCodeFound ){
				$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Please enter your zip code to add this item to your cart</div></div></div>');
				window.scrollTo(0,productContainer.$errorZone.offset().top-10);
				return false;				
			}			
			comLength++;
			form[catalogRefIdField].value = catalogRefId;
			form[quantityField].value = quantity;
			
			if (prodForms[x].$personalizeInput.length > 0) {
				personalizeField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].personalize';
				fontAttributeIdField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].fontAttributeId';
				textLine1Field = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].textLine1';
				textLine2Field = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].textLine2';
				textLine3Field = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].textLine3';
				threadColorAttrIdField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].threadColorAttrId';
				if(prodForms[x].$personalizeInput.is(':checked')){
					var monogramStyleForm = prodForms[x].$prodGroup.find('input[name=prod'+x+'-fontAttributeId]');
					var monogramColorForm = prodForms[x].$prodGroup.find('input[name=prod'+x+'-threadColorAttrId]');
					var textLine1FieldForm = prodForms[x].$prodGroup.find('input[name=prod'+x+'-textLine1]');
					var textLine2FieldForm = prodForms[x].$prodGroup.find('input[name=prod'+x+'-textLine2]');
					var textLine3FieldForm = prodForms[x].$prodGroup.find('input[name=prod'+x+'-textLine3]');
					
					form[personalizeField].value = 'true';
					form[fontAttributeIdField].value = (monogramStyleForm.length != 0) ? prodForms[x].$prodGroup.find('input[name=prod'+x+'-fontAttributeId]:checked').val():'';
					form[threadColorAttrIdField].value = (monogramColorForm.length != 0) ? prodForms[x].$prodGroup.find('input[name=prod'+x+'-threadColorAttrId]:checked').val():'';
					form[textLine1Field].value = textLine1FieldForm.val();

					if (textLine2FieldForm.attr('disabled') != true){
						$(form[textLine2Field]).removeAttr('disabled');
						form[textLine2Field].value = textLine2FieldForm.val();
					} else {
						$(form[textLine2Field]).attr('disabled','disabled');
					}
					
					if (textLine3FieldForm.attr('disabled') != true){
						$(form[textLine3Field]).removeAttr('disabled');
						form[textLine3Field].value = textLine3FieldForm.val();
					} else {
						$(form[textLine3Field]).attr('disabled','disabled');
					}
					
					if (monogramStyleForm.length != 0){
						$(form[fontAttributeIdField]).removeAttr('disabled');
					} else {
						$(form[fontAttributeIdField]).attr('disabled','disabled');
					}
					if (monogramColorForm.length != 0){
						$(form[threadColorAttrIdField]).removeAttr('disabled');
					} else {
						$(form[threadColorAttrIdField]).attr('disabled','disabled');
					}
					
					if(form[fontAttributeIdField].value == 'undefined' || form[threadColorAttrIdField].value == 'undefined' || form[textLine1Field].value == '') {
						$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Missing required personalization options. Please review your selections and try again. </div></div></div>');
						window.scrollTo(0,productContainer.$errorZone.offset().top-10);
						return false;
					}
				}else{
					form[personalizeField].value = 'false';	
				}
			}
			// Gift Certificate
			if($('#gift-from').length > 0){
				giftCertToId = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].value.toField';
				giftCertFromId = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].value.fromField';
				toValue = $('#gift-to').val();
				fromValue = $('#gift-from').val();
				form[giftCertToId].value = toValue;
				form[giftCertFromId].value = fromValue;
				if(fromValue == '' && toValue == ''){
					$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Missing required To and From values. Please review your selections and try again. </div></div></div>');
					window.scrollTo(0,productContainer.$errorZone.offset().top-10);
					return false;
				} else if (fromValue == ''){
					$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Missing required From value. Please review your selections and try again. </div></div></div>');
					window.scrollTo(0,productContainer.$errorZone.offset().top-10);
					return false;
				} else if (toValue == ''){
					$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Missing required To value. Please review your selections and try again. </div></div></div>');
					window.scrollTo(0,productContainer.$errorZone.offset().top-10);
					return false;
				}
				
			}
			
			
		} else {
			form[catalogRefIdField].value = '';
			form[quantityField].value = quantity;
			if (prodForms[x].$personalizeInput.length > 0) {
				personalizeField = '/atg/commerce/order/purchase/CartModifierFormHandler.items['+ x +'].personalize';
				form[personalizeField].value = 'false';	
			}
		}
	}
	
	if(comLength == 0 && !postalCodeFound) {
		$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">There were no items selected to add to the order.</div></div></div>');
		window.scrollTo(0,productContainer.$errorZone.offset().top-10);
		return false;
	}
	return true;
}

function updateMonogramFormFields($form, options) {
	var form = $form[0],
		attributeField = '',
		iterator = form.attributeIter.value;
	for(var x=0;x<iterator;x++){
		attributeField = '/rh/monogram/MonogramAttributeCollector.monogramAttributes['+x+'].attributeId';
		if ($(form[attributeField]).fieldValue() == ''){
			$('#error-zone-top','#modal-product-actions').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Errors</h3><div class="error-msg-block"><div class="error-msg">Please enter all monogram values</div></div></div>');
			return false;
		}
	}
	$('#modal-product-actions').addClass('loading');
	return true;
}

//ADD TO CART/LIST
function handleResponse(responseText, statusText, xhr, $form) {	
	var modalFlag = (this.closeModal != undefined)?this.closeModal:true;
	var $modal = $('#modal-product-actions'),
		$contentWrap = $('div.content', $modal),
		productContainer = window[this.productContainer],
		jsonResponse = '',
		myHeight = '',
		viewportHeight = '',
		utilityHeight = '';
		
	if(statusText == 'success'){ 
		
		// Check for json response
		try {
			jsonResponse = $.parseJSON(responseText);
		} catch(ex) {
			jsonResponse = false;
		}
		
		if(!jsonResponse){
			if (responseText.indexOf('mod-order-items') > 0){
				// ACTION SUCCESS
				$contentWrap.html(responseText);
				myHeight = $contentWrap.height();
				viewportHeight = window.innerHeight ? window.innerHeight : $(window).height();
				if(myHeight >= viewportHeight * 0.8 ){
					myHeight = viewportHeight * 0.8;
					utilityHeight = $('.title-bar' ,$contentWrap).height() + $('.confirm-actions' ,$contentWrap).height();
					$('#mod-order-items').height(myHeight - utilityHeight);
				}
				$modal.animate({height:myHeight}, 400, 'linear', function(){$(this).removeClass('loading').css('height','');});
				productContainer.resetProductForm();
				$('#error-zone-top').empty();
			} else {
				if (responseText.indexOf('Session Error') != -1){	
					window.location.replace('/error/session.jsp');
				} else {
					handleError();
				}
			}
		} else {
			if (jsonResponse.type != undefined && jsonResponse.type == 'postal' && jsonResponse.success != 'false'){
				productContainer.updateAvailability(jsonResponse);
				$('input.postal-code').val('');
				$('.postalcodeform-inline').hide();
				$('#postalSubmit').remove();
				removeOverlay();
			}else{
				//ACTION FAILED
				var errorMessage = '';
				if (jsonResponse.errors.length != 0){
					for (var x=0; x < jsonResponse.errors.length; x++){
						errorMessage += '<div class="error-msg">'+jsonResponse.errors[x] +'</div>';
					}
				} else {
					errorMessage = '<div class="error-msg">Your request could not be processed. Please try again.</div>';
				}
				if(modalFlag){
					removeOverlay();
				} else {
					$modal.removeClass('loading').css('height',''); 
				}
				productContainer.$errorZone.html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Errors</h3><div class="error-msg-block">'+ errorMessage +'</div></div>');
				window.scrollTo(0,productContainer.$errorZone.offset().top-10);
			}
		}
			
	} else { 
		//AJAX FAILED
		if(modalFlag){
			removeOverlay();
		} else {
			$modal.removeClass('loading'); 
			$contentWrap.css('visibility','visible');
		}
		$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Errors</h3><div class="error-msg-block">There was a communication error. Please try again.</div></div>');
	}

}

function handleError(){
	var errorUrl = '',
		baseUrl = window.location.href.slice(0,window.location.href.indexOf('?')),
		urlHash = getUrlVars();	
	
	(urlHash['count'])?urlHash['count']=parseInt(urlHash['count'])+1:urlHash['count'] = 1;
	urlHash['errorCode'] = 'redirect';
	errorUrl = baseUrl + '?' + $.param(urlHash,true) + '#error-zone-top';
	window.location.replace(errorUrl);
}

// PRODUCT CONTAINER
function ProductContainer(name, container, data){
		var skuGroup,
			lineItems = [],
			$container = $(container);
		this.availability = {};
		this.lineItems = [];
		this.$errorZone = $('#error-zone-top');
		this.name = name;
				
		$container.each( function(i){
			prodId= $(this).attr('data-productId');
			if(data[prodId]){
				skuGroup = new SkuGroup(this, data[prodId], i, name);
				lineItems.push(skuGroup);
			}else{
				$container.hide();
			}
		});
		this.lineItems = lineItems;
	}

	/**
	 * Loops through all Line Items in this container and initializes them
	 * Function called in dom ready after the product container has been instantiated.
	*/
	ProductContainer.prototype.initializeSkus = function(){
		var skuList = [],
			urlHash = getUrlVars();
		
		for (var i=0; i < this.lineItems.length; i++){
			this.lineItems[i].initialize(i);
		}	
		
		if (typeof(urlHash['skuId']) != 'undefined'){
			if (typeof(urlHash['skuId']) == 'string'){
				skuList.push(urlHash['skuId']);
			}else{
				skuList = urlHash['skuId'];
			}
			skuList.dedup();
			this.selectSkus(skuList);
		}
	};

	/**
	 * Loops through all Line Items in this container and resets them.
	 * Clears values from inline personalization form if found.
	 * Function called after ajax success 
	*/
	ProductContainer.prototype.resetProductForm = function(){
		for(var i=0; i < this.lineItems.length; i++){
			this.lineItems[i].resetSku();
			if (this.lineItems[i].$personalizeInput.length > 0) {
				$('.item-personalize :radio', this.lineItems[i].$prodGroup).removeAttr('selected').removeAttr('checked');
				$('.item-personalize :text', this.lineItems[i].$prodGroup).val('');
				$('.instructions').html('');
			}
		}
	};
	/**
	 * Loops through all Line Items in this container and selects attributes based on swatch attributes.
	 * Function called by swatch click
	*/
	ProductContainer.prototype.selectSwatchAttributes = function(swatchId, attributes){
		for(var i=0; i < this.lineItems.length; i++){
			if(this.lineItems[i].enabled != true || (this.lineItems[i].enabled == true && (this.lineItems[i].$qtyInput.val() == '0' ||this.lineItems[i].$qtyInput.val() == ''))){
				for(var l=0;l<this.lineItems[i].$selectArray.length;l++){
					if(this.lineItems[i].$selectArray[l] != undefined){
						for(var a in attributes){
							try {
								$(this.lineItems[i].$selectArray[l]).val(attributes[a]);
							} catch(ex) {
								//prevents IE6 timing bug
							}
							if($(this.lineItems[i].$selectArray[l]).val() == attributes[a]){
								this.lineItems[i].updateOptions(this.lineItems[i].$selectArray[l],0);
								break;
							} else {
								$(this.lineItems[i].$selectArray[l]).val(-1);
							}
						}
					}
				}
			}
		}
	};
	
	/**
	 * Opens the monogram form using the selected data from the specified line item.
	 * If qty is 0 on the line item, throws an error.
	 * Function called by the monogram button. 
	*/
	ProductContainer.prototype.showMonogramForm = function(index){	

		var qty = this.lineItems[index].$qtyInput.val(),
			parentId = this.lineItems[index].data.parentId,
			prodId = this.lineItems[index].data.prodId,
			catalogRefId = this.lineItems[index].catalogRefId;
		
		if(qty > 0){
			showOverlay();
			var ajaxOptions = {
					url: '/catalog/product/includes/monogram-form.jsp?collectionProductId=' + parentId + '&monogramProductId=' + prodId + '&skuId=' + catalogRefId +'&quantity=' + qty,
					dataType: 'html',
					modal: '#modal-product-actions',
					contentWrap: '.content',
					modalType: 'monogram',
					success: loadModalContents,
					productContainer: this
				};
			$.ajax(ajaxOptions);
		}else{
			$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Error</h3><div class="error-msg-block"><div class="error-msg">Please specify a quantity before you add a monogram.</div></div></div>');
		}	
	};

	/**
	 * Handles successful zip code update. Clears out all saved inventory codes, 
	 * and re-queries availability for any selected items.
	 * Function called from handleResponse.
	*/
// TODO: fix error zone reference, add button reference to be specific to product container
	ProductContainer.prototype.updateAvailability = function(jsonResponse){
		var selectedItems, qty, errorMessage;
		
		if (jsonResponse.success == 'true'){
			for (var k in availability){
				if(availability[k].postalCodeSpecific == 'true'){
					//reset inventory values
					availability[k].inventoryCode = '';
					availability[k].inventoryMessage = '';
				}
			}
			for(var i=0; i < this.lineItems.length; i++){
				if(this.lineItems[i].enabled == true){
					selectedItems = this.lineItems[i].getSelectedItems();
					qty = this.lineItems[i].$qtyInput.val();
					this.lineItems[i].enableSku(selectedItems, qty);
				}
			}
			this.$errorZone.empty();
			$('#addButton').show();
			$('#postalcodeform','#cart-actions').hide();
			
			
		} else {			
			//ACTION FAILED
			if (jsonResponse.errors.length != 0){
				for (var x=0; x < jsonResponse.errors.length; x++){
					errorMessage += '<div class="error-msg">'+jsonResponse.errors[x] +'</div>';
				}
			} else {
				errorMessage = '<div class="error-msg">Your request could not be processed. Please try again.</div>';
			}		
			$('#error-zone-top').html('<div class="mod mod-error-msg group group-notflush-top"><h3 class="brand">Errors</h3><div class="error-msg-block">'+ errorMessage +'</div></div>');
		}
	};

	/**
	 * Shows or hides the zip code form in the main actions block based on response from requireZip (true/false)
	 * Function called from enableSku and disableSku.
	*/
// TODO: fix error zone reference, add button reference to be specific to product container
	ProductContainer.prototype.toggleZip = function(){
		var showZip = this.requireZip();
		if(showZip){
			$('#addButton').hide();
			$('#postalcodeform').show();
		}else{
			$('#addButton').show();
			$('#postalcodeform').hide();
		}
	};
	
	/**
	 * Loops through all the line items and looks for inventory code '9999' 
	 * indicating that the item requires a postal code. Returns true or false.
	 * Function called from toggleZip.
	*/
	ProductContainer.prototype.requireZip = function(){
		for(var i = 0; i < this.lineItems.length; i++){		
			if(this.lineItems[i].enabled == true && availability[this.lineItems[i].catalogRefId] != undefined){		
				if(availability[this.lineItems[i].catalogRefId].inventoryCode == '9999'){
					return true;
				}
			}
		}
		return false;
	};

	/**
	 * Loops through all Line Items in this container and searches for a sku
	 * If found, selects each text attribute and triggers change event.
	 * Changes the product photo to the first colorizable text attribute combo.
	*/
	ProductContainer.prototype.selectSkus = function(skuList){
		var l = 0;
		var prodAttributes = {};
		var swatchFilter = [];
		var colorized = false;
		var jump = false;
		var swatch = [];
		var new_position = "";
		for (var i = 0; i < skuList.length; i++) {
			for(var j = 0; j < this.lineItems.length; j++){
				for(var k =0; k < this.lineItems[j].data.skus.length; k++){
					if (this.lineItems[j].data.skus[k].catalogRefId == skuList[i]){
						l = 0;
						swatchFilter = [];
						prodAttributes = this.lineItems[j].data.skus[k].attributes;
							for (var key in prodAttributes) {
								$(this.lineItems[j].$selectArray[l]).val(prodAttributes[key][0]);
								this.lineItems[j].updateOptions(this.lineItems[j].$selectArray[l]);
								l++;
							}
							
							if(colorized == false){
								swatch = getFilteredSwatchArray(prodAttributes);
								if(swatch.length >0){
									if(productSwatches[swatch[0]].colorize == 'true'){
										$('#swatch-'+swatch).click();
										colorized = true;
									}
								}
							}
							if(jump == false){
								new_position = this.lineItems[j].$prodGroup.offset();
								window.scrollTo(new_position.left,new_position.top);
								jump == true;
							}
						break;
					}
				}
			}
		}
	};
	
// SKU GROUP
function SkuGroup(container, data, index, parent){
		
	// THIS VARS
	this.$prodGroup = $(container);
	this.data = data;
	this.enabled = false;
	this.catalogRefId = '';
	this.$selectArray = [];
	this.parent = parent;
	this.$qtyInput = $('.qtyInput',this.$prodGroup);
	this.$personalizeInput = $('.personalizeInput',this.$prodGroup);
	this.$sku = this.$prodGroup.find('.item-sku');
	this.$price = this.$prodGroup.find('.item-price');
	this.$availability = this.$prodGroup.find('.availability');
	this.$details = this.$prodGroup.find('.details');
}

	SkuGroup.prototype.initialize = function(index){

		var prodAttributes = (this.data.skus.length!= 0)?this.data.skus[0].attributes:false;
		var selectCount = 0;
		var selectedItems = [];
		var $variantDropdown;
		
		// loop through attributes to set up dropdowns
		// assumes all skus have the same attributes
		// therefore only uses first sku to initialize.	
		if (prodAttributes != false) {
			dropdownGroup = '<div class="item-selectors group">';
			for (var key in prodAttributes) {
				dropdownGroup += '<fieldset><label>'+ key +'</label><select id="prod1_'+ key +'" disabled="disabled" class="attribute" data-parent="'+this.parent+'" data-index="'+index+'" data-attribute="'+key+'"><option value = "-1">Choose your '+ key +'</option></select></fieldset>';
				selectCount++;
			}
			dropdownGroup += '</div>';
			if (selectCount > 0){
				$('.item-info',this.$prodGroup).prepend(dropdownGroup);
			}
			
		} else {
			this.$prodGroup.hide();
			return;
		}
		this.$selectArray = $('select',this.$prodGroup);
		
		//BC MONOGRAM
		if (this.$personalizeInput.length > 0) {
			if(this.$personalizeInput.is(':checked')){
				this.$personalizeInput.closest('.item-personalize').find('.personalize-form').css('display','block');
			}
			this.$personalizeInput.click(function(){
				$(this).closest('.item-personalize').find('.personalize-form').toggle();
			});
		}
		
		
		// NO ATTRIBUTES, ENABLE DROPDOWN
		if(selectCount == 0){	
			this.enableSku(selectedItems, '0');
			return;
		}
			
		// INITIALIZE FIRST DROPDOWN
		this.populateOptions('', selectedItems);
		
	};

	/**
	 * Updates next select element. If is the final select or there are no selects, enables sku.
	 * Function called when select element is changed. 
	*/
	SkuGroup.prototype.updateOptions = function(selectElement, qtyOverride){
		
		// VARS
		var $selectElement,
			total = 0,
			position = 0,
			selectedItems = [],
			qty = (typeof(qtyOverride) != 'undefined')?qtyOverride:1;
		
		// DISABLED ITEM, LEAVE
		if (this.data.skus.length== 0) {
			return;
		}
				
		// NO ATTRIBUTES, ENABLE DROPDOWN
		if(this.$selectArray.length == 0){
			this.enableSku(selectedItems, '0');
			return;
		}
			
		$selectElement = (selectElement)?$(selectElement):$('select:first',this.$prodGroup);
		total = this.$selectArray.length;
		position = this.$selectArray.index($selectElement) + 1;
		selectedItems = this.getSelectedItems(this.$selectArray);
	
		// LAST SELECT DROPDOWN
		if (position == total) {
			if ($selectElement.val() != -1) {
				this.enableSku(selectedItems, qty);
				return;
			}else{
				this.disableSku();
				return;
			}
		}
	
		// REMOVE PREVIOUSLY SELECTED SKU DATA
		this.disableSku();
	
		// REMOVE SELECTED ITEMS PAST THIS DROPDOWN
		if(selectedItems.length > position ){
			selectedItems.length = position;
		}
					
		// IF THIS DROPDOWN'S VALUE IS NOT SELECTED, CLEAR VALUES PAST HERE
		if ($selectElement.val() == -1){
			for (var i = position; i < this.$selectArray.length; i++){
				if (i >= position) {
					this.clearOptions(this.$selectArray[i]);
				}				
			}
		// IF THIS DROPDOWN'S VALUE IS SELECTED, POPULATE NEXT AND CLEAR ANY FURTHER
		} else {
			for (var n = this.$selectArray.length -1; n >= position; n--){
				if (n > position )  {
					this.clearOptions(this.$selectArray[n]);
				} else if (n == position ) {
					this.populateOptions(this.$selectArray[n], selectedItems);
				}
			}
		}
	};
	
	/** 
	 * Given a select element, pulls sku attribute list based on selected attributes and populates options for the element.
	 * Called by Initialization and Update Options
	 */
	SkuGroup.prototype.populateOptions = function(selectElement, selectedItems){
			if (!selectElement){
				selectElement = $('select:first',this.$prodGroup);
				}
			this.clearOptions(selectElement);
			var optionList = '',
				skuData = this.data,
				attributeName = $(selectElement).attr('data-attribute'),
				filteredSkus = (selectedItems.length > 0)?getFilteredArray(skuData,selectedItems):skuData.skus,
				attributeData = getAttributes(filteredSkus, attributeName);

			if (attributeData.length > 1){
				for (var i=0;i<attributeData.length;i++){
					optionList += '<option value="' + attributeData[i][0] + '">'+attributeData[i][1]+'</option>';
				}
				$(selectElement).append(optionList).removeAttr('disabled');
			} else if (attributeData.length == 1){
				optionList += '<option value="' + attributeData[0][0] + '" selected>'+attributeData[0][1]+'</option>';
				$(selectElement).append(optionList).removeAttr('disabled');
				this.updateOptions(selectElement,0);
			}
		};

	/**
	 * Removes all options from a select element.
	 */
	SkuGroup.prototype.clearOptions = function(selectElement){
			$('option',selectElement).each(function(i){
				if (i == 0) {
					$(this).attr('selected', 'selected');
				} else { 
					$(this).remove();
				}
			}).end().attr('disabled',true);
		};
	
	/**
	 * Gets sku data for selected items combo.
	 * Called by Update Options.
	 * Calls toggleZip
	 */
	SkuGroup.prototype.enableSku = function(selectedItems, qty){
		
		var skuData = this.data,
			jsonResponse,
			selectedSku = getFilteredArray(skuData, selectedItems),
			catalogRefId = selectedSku[0].catalogRefId,
			availabilityMsg = "",
			inventoryMessage = "",
			deliveryMessage = "",
			price = "",
			postalCodeLabel = 'Enter Zip/Postal Code',
			postalCodeUpdateLabel = 'Change Zip/Postal Code',
			postalCodeInputs = '<input type="text" id="postal-code" class="postal-code" size="6" maxlength="6" autocomplete="off" tabindex="0" value=""/><input type="submit" value="Enter" class="submit postal-trigger"/>',
			itemId = '<span class="label">Item #</span>'+ selectedSku[0].skuId,
			$zipTrigger,
			$zipForm;

			if(skuData.monogramFlag == 'true'){
				$('.monogram > input',this.$prodGroup).removeAttr('disabled');
			}
			//BC MONOGRAM
			if (this.$personalizeInput.length > 0) {
				this.$personalizeInput.removeAttr('disabled');
			}
								
			if (availability[catalogRefId] == undefined || availability[catalogRefId].inventoryCode == ''){	
				availabilityMsg = $.ajax({
						url: '/catalog/product/includes/sku-availability.jsp?skuId='+catalogRefId,
						dataType: 'json',
						async:false
					 }).responseText;
				try{
					jsonResponse = $.parseJSON(availabilityMsg);
					availability[catalogRefId] = jsonResponse;
				} catch(ex){
					this.showInventoryError();
					return;
				}
			}
			
			if(availability[catalogRefId].listPrice != undefined && availability[catalogRefId].listPrice != ''){
				price = (availability[catalogRefId].saleFlag == 'true')?'<div class="label">Price</div><strike>'+ availability[catalogRefId].listPrice +' ea</strike><strong>'+ availability[catalogRefId].salePrice +' ea</strong>':'<div class="label">Price</div>'+availability[catalogRefId].listPrice +' ea';
				if (availability[catalogRefId].shippingFlag == 'true'){
					if(availability[catalogRefId].shippingPrice != undefined){
						price += '<p class="surcharge">+ '+ availability[catalogRefId].shippingPrice+' Shipping Surcharge</p>';
					}
				}
			} else {
				this.showInventoryError();
				return;
			}
			this.enabled = true;

			if (availability[catalogRefId].inventoryMessage != undefined && availability[catalogRefId].inventoryMessage != ''){
				inventoryMessage = '<div class="availability"><label>Availability</label>'
				inventoryMessage += availability[catalogRefId].inventoryMessage;
				if(availability[catalogRefId].postalCodeSpecific == 'true' && availability[catalogRefId].inventoryCode != '9999'){
					inventoryMessage += ' <a class="postalform-trigger">'+postalCodeUpdateLabel+'</a>';
				}
				inventoryMessage += '</div>';
			}
			if (availability[catalogRefId].deliveryMessage != undefined && availability[catalogRefId].deliveryMessage != ''){
				deliveryMessage = '<div class="delivery"><label>Delivery</label>'+availability[catalogRefId].deliveryMessage + '</div>';
			}
			
			if(availability[catalogRefId].inventoryCode != '1001' && availability[catalogRefId].inventoryCode != undefined) {
				this.$qtyInput.removeAttr('disabled').val(qty);
				this.$sku.html(itemId);
				this.$price.html(price);
				this.$details.html(deliveryMessage + inventoryMessage);
				this.catalogRefId = catalogRefId;
			} else {
				this.$qtyInput.attr('disabled','true').val('');
				this.$sku.html(itemId);
				this.$price.html('<div class="label">Price</div>');
				this.$details.html('<div class="availability error">'+inventoryMessage+'</div>');
				this.catalogRefId = catalogRefId;
			}

			if(availability[catalogRefId].postalCodeSpecific == 'true'){
				if (this.$prodGroup.find('.postalcodeform-inline').length == 0){
					if(availability[catalogRefId].inventoryCode != '9999') {
						postalForm = '<div class="postalcodeform-inline" style="display:none;"><fieldset><label>'+postalCodeUpdateLabel+'</label>'+ postalCodeInputs + '</fieldset></div>';
					} else {
						postalForm = '<div class="postalcodeform-inline"><fieldset ><label>'+postalCodeLabel+'</label>'+ postalCodeInputs + '</fieldset></div>';
					}
					this.$prodGroup.find('.item-info').append(postalForm);
				}
			}
			window[this.parent].toggleZip();
	};

	/**
	 * Removes Sku data (delivery/inventory message, price, item id). Clears and disables the qty box.
	 * If this is a monogram item, disables the monogram button.
	 * Called by Update Options
	 * Calls toggleZip
	 */
	SkuGroup.prototype.disableSku = function(){
		this.enabled = false;
		this.$qtyInput.val('');
		this.$sku.html('<span class="label">&nbsp;</span>');
		this.$price.html('<div class="label">Price</div>');
		this.$availability.html('');
		this.$details.html('');
		
		if(this.data.monogramFlag == 'true'){
			this.$prodGroup.find('.monogram > input').attr('disabled','disabled');
		}
		//BC MONOGRAM
		if (this.$personalizeInput.length > 0) {
			this.$personalizeInput.attr('disabled','disabled');
			if(this.$personalizeInput.is(':checked')){
				this.$personalizeInput.removeAttr('checked').click();
			}

		}
		this.catalogRefId = '';		
		window[this.parent].toggleZip();
	};

	/**
	 * Returns Sku Group to original state
	 */
	SkuGroup.prototype.resetSku = function(){
		
		// VARS
		var $selectElement,
			total = 0,
			position = 0,
			selectedItems = [];
		
		// DISABLED ITEM, LEAVE
		if (this.data.skus.length == 0) {
			return;
		}
		
		// NO ATTRIBUTES, ENABLE DROPDOWN
		if(this.$selectArray.length == 0){
			this.enableSku(selectedItems, '0');
			return;
		}
		
		// REMOVE PREVIOUSLY SELECTED SKU DATA
		this.disableSku();
		
		$selectElement = $('select:first',this.$prodGroup);
		$selectElement.val('-1');
		total = this.$selectArray.length;
		position = 1;
		
		
		for (var i = 0; i < total; i++){
			if (i >= position) {
				this.clearOptions(this.$selectArray[i]);
			}
		}
	};
	
	/** 
	 * Display error message when availability is down
	 * Called by Enable Sku
	*/
	SkuGroup.prototype.showInventoryError = function(){
		var errorMessage = '';
		if (typeof(ajaxError) == 'undefined'){
			errorMessage = '<div class="delivery error"><label>Details</label>We\'re sorry, product information is unavailable at this time. To order this item call customer service.</div>';
		} else {
			errorMessage = '<div class="delivery error"><label>Details</label>'+ ajaxError +'</div>';
		}
		this.$prodGroup.find('.details').html(errorMessage);
	};

	/**
	 * Returns Array of selected attributes from selects
	 */ 
	SkuGroup.prototype.getSelectedItems = function(){
		var selectedItems = [];
		
		for (var i = 0; i < this.$selectArray.length; i++){
			if (this.$selectArray[i].options[this.$selectArray[i].selectedIndex].value == -1) {
				break;
			}
			selectedItems[i] = [];
			selectedItems[i].push($(this.$selectArray[i]).attr('data-attribute'));
			selectedItems[i].push(this.$selectArray[i].options[this.$selectArray[i].selectedIndex].value);
		}
		return selectedItems;	
	};
	
	// END SKU GROUP
	

// DATA FUNCTIONS
function getAttributes(skuData, attributeName){
	var tempArray = [];
		for(var i=0;i<skuData.length;i++){
			if( skuData[i].attributes[attributeName] != null){
				tempArray.push(skuData[i].attributes[attributeName]);
			}
		}
	
	tempArray = tempArray.dedup();
	return tempArray.sort(keySort);
	
}

function keySort(a,b){
	var firstChar = a[1].charAt(0);
	if(firstChar != '$' ){
		return a[2] - b[2];
	} else {
		var x = a[1].replace(/[^0-9]/g, '');
		var y = b[1].replace(/[^0-9]/g, '');
		return x - y;
	}
}

function getFilteredArray(skuArray,filters){
	var tempArray = [];
	var tmpSkuArray = skuArray.skus;
	
	for(var i=0;i<filters.length;i++){
		for(var j=0; j < tmpSkuArray.length; j++){
			if(typeof(filters[i][1]) != 'undefined' && typeof(filters[i][0]) != 'undefined' && typeof(tmpSkuArray[j].attributes[filters[i][0]]) != 'undefined'){
				if(tmpSkuArray[j].attributes[filters[i][0]][0] == filters[i][1]){
					tempArray.push(tmpSkuArray[j]);
				}
			}
		}
			tmpSkuArray = tempArray;
			tempArray = [];
		}
	return  tmpSkuArray;
}
function getFilteredSwatchArray(filters){
	var tempArray = [],
		attributes = {},
		match = false,
		attributeMatch = false,
		swatchObj = {},
		filteredSwatches = productSwatches;
	
	for(var i in filters){
		attributeMatch = false;
		match = false;
		for (var k in filteredSwatches){
			attributes = filteredSwatches[k].attributes;
			if (attributes[i] != undefined){
				attributeMatch = true;
				if (attributes[i] == filters[i][0]){
					match = true;
					swatchObj[k] = filteredSwatches[k];
				}
			}
		}
		if(attributeMatch == false || (attributeMatch == true && match == false)){
			break;
		}
		filteredSwatches = swatchObj;
		swatchObj = {};
	}
	for (var o in filteredSwatches){
		tempArray.push(o);
	}
	return tempArray;
}

// MONOGRAM
function updateInitialSelect(trigger, toggleOption) {
	if (toggleOption == 'one'){
		$('#secondInitial').attr('disabled', 'disabled');
		$('#thirdInitial').attr('disabled', 'disabled');
	} else {
		$('#secondInitial').removeAttr('disabled');
		$('#thirdInitial').removeAttr('disabled');
	}
}

function selectScript(el, minLength, maxLength, type) {
	var $container = $(el).closest('.item-personalize'),
		$line1container = $container.find('.line1'),
		$line2container = $container.find('.line2'),
		$line3container = $container.find('.line3'),
		$line1 = $line1container.find('input.line1-text'),
		$line2 = $line2container.find('input.line2-text'),
		$line3 = $line3container.find('input.line3-text'),
		$line1instructions = $line1container.find('.instructions'),
		$line2instructions = $line2container.find('.instructions'),
		$line3instructions = $line3container.find('.instructions'),
		$line1label = $line1container.find('label');
		
	//delete values if previous specs does not equal new specs
	if (maxLength != $line1.attr('maxLength')) {
		$line1.val('');
		$line2.val('');
		$line3.val('');
	}

	//set line 1 input to the maxLength & minLength
	$line1.attr('maxLength', maxLength)
		.attr('minLength', minLength)
		.removeAttr('disabled'); // as long as a script is selected, always enable line 1
	
	//change out the line 1 instructional copy
	$line1instructions.html(instructionalText(minLength, maxLength));

	//multi-line?
	if (type != 'multi-line') {
		$line1label.html('Text:');
		$line2container.css('visibility','hidden');
		$line2.val('').attr('disabled','disabled'); 
		$line3container.css('visibility','hidden');
		$line3.val('').attr('disabled','disabled'); 
	} else {
		$line1label.html('Line 1:');
		$line2container.css('visibility','visible');
		$line2.attr('maxLength', maxLength).removeAttr('disabled');
		$line2instructions.html(instructionalText(0, maxLength));
		$line3.attr('maxLength', maxLength).removeAttr('disabled');
		$line3instructions.html(instructionalText(0, maxLength));
	}
	$line1.focus();
}

//determines the copy of instructional text given min max values
function instructionalText(min, max) {
	var textOutput;
	if (min == max) {
		if (min == 1) {
			textOutput = '(enter 1 character)';
		} else {
			textOutput = '(enter '+min+' characters)';
		}
	} else {
		textOutput = '(enter '+min+'-'+max+' characters)';
	}
	return textOutput;
}
