//**********************************************************************
//
// Object structure defination
// 
// Objects in multidementional structure: products -> product -> colors -> sizes.
// 
// Each objects has it own operational functions.
//
//**********************************************************************

// This object provide the top level structure to hold products.
// Each productList element is a product.
//
function productsObj (n) {

	this.productList = new Array(n);
	
	this.updateByColor = updateByColor;
	
	this.updateByColorAndSize = updateByColorAndSize;
	
	this.updateQuantity = updateQuantity;
	
	this.Add2ShopCart = Add2ShopCart;
		
	this.toString = productsToString;
}

// This object is product.
// Each each colorList element is color. 
//
function productObj (styleIdProductId, styleId, n) {

	this.productShortDesc = "";					// Product short description.
	
	this.userSelectedSizeId = null;				// User actually click and select a size value at anytime store the size Id here. This change as user change size.
												// Another word this is the user clicked size and not the pre-selected size.
	
	this.styleIdProductId = styleIdProductId;  	// Unique id for this product use in this javaScript object structure.
	this.styleId = styleId;
	this.colorList = new Array(n);
	
	this.lastSelectedColor = null;				// This track the last color the user selected.
	this.lastSelectedSize = null;				// This keep track the user last selected size Object use for presistent logic part.
	
	this.buyQty = 1;							// This store user buy quantity value.
	
	this.updateUserSelectedSizeId = updateUserSelectedSizeId;
	
	this.toString = productToString;
}

// This object is color.
// Each each sizeList element is size. 
//
function colorObj (colorId, n) {

	this.colorId = colorId;
	this.sizeList = new Array(n);

	this.findSizeByColorAvailableSize = findSizeByColorAvailableSize;
	
	this.findLastSizeByColor = findLastSizeByColor;
	
	this.updateColorSizeToSelectedSize = updateColorSizeToSelectedSize;
	
	this.resetColorSizeIsSelectedStatus = resetColorSizeIsSelectedStatus;
	
	this.toString = colorToString;
}

// This object is size.
// 
function sizeObj (sizeId, isAvailable, catentryId, availQty, isSelectedSize) {

	this.sizeId = sizeId;
	this.isAvailable = isAvailable;
	this.catentryId = catentryId;
	this.availQty = availQty;
	
	this.isSelectedSize = isSelectedSize;
	
	this.toString = sizeToString;
}

//**********************************************************************
//
// Structure functon defination
//
//**********************************************************************

// This function update the tracking structure when user change color.
//
function updateByColor(thisColorElement, sizePos, styleIdProductId, colorId){
			
	// Find the correct product, color and size in the array.
	
	for (var i = 0; i < this.productList.length; ++i){
	
		if(this.productList[i].styleIdProductId == styleIdProductId){
		
			// Product found. Next find the color.
			
			for (var j = 0; j < this.productList[i].colorList.length; ++j){
				
				if(this.productList[i].colorList[j].colorId == colorId){
					
					// Color found.
					
					// If last selected size has value, then select the current color with same size, iff the size is available for this color.
					
					var lastSelectedSizeId = null;
					
					if(this.productList[i].userSelectedSizeId != null){
					
						lastSelectedSizeId = this.productList[i].userSelectedSizeId;
						
					}else if(this.productList[i].lastSelectedSize != null){
						//lastSelectedSizeId = this.productList[i].lastSelectedSize.sizeId;
					}
					
					var currentSelectedSizeObj = null;
					
					if(lastSelectedSizeId != null){
					
						// No most current user selected size id was found.
						// Find out if last selected size is available in the current selected color.
						currentSelectedSizeObj = this.productList[i].colorList[j].findSizeByColorAvailableSize(lastSelectedSizeId);
						
						if (currentSelectedSizeObj != null){
							
							// Found it.  Reset and update the current color size to indicate it is now the most recent selected size.
							this.productList[i].colorList[j].resetColorSizeIsSelectedStatus();
							this.productList[i].colorList[j].updateColorSizeToSelectedSize(lastSelectedSizeId);								
								
						}else{
						
							// Not size availble found in this color.  
							// Find out if the original selected size in this color is available.
							
							currentSelectedSizeObj = this.productList[i].colorList[j].findLastSizeByColor();
						}
						
					}else{
					
						// Empty lastSelectedSize mean that there were no size for that last color or size selected by the user.
						// Find out from this color where the last selected size is and assign to lastSelectedSize.
						
						//debug("Check: " + this.productList[i].colorList[j].colorId);
						
						currentSelectedSizeObj = this.productList[i].colorList[j].findLastSizeByColor();
					}
										
					// Update size.
										
					this.productList[i].lastSelectedSize = currentSelectedSizeObj;
					
					if(currentSelectedSizeObj != null){
						
						//debug("Update to the current seleted color");
						
						// Update productObj last selected size.
						this.productList[i].lastSelectedSize = currentSelectedSizeObj;
						

						//debug("currentSelectedSizeObj: " + this.productList[i].lastSelectedSize);
						
						// Now update the UI CSS selection to remove the pre-selected size value from FRY original code.
						// This is vitual view only for the frontend.

						var sizeWrapper = thisColorElement.parentNode.parentNode.getElementsByTagName("div")[0];
						var sizeLists = sizeWrapper.getElementsByTagName('ul');
						var totalList = sizeLists.length;
				
						for(var n = 0; n<totalList; n++) {
							sizeLists[n].className = '';
						}
										
						for(var n = 0; n<totalList; n++) {
					
							if (n == sizePos){
							
								var sizeListDefination = sizeLists[n].getElementsByTagName("li");
								
								var sizeListDefinationLength = sizeListDefination.length;
								
								for(var m = 0; m<sizeListDefinationLength; m++) {			
					
									//debug("update: " + this.productList[i].lastSelectedSize.sizeId + ", value: " + sizeListDefination[m].getElementsByTagName("span")[0].firstChild.nodeValue);
									
									// Clear the last marked selected-size
									if( sizeListDefination[m].className == "selected-size"){
									
										sizeListDefination[m].className ="";
									}
									
									if(this.productList[i].lastSelectedSize.sizeId == sizeListDefination[m].getElementsByTagName("span")[0].firstChild.nodeValue){
								
										sizeLists[n].className = 'current-sizes';
										sizeListDefination[m].className = 'selected-size';
									
									}
								}
							}
						}
				
						
					}else{
					
						//debug("Not update to the current seleted color");
					}
					
					// Update to current selected color
					this.productList[i].lastSelectedColor = colorId;
				}
			
			}
		}
	}	
	
	//debug("In updateByColor: \n\n " + this.toString());
}

// This funciton add product to cart
// submitType: 	0 - single product detail page submit.
//				1 - multiproduct page submit.
//
function Add2ShopCart(fm, submitType){

	var catentryIdList = "";
	var quantityList = "";
	var styleIdList = "";
	var selectedItemCount = 0;
	var processedItemCount = 0;
	var selectedItemNotAvailableCount = 0;
	
	var groupItemNotAvailableMsg = "";
	
	var appendComma = false;
	
	var msgItemNotAvailable = "not available in the quantity you requested";
	var msgOutOfStock = "out of stock";
	
	var submitFormCheck = true;
	
	for (var i = 0; i < this.productList.length; ++i){
		
		var checkedItem = false;
		
		// Single product page item always mark as checked becuase it does not have the check box.
		if(submitType == '0'){
			checkedItem = true;
		}
		
		if(submitType == '1'){
			checkedItem = document.getElementsByName(this.productList[i].styleIdProductId)[0].checked;
		}
		
		if (checkedItem){
						
			++selectedItemCount;					

			if(this.productList[i].lastSelectedSize != null){
			
				var inValidQtyMsg = "Please enter valid quantity for item: " + this.productList[i].productShortDesc;

				// 	This is a speical condition for qty check and IMPORTANT for submit of the right qty:
				// 	Validate qty value format at run time.
				// 	In this case user may update and keep ignore the warning and not to change the value
				// 	and the tracking structure does not get update due to FRY code triger last. 
				//	Drill right into the form and get the quantity value that user see on the page.
				//				
				// For multiproduct submit.
				if(submitType == '1'){
					
					var addToBagElement = document.getElementsByName(this.productList[i].styleIdProductId)[0];			
								
					var dlWrapper = addToBagElement.parentNode.parentNode.getElementsByTagName("dl")[0];
					var ddWrapper = dlWrapper.getElementsByTagName("dd")[0];
					var inputQtyWrapper = ddWrapper.getElementsByTagName("input")[0];
					
					if(inputQtyWrapper.name == "qty"){
		
						if(!isValidQty(inputQtyWrapper.value)){
						
							alert(inValidQtyMsg);
							return;
							
						}else{
						
							this.productList[i].buyQty = inputQtyWrapper.value;
						}
					}
				
				}
				
				// For single product submit.
				if(submitType == '0'){
				
					var quantity = document.getElementsByName("quantity")[0].value;	
					
					this.productList[i].buyQty = quantity;
					
				}
				
				// End speical condition for qty check above.
				
				// Validate qty.				
				if(!isValidQty(this.productList[i].buyQty)){
				
					alert(inValidQtyMsg);
					return;
				}
				
				if (parseInt(this.productList[i].lastSelectedSize.availQty) == 0){
	
					groupItemNotAvailableMsg += "\nItem: " + this.productList[i].productShortDesc + " - " + msgOutOfStock;
					++selectedItemNotAvailableCount;
						
				}
				
				// Validate qty verse available qty.
				if (parseInt(this.productList[i].lastSelectedSize.availQty) < parseInt(this.productList[i].buyQty)){
				
					groupItemNotAvailableMsg += "\nItem: " + this.productList[i].productShortDesc + " - " + msgItemNotAvailable;
					++selectedItemNotAvailableCount;
				
				}
	
				// Append comma only in this format: [a, b, c,....,z] where a-z can be any number or char string.  Only and skip last comma.
				if (appendComma == true){
	
					catentryIdList += ",";
					quantityList += ",";
					styleIdList += ",";
				}
				
				if(this.productList[i].lastSelectedSize != null){
	
					catentryIdList += this.productList[i].lastSelectedSize.catentryId;
					quantityList += this.productList[i].buyQty;		// Note that this value is actually come from the same value as the user see at the last movement of submit getting in above  logic.
					styleIdList += this.productList[i].styleId;
					appendComma = true;
					++processedItemCount;
							
				}			
			}else{

				groupItemNotAvailableMsg += "\nItem: " + this.productList[i].productShortDesc + " - " + msgOutOfStock;
				++selectedItemNotAvailableCount;			
			}
		}
	}

	// No item was checked
	if (selectedItemCount == 0){
	
		alert("Please check item Add to Bag checkbox to add to bag");
		return;
	}	
	
	// Item not availlable.
	if(selectedItemNotAvailableCount > 0){

		alert("Sorry, the item you tried to add to your shopping bag is either out of stock or not available in the quantity you requested." 
				+ "\n" + groupItemNotAvailableMsg);
		return;	
	}
	
	// Build submit form.
	fm.catEntryId.value = catentryIdList;
	fm.quantity.value = quantityList;
	fm.addCatID.value = styleIdList;
	fm.numOfProducts.value = processedItemCount;
	
	// Single product submit.
	if(submitType == '0'){

		fm.action='TCPOrderItemAdd';
		fm.URL.value='OrderItemDisplay';	
	}
	
	fm.submit();	
}

// This function update sizeid to a color.
//
function updateByColorAndSize(styleIdProductId, colorId, sizeId){

	// Find the product in the list.
	for (var i = 0; i < this.productList.length; ++i){
	
		if(this.productList[i].styleIdProductId == styleIdProductId){
		
			// Product found, next find the color.

			for (var j = 0; j < this.productList[i].colorList.length; ++j){
				
				if(this.productList[i].colorList[j].colorId == colorId){
		
					// Color found. Check if the size is available to be selected for this color.
					
					var currentSelectedSizeObj = this.productList[i].colorList[j].findSizeByColorAvailableSize(sizeId);
					
					if(currentSelectedSizeObj != null){
					
						// Found size is available to be selected for this color.
						
						//debug("currentSelectedSizeObj: " + currentSelectedSizeObj.toString());
						
						// Keep track of the initial selected with new selected size value.
						// The initial selected size is either marked as first page load or when user selected it.
						this.productList[i].colorList[j].resetColorSizeIsSelectedStatus();
						this.productList[i].colorList[j].updateColorSizeToSelectedSize(sizeId);
						
						// Keep track of what being selected in product level and that will be used for final sumbit of the form later.
						this.productList[i].lastSelectedColor = colorId;
						this.productList[i].lastSelectedSize = currentSelectedSizeObj;
						
						// No need to update the UI CSS selection to remove the pre-selected size value from FRY original code.
						// FRY original code is working correctly to highlight the user wanted size.
						// Keep track of the user wanted size in product level and it will be used to first check for the user wanted size if available when user switch color.
						this.productList[i].updateUserSelectedSizeId(sizeId);
					}
				}
			}
		}
	}
	
	//debug("In updateByColorAndSize: \n\n " + this.toString());
}

// This function update the product buy quantity, if available.
//
function updateQuantity (styleIdProductId, buyQty, obj){

	// Check for buyQty is number or greater than 1;
	if(!isValidQty(buyQty)){
	
		// Invalid qty set the tracking structure buyQty to zero.
		for (var i = 0; i < this.productList.length; ++i){
			if(this.productList[i].styleIdProductId == styleIdProductId){
				this.productList[i].buyQty = 0;
			}
		}
	
		/*
		alert("Please enter valid quantity");
		obj.focus();
		obj.select();
		*/
		return;
	}
	
	// Find the product in the list.
	for (var i = 0; i < this.productList.length; ++i){
	
		if(this.productList[i].styleIdProductId == styleIdProductId){
		
			// Found the product.
			var outOfStockMsg = "Sorry, the item you tried to add to your shopping bag is either out of stock or not available in the quantity you requested.";
			
			if(this.productList[i].lastSelectedSize != null){
			
				//debug(this.productList[i].lastSelectedSize.availQty + " >= " + buyQty);
				
				this.productList[i].buyQty = buyQty;
			
				/*
				if(parseInt(this.productList[i].lastSelectedSize.availQty) >= parseInt(buyQty)){
				
					// Update buying quantity.
					this.productList[i].buyQty = buyQty;
					
				}else{
				
					
					alert(outOfStockMsg);
					obj.focus();
					obj.select();
				}
				*/
			
			}else{
			
				// Quantity not available.
				
				/*
				alert(outOfStockMsg);
				obj.focus();
				obj.select();
				*/
				
			}
			
			return;
		}
	}

	//debug("In updateProductQuantity: \n\n " + this.toString());
}

// This function find out from this color where the last selected or available first selected size is.
//
function findLastSizeByColor(){

	for (var i = 0; i < this.sizeList.length; ++i){
		
		if(this.sizeList[i].isSelectedSize == true){
			return this.sizeList[i];
		}
	}
	return null;
}

// This function find out if the given size id is available to this color.
//
function findSizeByColorAvailableSize(sizeId){

	for (var i = 0; i < this.sizeList.length; ++i){
		
		if(this.sizeList[i].sizeId == sizeId && this.sizeList[i].isAvailable == true){
			return this.sizeList[i];
		}
	}
	return null;
}

// This function reset the previous selected status to false.
//
function resetColorSizeIsSelectedStatus(){

	for (var i = 0; i < this.sizeList.length; ++i){
		
		this.sizeList[i].isSelectedSize = false;
	}
}

// This function mark the size in this color as selected.
//
function updateColorSizeToSelectedSize(sizeId){

	for (var i = 0; i < this.sizeList.length; ++i){
		
		if(this.sizeList[i].sizeId == sizeId && this.sizeList[i].isAvailable == true){
			this.sizeList[i].isSelectedSize = true;
		}
	}
}

// This function update user initial selected size in product level.
//
function updateUserSelectedSizeId(sizeId){

	this.userSelectedSizeId = sizeId;
}

// This function validate a quantity value.
//
function isValidQty(qty){

	var rc = true;
	
	if(!isInteger(qty) || qty <= 0){
	
		rc = false;
	}
	
	return rc;
}

// This function add muiltiProduct page item to wish list.
// Note that current design only allow one product to be added to wish list at a time.
//
function AddToWishListMultiProducts(form, errMsgBadQty, isRegisterUser, styleIdProductId){

	var rc = true;
	
	for (var i = 0; i < productsTrack.productList.length; ++i){
	
		if(productsTrack.productList[i].styleIdProductId == styleIdProductId){
			
			if(productsTrack.productList[i].lastSelectedSize == null){
			 	rc = false;
			 	break;
			}
			
			form.catEntryId.value = productsTrack.productList[i].lastSelectedSize.catentryId;

			// 	This is a speical condition for qty check and IMPORTANT for submit of the right qty:
			// 	Validate qty value format at run time.
			// 	In this case user may update and keep ignore the warning and not to change the value
			// 	and the tracking structure does not get update due to FRY code triger last. 
			//	Drill right into the form and get the quantity value that user see on the page.
			//				
			// For multiproduct submit.
							
			var inValidQtyMsg = "Please enter valid quantity for item: " + productsTrack.productList[i].productShortDesc;
			
			var addToBagElement = document.getElementsByName(productsTrack.productList[i].styleIdProductId)[0];	
			var dlWrapper = addToBagElement.parentNode.parentNode.getElementsByTagName("dl")[0];
			var ddWrapper = dlWrapper.getElementsByTagName("dd")[0];
			var inputQtyWrapper = ddWrapper.getElementsByTagName("input")[0];
			
			if(inputQtyWrapper.name == "qty"){

				if(!isValidQty(inputQtyWrapper.value)){
				
					alert(inValidQtyMsg);
					return;
					
				}else{
				
					productsTrack.productList[i].buyQty = inputQtyWrapper.value;
				}
			}
			
			
			form.quantity.value = productsTrack.productList[i].buyQty;
		}
	}

	if(!rc){
		alert("Sorry, this item can not be added to the wish list");
	}else{
		
		// Reuse the generic add to wish list function.
		AddToWishList(form, errMsgBadQty, isRegisterUser, styleIdProductId);
	}

}

// This function add item to wish list.
//
function AddToWishList(form, errMsgBadQty, isRegisterUser, styleIdProductId)
{
	// Find the product in the list.
	for (var i = 0; i < productsTrack.productList.length; ++i){
	
		if(productsTrack.productList[i].styleIdProductId == styleIdProductId){
			
			if(isEmpty(form.catEntryId.value)){
			
				alert(errMsgBadQty);
				return false;
			}
			
			if(!checnNumeric(form.quantity.value)){
				alert(errMsgBadQty);
				return false;
			}
			
			// Found the product.
			if(productsTrack.productList[i].lastSelectedSize != null){
			
				form.quantity.value = productsTrack.productList[i].buyQty;
				form.catEntryId.value = productsTrack.productList[i].lastSelectedSize.catentryId;

				if (isRegisterUser == 'true'){
				
					form.action='InterestItemAdd';
					form.URL.value='InterestItemDisplay';
					
				}else{
				
					form.action='LogonForm';
					form.URL.value= getNotLoginWishListUrl(form.storeId.value, form.langId.value, form.catEntryId.value, form.catalogId.value, form.quantity.value);
				}
				
				form.submit();
						
			}else{
			
				alert("Sorry, this item can not be added to the wish list");
				
				return false;
			}
			
		}
	}
}

// This function construct a url for none login user to add item to wish list.
//
function getNotLoginWishListUrl(storeId, langId, catEntryId, catalogId, qty){

	return 'InterestItemAdd?storeId='+storeId+'&langId='+langId+'&catEntryId='+catEntryId+'&catalogId='+catalogId+'&quantity='+qty+'&URL=InterestItemDisplay';
}

//**********************************************************************
//
// Defination of function [x]ToString().
// Mostly use for debug purpose.
//
//**********************************************************************

function productsToString(){

	var s = this.productList.toString() + "\n";
	return s;
}

function productToString(){

	var s = "product: " + this.productShortDesc + ", " + this.styleIdProductId + ", styleId" + this.styleId + ", userSelectedSizeId=" + this.userSelectedSizeId + ", buyQty=" + this.buyQty + "\n lastSelectedColor=" +this.lastSelectedColor + "\n lastSelectedSize= " + this.lastSelectedSize + "\n " + this.colorList.toString() + "\n";
	return s;
}

function colorToString(){

	var s = "colorId: " + this.colorId + ":\n " + this.sizeList.toString() + "\n";
	return s;
}

function sizeToString(){

	var s = "sizeId: " + this.sizeId + ", isAvailable=" + this.isAvailable + ", catentryId=" + this.catentryId + ", availQty=" + this.availQty 
			+ ", isSelectedSize=" + this.isSelectedSize + "\n";
	return s;
}

function debug(s){

	//alert(s);
}


// Code for larger image rollovers
$(document).ready(function() {
  $(".item-image-area div").hover(function() {
    if ( $(".imagePopOver").length > 0 ) {
       $(".imagePopOver").remove();
    }
    var imgTag = $(this).html();
    imgTag = imgTag.replace("width=\"185\"", "width=\"300\"");
    imgTag = imgTag.replace("height=\"185\"", "height=\"300\"");
    imgTag = imgTag.replace("width=185", "width=\"300\"");
    imgTag = imgTag.replace("height=185", "height=\"300\"");
    imgTag = imgTag.replace("_m.jpg", "_l.jpg");
    imgTag = imgTag.replace("class=\"image\"", "");
    $(this).parent().parent().before("<div class=\"imagePopOver newImagePopOver\">"+imgTag+"</div>");

    // Create the action on mouseout
    $(".newImagePopOver").hover(function() {
    // Do nothing
    },function(){
    $(this).fadeOut(300);
    });
    // Remove the new Class
    $(".newImagePopOver").removeClass("newImagePopOver");
  },function(){
  });
});
