/**
 * Class for the Product page that shows the product's accessories.
 */
var AccessoryProduct = Class.create();
AccessoryProduct.prototype = {
	// Constructor.
	initialize: function() {
	},
	
	// On-load setup.
	onLoad: function() {
		common.log("onLoad");
		var accessoriesDiv = $("acc_product_accessories");
		
		// Add "redirect=true" parameter to all links inside the accessory DIVs.
		// The redirect parameter causes the overview.jsp to redirect to a bare URL with just
		// the proper state (after the #), so that the JSP does not retrieve anything.
		var links = accessoriesDiv.getElementsByTagName("A");
		for( var i = 0; i < links.length; ++i ) {
			var link = links[i];
			if (link.href.indexOf("redirect=") == -1) {
				link.href += "&redirect=true";
			}
		}
		
		// Add "redirect=true" parameter to the view all accessories link.
		var viewAll = $("viewAllAccessories");
		if (viewAll) {
			if (viewAll.href.indexOf("redirect=") == -1) {
				viewAll.href += "&redirect=true";
			}
		}

		// Wire up wish list links.
		$("product_view_wishlist").onclick = this.viewWishList.bind(this);
		var aboutLink = $("product_help_wishlist");
		if (aboutLink) {
			aboutLink.onclick = this.aboutWishList.bind(this);
		}
		
		// Wire up "Add to wish list" links.
		var divs = accessoriesDiv.getElementsByTagName("DIV");
		for( var i = 0; i < divs.length; ++i ) {
			// Variation count and first part code is stored in the "name" attribute of the DIV.
			var div = divs[i];
			var divName = div.getAttribute("name");
			if (divName == null || divName.length == 0) {
				continue;
			}
			
			// Create accessory object from DIV information generated by JSP.
			var accessory = {};
			accessory.id = parseInt(div.id.substring(5));
			accessory.variationCount = 0;
			accessory.variationPartCodes = [];
			div.accessory = accessory;
			
			// Get main part code from the encoded name in case variation count > 1.
			var endMain = divName.indexOf(";");
			accessory.partCode = divName.substring(0, endMain);
			
			divName = divName.substring(endMain + 1);
			var colon = divName.indexOf(":");
			if (colon != -1) {
				accessory.variationCount = parseInt(divName.substring(0, colon));
				accessory.variationPartCodes = divName.substring(colon + 1).split(";");
			}
			
			// Second link is the Add wish list link.
			var links = div.getElementsByTagName("A");
			var wishListLink = links[1];
			wishListLink.onclick = this.addToWishList.bind(this, accessory.id);
			wishListLink.href = "#";
		}
		
		this.inOnLoad = true;
		try {
			// Initialize history manager; calls the listener already.
			Util.initializeHistory();
			Util.setHistoryListener(this.onChangeHistory.bind(this));
		
			// Refresh wish list links by retrieving wish list from server.
			this.wishListChanged();
		} finally {
			this.inOnLoad = false;
		}
	},

	// Called when user presses the Back or Forward button.
	onChangeHistory: function(newLocation) {
		common.log("History changed: " + newLocation);
		if (!this.inOnLoad) {
			this.wishListChanged();
		}
	},
	
	// Retrieve the results accessory DIV for the given accessory ID.
	getAccessoryDiv: function(accessoryId) {
		return $("div-A" + accessoryId);
	},
	
	// Invoked by the "View wish list" button to show the current wish list.
	viewWishList: function() {
		var link = $("product_view_wishlist").href;
		Util.showPopup(link, "viewWishList", {center: true, width: 431, height: 585, scrollbars: true, closeOnEscape: true});
		return false;
	},

	// Invoked by the "What's wish list" button to show an explanation of the wish list.
	aboutWishList: function() {
		var aboutLink = $("product_help_wishlist");
		if (aboutLink) {
			var link = aboutLink.href;
			Util.showPopup(link, "helpWishList", {center: true, width: 431, height: 400, scrollbars: true, closeOnEscape: true});
		}
		return false;
	},
	
	// Check if the accessory with given part code is in the wish list.
	isInWishList: function(accessory) {
		// Check variations of accessory; if any of them in wish list, return true.
		var partCodes = accessory.variationPartCodes;
		for( var i = 0; i < partCodes.length; ++i ) {
			if (common.isInClientWishList(partCodes[i])) {
				return true;
			}
		}
		return false;
	},
	
	// Invoked when returning to this page via the Back button.
	wishListChanged: function() {
		common.retrieveWishList(this.handleWishListAfterRetrieve.bind(this));
	},
	
	// To be called by external windows (e.g. the wish list popup) to refresh
	// the accessories overview according to the current wish list. The
	// readyCallback is an optional function that is called after the new
	// wish list has been retrieved and processed. Used in wishlist.jsp to
	// finally close the popup window. This cannot be done directly since
	// then the remote DWR call fails if the calling window is already closed.
	wishListChangedExtern: function(readyCallback) {
		common.retrieveWishListSynch(this.handleWishListAfterRetrieve.bind(this, readyCallback));
	},
	
	// Process the retrieved wish list.
	handleWishListAfterRetrieve: function(readyCallback) {
		common.log("Retrieved wish list from server...");
		var results = $("acc_product_accessories");
		var accessoryDivs = results.getElementsByTagName("DIV");
		for( var i = 0; i < accessoryDivs.length; ++i ) {
			var div = accessoryDivs[i];
			var accessory = div.accessory;
			if (accessory != null) {
				common.log(" - updating wish list link for accessory: " + accessory.id);
				this.showAddWishList(accessory.id, !this.isInWishList(accessory), true);
			}
		}
		
		if (readyCallback != null) {
			readyCallback();
		}
	},
	
	// Invoked when the "Add to wish list" button is clicked.
	addToWishList: function(accessoryId) {
		if (!common.cookieCheck()) {
			return false;
		}
		
		var div = this.getAccessoryDiv(accessoryId);
		if (div != null && div.accessory != null) {
			var accessory = div.accessory;
			common.log("Adding: " + accessoryId + ", variations: " + accessory.variationCount + ", part code: " + accessory.partCode);
			if (accessory.variationCount == 1) {
				// No variations, we can added the first variant part code part code directly.
				var varPartCode = accessory.variationPartCodes[0];
				AccessoryService.addToWishList(varPartCode, Config.countryCode, Config.languageCode,
											   this.handleAddToWishList.bind(this, accessory, varPartCode));
				
			} else if (accessory.variationCount > 1) {
				// Open the details view to let the user choose which variation to add to the wish list.
				window.location.href = Config["overview.jsp"] +
					"?productCode=" + encodeURIComponent(this.currentProductCode) +
					"&accessoryCode=" + encodeURIComponent(accessory.partCode) +
					"&redirect=true&showbackbutton=true";
			}
		}
		return false;
	},
	
	// Callback for DWR request AccessoryService.addToWishList() above.
	handleAddToWishList: function(accessory, varPartCode, added) {
		common.log("Added: " + accessory.id + ", variations: " + 1 + ", part code: " + varPartCode + " added: " + added);
		if (added) {
			// Add partcode to local wish list.
			common.addToClientWishList(varPartCode);

			// Replace "Add to wish list" link.
			this.showAddWishList(accessory.id, false);
		}
	},
	
	// Invoked by the "Remove from wish list" button.
	removeFromWishList: function(accessoryId) {
		if (!common.cookieCheck()) {
			return false;
		}
		
		var div = this.getAccessoryDiv(accessoryId);
		if (div != null && div.accessory != 0) {
			var accessory = div.accessory;
			AccessoryService.removeFromWishList(accessory.variationPartCodes, Config.countryCode, Config.languageCode,
												this.handleRemoveFromWishList.bind(this, accessory));
		}
		
		return false;
	},
	
	// Callback for DWR request AccessoryService.removeFromWishList() above.
	handleRemoveFromWishList: function(accessory, removed) {
		if (removed) {
			// Remove all accessories from local wish list.
			for( var i = 0; i < accessory.variationPartCodes.length; ++i ) {
				var partCode = accessory.variationPartCodes[i];
				common.removeFromClientWishList(partCode);
			}
			
			// Replace "Add to wish list" link.
			this.showAddWishList(accessory.id, true);
		}
	},
	
	// Show "Add to wish list" or "In wish list" for the selected accessory.
	showAddWishList: function(accessoryId, showAdd, highlight) {
		// Replace "Add to wish list" link.
		var div = this.getAccessoryDiv(accessoryId);
		if (div != null && div.accessory.variationCount > 0) {
			// Find second link, that is the wish list button.
			var links = div.getElementsByTagName("A");
			
			// Retrieve elements to change.
			var wishListLink = links[1];
			var img = wishListLink.getElementsByTagName("IMG")[0];
			var span = wishListLink.getElementsByTagName("SPAN")[0];
			var changed = (showAdd && String(img.src).indexOf(Config["addWishList.gif"]) == -1) ||
						  (!showAdd && String(img.src).indexOf(Config["addWishList.gif"]) != -1);
			if (changed) {
				if (highlight && span != null) {
					Effects.highlight(span);
				}
				
				if (showAdd) {
					wishListLink.onclick = this.addToWishList.bind(this, accessoryId);
					wishListLink.title = "";
					wishListLink.href = "#";
					
					img.src = Config["addWishList.gif"];
					if (span != null) {
						span.innerHTML = Messages["common.addWishList"];
					}
				} else {
					if (common.enableRemoveFromWishList) {
						wishListLink.onclick = this.removeFromWishList.bind(this, accessoryId);
						wishListLink.href = "#";
					} else {
						wishListLink.onclick = common.ignoreClickHandler;
						wishListLink.removeAttribute("href");
					}
					img.src = Config["inWishList.gif"];
					
					if (common.enableRemoveFromWishList) {
						wishListLink.title = Messages["common.removeWishList"];
						if (span != null) {
							span.innerHTML = Messages["common.removeWishListShort"];
						}
					} else {
						wishListLink.title = "";
						if (span != null) {
							span.innerHTML = Messages["common.inWishList"];
						}
					}
				}
			}
		}
	}
}

// Create page class and initialize page when done loading.
var page = new AccessoryProduct();
Event.observe(window, "load", page.onLoad.bind(page));