// shortened version of key sort from http://phpjs.org/functions/ksort
function ksort(array) {
	var tmp_arr={}, keys=[], i, key,

	sorter = function (a, b) { 
		return(a - b);
	}; 
	
	// Make a list of key names 
	for (key in array) { 
		keys.push(key); 
	}
	
	// Sort keys
	keys.sort(sorter);
	
	// Rebuild array with sorted key names 
	for (i = 0; i < keys.length; i++) {
		key = keys[i];
		tmp_arr[key] = array[key];
	}
	return tmp_arr; 
}

// holds the min width on the page container for IE6
function IE6MinWidthFix(){
	var tick = function(){
		var pageContainer = document.getElementById('page-container'), oldPageWidth = -1;
		return function(){
			if(oldPageWidth !== document.body.offsetWidth){
				pageContainer.style.width = document.body.offsetWidth > 940 ? '' : '702px';
				oldPageWidth = document.body.offsetWidth;
			}
		};	
	};
	window.setInterval(tick(), 80);
}

// does those super cool text boxes
// use `title` property of a text or password input box to set default text
function TextBoxHint(inputBox){
	if(!inputBox){
		return;
	}
	if((inputBox.type !== 'text' && inputBox.type !== 'password') || !inputBox.title || inputBox.title === ''){
		return;
	}
	var  opera = false, ie = false, type, inputBoxShadow,
	setClass = function (name,caller) {
		caller.className = 'input-text-' + name + caller.className.replace(/input-text-(:?blur|focus)\s?/g, '');
	},
	focusEventHandler = function () {
		return function (e) {
			if (ie && inputBoxShadow) {
				inputBoxShadow.style.display = 'none';
				inputBox.style.display = '';
				inputBox.focus();
			} else {
				if (inputBox.type !== type) {
					inputBox.type = type;
					if (opera) {
						inputBox.focus();
					}
				}
				if (inputBox.value === inputBox.title) {
					inputBox.value = '';
				}
				setClass('focus',inputBox);
			}
		};
	},
	blurEventHandler = function () {
		return function (e) {
			if (inputBox.value === inputBox.title || inputBox.value === '') {
				if (ie && inputBoxShadow) {
					if (inputBox.value === '') {
						inputBox.style.display = 'none';
						inputBoxShadow.style.display = '';
					}
				} else {
					setClass('blur',inputBox);
					inputBox.type = 'text';
					inputBox.value = inputBox.title;
				}
			}
		};
	};
	type = inputBox.type;
	if (document.all) {
		if(window.external)	{
			ie = true;
			if (type === 'password') {
				inputBoxShadow = document.createElement('input');				
				inputBoxShadow.outerHTML = inputBox.outerHTML.replace(/type=(["']?)(password|text)\1/i,'type="text"');
				inputBoxShadow.value = inputBox.title;
				setClass('focus',inputBox);
				setClass('blur',inputBoxShadow);
				inputBox.parentNode.insertBefore(inputBoxShadow,inputBox);
			}
		} else {
			opera = true;	
		}
	}

	if (ie && inputBoxShadow) {
		inputBoxShadow.onfocus = focusEventHandler();
	} else {
		inputBox.onfocus = focusEventHandler();		
	}
	inputBox.onblur = blurEventHandler();
	blurEventHandler()();
}

// enables all the cool stuff that the left menu does
function LeftMenu () {
	var menu = document.getElementById('left-menu'), clickArea, menuItems, i, expandedNode,  
	clickEventHandler = function () {
		return function (e)	{
			if (this.parentNode.parentNode.className === '') {
				if (expandedNode) {
					expandedNode.className = '';
				}
				expandedNode = this.parentNode.parentNode;
				expandedNode.className = 'left-menu-expanded';
			} else {
				expandedNode.className = '';
				expandedNode = null;
			}
		};
	};
	mouseOverEventHandler = function () {
		return function (e)	{
			this.className = 'left-menu-ca-over';
		};
	};
	mouseOutEventHandler = function () {
		return function (e)	{
			this.className = 'left-menu-ca-out';
		};
	};
	
	if(menu){
		expandedNode = document.getElementById('left-menu-selected-top-level');
		clickArea = document.createElement('span');
		clickArea.className = 'left-menu-ca-out';
		menuItems = menu.getElementsByTagName('ul');
		for (i = 0; i < menuItems.length; i++) {
			if (menuItems[i].getElementsByTagName('li').length > 0)	{
				clickArea = clickArea.cloneNode(false);
				clickArea.onclick = clickEventHandler();
				clickArea.onmouseover = mouseOverEventHandler();
				clickArea.onmouseout = mouseOutEventHandler();
				menuItems[i].parentNode.getElementsByTagName('div')[0].appendChild(clickArea);
			}
		}
	}
}


// makes the cart flyout work
function CartFlyout (cartIsEmpty) {
	var theFrame, frameDoc, checkoutButtonTop, element,
	showCart = function () {
		return function () {
			if(!document.all){ // don't lose window focus in IE
				this.blur(); // prevent ugly selection in FF
			}
			pageFade.enable();
			theFrame.className = '';
			if(checkoutButtonTop){
				checkoutButtonTop.style.display = 'none';
			}
			return false;
		};
	},
	hideCart = function () {
		return function () {
			pageFade.disable();
			theFrame.className = 'header-cart-flyout-clip';
			if(checkoutButtonTop){
				checkoutButtonTop.style.display = '';
			}
			return false;
		};
	};
	theFrame = document.getElementById('header-cart-flyout');
	if (theFrame) {
		frameDoc = theFrame.contentWindow;
		if(!cartIsEmpty){
			element = frameDoc.document.getElementById('show-cart');
			if(element) {
				element.onclick = showCart();
			}
			
			element = frameDoc.document.getElementById('keep-shopping');
			if(element) {
				element.onclick = hideCart();
			}
			
			element = frameDoc.document.getElementById('close-cart');
			if(element) {
				element.onclick = hideCart();
			}
		}
		checkoutButtonTop = frameDoc.document.getElementById('checkout-button-top');
		if(miniCartAutoShow && !cartIsEmpty){
			showCart()();
		}else if(cartIsEmpty){
			hideCart()();
		}
	}
}

// fixes the height of each contents row to make it look nice
function ContentsRows (contentsList) {
	var contents = contentsList.getElementsByTagName('li'), lastWidth = 0, lastNumCols = 0, numCols, i, j, tallest = 0,
	redraw = function () {
		return function () {
			if (lastWidth != contentsList.offsetWidth) {
				lastWidth = contentsList.offsetWidth;
				numCols = Math.floor(lastWidth/320);
				if (lastNumCols != numCols) {
					lastNumCols = numCols;
					for (i = 0; i < contents.length; i++) {
						contents[i].style.height = '';
						if (i%numCols === 0) {
							contents[i].style.clear = 'left';
							if(i !== 0){
								for (j = i - numCols; j < i; j++) {
									contents[j].style.height = tallest + 'px';
								}
							}
							tallest = contents[i].offsetHeight;
						} else {
							if (contents[i].offsetHeight > tallest){
								tallest = contents[i].offsetHeight;
							}
							contents[i].style.clear = 'none';
						}						
					}
				}
			}
		};
	};
	window.setInterval(redraw(), 80);
}

// does all the fun stuff with images of a product
function ProductImages () {
	var i,
	iconContainer = document.getElementById('product-image-icons'), icons, selectedIcon,
	imageContainer = document.getElementById('product-image-panel'), images, selectedImage, 
	insertPoint = document.getElementById('page-border-bottom'),
	largeImageContainer, largeImages = [], largeImage, buttonClose, 
	
	iconMouseOverEventHandler = function (image) {
		return function () {
			this.className = 'hover';
			if (image !== selectedImage){
				selectedImage.className = '';
				image.className = 'selected';
			}
		};
	},
	iconMouseOutEventHandler = function (image) {
		return function () {
			this.className = this === selectedIcon ? 'selected' : '';
			if (image !== selectedImage){
				image.className = '';
				selectedImage.className = 'selected';
			}
		};
	},
	iconClickEventHandler = function (image,largeImage) {
		return function () {
			if (this !== selectedIcon) {
				selectedIcon.className = '';
				selectedIcon = this;
				selectedImage = image;
			}
			imageClickEventHandler(largeImage)();
		};
	},
	imageClickEventHandler = function (image) {
		return function () {
			pageFade.enable();
			image.className = 'visible';
		};
	},
	imageMouseOverEventHandler = function () {
		return function () {
			if(this === selectedImage){
				this.className = 'selected hover';
			}
		};
	},
	imageMouseOutEventHandler = function () {
		return function () {
			if(this === selectedImage){
				this.className = 'selected';
			}
		};
	},
	largeImageClickEventHandler = function () {
		return function () {
			this.className = 'hidden';
			pageFade.disable();
		};
	};
	if(imageContainer){
		if(iconContainer){
			icons = iconContainer.getElementsByTagName('img');
		}
		images = imageContainer.getElementsByTagName('img');
		
		largeImageContainer = document.createElement('div');
		largeImageContainer.id = 'product-image-large-container';
		
		buttonClose = document.createElement('img');
		buttonClose.src = 'i/cart-close.png';
		buttonClose.alt = 'Close';
		buttonClose.className = 'close-image';
		
		for (i = 0; i < images.length; i++) {
			largeImages[i] = document.createElement('div');
			largeImages[i].className = 'hidden';
			largeImage = document.createElement('img');
			largeImage.src = images[i].src.replace(/D.cache.dpthmbn.*\//, 'D/');
			largeImage.alt = images[i].alt;
			largeImages[i].appendChild(largeImage);
			largeImages[i].appendChild(buttonClose.cloneNode(false));
			largeImages[i].onclick = largeImageClickEventHandler();
			
			largeImageContainer.appendChild(largeImages[i]);
			images[i].onmouseover = imageMouseOverEventHandler();
			images[i].onmouseout = imageMouseOutEventHandler();
			images[i].onclick = imageClickEventHandler(largeImages[i]);
			
			if(iconContainer){
				icons[i].onmouseover = iconMouseOverEventHandler(images[i]);
				icons[i].onmouseout = iconMouseOutEventHandler(images[i]);
				icons[i].onclick = iconClickEventHandler(images[i],largeImages[i]);
			}
		}
		insertPoint.parentNode.insertBefore(largeImageContainer,insertPoint);
		if(iconContainer){
			selectedIcon = icons[0];
			selectedIcon.className = 'selected';
		}
		selectedImage = images[0];
		selectedImage.className = 'selected';
	}
}

// makes options feel active
function ProductOptions () {
	var i, j, checkVariant, currentVariant, optionsContainer, documentOptionSets, optionSets = [], optionSetId, priceContainer, skuContainer, currentVariantPrice, currentPrice,
	selectOption = function (set,element) {
		return function () {
			optionSets[set].selected = element;
			recalculate()
		};
	},
	recalculate = function () {
		currentVariant = '';
		for (i in optionSets) {
			if (optionSets[i].type === 'option-variant') {
				currentVariant += '__' + i + '_' + optionSets[i].selected;
				checkVariant = '';
				for (j in optionSets) {
					if (optionSets[j].type === 'option-variant') {
						checkVariant += '__' + j + '_' + (i === j ? 'X' : optionSets[j].selected);
					}
				}
				for (j = 0; j < optionSets[i].elements.length; j++) {
					if (optionSets[i].elements[j].value !== optionSets[i].selected) {
						if(product.variants[checkVariant.replace('X',optionSets[i].elements[j].value)]) {
							optionSets[i].elements[j].disabled = false;
							optionSets[i].elements[j].parentNode.className = '';
						} else {
							optionSets[i].elements[j].disabled = true;
							optionSets[i].elements[j].parentNode.className = 'option-disabled';
						}
					}
				}
			}
		}
		if (currentVariant !== '') {
			skuContainer.innerHTML = product.variants[currentVariant].code;
			currentVariantPrice = product.variants[currentVariant].price;
		}
		currentPrice = currentVariantPrice;
		for (i in optionSets) {
			if (optionSets[i].type === 'option-modifier') {
				currentPrice += currentVariantPrice * product.options[i][optionSets[i].selected].multiply + product.options[i][optionSets[i].selected].add;
			}
		}
		priceContainer.innerHTML = '$' + currentPrice.toFixed(2);
	};
	
	optionsContainer = document.getElementById('options');
	priceContainer = document.getElementById('product-price');
	skuContainer = document.getElementById('product-seller-sku');
	
	if (optionsContainer && product) {
		currentVariantPrice = product.basePrice;
		documentOptionSets = optionsContainer.getElementsByTagName('ul');
		for (i = 0; i < documentOptionSets.length; i++) {
			optionSetId = documentOptionSets[i].id.replace(/[^0-9]+/,'');
			optionSets[optionSetId] = {
				type : documentOptionSets[i].className,
				elements : documentOptionSets[i].getElementsByTagName('input')
			};
			for (j = 0; j < optionSets[optionSetId].elements.length; j++) {
				optionSets[optionSetId].elements[j].onclick = selectOption(optionSetId,optionSets[optionSetId].elements[j].value);
				if (optionSets[optionSetId].elements[j].checked) {
					optionSets[optionSetId].selected = optionSets[optionSetId].elements[j].value;
				}
			}
		}
		optionSets = ksort(optionSets);
		recalculate();
	}
}


// fades the whole page
function PageFade () {
	pageContainer = document.getElementById('page-container');
	this.enable = function () {
		pageContainer.className = 'fade-all';
	}
	this.disable = function () {
		pageContainer.className = '';
	}
}

// ouch! globals :(
var pageFade = new PageFade(), miniCartAutoShow = false;

// starts everything
function initPage () {
	var inputs, i, inputsForIe = [], contentsBlocks, cartFlyout, productForm;
	
	// Say hello to IE6
	if (window.external && typeof window.XMLHttpRequest === "undefined") { 
		IE6MinWidthFix();
	}
	
	// load the cart
	cartFlyout = document.getElementById('header-cart-flyout');
	if(cartFlyout){
		cartFlyout.src = '/cart.php?mini-cart=true';
	}
	
	// enable mini cart adding
	productForm = document.getElementById('product-form');
	if(productForm){
		productForm.target = 'mini-cart';
		productForm.onsubmit = function () {
			miniCartAutoShow = true;
		}
	}
	
	// init product options
	ProductOptions();
	
	// make the inputs look cute
	inputs = document.body.getElementsByTagName('input');
	// ok, this is gonna look really strange, what happens is that TextBoxHint sometimes inserts 
	// extra input boxes into the DOM tree, just because IE can't change the `type` property via JS.
	// getElementsByTagName doesn't actually return an array, it returns an object that acts 
	// like an array that updates itself if things are added or removed from the DOM. That 
	// creates an infinite loop in our case, so we have to copy only those items that we
	// want to deal with to a real array and then run TextBoxHint on them
	for (i = 0; i < inputs.length; i++) {
		inputsForIe[i] = inputs[i];
	}
	for (i = 0; i < inputsForIe.length; i++) {
		TextBoxHint(inputsForIe[i]);
	}
	
	// make the left menu shine
	LeftMenu();
	
	// start contents redraw
	contentsBlocks = document.body.getElementsByTagName('ul');
	for (i = 0; i < contentsBlocks.length; i++) {
		if (contentsBlocks[i].className === 'category-contents') {
			ContentsRows(contentsBlocks[i]);
		}
	}

	// init product images
	ProductImages();
}
initPage();


