﻿//global variables
var attribSectionID = 'Attributes';
var attribContainerClass = 'attribContainer';
var attribIDPrefix = 'attrib';
var attribTagType = 'input';
var selectedClassName = 'select';
var inactiveClassName = 'inactive';
var hoverClassName = 'hover';
var attribState;

var Variant = Class.create({
	initialize: function(ID, Inventory, Price, Image, Name) 
		{
			this.ID = ID;
			this.Inventory = Inventory;
			this.Price = Price;
			this.Image = Image;
			this.Name = Name;
		}
	});

function SaveState()
{
	attribState = new Hash();	
	$(attribSectionID).getElementsBySelector(attribTagType).each(function (attribute)
		{
			attribState.set(attribute.identify(), attribute.className);
		});
}

function RestoreState()
{
	if (attribState != null)
	{
		attribState.each( function(pair) 
			{
				$(pair.key).className = pair.value;
			});
	}
}

//called from onmouseover event
function Hover(elem)
{
	//store the current state
	SaveState();
	//get the element being hovered over as a Prototype.js element
	var pElem = $(elem.id);
	
	//if the element is active, add the hover class to the element
	if (!pElem.hasClassName(inactiveClassName))
	{
		pElem.addClassName(hoverClassName);		
	}
		
	//show the other attributes that can be selected with the current attribute
	ShowValidCombosForHover(pElem);
}

//called from onmouseout event
function Off(elem)
{
	//get the element that was just 'moused out' as a Prototype.js element
	var pElem = $(elem.id);
	
	//remove the hover class from the element
	pElem.removeClassName(hoverClassName);
	
	if (!pElem.hasClassName(selectedClassName))
	{
		//if the element that was being hovered over was not selected, 
		//simply restore the state to what it was before the hover action
		//this logic is simpler than having to run through the select logic again
		RestoreState();	
	}
	else
	{
		//otherwise, the hover item was actually selected, so now need to show the valid items
		ShowValidCombosForSelect(GetSelectedAttributes());
	}
}

//called from onclick event
function Select(elem)
{	
	//get the element that was just selected as a Prototype.js element
	var pElem = $(elem.id);
	
	//if the element has the hover class then remove it
	if (pElem.hasClassName(hoverClassName))
	{
		pElem.removeClassName(hoverClassName);
	}
	
	//remove the 'selected' class from all siblings of the currently selected element
	//the logic is that you can only select one attribute from each attributeContainer
	pElem.siblings().each(function(sib)
		{
			sib.removeClassName(selectedClassName);
		});
	
	//add the 'selected' class to the currently selected element
	pElem.addClassName(selectedClassName);
	
	var attribSelectName = pElem.up().previous('.attribSelectName');
	if (attribSelectName != null)
	{				
		attribSelectName.innerHTML = '&#160;&#160;' + GetAttributeName(pElem);
	}
	
	var selectedAttributes = GetSelectedAttributes();
	if (selectedAttributes.length == NumAttributeSections)
	{
		ShowVariantInfo(selectedAttributes, ProductID);
	}
	ShowValidCombosForSelect(selectedAttributes);
}

function ShowValidCombosForHover(hoverAttribute)
{
	//extract the numbered ID of the attribute being hovered over	
	var hoverAttributeID = hoverAttribute.identify().replace(attribIDPrefix, '');
	
	var validIDs = new Array();
	//get an array of ALL the combos that the hovered attribute belongs to
	//this array contains IDs of attributes that need to be 'activated'
	for (var i = 0, len = ValidCombos.length; i < len; i++)
	{
		var combo = ValidCombos[i].split(',');		
		if (combo.indexOf(hoverAttributeID) != -1)
		{
			validIDs = validIDs.concat(combo);			
		}									
	}	
	
	//loop through every attribute in the Attributes container
	$(attribSectionID).getElementsBySelector(attribTagType).each(function (attribute)
		{
			//extract the numbered ID of the element currently being iterated through
			var iteratedAttributeID = attribute.identify().replace(attribIDPrefix, '');
			//if the element is not a sibling of the hover element and not the hover element itself then continue
			if (!hoverAttribute.siblings().member(attribute) && hoverAttributeID != iteratedAttributeID)
			{			
				//if the current element of the loop is not in the validIDs array				
				//then set it as 'inactive'
				if (validIDs.indexOf(iteratedAttributeID) == -1)
				{
					attribute.addClassName(inactiveClassName);
				}
				//otherwise 'activate' the element
				else
				{
					attribute.removeClassName(inactiveClassName);
				}
			}
		});
}

function ShowValidCombosForSelect(selectedAttributes)
{
	if (selectedAttributes.length > 0)
	{		
		if (selectedAttributes.length > 1)
		{
			$(attribSectionID).getElementsBySelector(attribTagType).invoke('addClassName', inactiveClassName);
		}
		else
		{
			$(attribSectionID).getElementsBySelector(attribTagType).each(function (attribute)
				{
					if (!(selectedAttributes[0].siblings().member(attribute)))
					{
						attribute.addClassName(inactiveClassName);
					}
				});
		}				
		
		//loop through all validcombos
		//	if the combo does not contain ALL of the selectedAttributes 
		//		then parse the combo and 'inactivate' the elements in that combo
		var selectedAttributeIDs = selectedAttributes.pluck('id').invoke('replace', attribIDPrefix, '');
		
		var validIDs = new Array();
		for (var i = 0, len = ValidCombos.length; i < len; i++)
		{
			var combo = ValidCombos[i].split(',');
			var flag = true;
			selectedAttributeIDs.each(function (attributeID) 
				{
					if (combo.indexOf(attributeID) == -1)
					{
						flag = false;
					}
				});
			if (flag)
			{
				validIDs = validIDs.concat(combo);
			}									
		}		
		
		if (validIDs.length > 0)
		{
			validIDs.each(function (validID)
				{
					$(attribIDPrefix + validID).removeClassName(inactiveClassName);
				});
		}		
	}	
	
	else
	{
		//this should occur when the Off method is invoked and no items are selected
		Reactivate();
	}	
}

//remove the inactive class from all attribute elements
function Reactivate()
{	
	$(attribSectionID).getElementsByClassName(inactiveClassName).invoke('removeClassName', inactiveClassName);
}

//get an array of the selected attribute IDs
function GetSelectedAttributes()
{
	return $A($(attribSectionID).getElementsByClassName(selectedClassName));
}

function GetAttributeName(element)
{
	var elementName = '';
	if (element != null)
	{		
		if (element.hasClassName('attribImage'))
		{
			elementName = element.readAttribute('alt');
		}
		else if (element.hasClassName('attribButton'))
		{
			elementName = element.readAttribute('value');
		}
	}
	return elementName;
}

function ShowVariantInfo(selectedAttributes, productID)
{				
	var attributeIDs = selectedAttributes.pluck('id').invoke('replace', attribIDPrefix, '');
	
	//generate a list of the selected attributes and display the list
	var variantAttributesList = $('VariantAttributes');
	var variantAttributesText = '';
	for (var i=0; i<selectedAttributes.length; i++)
	{
		variantAttributesText += GetAttributeName(selectedAttributes[i]);
		if (i < selectedAttributes.length - 1)
		{
			variantAttributesText += ',&#160;';
		}
	}
	variantAttributesList.update(variantAttributesText);	
	
	//show variant pricing, availability and add to cart button
	if (attributeIDs != null && attributeIDs.length > 0)
	{
		attributeIDs = attributeIDs.sort(sortNumber);
				
		var addToCartButton = $('AddToCartButton');
		var availability = $('Availability');
		var variantID = $('VariantID');
		var price = $('VariantPrice');
		
		var comboIndex = ValidCombos.indexOf(attributeIDs.join(','));
		if (comboIndex != -1)
		{
			var variant = Variants[comboIndex];
			
			var variantImage = variant.Image;
			if (variantImage.indexOf('nopicture') == -1)
			{
				$('VariantImage').update(variantImage.unescapeHTML());
			}
			if (variant.Inventory > 0)
			{
				variantID.value = variant.ID;
				addToCartButton.show();
				price.update(variant.Price.unescapeHTML()).show();
				availability.update('');
			}
			else
			{
				addToCartButton.hide();
				price.hide();
				availability.update('Out of stock');
			}
		}
		else
		{		
			addToCartButton.hide();
			price.hide();
			availability.update('Not available');
		}		
	}
}

function sortNumber(a,b)
{
	return a - b;
}

function AddToCart()
{
	var miniCart = $('MiniCart');
	
	Ajax.Responders.register({
		onCreate : function() { miniCart.show(); miniCart.update('<div id="MiniCartLoading"><img src="images/spinner.gif" alt="Loading..." style="vertical-align:middle;" /> <strong>Adding item to cart...</strong></div>'); },
		onComplete : function() { $('MiniCartLoading').hide(); }
	  });
	
	new Ajax.Request("ajaxAddToCart.ashx", {
						method: 'post',
						parameters: { ProductID: $('ProductID').value, VariantID: $('VariantID').value, Quantity: $('Quantity').value },
						evalJSON: true,
						sanitizeJSON: true,
						onSuccess: function(transport) {
							var response = transport.responseText;
							//strip out the ADNSF un-licensed garbage
							if (response.indexOf('<div') != -1)
							{
								response = response.substr(0, response.indexOf('<div'));
							}
							
							var jsonObject = response.evalJSON(true);
							
							if (jsonObject != null)
							{
								var cartItemsPartitioned = jsonObject.partition(function (item) { return item.MostRecent; });
								if (cartItemsPartitioned.length > 0)
								{
									var mostRecentCartItem = cartItemsPartitioned[0][0];
									var cartItems = cartItemsPartitioned[1];									
									
									var cartItemsText = '<table cellpadding="0" cellspacing="0">';
									cartItemsText += '<tr>';
									cartItemsText += '<th colspan="2" class="justAddedHeader">Just Added</th>';									
									cartItemsText += '</tr>';
									
									cartItemsText += '<tr>';
									cartItemsText += '<td class="productNameCell mostRecent">';
									cartItemsText += '<span class="productName">' + mostRecentCartItem.ProductName + '</span><br />';
									cartItemsText += '<span class="variantName">' + mostRecentCartItem.VariantName + '</span>';
									cartItemsText += '</td>';
									cartItemsText += '<td class="quantityCell mostRecent">';
									cartItemsText += mostRecentCartItem.Quantity;
									cartItemsText += '</td>';
									cartItemsText += '</tr>';
									
									var cartItemsCount = mostRecentCartItem.Quantity;
									
									if (cartItems.length > 0)
									{
										cartItemsText += '<tr>';
										cartItemsText += '<th class="productHeader">Product</th>';
										cartItemsText += '<th class="quantityHeader">Quantity</th>';
										cartItemsText += '</tr>';
										
										for (var i=0; i<cartItems.length; i++)
										{
											cartItemsText += '<tr>';
											cartItemsText += '<td class="productNameCell">';
											cartItemsText += '<span class="productName">' + cartItems[i].ProductName + '</span><br />';
											cartItemsText += '<span class="variantName">' + cartItems[i].VariantName + '</span>';
											cartItemsText += '</td>';
											cartItemsText += '<td class="quantityCell">';
											cartItemsText += cartItems[i].Quantity;
											cartItemsText += '</td>';
											cartItemsText += '</tr>';
											cartItemsCount += cartItems[i].Quantity;
										}
									}
									cartItemsText += '</table>';
									
									miniCart.update(cartItemsText);
									$('NumCartItems').update(cartItemsCount);
								}
							}
						},
						onFailure: function(transport) {
							miniCart.update('There was an error adding the selected item to your cart');							
						}
					});
}