var baseAddUrl = "/webapp/wcs/stores/servlet/IrwWSInterestItemAdd?partNumber="; // The first part of the WS call to add a product to the shopping list
var addUrlSuffix = "&quantity=1"; // The last part of the call to add a product to the shopping list
var pipParameter = "?type=xml&dataset=allChildren,small,attributes"; // Needed parameters for the IOWS call

var addToShopListPopup = IkeaPopup();

/**
* The complete URL for fetching product data will look like this for the Goliat drawer unit:
* http://localhost/webapp/wcs/stores/servlet/products/se/en/-/40103685?type=xml&dataset=allChildren,small,attributes
* In production environment, this corresponds to:
* http://www.ikea.com/se/sv/catalog/products/40103685?type=xml&dataset=allChildren,small,attributes
* The complete URL is constructed in fetchRemoteProductData.
*
* Here is an example for a complete URL to add the product with product number 40103685 
* to the shopping list:
* http://localhost/webapp/wcs/stores/servlet/IrwWSInterestItemAdd?partNumber=40103685&quantity=1
*/	


/**
 * Entry point method from Prototype. Fetches the ID value of the product and starts the popup.
 * @param targetObject		A DOM object (from prototype) with ID value in the format id="popupShoppingList40103685"
 *							where "40103685" is a valid product number.
 * @param countryCode		Two letter country code (Example "se" = Sweden)
 * @param languageCode		Two letter language code (Example "en" = English)
 * @return					Nothing
 */
function respondToClick(targetObject,baseUrl,storeId,languageId) {
	var targetId = targetObject.attributes.id.value;
	targetId = targetId.replace("popupShoppingList","");
	try {
		irwStatShoppingList("POPpopupOpened");
	} catch(e) {
	}
	activateAddToBasketPopup(targetObject,targetId,baseUrl,storeId,languageId);
}

/**
 * Calls the IOWS to get product data for a specific product number.
 * The data call is made asynchronously, when the result is returned
 * the method onRemoteProductDataRecieved is called. This function is meant
 * to be called by activateAddToBasketPopup. 
 * @param productNumber		The product number thata data is required for. (Example "40103685" = Goliat)
 * @param countryCode		Two letter country code (Example "se" = Sweden)
 * @param languageCode		Two letter language code (Example "en" = English)
 * @return					Nothing
 */
function fetchRemoteProductData(productNumber,baseUrl) {
    // Show the user that we are waiting for data
    loadingPopup();
    // Build the complete IOWS URL
	var completeURL = baseUrl+pipParameter;
	// Call the completed IOWS URL
	new Ajax.Request(completeURL, {
		method: 'get',
		contentType: 'application/xml',
		onSuccess: function(response) {
		    onRemoteProductDataRecieved(response.responseXML);		
		}
	});		
}

/**
 * Handles the data returned from the retchRemoteProductData asynchronous call.
 * The data is parsed to an array of Javascript objects describing the versions available.
 * The method either alters the popup layout to show the available product attributes,
 * or if only one version is available, directly adds that version to the shopping list
 * and shows the layout that informs the user that the operation is complete.
 * @param doc				The returned IOWS XML data
 * @return					Nothing
 */
function onRemoteProductDataRecieved(doc) {
    // Parse the returned data
    var items = doc.getElementsByTagName("item");
    var productData = new Array();
    for(var i=0;i<items.length;i++) {
        var productDataItem = parseXmlItemToProdInfo(items[i]);
        productData[i] = productDataItem;
    }
    // Either allow the user to choose from possible attribute combinations, or add the product to the shopping list
    if(productData.length > 1 && productData[0].attributeItems.length > 1) {
    	// Multiple versions of the product is available. The user must choose one before proceeding.
	    var newLayout = generateProductInfoLayoutForShopListPopup(productData);
	    addToShopListPopup.setGenericContent(newLayout);
    } else {
    	// Only one version was found. Add the item to the shopping list and show that the operation is done.
    	callAddItemToShoppingList(productData[0].partNumber);
    }
}


/**
 * Makes an asynchronous call to the webservice for adding a product to the shopping list.
 * The data call is made asynchronously, when the result is returned
 * the method onAddToShoppingListComplete is called. This function is meant
 * to be called by onRemoteProductDataRecieved.
 * @param prodNbr			The product number that data is required for. (Example "40103685" = Goliat). 
 * @return					Always false, in order to stop link execution
 */
function callAddItemToShoppingList(prodNbr,storeId,languageId) {
    // Show the user that we are waiting for data
    loadingPopup();
	var productNumber = 0;
	if(prodNbr==0) {
		productNumber = $F('platSelect');
	} else {
		productNumber = prodNbr;
	}
	// Call the WS to add the product to the shopping list
	var completeURL = baseAddUrl + productNumber + "&langId=" + languageId + "&storeId=" + storeId + addUrlSuffix;
	new Ajax.Request(completeURL, {
		method: 'get',
		contentType: 'application/xml',
		onSuccess: function(response) {
		    onAddToShoppingListComplete(response.responseXML);		
		}
	});					
	return false;
}


/**
 * Handles the data returned from the callAddItemToShoppingList asynchronous call.
 * The data is parsed to an operation code that should normally be 0.
 * Depending on success, the user is either shown a message that things went well, or an error message.
 * @param doc				The returned WS XML data
 * @return					Nothing
 */
function onAddToShoppingListComplete(doc) {
	var responseTags = doc.getElementsByTagName("actionResponse");
	var responseTag = doc.getElementsByTagName("actionResponse")[0];
	var codeTag = responseTag.getElementsByTagName("code")[0];
	var operationCode = parseInt(codeTag.firstChild.nodeValue);
	var operationSuccess = (parseInt(codeTag.firstChild.nodeValue) == 0);
	if(operationSuccess) {
		try	{
			irwStatShoppingList("addFromPIPorSC");
		} catch (e) {
		}
		donePopup();
	} else {
		errorPopup(operationCode);
	}
}


/**
 * Helper method to onRemoteProductDataRecieved that parses a single item XML node from a call to IOWS.
 * @param item				An item XML node. See IOWS call (example http://www.ikea.com/se/sv/catalog/products/40103685?type=xml&dataset=allChildren,small,attributes)
 *							for details on how the item node is expected to be formed.
 * @return					A javscript object with the attributes: name (string), partNumber (string), attributeItems (Array)
 *							The object in the attributeItems array contains: name (string), value (string)
 */
function parseXmlItemToProdInfo(item) {
    var itemName = item.getElementsByTagName("name")[0].firstChild.nodeValue;
    var partNbr = item.getElementsByTagName("partNumber")[0].firstChild.nodeValue;
    var tempArray = item.getElementsByTagName("attributesItems");
    var attributeItemArray = parseAndSortAttributeItems(tempArray);
    var returnObject = {name:itemName, partNumber:partNbr, attributeItems:attributeItemArray};
    return returnObject;
}

		
/**
 * Helper method to parseXmlItemToProdInfo that parses a single attributesItems XML node from a call to IOWS.
 * The attributes objects are sorted alphabetically (on the name field) before they are returned.
 * @param item				An attributesItems XML node. See IOWS call:
 * 							(example http://localhost/webapp/wcs/stores/servlet/products/se/en/-/40103685?type=xml&dataset=allChildren,small,attributes)
 *							for details on how the attributesItems node is expected to be formed.
 * @return					A javscript object with the attributes: name (string), value (string)
 */
function parseAndSortAttributeItems(attributeItems)	{
    var items = attributeItems[0].getElementsByTagName("attributeItem");
    var unsortedArray = new Array(items.length);
    for(var j=0;j<items.length;j++) {
    	var item = items[j];
    	var attributeName = item.getAttribute("name");
    	var attributeValue = item.firstChild.firstChild.nodeValue;
    	var dataItem = {name:attributeName,value:attributeValue};
    	unsortedArray[j] = dataItem;
    }
    return unsortedArray.sort(sortAttributeItems);
}


/**
 * Helper method to parseAndSortAttributeItems that sorts two name/value objects on the name field.
 * The method follows the pattern for the Javascript Array.sort method. (Read more here: http://www.elated.com/articles/sorting-javascript-arrays/) 
 * @param a					The first Javascript object. Must have a field called "name"
 * @param b					The second Javascript object. Must have a field called "name"
 * @return					-1,0 or 1. -1 means that a comes before b. 0 means they are equal. 1 means b comes before a.
 */
function sortAttributeItems(a,b) {
    if(a.name < b.name) return -1;
    if(a.name == b.name) return 0;
    if(a.name > b.name) return 1;
}

/**
 * Helper function to respondToClick. It shows and places the popup, and starts the ajax call.
 * @param targetElement		A DOM object (from prototype) that should be used for guiding the position of the popup
 * @param itemId			The product number thata data is required for. (Example "40103685" = Goliat)
 * @param baseUrl			The URL that opens this partNumbers PIP-page
 * @return					Nothing
 */
function activateAddToBasketPopup(targetElement,itemId,baseUrl,storeId,languageId) {
	addToShopListPopup.createGenericPopup(170,"","slPopup","slPopup",targetElement,-20,-108);
	//fetchRemoteProductData(itemId,baseUrl); // Selection between attributes disabled. Product is added directly.
	var currentPartNumber = itemId;
	var partNumberInForm = getObj("thePartnumberInForm");
	if (""+partNumberInForm != "null") {
		currentPartNumber = partNumberInForm.value;
	}
	callAddItemToShoppingList(currentPartNumber,storeId,languageId);
}


/**
 * Closes the popup
 * @return					false to stop link exection
 */
function closePopup() {
    addToShopListPopup.hide();
    return false;
}


/**
 * Makes the popup show the layout that informs the user that the product has been added to the shopping list.
 * Requires that a method called generateDoneLayoutForShopListPopup that returns valid HTML layout is defined.
 * @return					false to stop link exection
 */
function donePopup() {
    var newLayout = generateDoneLayoutForShopListPopup();
    addToShopListPopup.setGenericContent(newLayout);
    return false;
}


/**
 * Makes the popup show the layout that informs the user of an unexpected problem.
 * If the product is visible in the product listing none of these errors should occur.
 * Requires that a method called generateErrorLayoutForShopListPopup that returns valid HTML layout is defined.
 * @param errorCode			Diagnostic information to help identify the problem
 * @return					false to stop link exection
 */
function errorPopup(errorCode) {
    var newLayout = generateErrorLayoutForShopListPopup(errorCode);
    addToShopListPopup.setGenericContent(newLayout);
    return false;
}


/**
 * Makes the popup show the layout that informs the user that a remote call is loading.
 * Requires that a method called generateLoadingLayout that returns valid HTML layout is defined.
 * @return					false to stop link exection
 */
function loadingPopup() {
	addToShopListPopup.loadingPopup();
	return false;
}


/**
 * Takes an Array of Javascript objects and generates a string with a sequence of option-tags.
 * Helper function to generateProductInfoLayoutForCartPopup defined in JSP file.
 * @param productData		An Array of JavaScript objects with the attributes: 
 * 							name (string), partNumber (string), attributeItems (Array)
 *							The object in the attributeItems array contains: name (string), value (string)
 * @return					A string with a sequence of option-tags. Example:
 *							<option value="60115753">black, 33x33 cm</option><option value="90115756">red, 33x33 cm</option>
 *							The attribute 'value' is the product number, the description is the attributes seperated by ', '
 */
function generateCartOptions(productData) {
    var retString = "";
    for(var i=0;i<productData.length;i++) {
    	retString += generateCartSingleOption(productData[i]);
    }
    return retString;
}


/**
 * Takes a Javascript object and generates a string with an option-tag.
 * Helper function to generateCartOptions.
 * @param productData		A JavaScript object with the attributes: 
 * 							name (string), partNumber (string), attributeItems (Array)
 *							The object in the attributeItems array contains: name (string), value (string)
 * @return					A string with an option-tag. Example:
 *							<option value="60115753">black, 33x33 cm</option>
 *							The attribute 'value' is the product number, the description is the attributes seperated by ', '
 */
function generateCartSingleOption(productDataItem) {
    var description = generateCartOptionDescription(productDataItem.attributeItems);
    var retString = "    <option value=\""+productDataItem.partNumber+"\">"+description+"</option>\n";
    return retString;
}


/**
 * Takes an Array of generateCartSingleOption objects and generates a string with a sequence of comma-seperated attributes
 * Helper function to generateCartOptions.
 * @param productData		A JavaScript object with the attributes: 
 * 							name (string), value (string)
 * @return					A string with comma-seperated attributes. Example: "black, 33x33 cm"
 */
function generateCartOptionDescription(optionSet) {
    var retString = "";
    for(var i=0;i<optionSet.length;i++) {
        retString += optionSet[i].value;
        if(i<optionSet.length-1) {
            retString += ", ";
        }
    }
    return retString;
}
