Zapatec Suite

amazon.js

Summary

Zapatec Amazon Shop application

 Copyright (c) 2004-2009 by Zapatec, Inc.
 http://www.zapatec.com
 1700 MLK Way, Berkeley, California,
 94709, U.S.A.
 All rights reserved.
 



Class Summary
Zapatec.Shop  

// $Id: amazon.js 15736 2009-02-06 15:29:25Z nikolai $
/**
 * @fileoverview Zapatec Amazon Shop application
 *
 * <pre>
 * Copyright (c) 2004-2009 by Zapatec, Inc.
 * http://www.zapatec.com
 * 1700 MLK Way, Berkeley, California,
 * 94709, U.S.A.
 * All rights reserved.
 * </pre>
 */

/**
 * Namespace definition.
 * @constructor
 */
Zapatec.Shop = function() {
	//Globals
	this.objSearchInput = null;
	this.objSearchIndex = null;
	this.objContainer = null;
	this.itemGrid = null;
	this.cartGrid = null;
	this.totalResults = 0;
	// Cart unique identifiers
	this.cartId = null;
	this.cartHmac = null;
	this.cartWin = null;
};

Zapatec.Shop.NO_IMAGE_URL = 'images/no-img-small.gif';
Zapatec.Shop.NO_IMAGE_BIG_URL = 'http://ec3.images-amazon.com/images/G/01/nav2/dp/no-image-avail-img-map.gif';
// URLs for the review rating star system
Zapatec.Shop.STARS_URL = new Array();
Zapatec.Shop.STARS_URL[0] = "images/stars/stars-0-0.gif";
Zapatec.Shop.STARS_URL[5] = "images/stars/stars-0-5.gif";
Zapatec.Shop.STARS_URL[10] = "images/stars/stars-1-0.gif";
Zapatec.Shop.STARS_URL[15] = "images/stars/stars-1-5.gif";
Zapatec.Shop.STARS_URL[20] = "images/stars/stars-2-0.gif";
Zapatec.Shop.STARS_URL[25] = "images/stars/stars-2-5.gif";
Zapatec.Shop.STARS_URL[30] = "images/stars/stars-3-0.gif";
Zapatec.Shop.STARS_URL[35] = "images/stars/stars-3-5.gif";
Zapatec.Shop.STARS_URL[40] = "images/stars/stars-4-0.gif";
Zapatec.Shop.STARS_URL[45] = "images/stars/stars-4-5.gif";
Zapatec.Shop.STARS_URL[50] = "images/stars/stars-5-0.gif";
// A bounding rect dimensions for item images in details window
// Small search results grid images will not get bigger than this. Keeps aspect ratio.
Zapatec.Shop.MAX_SMALL_WIDTH = 50;
Zapatec.Shop.MAX_SMALL_HEIGHT = 75;
// A bounding rect dimensions for search grid item images in details window.
// Large detail window images will not get bigger than this. Keeps aspect ratio.
Zapatec.Shop.MAX_LARGE_WIDTH = 250;
Zapatec.Shop.MAX_LARGE_HEIGHT = 200;
// Show shopping cart anchor DOM reference
Zapatec.Shop.objShowCart = null;
// Last shoppring cart xml content
Zapatec.Shop.lastShoppingCartXml = null;
// Index of the last received page (in terms of the proxy, not grid)
Zapatec.Shop.lastResponsePageIndex = 1;
// Max count of consecutive search requests to send as a result of one search button click
Zapatec.Shop.maxSearchRequestCount = 10;
// Current count of background search requests done so far
Zapatec.Shop.searchRequestCount = 0;
//Maximun and Minimun price of resultSet
Zapatec.Shop.resultMaxPrice = null;
Zapatec.Shop.resultMinPrice = null;

/**
 * Set the Filters by Price Range
 *
 * @private
 * @param [min,max]
 */
Zapatec.Shop.FilterByPrice = function(minv,maxv){
	Zapatec.Shop.PriceSliderFilterLegend(minv,maxv);
	if(Zapatec.Shop.itemGrid){
		Zapatec.Shop.itemGrid.limitRange({
			column: 8,
			min: minv,
			max: maxv
		});
	}
}
Zapatec.Shop.PriceSliderFilterLegend = function(minv,maxv){
	myminv = parseInt(minv*100)/100;
	mymaxv = parseInt(maxv*100)/100;
	if(document.getElementById('price_slider_legend').childNodes.length==0){
		document.getElementById('price_slider_legend').appendChild(document.createTextNode(''));
	}
	document.getElementById('price_slider_legend').childNodes[0].nodeValue = '$'+myminv.toString()+'  to  '+'$'+mymaxv.toString();
}

/**
 * Set the Filters by Average Rating
 *
 * @private
 * @param [min,max]
 */
Zapatec.Shop.FilterByACR = function(minv,maxv){
	Zapatec.Shop.ACRSliderLegend(minv,maxv);
	if(Zapatec.Shop.itemGrid){
		Zapatec.Shop.itemGrid.limitRange({
			column: 12,
			min: minv,
			max: maxv
		});
	}
}
Zapatec.Shop.ACRSliderLegend = function(minv,maxv){
	if(document.getElementById('acr_slider_legend').childNodes.length==0){
		document.getElementById('acr_slider_legend').appendChild(document.createTextNode(''));
	}
	document.getElementById('acr_slider_legend').childNodes[0].nodeValue = minv.toString()+' stars  to  '+maxv.toString()+' stars';
}


/**
 * Gets called on initial page load
 */
window.onload = function() {
	// Focus search input textfield
	document.getElementById('AmazonSearchForm').onsubmit = function(){ return Zapatec.Shop.doSearch(); };
	document.getElementById('searchInput').focus();
	// Get search domain combobox
	objSearchInput = document.getElementById('searchInput');
	objSearchIndex = document.getElementById('searchIndex');
	objContainer = document.getElementById('searchOutput');
	Zapatec.Shop.objShowCart = document.getElementById('showCart');
	Zapatec.Shop.objShowCart.onclick = Zapatec.Shop.showShoppingCartWindow;
	// Warn the user if he tries to leave the page
	Zapatec.Utils.warnUnload('Your search and shopping results will be lost');
	//Slider Filters
	Zapatec.Shop.PriceSliderFilter = new Zapatec.Slider({
		parent : document.getElementById('price_slider'),
		range : [0,1],
		length : 100,
		orientation : 'H',
		dual : true,
		eventListeners: {
			newPosition : Zapatec.Shop.FilterByPrice
		}
    });
	Zapatec.Shop.ACRSliderFilter = new Zapatec.Slider({
		parent : document.getElementById('acr_slider'),
		range : [0,5],
		length : 100,
		orientation : 'H',
		dual : true,
		eventListeners: {
			newPosition : Zapatec.Shop.FilterByACR
		}
    });
	document.getElementById('dvControls').style.display = 'none';
}

/**
 * Gets called by the search results grid to display headers.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.searchCallbackHeader = function(objGrid) {
	var html = [];
	html.push('<div class="zpHeader">');
	html.push('<div class="zpSortingText">');
	html.push('Sort by: ');
	var arrFields = objGrid.getFields();
	for (var iCol = 1; iCol < arrFields.length; iCol++) {
		var objField = arrFields[iCol];
		if(objField.nosort){ continue; }
		html.push('<span class="zpHeaderColumn" style="');
		html.push(objGrid.getFieldStyle(objField));
		html.push('" onclick="');
		html.push(objGrid.getFieldOnclick(objField));
		html.push('">');
		html.push(objGrid.getFieldTitle(objField));
		html.push('</span>');
	}
	html.push('</div>');
	html.push('<div class="zpSearchCompare"><input type="button" value="Compare" onclick="Zapatec.Shop.compareSelectedItems()" /></div>');
	html.push('</div><br/>');
	objContainer.innerHTML = html.join('');
};

var CELL_INDEX_ID = 0;
var CELL_INDEX_IMAGE = 1;
var CELL_INDEX_TITLE = 2;
var CELL_INDEX_AUTHOR = 3;
var CELL_INDEX_BINDING = 4;
var CELL_INDEX_PUBLICATION_DATE = 5;
var CELL_INDEX_PUBLISHER = 6;
var CELL_INDEX_ISBN = 7;
var CELL_INDEX_LIST_PRICE = 8;
var CELL_INDEX_LIST_PRICEFORMATTED = 9;
var CELL_INDEX_AMAZON_OFFER_PRICE = 10;
var CELL_INDEX_LOWEST_USED_PRICE = 11;
var CELL_INDEX_ACR = 12;

/**
 * Gets called by the search results grid to display rows.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.searchCallbackRow = function(objGrid, objRow) {
	var output = '<div class="zpRow">';
	output += '<div class="zpRowData">';
	var arrCells = objGrid.getRowCells(objRow);
	var isNoListPrice = false;
	var isNoAmazonOfferPrice = false;
	var isNoLowestNewPrice = false;
	var isNoLowestUsedPrice = false;

	for(var iCol = 0; iCol < arrCells.length; iCol++){
		var itemHTML = '';
		var objCell = arrCells[iCol];
		var isUseAnchor = CELL_INDEX_TITLE == iCol || CELL_INDEX_IMAGE == iCol;
		if(isUseAnchor){
			var params = "'" + objRow.asin + "', '" + objRow.searchIndex + "'";
			itemHTML += '<a href="#" onclick="return Zapatec.Shop.onTitleClick(' + params + ');"';
		}else{
			itemHTML += '<span';
		}
		itemHTML += (objRow.cells[iCol].className) ? ' class="'+objRow.cells[iCol].className+'"' : '';
		itemHTML += '>';
	    var data = objGrid.getCellValueString(objCell);
	    if (CELL_INDEX_ID == iCol || CELL_INDEX_PUBLISHER == iCol || iCol == CELL_INDEX_LIST_PRICE) {  // If this is the ID column
	    	continue;
		}else if(CELL_INDEX_IMAGE == iCol ){  // If this is the image
			var imgUrl = data;
			var imgHtml = Zapatec.Shop.getFitImageHtml(imgUrl,objRow.smallWidth, objRow.smallHeight,Zapatec.Shop.MAX_SMALL_WIDTH, Zapatec.Shop.MAX_SMALL_HEIGHT,'zpSearchImage');
			itemHTML += imgHtml;
		}else if (iCol == CELL_INDEX_AUTHOR){	// If this is the author
			if("null" != data){ itemHTML += " by "+data; }
		}else if (iCol == CELL_INDEX_ISBN){	// If this is the ISBN
			continue;
		}else if(iCol == CELL_INDEX_BINDING){	// If this is the binding
			var bindingAndDate = "";
			if ("null" != data) {
				bindingAndDate += '<span class="zpBindingAndDate">(';
				bindingAndDate += '<span class="zpBinding">' + data + "</span>";
				var objPublicationDateCell = arrCells[iCol+1];
				var publicationDateData = objGrid.getCellValueString(objPublicationDateCell);
				if("null" != publicationDateData){ bindingAndDate += " - "+publicationDateData; }
				bindingAndDate += ')</span>';
				itemHTML += bindingAndDate;
			}
		}else if(iCol == CELL_INDEX_PUBLICATION_DATE){	// If this is the publication date
			continue;
		}else if(iCol == CELL_INDEX_LOWEST_USED_PRICE){	// If this is the Lowest Used Price
			if ("null" != data && "undefined" != data) {
				itemHTML += "Used: "+data;
			}else{
				isNoLowestUsedPrice = true;
				if(isNoAmazonOfferPrice){ itemHTML += "Currently unavailable<br/>"; }
			}
		}else if(iCol == CELL_INDEX_AMAZON_OFFER_PRICE){	// If this is the Lowest New Price
			if("null" != data && "undefined" != data){ itemHTML += data; }
			else{ isNoAmazonOfferPrice = true; }
		}else if(iCol == CELL_INDEX_LIST_PRICEFORMATTED){	// If this is the List Price
			if ("null" != data && "undefined" != data) { itemHTML += data; }
			else{ isNoListPrice = true; }
		}else if(iCol == CELL_INDEX_ACR){
		    var indexStars = parseInt(parseFloat(data)*10);
		    itemHTML += Zapatec.Shop.getFitImageHtml(Zapatec.Shop.STARS_URL[indexStars],64,12,64,12,'zpStars');
		}else{	// If this is the title or other info
			if("null" != data && "undefined" != data){ itemHTML += data; }
		}
		itemHTML += (isUseAnchor===true) ? '</a>': '</span>';
		if ("null" != data) {
			if (iCol == CELL_INDEX_PUBLISHER || iCol == CELL_INDEX_ISBN || iCol == CELL_INDEX_AMAZON_OFFER_PRICE || iCol == CELL_INDEX_BINDING) {
				itemHTML += '<br/>';
			}
		}
		output += itemHTML;
	}
	output += '</div>';
	output += '<div class="zpRowCompare"><input type="checkbox" onclick="Zapatec.Shop.selectToCompare.call(this,['+objGrid.getRowId(objRow)+'])" class="zpSearchCompareCheckbox" /></div>';
	output += '</div>';
	output += '<div class="clearer"></div>';
	output += '<br/>';
	objContainer.innerHTML = objContainer.innerHTML + output;
};

/**
 * Comparison
 *
 */
Zapatec.Shop.oGridCompareConfig = {
	source: {
		fields: [
			{hidden: true},
			{title: "Image", style:'font-weight:bold;'},
			{title: "Title", style:'font-weight:bold;'},
			{title: "Author", style:'font-weight:bold;'},
			{title: "Binding", style:'font-weight:bold;'},
			{title: "PublicationDate", style:'font-weight:bold;'},
			{hidden: true},
			{title: "ISBN", style:'font-weight:bold;'},
			{hidden: true}, //Unformatted Price
			{title: "List Price", style:'font-weight:bold;'},
			{title: "Lowest Price", style:'font-weight:bold;'},
			{title: "Lowest Used Price", style:'font-weight:bold;'},
			{title: "Average Customer Review", style:'font-weight:bold;'}
		]
	},
	sourceType: 'json',
	horizontal: true,   // Use horizontal layout
	fixedLeft: 1,   // Mark first row
	theme: 'winxp', // Use "winxp" theme
	headerContainer: 'gridCompareHeaderContainer',  // Put grid header into separate div
	container: 'gridCompareDataContainer',  // Put grid data into separate div
	selectCells: false, // Do not mark selected cells with different color
	selectRows: false,  // Do not mark selected rows with different color
	activeCells: false, // Do not mark active cells with different color
	activeRows: false,  // Do not mark active rows with different color
	eventListeners: {
		gridModified: function(){
			if(Zapatec.Shop.oWinCompare) Zapatec.Shop.oWinCompare.show();
	        var rows = this.getRows(), imgCell = null, titleCell = null, linkTag = '';
	        for(var i=0;i<rows.length;i++){
       			var params = "'" + rows[i].asin + "', '" + rows[i].searchIndex + "'";
				linkTag += '<a href="#" onclick="return Zapatec.Shop.onTitleClick(' + params + ');">';
				//Image value to (image + link) tag
				imgCell = this.getCellByRow(rows[i],1);
	            this.setCellValue(imgCell,linkTag+'<img src="'+this.getCellValue(imgCell)+'"></a>');
	            //Title value to link tag
				titleCell = this.getCellByRow(rows[i],2);
	            this.setCellValue(titleCell,linkTag+this.getCellValue(titleCell)+'"</a>');
	            //Sets title style
	            this.setCellStyle(this.getCellByRow(rows[i],2),"background-color:#EAEBDB;");
	        }
			rows = null;
			cell = null;
		},
		gridRefreshed: function(){
			var oContent = document.getElementById('gridCompareContainer');
		    var oContainer = oContent.parentNode;
		    var oGridHeader = document.getElementById('gridCompareHeaderContainer');
		    var oGridData = document.getElementById('gridCompareDataContainer');
		    oContainer.style.overflow = 'hidden';
		    var oOffset = Zapatec.Utils.getElementOffset(oContainer);
		    var iHeight = oOffset.height - oGridHeader.offsetHeight;
		    var iWidth = oOffset.width;
		    oGridData.style.height = iHeight + 'px';
		    oGridData.style.width = iWidth + 'px';
		    oGridHeader.style.width = oGridData.clientWidth + 'px';
		    var oDims = this.getGridDimensions();
			if(oDims.width && oDims.height){
				oGridData.style.overflow = 'scroll';
				oGridData.style.overflowX = (oDims.width < iWidth) ? 'hidden' : 'scroll';
				oGridData.style.overflowY = (oDims.height < iHeight) ? 'hidden' : 'scroll';
		    }else{
		      oGridData.style.overflow = 'scroll';
		      oGridData.style.overflowX = 'scroll';
		      oGridData.style.overflowY = 'scroll';
		    }
		}
	}
}


Zapatec.Shop.oWinCompare = Zapatec.Window.setup({
	// Window dimensions and position
	width: 470,
	height: 470,
	left: 200,
	top: 100,
	divContent: 'gridCompareContainer',
	title: 'Compare Selected Rows', // Window title
	initialState: 'hidden', // Initially hide
	hideOnClose: true,  // Do not destroy window on close
	fixed: true // Will be always visible
});

Zapatec.Shop.selectToCompare = function(rowId){
	var oRow = Zapatec.Shop.itemGrid.getRowById(rowId);
	if(this.checked)	Zapatec.Shop.itemGrid.selectRow(oRow);
	else	Zapatec.Shop.itemGrid.unselectRow(oRow);
}

Zapatec.Shop.compareSelectedItems = function(){
	if(Zapatec.Shop.itemGrid && Zapatec.Shop.itemGrid.getSelectedRows().length>1){
	    if(typeof(Zapatec.Shop.oGridCompare)==='undefined'){
      		Zapatec.Shop.oGridCompare = new Zapatec.Grid(Zapatec.Shop.oGridCompareConfig);
		}
    	Zapatec.Shop.itemGrid.editSelectedRows(Zapatec.Shop.oGridCompare);
	}else if(Zapatec.Shop.itemGrid.getSelectedRows().length<=1){
	    alert('You must choose 2 or more items to compare');
	}
	return;
}

/**
 * Gets called by the pagination slider to update the grid.
 *
 * @private
 * @param {object} iValue New page number
 */
Zapatec.Shop.onPaginationSliderMove = function(iValue) {
	Zapatec.Shop.itemGrid.gotoPage(Math.ceil(iValue));
};

/**
 * Gets called by the search results grid to display pagination.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.searchCallbackPagination = function(objGrid) {
	// Get number of pages
	var iPages = Zapatec.Shop.itemGrid.totalPages();
	if(iPages < 2){
		document.getElementById('zpShopGridPagination').style.display = 'none';
		return;
	}else{
		document.getElementById('zpShopGridPagination').style.display = '';
	}
	// Gat current page
	var iCurrentPage = Zapatec.Shop.itemGrid.getCurrentPageNumber();
	// Print current page number
	document.getElementById('zpShopGridPaginationContainer').innerHTML = 'Page ' + iCurrentPage + ' of ' + iPages + ' : ';
	// Reset slider
	if (Zapatec.Shop.paginationSlider) {
		// Need to reset slider only after filtering or searching
		var aSliderRange = Zapatec.Shop.paginationSlider.config.range;
		if (!(aSliderRange instanceof Array) || aSliderRange[1] != iPages - 1) {
			Zapatec.Shop.paginationSlider.setRange(0, iPages - 1);
		}
		// Correct slider position when page was changed programmatically
		var iSliderPos = Zapatec.Shop.paginationSlider.getPos().first;
		if(!isNaN(iSliderPos)){
			iCurrentPage--;
			if(iCurrentPage != iSliderPos){
				Zapatec.Shop.paginationSlider.setPos(iCurrentPage);
			}
		}
	}else{
		// Initialize slider
		Zapatec.Shop.paginationSlider = new Zapatec.Slider({
	        div: 'zpShopGridPaginationSlider',
			length: 99,
			orientation: 'H',
			step: 1,
			range: [0, iPages - 1],
			newPosition: Zapatec.Shop.onPaginationSliderMove
		});
	}

	// Get number of results per page
	var aSelectd = ['', '', '', ''];
	var oConfig = Zapatec.Shop.itemGrid.getConfiguration();
	if(oConfig.rowsPerPage == 5){
		aSelectd[0] = ' selected';
	}else if(oConfig.rowsPerPage == 15) {
		aSelectd[2] = ' selected';
	}else if(oConfig.rowsPerPage == 20) {
		aSelectd[3] = ' selected';
	}else{    // Default is 10
 		aSelectd[1] = ' selected';
	}

	// Print number of results per page
	document.getElementById('zpShopGridPaginationPerPage').innerHTML =
	'<select onclick="Zapatec.Shop.setResultsPerPage(\
	this[this.selectedIndex].value)">\
	<option value="5"' + aSelectd[0] + '>5</option>\
	<option value="10"' + aSelectd[1] + '>10</option>\
	<option value="15"' + aSelectd[2] + '>15</option>\
	<option value="20"' + aSelectd[3] + '>20</option>\
	</select>';
};

/**
 * Changes number of results per page.
 *
 * @private
 * @param {number} iRowsPerPage Number of results per page
 */
Zapatec.Shop.setResultsPerPage = function(iRowsPerPage) {
	// Check argument
	var oConfig = Zapatec.Shop.itemGrid.getConfiguration();
	if (oConfig.rowsPerPage == iRowsPerPage) { return; }
	// Reconfigure grid
	Zapatec.Shop.itemGrid.reconfigure({
		rowsPerPage: iRowsPerPage
	});
	// Go to first page
	Zapatec.Shop.itemGrid.gotoPage(0);
};

/**
 * Goes to the next page.
 *
 * @param {number} iGridId Id of the grid
 */
Zapatec.Shop.next = function(iGridId) {
	Zapatec.Grid.nextPage(iGridId);
	this.showResults(this.totalResults,this.itemGrid.currentPage,this.itemGrid.config.rowsPerPage);
}

/**
 * Goes to the previous page.
 *
 * @param {number} iGridId Id of the grid
 */
Zapatec.Shop.previous = function(iGridId) {
	Zapatec.Grid.previousPage(iGridId);
	this.showResults(this.totalResults,this.itemGrid.currentPage,this.itemGrid.config.rowsPerPage);
}

/**
 * Create and populate the search results item grid
 *
 * @private
 * @param {object} objXmlSource parsed xml response for an Item operation
 */
Zapatec.Shop.createItemGrid = function(objXmlSource) {
	var objJsonGrid = [];
	var rowsPerPage = 0;
	if(objXmlSource) { // Convert xml response to something the grid will understand
		objJsonGrid = this.convertResultsXmlToGrid(objXmlSource);
		rowsPerPage = objXmlSource.rowsPerPage;
		//GRID
		//And now display the grid
		Zapatec.Shop.itemGrid = new Zapatec.Grid({	// Use object as source
			source: objJsonGrid,
			sourceType: 'json',
			// Use searchCallbackHeader function to display grid header
			callbackHeaderDisplay: Zapatec.Shop.searchCallbackHeader,
			// Use searchCallbackRow function to display grid row
			callbackRowDisplay: Zapatec.Shop.searchCallbackRow,
			// Use searchCallbackPagination function to display grid pagination
			callbackPaginationDisplay: Zapatec.Shop.searchCallbackPagination,
			theme: "winxp",
			// Use paging, display rows per page given by the proxy
			rowsPerPage: rowsPerPage
		});
		document.getElementById('dvControls').style.display = 'block';
	}
}

/**
 * Shows/Hides the loading animation
 *
 * @private
 * @param {boolean} isVisible if true the animation is to be shown,
 * false otherwise
 */
Zapatec.Shop.showLoadingMark = function(isVisible) {
	document.getElementById('loading').style.display = (isVisible===true) ? 'inline' : 'none';
}

/**
 * Shows the shopping cart window
 *
 * @private
 */
Zapatec.Shop.showShoppingCartWindow = function() {
	// Hide "Show Cart" anchor
 	Zapatec.Shop.objShowCart.style.display = "none";
	// If a cart window does not exist
	if(this.cartWin===null || typeof(this.cartWin)=='undefined'){
		// Create a new zapatec shopping cart window
		Zapatec.Shop.cartWin = Zapatec.Shop.createWindow(true,function(win){
	        Zapatec.Shop.cartWin = null;
	        // Show "Show Cart" anchor
	        Zapatec.Shop.objShowCart.style.display = "inline";
	    });
		Zapatec.Shop.cartWin.setTitle('Shopping Cart');
	}
	if (Zapatec.Shop.lastShoppingCartXml!==null){   // Show last cart contents xml in window
		Zapatec.Shop.showCartContent(Zapatec.Shop.lastShoppingCartXml);
	}
	return false;
}

/**
 * Returns the selected search domain option
 * (e.g. Books, Music or PCHardware, Blended)
 *
 * @private
 */
Zapatec.Shop.getSearchDomain = function(page) {
	// Get selected search combobox item
	var searchIndex = objSearchIndex.selectedIndex;
	switch(objSearchIndex.selectedIndex){   // Convert combobox item to amazon SearchIndex parameter
		case 0: return 'Books'; break;
		case 1: return 'Music'; break;
		case 2: return 'PCHardware'; break;
		case 3: return 'Blended'; break;
	}
	return 'Books';
}

/**
 * Returns the amazon proxy request URL based on the keywords text input field
 * and the search domain option selected
 *
 * @private
 */
Zapatec.Shop.getSearchUrl = function(page) {
	var searchIndex = Zapatec.Shop.getSearchDomain();
	// Create amazon AWS request URL
	var url = 'proxy.php?Keywords=' + objSearchInput.value + '&SearchIndex=' + searchIndex;
    return !isNaN(page) ? url+'&Page='+page : url;
}

/**
 * Makes an AJAX request to proxy.php using the entered keywords and selected
  domain. Called from the form submit button.
 *
 * @private
 */
Zapatec.Shop.doSearch = function() {
	//reset all
	Zapatec.Shop.resultMaxPrice = null;
	Zapatec.Shop.resultMinPrice = null;
	Zapatec.Shop.PriceSliderFilterLegend(0,1);
	Zapatec.Shop.ACRSliderLegend(0,5);
	Zapatec.Shop.PriceSliderFilter.reset(0,1);
	Zapatec.Shop.ACRSliderFilter.reset(0,5);
	document.getElementById('dvControls').style.display = 'none';

	Zapatec.Shop.searchRequestCount = 1;
	Zapatec.Shop.fetchSearch(1);    // Fetch first search page
	return false;
};

/**
 * Makes an AJAX reques to proxy.php using the entered keywords and selected
  domain. Called from the form submit button.
 *
 * @private
 */
Zapatec.Shop.fetchSearch = function(page) {
	this.showLoadingMark(true);
	// If this is not the first page
	if(1 == page){ Zapatec.Shop.createItemGrid(); } // Create an empty search results grid
	var url = Zapatec.Shop.getSearchUrl(page);
	// Fetch HTML fragment
	Zapatec.Transport.fetchXmlDoc({
		// URL to fetch
		url: url,
		// Onload event handler
		onLoad: function(objXmlDoc) {
			// Parse xml response
			var objXmlSource = Zapatec.Shop.parseItemXmlResponse(objXmlDoc, false);
			// If this is not the first page
			if(1 < page){
				// Convert xml response to something the grid will understand
				var objJsonGridData = Zapatec.Shop.convertResultsXmlToGrid(objXmlSource);
				// Get current page number
				var pageNumber = Zapatec.Shop.itemGrid.getCurrentPageNumber();
				// Merge rows into grid
				Zapatec.Shop.itemGrid.splice({
					rows: objJsonGridData.rows
				});
				// Restore to previous page number
				Zapatec.Shop.itemGrid.setCurrentPage(pageNumber -1);
			}else{
				// Create a new search results grid and fill it
				Zapatec.Shop.createItemGrid(objXmlSource);
			}
			// If there are more search requests to be sent in background
			if(Zapatec.Shop.searchRequestCount < Zapatec.Shop.maxSearchRequestCount){
				Zapatec.Shop.searchRequestCount++;
				// Schedule Make  a search request to our amazon proxy  Play nice with amazon. It requires at least one second timeout between requests
				setTimeout(function(){ Zapatec.Shop.fetchSearch(page +1); },1000);
				//Update price filter for each resultset loaded
				if(Zapatec.Shop.resultMinPrice!==null && Zapatec.Shop.resultMaxPrice!==null){
					Zapatec.Shop.PriceSliderFilter.reset(Zapatec.Shop.resultMinPrice,Zapatec.Shop.resultMaxPrice);
					Zapatec.Shop.PriceSliderFilterLegend(Zapatec.Shop.resultMinPrice,Zapatec.Shop.resultMaxPrice);
				}else{
					document.getElementById('price_filter').style.display = 'none';
				}
			}
		}
	});
}

/**
 * Shows total search results count and current view range
 *
 * @private
 * @param {number} totalResults count of all search results for this keyword
 * @param {number} currentPage page index we are seeing from all search results
 * @param {number} rowsPerPage number of search results per page
 */
Zapatec.Shop.showResults = function(totalResults, currentPage, rowsPerPage ) {
	//First display somethine like "Results 1 - 10 of about 225073"
	var strTotalResults = totalResults;
	var strFirstResPos = currentPage*rowsPerPage +1;
	var iLastResPos = strFirstResPos * 1 + rowsPerPage * 1 - 1;
	document.getElementById('results').innerHTML = 'Results ' + strFirstResPos + ' - ' + iLastResPos +' of about ' + strTotalResults;
}

/**
 * Converts a parsed xml response for a ItemSearch or ItemLookup operation to
 * something that the search results grid will understand
 *
 * @private
 * @param {array} objXmlSource parsed xml response from the proxy
 */
Zapatec.Shop.convertResultsXmlToGrid = function(objXmlSource) {
	//Structure of the output(grid) object
	var objJsonGrid = {
		fields: [
			{hidden: true},
			{title: "Image", dataType: "string", nosort: true},
			{title: "Title", dataType: "string", className: "zpTitle"},
			{title: "Author", dataType: "string", className: "zpAuthor"},
			{title: "Binding", dataType: "string", className: "zpBinding"},
			{title: "PublicationDate", dataType: "string"},
			{hidden: true},
			{title: "ISBN", dataType: "string", className: "zpIsbn"},
			{hidden: true}, //Unformatted Price
			{title: "List Price", dataType: "string", className: "zpListPrice"},
			{title: "Lowest Price", dataType: "string"},
			{title: "Lowest Used Price", dataType: "string"},
			{title: "Average Customer Review", dataType: "string"}  //ACR Index
		],
		rows: []
	};

	var rowId = objXmlSource.itemPage * objXmlSource.rowsPerPage;
	// Iterate all parsed response items
	for (var index = 0; index < objXmlSource.length; ++index) {
		var item = objXmlSource[index];
		var imgUrl = item.smallImageUrl;
		if (!imgUrl){ imgUrl = Zapatec.Shop.NO_IMAGE_URL; }
		// Determine "by ...." part in the row
		var byString = null;
		if (item.authors) {
			var author = null;
			// Enumerate all authors for this item
			for (var iAuthor = 0; iAuthor < item.authors.length; ++iAuthor) {
				var currentAuthor = item.authors[iAuthor];
				if(null == author){ author = currentAuthor; }
				else{ author += " and " + currentAuthor; }
			}
			byString = author;
		}else if(item.manufacturer){
			byString = item.manufacturer;
		}
		// Get binding
		var binding = null;
		if(item.binding){ binding = item.binding; }
		// Get publication date
		var publicationDate = null;
		if(item.publicationDate){ publicationDate = item.publicationDate; }

		// Determine publisher part in the row
		var publisher = null;
		if (item.publisher) {
			publisher = item.publisher;
		}else if (item.manufacturer) {
			publisher = item.manufacturer;
		}
		// Determine the new Price after offers
		var newPrice = null;
		if (item.offers && 0 < item.offers.length) {
			if (-1 != item.offers[0].merchantName.indexOf('Amazon')) {
				newPrice = item.offers[0].price;
			}
		}
		
    // Add a row
	objJsonGrid.rows.push({
		cells:[
			{v: rowId},
			{v: imgUrl},
			{v: item.title, className: "zpTitle"},
			{v: byString, className: "zpAuthor"},
			{v: binding},
			{v: publicationDate},
			{v: publisher},
			{v: item.isbn, className: "zpIsbn"},
			{v: item.filterPrice },
			{v: item.listPrice, className: "zpListPrice"},
			{v: newPrice, className: "zpLowestPrice"},
			{v: item.lowestUsedPrice, className: "zpLowestUsedPrice"},
			{v: item.customerReviewsAverageRating }
		],
		asin: item.asin,
		offerId: item.offerId,
		searchIndex: objXmlSource.searchIndex,
		productGroup: item.productGroup,
		manufacturer: item.manufacturer,
		smallWidth: item.smallImageWidth,
		smallHeight: item.smallImageHeight
	});

    rowId++;
  }

  return objJsonGrid;
}

/**
 * Parse xml document returned as a ItemSearch/ItemLookup operation response
 * from the amazon proxy
 *
 * @private
 * @param {object} objXmlDoc received xml document
 * @param {boolean} isDetails if true an ItemLookup operation is to be parsed,
 * false - ItemSearch is being parsed
 */
Zapatec.Shop.parseItemXmlResponse = function(objXmlDoc, isDetails) {
	this.showLoadingMark(false);
	var arrItems = [];
	// Check fetched object
	if(objXmlDoc && objXmlDoc.documentElement){
		var items = objXmlDoc.documentElement.getElementsByTagName('Items');
		var responseKeywords = null;
		var itemPage = null;
		var responseSearchIndex = null;
		// Get total results that match search critetion
		var totalResults = items[0].getElementsByTagName('TotalResults');
		if(totalResults && totalResults.length){ this.totalResults = totalResults[0].firstChild.nodeValue; }
		// Get total results that match search critetion
		var requests = items[0].getElementsByTagName('Request');
		if (requests && requests.length){
			var searchRequests = requests[0].getElementsByTagName('ItemSearchRequest');
				if (searchRequests && searchRequests.length) {
					var itemPages = searchRequests[0].getElementsByTagName('ItemPage');
					if (itemPages && itemPages.length) {
						itemPage = itemPages[0].firstChild.nodeValue;
					}
					// Get keyowrds that this response is for
					var keywords = searchRequests[0].getElementsByTagName('Keywords');
					if (keywords && keywords.length) {
						responseKeywords = keywords[0].firstChild.nodeValue;
					}
					// Get search index that this response is for
					var searchIndexes = searchRequests[0].getElementsByTagName('SearchIndex');
					if (searchIndexes && searchIndexes.length) {
						responseSearchIndex = searchIndexes[0].firstChild.nodeValue;
					}
				}
		}
		// Get response page (in 10 items per page)
		//var currentPage = objXmlDoc.documentElement.getAttribute('currentPage');
		// todo: change configuration
		// Get rows per page provided from server
		var rowsPerPage = 10;//objXmlDoc.documentElement.getAttribute('rowsPerPage');
		if (null != rowsPerPage && "" != rowsPerPage) {
			arrItems.rowsPerPage = parseInt(rowsPerPage);
		}
		// Store global response details in arrItems object
		arrItems.totalRows = parseInt(this.totalResults);
		arrItems.displayedRows = parseInt(this.totalResults);
		arrItems.itemPage = parseInt(itemPage)-1;
		arrItems.keywords = responseKeywords;
		arrItems.searchIndex = responseSearchIndex;
		// Remember what page index the proxy returned
		Zapatec.Shop.lastResponsePageIndex = arrItems.itemPage+1;
		// Parse XML document object
		var arrItem = items[0].getElementsByTagName('Item');
		if (false == isDetails && 1 == itemPage) {
			// display somethine like "Results 1 - 10 of about 225073"
			this.showResults(this.totalResults, arrItems.itemPage, arrItems.rowsPerPage);
		}
		if (arrItem && arrItem.length) {
			for (var iItem = 0; iItem < arrItem.length; iItem++) {
				var item = arrItem[iItem];
				var objItem = {};
				// Get search index that this response is for
				var asins = item.getElementsByTagName('ASIN');
				if (asins && asins.length) {
					objItem.asin = asins[0].firstChild.nodeValue;
				}
				// Get small image for this item
				var smallImage = this.parseImageXmlResponse(item, 'SmallImage');
				objItem.smallImageUrl = smallImage.url;
				objItem.smallImageWidth = smallImage.width;
				objItem.smallImageHeight = smallImage.height;
				// Get medium image for this item
				var mediumImage = this.parseImageXmlResponse(item, 'MediumImage');
				objItem.mediumImageUrl = mediumImage.url;
				objItem.mediumImageWidth = mediumImage.width;
				objItem.mediumImageHeight = mediumImage.height;
				// Get large image for this item
				var largeImage = this.parseImageXmlResponse(item, 'LargeImage');
				objItem.largeImageUrl = largeImage.url;
				objItem.largeImageWidth = largeImage.width;
				objItem.largeImageHeight = largeImage.height;
				// Get item attributes
				var itemAttributes = item.getElementsByTagName('ItemAttributes');
				if (itemAttributes && itemAttributes.length) {
					// Get item title
					var titles = itemAttributes[0].getElementsByTagName('Title');
					if (titles && titles.length) {
						objItem.title = titles[0].firstChild.nodeValue;
					}
					// Get item binding
					var bindings = itemAttributes[0].getElementsByTagName('Binding');
					if (bindings && bindings.length) {
						objItem.binding = bindings[0].firstChild.nodeValue;
					}
					// Get item publication date
					var publicationDates = itemAttributes[0].getElementsByTagName('PublicationDate');
					if (publicationDates && publicationDates.length) {
						objItem.publicationDate = publicationDates[0].firstChild.nodeValue;
					}
					// Get item edition
					var editions = itemAttributes[0].getElementsByTagName('Edition');
					if (editions && editions.length) {
						objItem.edition = editions[0].firstChild.nodeValue;
					}
					// Get item number of pages
					var numberPages = itemAttributes[0].getElementsByTagName('NumberOfPages');
					if (numberPages && numberPages.length) {
						objItem.numberOfPages = numberPages[0].firstChild.nodeValue;
					}
					// Get item author
					var authors = itemAttributes[0].getElementsByTagName('Author');
					if (authors && authors.length) {
						objItem.authors = [];
						// Enumerate all authors
						for (var authorIndex = 0; authorIndex < authors.length; ++authorIndex) {
							var author = authors[authorIndex].firstChild.nodeValue;
							objItem.authors.push(author);
						}
					}
					// Get item publisher
					var publishers = itemAttributes[0].getElementsByTagName('Publisher');
					if (publishers && publishers.length) {
						objItem.publisher = publishers[0].firstChild.nodeValue;
					}
					// Get item manufacturer
					var manufacturers = itemAttributes[0].getElementsByTagName('Manufacturer');
					if (manufacturers && manufacturers.length) {
						objItem.manufacturer = manufacturers[0].firstChild.nodeValue;
					}
					// Get item product group
					var productGroups = itemAttributes[0].getElementsByTagName('ProductGroup');
					if (productGroups && productGroups.length) {
						objItem.productGroup = productGroups[0].firstChild.nodeValue;
					}
					// Get item ISBN
					var isbns = itemAttributes[0].getElementsByTagName('ISBN');
					if (isbns && isbns.length) {
					objItem.isbn = isbns[0].firstChild.nodeValue;
					}
					// Get item list price
					var listPrices = itemAttributes[0].getElementsByTagName('ListPrice');
					filterPrice = null;
					if (listPrices && listPrices.length) {
						var formated = listPrices[0].getElementsByTagName('FormattedPrice');
						if (formated && formated.length) {
							objItem.listPrice = formated[0].firstChild.nodeValue;
							filterPrice = parseFloat(objItem.listPrice.toString().slice(1));
						}
					}
					// Get item unformatted list price
					if(filterPrice!==null){
						objItem.filterPrice = filterPrice;
						Zapatec.Shop.resultMinPrice = (Zapatec.Shop.resultMinPrice===null) ? objItem.filterPrice : (Zapatec.Shop.resultMinPrice>objItem.filterPrice ? objItem.filterPrice : Zapatec.Shop.resultMinPrice);
						Zapatec.Shop.resultMaxPrice = (Zapatec.Shop.resultMaxPrice===null) ? objItem.filterPrice : (Zapatec.Shop.resultMaxPrice<objItem.filterPrice ? objItem.filterPrice : Zapatec.Shop.resultMaxPrice);
					}else{
						objItem.filterPrice = 0;
					}
					// Get item package dimensions
					var packageDimensions = itemAttributes[0].getElementsByTagName('PackageDimensions');
					if (packageDimensions && packageDimensions.length) {
						// Get package width
						var widths = packageDimensions[0].getElementsByTagName('Width');
						if (widths && widths.length) {
							objItem.packageWidth = widths[0].firstChild.nodeValue;
							// Get package width units
							objItem.packageWidthUnits = widths[0].getAttribute('Units');
						}
						// Get package height
						var heights = packageDimensions[0].getElementsByTagName('Height');
						if (heights && heights.length) {
							objItem.packageHeight = heights[0].firstChild.nodeValue;
							// Get package height units
							objItem.packageHeightUnits = heights[0].getAttribute('Units');
						}
						// Get package length
						var lengths = packageDimensions[0].getElementsByTagName('Length');
						if (lengths && lengths.length) {
							objItem.packageLength = lengths[0].firstChild.nodeValue;
							// Get package length units
							objItem.packageLengthUnits = lengths[0].getAttribute('Units');
						}

						// Get package weight
						var weights = packageDimensions[0].getElementsByTagName('Weight');
						if (weights && weights.length) {
							objItem.packageWeight = weights[0].firstChild.nodeValue;
							// Get package weight units
							objItem.packageWeightUnits = weights[0].getAttribute('Units');
						}
					}
				}//IF   ITEMATTRIBUTES
				// Get item offer summary
				var offerSummaries = item.getElementsByTagName('OfferSummary');
				if (offerSummaries && offerSummaries.length) {
					// Get lowest new price
					var lowestNewPrices = offerSummaries[0].getElementsByTagName('LowestNewPrice');
					if (lowestNewPrices && lowestNewPrices.length) {
						var formated = lowestNewPrices[0].getElementsByTagName('FormattedPrice');
						if (formated && formated.length) {
							objItem.lowestNewPrice = formated[0].firstChild.nodeValue;
						}
					}
				// Get lowest used price
					var lowestUsedPrices = offerSummaries[0].getElementsByTagName('LowestUsedPrice');
					if (lowestUsedPrices && lowestUsedPrices.length) {
						var formated = lowestUsedPrices[0].getElementsByTagName('FormattedPrice');
						if (formated && formated.length) {
							objItem.lowestUsedPrice = formated[0].firstChild.nodeValue;
						}
					}
				}

				arrItems.push(objItem);
				// Parse editorial reviews
				var editorialReviewsTag = item.getElementsByTagName('EditorialReviews');
				if (editorialReviewsTag && editorialReviewsTag.length) {
					var editorialReviews = editorialReviewsTag[0].getElementsByTagName('EditorialReview');
					if (editorialReviews && editorialReviews.length){
						var arrReviews = [];
						for (var iReview = 0; iReview < editorialReviews.length; iReview++) {
							var review = editorialReviews[iReview];
							var objReview = {};
							var source = review.getElementsByTagName('Source');
							if (source && source.length) {
								objReview.source = source[0].firstChild.nodeValue;
							}
							var content = review.getElementsByTagName('Content');
							if (content && content.length) {
								objReview.content = content[0].firstChild.nodeValue;
							}
							arrReviews.push(objReview);
						}
						objItem.editorialReviews = arrReviews;
					}
				}
				// Parse customer reviews
				objItem.customerReviewsAverageRating = 0;
				var customerReviewsTag = item.getElementsByTagName('CustomerReviews');
				if (customerReviewsTag && customerReviewsTag.length) {
					var average = customerReviewsTag[0].getElementsByTagName('AverageRating');
					if (average && average.length) {
						objItem.customerReviewsAverageRating = average[0].firstChild.nodeValue;
					}
					var reviews = customerReviewsTag[0].getElementsByTagName('Review');
					if (reviews && reviews.length) {
						var arrReviews = [];
						for (var iReview = 0; iReview < reviews.length; iReview++) {
							var review = reviews[iReview];
							var objReview = {};
							var summary = review.getElementsByTagName('Summary');
							if (summary && summary.length) {
								objReview.summary = summary[0].firstChild.nodeValue;
							}
						var content = review.getElementsByTagName('Content');
						if (content && content.length) {
							objReview.content = content[0].firstChild.nodeValue;
						}
						var rating = review.getElementsByTagName('Rating');
						if (rating && rating.length) {
							objReview.rating = rating[0].firstChild.nodeValue;
						}
						var helpfulVotes = review.getElementsByTagName('HelpfulVotes');
						if (helpfulVotes && helpfulVotes.length) {
							objReview.helpfulVotes = helpfulVotes[0].firstChild.nodeValue;
						}
						var totalVotes = review.getElementsByTagName('TotalVotes');
						if (totalVotes && totalVotes.length) {
							objReview.totalVotes = totalVotes[0].firstChild.nodeValue;
						}
						arrReviews.push(objReview);
					}
					objItem.customerReviews = arrReviews;
				}
			} // END IF CustomerReviews
			// Parse similar products
			var similarProductsTag = item.getElementsByTagName('SimilarProducts');
			if (similarProductsTag && similarProductsTag.length) {
				var products = similarProductsTag[0].getElementsByTagName('SimilarProduct');
				if (products && products.length) {
					var arrProducts = [];
					for (var iProduct = 0; iProduct < products.length; iProduct++) {
						var product = products[iProduct];
						var objProduct = {};
						var asin = product.getElementsByTagName('ASIN');
						if (asin && asin.length) {
							objProduct.asin = asin[0].firstChild.nodeValue;
						}
						var title = product.getElementsByTagName('Title');
						if (title && title.length) {
							objProduct.title = title[0].firstChild.nodeValue;
						}
						arrProducts.push(objProduct);
					}
					objItem.similarProducts = arrProducts;
				}
			}
			// Parse offers
			var offersTag = item.getElementsByTagName('Offers');
				if (offersTag && offersTag.length) {
					var offers = offersTag[0].getElementsByTagName('Offer');
					if (offers && offers.length) {
						var arrOffers = [];
						for (var iOffer = 0; iOffer < offers.length; iOffer++) {
							var offer = offers[iOffer];
							var objOffer = {};
							// Get offer listing id
							var offerListingId = offer.getElementsByTagName('OfferListingId');
							if (offerListingId && offerListingId.length) {
								objOffer.offerListingId = offerListingId[0].firstChild.nodeValue;
							}
							// Get offer merchant
							var merchants = offer.getElementsByTagName('Merchant');
							if (merchants && merchants.length) {
								// Get offer merchant name
								var names = merchants[0].getElementsByTagName("Name");
								if (names && names.length) {
									objOffer.merchantName = names[0].firstChild.nodeValue;
								}
							}
							// Get offer price
							var prices = offer.getElementsByTagName('Price');
							if (prices && prices.length) {
								var formattedPrices = prices[0].getElementsByTagName('FormattedPrice');
								if (formattedPrices && formattedPrices.length) {
									objOffer.price = formattedPrices[0].firstChild.nodeValue;
								}
							}
							arrOffers.push(objOffer);
						}
						objItem.offers = arrOffers;
					}
				}
			}
		}
	}
	return arrItems;
};

/**
 * Parse xml SmallItem, MediumItem or LargeItem section from an xml document
 *
 * @private
 * @param {object} item XMLElement of item
 * @param {string} imageName tag we are interested in
 */
Zapatec.Shop.parseImageXmlResponse = function(item, imageName) {
  var result = {};

  var images = item.getElementsByTagName(imageName);
  if (images && images.length) {
    var urls = images[0].getElementsByTagName('URL');
    if (urls && urls.length) {
      result.url = urls[0].firstChild.nodeValue;
    }

    var widths = images[0].getElementsByTagName('Width');
    if (widths && widths.length) {
      result.width = widths[0].firstChild.nodeValue;
    }

    var heights = images[0].getElementsByTagName('Width');
    if (heights && heights.length) {
      result.height = heights[0].firstChild.nodeValue;
    }
  }

  return result;
}

/**
 * Converts book package dimensions to string given the unit
 *
 * @private
 * @param {string} dimension package dimension number
 * @param {string} unit package dimension unit
 */
Zapatec.Shop.parsePackageDimension = function(dimension, unit) {
  var dimensionNum = parseInt(dimension);
  if (null != unit && -1 != unit.indexOf("hundredths")) {
    dimensionNum /= 100;
  }
  return dimensionNum;
}

/**
 * Handles clicks on book title and shows a new book details window
 *
 * @private
 * @param {string} asin book unique ASIN
 */
Zapatec.Shop.onTitleClick = function(asin, searchIndex) {
  var win = Zapatec.Shop.createWindow();
  // Convert search index to details window title
  var title = '';
  if ("Books" == searchIndex) {
    title = 'Book Details';
  }
  else if ("Music" == searchIndex) {
    title = 'Music Details';
  }
  else if ("PCHardware" == searchIndex) {
    title = 'Hardware Details';
  }
  else if ("Blended" == searchIndex) {
    title = 'Item Details';
  }

  // Set dialog title
  win.setTitle(title);

  // Request book details by doing an ItemSearch operation
  Zapatec.Transport.fetchXmlDoc({

    // URL to fetch
    url: 'proxy.php?Asin=' + asin,

    // Onload event handler
    onLoad: function(objXmlDoc) {
      // Parse ItemLookup operation xml response
      var objXmlSource = Zapatec.Shop.parseItemXmlResponse(objXmlDoc, true);

      var item = objXmlSource[0];

      // Show book details tabs content in a window
      Zapatec.Shop.showDetailsContent(item, win, searchIndex);
    }
  });

  return false;
}

/**
 * Prepares a book overview content html given the item object
 *
 * @private
 * @param {object} item parsed item object
 */
Zapatec.Shop.getItemOverviewHtml = function(item) {

  var overviewHtml;

  var imageHtml = Zapatec.Shop.getFitImageHtml(item.largeImageUrl,
          item.largeImageWidth, item.largeImageHeight,
          Zapatec.Shop.MAX_LARGE_WIDTH, Zapatec.Shop.MAX_LARGE_HEIGHT);

  overviewHtml = '<div style="background:red;"><a target="_blank" class="detailsImageHolder" href="' +
         item.largeImageUrl + '">' + imageHtml+ '</a></div>';
  overviewHtml += '<div class="cccccc1"><br/><span class="zpTitle zpTitleDetails">' +
                  item.title + '</span><br/>';

  // If author is set
  if (item.author) {
    overviewHtml += '<span class="zpPopupAuthor">by ' + item.author +
                    '</span></div><br/><br/>';
  }
  else if (item.manufacturer) {
    overviewHtml += '<span class="zpPopupAuthor">by ' + item.manufacturer +
                    '</span></div><br/><br/>';
  }

  // If list price is set
  if (item.listPrice) {
    overviewHtml += '<span class="detailsCategory">List Price: </span>' +
            '<span class="zpListPrice">' + item.listPrice + '</span><br/>';
  }

  // If lowest new price is set
  if (item.lowestNewPrice) {
    overviewHtml += '<span class="detailsCategory">Lowest Price: </span>' +
            '<span class="zpLowestPrice">' + item.lowestNewPrice + '</span><br/>';
  }

  // If lowest used price is set
  if (item.lowestUsedPrice) {
    overviewHtml += '<span class="detailsCategory">Used Price: </span>' +
            '<span class="zpLowestPrice">' + item.lowestUsedPrice + '</span><br/>';
  }

  // If author is set
  if (item.author) {
    // If binding is set
    if (item.binding) {
      overviewHtml += '<span class="detailsCategory">' + item.binding + ':</span>';
    }

    // If number of pages is set
    if (item.numberOfPages) {
      overviewHtml += '<span class="zpPopupSimpleText" >' + item.numberOfPages +
                      ' pages</span>';
    }

    overviewHtml += '<br/>';

    var publisher = item.publisher;
    if (null != item.edition) {
      publisher += ';' + item.edition + ' edition';
    }

    if (publisher) {
      // Write publisher name
      overviewHtml += '<span class="detailsCategory">Publisher: </span>' +
              '<span class="zpPopupSimpleText" >' + publisher + '</span><br/>';
    }
  }

  // If publication date is set
  if (item.publicationDate) {
    overviewHtml += '<span class="detailsCategory">Publication Date: </span>'+
     '<span class="zpPopupSimpleText">' + item.publicationDate + '</span><br/>';
  }

  // If ISBN is set
  if (item.isbn) {
    overviewHtml += '<span class="detailsCategory">ISBN: </span>'+
        '<span class="zpPopupSimpleText" >' + item.isbn + '</span><br/>';
  }

  var width = Zapatec.Shop.parsePackageDimension(
          item.packageWidth, item.packageWidthUnits);
  var height = Zapatec.Shop.parsePackageDimension(
          item.packageHeight, item.packageHeightUnits);
  var length = Zapatec.Shop.parsePackageDimension(
          item.packageLength, item.packageLengthUnits);
  var weight = Zapatec.Shop.parsePackageDimension(
          item.packageWeight, item.packageWeightUnits);
  if (width && height) {
    var units = "";
    if (null != item || -1 != item.packageLengthUnits.indexOf("inches")) {
      units = "inches";
    }
    var dimension = length + " x " + width + " x " + height + " " + units;

    overviewHtml += '<span class="detailsCategory">Product Dimensions: </span>'+
        '<span class="zpPopupSimpleText" >' + dimension + '</span><br/>';
  }

  var params = null;
  //params = "'" + item.asin + "'";

  if (item.offers && 0 < item.offers.length) {
    var offerListingId = item.offers[0].offerListingId;
    params += ", '" + offerListingId + "'";

    // Write Add To Cart button
    overviewHtml += '<a class="addToCart" href="#" onclick='+
              '"return Zapatec.Shop.addToCart(' + params + ');"></a>';
  }
  
  return overviewHtml;
}

/**
 * Prepares a book editorial review content html given the item object
 *
 * @private
 * @param {object} item parsed item object
 */
Zapatec.Shop.getItemEditorialReviewsHtml = function(item) {
  if (null == item.editorialReviews) {
    return null;
  }

  var editorialReviews = item.editorialReviews;

  var editorialHtml = '<div class="editorialHolder">';
  for (var iReview = 0; iReview < item.editorialReviews.length; ++iReview) {
    var review = item.editorialReviews[iReview];

    editorialHtml += '<span>'+review.source+'</span>' +
                     '<br/><span>' + review.content + '</span><br/>';
  }

  editorialHtml += '</div>';

  return editorialHtml;
}

/**
 * Prepares a book customer review content html given the item object
 *
 * @private
 * @param {object} item parsed item object
 */
Zapatec.Shop.getItemCustomerReviewsHtml = function(item) {
  if (null == item.customerReviews) {
    return null;
  }

  var averageRating = parseInt(parseFloat(item.customerReviewsAverageRating)*10);    //RICARDO

  var averageUrl = Zapatec.Shop.STARS_URL[averageRating];

  var customerReviews = item.customerReviews;

  var customerHtml = '<div class="customerReviewHolder">';
  customerHtml += '<span class="averageCustomerReview">\
  Average Customer Review:</span>'+
          '<img class="zpImage" src="'+averageUrl+'"/><br/><br/>';

  for (var iReview = 0; iReview < item.customerReviews.length; ++iReview) {
    var review = item.customerReviews[iReview];

    var rating = review.rating;

    var ratingUrl = Zapatec.Shop.STARS_URL[rating];

    var helpfulVotes = review.helpfulVotes;
    var totalVotes = review.totalVotes;

    if (totalVotes && '0' != totalVotes) {
      customerHtml += '<span>'+helpfulVotes+' of '+totalVotes+
                      ' people found the following review helpful:</span>';
    }

    customerHtml += '<br/>'+
                    '<img class="zpImage" src="'+ratingUrl+'"/>'+
                    '<span class="editorialSource">'+review.summary+'</span>' +
                    '<br/><span>' + review.content + '</span><br/><br/>';
  }

  customerHtml += '</div>';

  return customerHtml;
}

/**
 * Prepares a book similar products content html given the item object
 *
 * @private
 * @param {object} item parsed item object
 * @param {string} searchIndex search domain this item was obtained from
 */
Zapatec.Shop.getItemSimilarProductsHtml = function(item, searchIndex) {
  if (null == item.similarProducts) {
    return null;
  }

  var similarProducts = item.similarProducts;

  var productsHtml = '';
  for (var iProduct = 0; iProduct < similarProducts.length; ++iProduct) {
    var product = item.similarProducts[iProduct];

    productsHtml += '<a href="#" class="zpTitle"';

    var params = "'" + product.asin + "', '" + searchIndex + "'";
    productsHtml += ' onclick="return Zapatec.Shop.onTitleClick('+params+');"';

    productsHtml += '>'+product.title+'</a><br/>';
  }

  return productsHtml;
}

/**
 * Shows book details contents received by the proxy in separate tabs inside a
 * given window
 *
 * @private
 * @param {object} item an item from a parsed search operation response
 * @param {object} win details window to use
 * @param {string} searchIndex search domain this item was obtained from
 */
Zapatec.Shop.showDetailsContent = function(item, win, searchIndex) {
  if (null == item.largeImageUrl) {
    item.largeImageUrl = Zapatec.Shop.NO_IMAGE_BIG_URL;
  }

  var overviewHtml = Zapatec.Shop.getItemOverviewHtml(item);

  // Get html for editorial reviews tab
  var editorialReviewsHtml = Zapatec.Shop.getItemEditorialReviewsHtml(item);

  // Get html for customer reviews tab
  var customerReviewsHtml = Zapatec.Shop.getItemCustomerReviewsHtml(item);

  // Get html for similar products tab
  var similarProductsHtml = Zapatec.Shop.getItemSimilarProductsHtml(item, searchIndex);

  var tabsId = 'detailsTabs' + Zapatec.Shop.detailsWindowCount;

  var tabs = '<div id="'+tabsId+'"' +
             ' style="width:584px;height:342px;">' +
             '</div>  ';

  win.setContent(tabs);
  var objTabsSource = {
    tabs: [
    {
      id: 'overview',
      linkInnerHTML: '<u>O</u>verview',
      accessKey: 'o',
      title: 'Overview',
      content: overviewHtml,
      contentType: "html/text"
    }]
  };

  if (null != editorialReviewsHtml) {
    objTabsSource.tabs.push({
      id: 'editorial',
      linkInnerHTML: '<u>E</u>ditorial',
      accessKey: 'e',
      title: 'Editorial',
      content: editorialReviewsHtml,
      contentType: "html/text"
    });
  }
  if (null != customerReviewsHtml) {
    objTabsSource.tabs.push({
      id: 'customer',
      linkInnerHTML: '<u>C</u>ustomer',
      accessKey: 'c',
      title: 'Customer',
      content: customerReviewsHtml,
      contentType: "html/text"
    });
  }
  if (null != similarProductsHtml) {
    objTabsSource.tabs.push({
      id: 'similar',
      linkInnerHTML: '<u>S</u>imilar',
      accessKey: 's',
      title: 'Similar',
      content: similarProductsHtml,
      contentType: "html/text"
    });
  }
  var objTabs = new Zapatec.AccordionTabs({
    /*
    ID to get the LABEL contents to create the tabBar tabs
    Also, each DIV in this ID will contain the contents for each tab
    */
    tabs: tabsId,
    // Theme to use for the tabs
    theme: '',
    source: objTabsSource,
    sourceType: 'json',
    overflow: 'auto'
  });

  // Set the real title now that we know it
  win.setTitle(item.title);
}

/**
 * Count of book details windows created using createWindow call.
 */
Zapatec.Shop.detailsWindowCount = 0;

/**
 * Number of pixels to offset each new book details window vertically
 */
Zapatec.Shop.newWindowOffsetY = 30;

/**
 * Create a new zapatec window
 *
 * @param isShoppingCart [boolean] if true the window is to be used for a
 * shopping cart, false is for book details
 * @param onClose [function] a function to be called on window close
 *
 * @return [object] the new window
 */
Zapatec.Shop.createWindow = function(isShoppingCart, onClose) {
  var windowSize = Zapatec.Utils.getWindowSize();
  var pageScrollY = Zapatec.Utils.getPageScrollY();

  var width = 600;
  var height;
  var top = 20;
  if (true == isShoppingCart) {
    height = 210;
    // Bottom align window
    top = pageScrollY + windowSize.height - height - 50;
  }
  else {
    height = 380;

    // Top align window
    top = pageScrollY;

    // Calculate vertical offset of new window to avoid overlap
    var windowPositionsCount = (windowSize.height - 2*height) /
                               Zapatec.Shop.newWindowOffsetY;
    top += (Zapatec.Shop.detailsWindowCount % windowPositionsCount) *
           Zapatec.Shop.newWindowOffsetY;

    ++Zapatec.Shop.detailsWindowCount;
  }

  // Right aligned window
  var left = windowSize.width - width -30;

  var win = Zapatec.Window.setup({
    left : left,
    top : top,
    width : width,
    height : height,
    raiseOnlyOnTitle : false,
    showStatus : false,
    canResize: false,
    showMaxButton: false,
    theme : 'winxp',
    content : '<span style="margin-left: 40%; margin-top: 40%;">Loading...</span>',
    onClose : onClose
  });

  return win;
}



/**
 * Create and populate a shopping cart grid
 *
 * @private
 * @param {object} objXmlSource parsed xml response for a cart operation
 */
Zapatec.Shop.createCartGrid = function(objXmlSource) {
  // Convert xml response to something the grid will understand
  var objJsonGrid = this.convertCartXmlToGrid(objXmlSource);

  //And now display the grid
  Zapatec.Shop.cartGrid = new Zapatec.Grid({
    // Use object as source
    source: objJsonGrid,
    sourceType: 'json',

    // Use cartCallbackHeader function to display grid header
    callbackHeaderDisplay: Zapatec.Shop.cartCallbackHeader,

    // Use cartCallbackRow function to display grid row
    callbackRowDisplay: Zapatec.Shop.cartCallbackRow,

    // Use cartCallbackPagination function to display grid pagination
    callbackPaginationDisplay: Zapatec.Shop.cartCallbackPagination,

    theme: "winxp",


    // Use paging, display rows per page given by the proxy
    rowsPerPage: objXmlSource.rowsPerPage
  });
}

/**
 * Parse xml document returned as a cart operation response from the proxy
 *
 * @private
 * @param {object} objXmlDoc received xml document
 */
Zapatec.Shop.parseCartXmlResponse = function(objXmlDoc) {

  var arr = [];

  // Check xml document object
  if (objXmlDoc && objXmlDoc.documentElement) {

    // Parse cart unique cartId
    var cartId = objXmlDoc.documentElement.getAttribute('cartId');
    if (null != cartId) {
      arr.cartId = cartId;
    }

    // Parse cart unique HMAC
    var cartHmac = objXmlDoc.documentElement.getAttribute('hmac');
    if (null != cartHmac) {
      arr.cartHmac = cartHmac;
    }

    // Parse cart purchase URL
    var purchaseURL = objXmlDoc.documentElement.getAttribute('purchaseUrl');
    if (null != purchaseURL) {
      arr.purchaseUrl = purchaseURL;
    }

    // Parse cart subtotal price
    var subTotalPrice = objXmlDoc.documentElement.getAttribute('subTotalPrice');
    if (null != subTotalPrice) {
      arr.subTotalPrice = subTotalPrice;
    }

    // Parse XML response items
    var arrItem = objXmlDoc.documentElement.getElementsByTagName('item');

    // If there are items
    if (arrItem && arrItem.length) {

      for (var iItem = 0; iItem < arrItem.length; iItem++) {
        var item = arrItem[iItem];

        arr.push({
          itemId: item.getAttribute('itemId'),
          quantity: item.getAttribute('quantity'),
          title: item.getAttribute('title'),
          price: item.getAttribute('price'),
          itemTotal: item.getAttribute('itemtotal'),
          purchaseURL: item.getAttribute('purchaseUrl'),
          asin: item.getAttribute('asin')});
      }
    }
  }

  return arr;
};

/**
 * Creates an URL for CartCreate/CartAdd/CartModify operation
 *
 * @private
 * @param {string} asin Book ASIN
 */
Zapatec.Shop.getCartOperationUrl = function(operation, asin, offerListingId) {
  // Build operation URL
  var url = 'proxy.php?';

  if (null != this.cartId) {
    url += 'CartId='+this.cartId;
    url += '&HMAC='+this.cartHmac;
  }

  if ('CartAdd' == operation) {
    // If a cart has not been created
    if (null == this.cartId) {
      // Make CartCreate operation
      url += 'Operation=CartCreate';
    }
    else {
      // Make CartAdd operation
      url += '&Operation=CartAdd';
    }

    if (offerListingId) {
      url += '&OfferListingId='+offerListingId;
    }
    else {
      url += '&Asin='+asin;
    }
  }
  else if ('CartModify' == operation) {
    // Make CartModify operation
    url += '&Operation=CartModify';

    // Enumerate all rows in the grid
    var rows = Zapatec.Shop.cartGrid.getRows();
    var rowCount = rows.length;
    for (var i = 0; i < rowCount; ++i) {
      var row = rows[i];

      var itemIndex = i + 1;
      url += '&CartItemId'+itemIndex+'='+row.cartItemId;
      var value = document.getElementById('quantity.'+i).value;
      url += '&Quantity'+itemIndex+'='+value;

    }
  }

  return url;
}

/**
 * Shows cart contents received by the proxy in a special shopping cart window
 *
 * @private
 * @param {object} objXmlSource parsed cart xml
 */
Zapatec.Shop.showCartContent = function(objXmlSource) {
  // Write cart subtotal
  var html = '<div class="shoppingCartHolder">';

  html += '<div class="shoppingCart">Shopping Cart</div>';

  html += '<a class="checkoutAnchor" href="'+objXmlSource.purchaseUrl+
          '" target="_blank" onclick="return Zapatec.Shop.purchaseCart();">'+
          '<img class="zpImage" src="images/checkout.gif"/></a>';

  html += '<div class="clearer"></div>';
  html += '<br/>';

  html += '<div class="subtotalHolder">';
  // Determine subtotal price string
  var subtotal = "$0";
  if (objXmlSource.subTotalPrice) {
    subtotal = objXmlSource.subTotalPrice;
  }
  html += '<span class="zpSubtotal">Subtotal: </span>\
          <span class="subtotalPrice">'+subtotal+'</span>';
  html += '<a class="updateAnchor" href="#" \
          onclick="return Zapatec.Shop.updateCart();">\
          <img class="zpImage" src="images/update.gif"/></a>';
  html += '</div>';

  html += '<div class="clearer"></div>';
  html += '<br/>';

  html += '<div class="cartGridHolder">';
  html += '<div id="cartOutput"></div><br/>';
  html += '</div>';

  html += '</div>';

  // Store last shopping cart set in window content
  Zapatec.Shop.lastShoppingCartXml = objXmlSource;

  // Show cart html in cart window
  Zapatec.Shop.cartWin.setContent(html);

  // Populate the cart grid
  setTimeout(function() { Zapatec.Shop.createCartGrid(objXmlSource) }, 10);
}

/**
 * Adds a book to the cart creating a new cart if one does not already exist.
 * Called when addToCart image is clicked.
 *
 * @private
 * @param {string} asin Book ASIN
 */
Zapatec.Shop.addToCart = function(asin, offerListingId) {
  var url = Zapatec.Shop.getCartOperationUrl('CartAdd', asin, offerListingId);

  // Show shoppring cart window
  Zapatec.Shop.showShoppingCartWindow();

  // Request cart operation URL from amazon proxy
  Zapatec.Transport.fetchXmlDoc({

    // URL to fetch
    url: url,

    // Onload event handler
    onLoad: function(objXmlDoc) {
      // Parse xml response
      var objXmlSource = Zapatec.Shop.parseCartXmlResponse(objXmlDoc, false);

      // If a cart does not exist yet
      if (null == Zapatec.Shop.cartId) {
        // Store parsed cartID and HMAC.
        Zapatec.Shop.cartId = objXmlSource.cartId;
        Zapatec.Shop.cartHmac = objXmlSource.cartHmac;
      }

      // Show cart content in a window
      Zapatec.Shop.showCartContent(objXmlSource);
    }
  });

  return false;
}

/**
 * Updates the remote cart using value entered in quantity input fields
 * Called when update image is clicked.
 *
 * @private
 */
Zapatec.Shop.updateCart = function() {
  var rowCount = Zapatec.Shop.cartGrid.getRows().length;

  var url = Zapatec.Shop.getCartOperationUrl('CartModify');

  // Request CartModify operation URL from amazon proxy
  Zapatec.Transport.fetchXmlDoc({

    // URL to fetch
    url: url,

    // Onload event handler
    onLoad: function(objXmlDoc) {
      // Parse xml response
      var objXmlSource = Zapatec.Shop.parseCartXmlResponse(objXmlDoc, false);

      // Show cart content in a window
      Zapatec.Shop.showCartContent(objXmlSource);
    }
  });

  return false;
}

/**
 * Navigates the cart window to amazon purchase URL
 * Called when proceed to checkout image is clicked.
 *
 * @private
 */
Zapatec.Shop.purchaseCart = function() {
  var src = Zapatec.Shop.lastShoppingCartXml.purchaseUrl;
  
  var html = '<iframe src="'+src+'" style="width: 100%; height: 100%; border: 0;"></iframe>';
  // Show cart html in cart window
  Zapatec.Shop.cartWin.setContent(html);

  return false;
}

/**
 * Updates the remote cart using value entered in quantity input fields
 * Called when update image is clicked.
 *
 * @private
 */
Zapatec.Shop.deleteCartItem = function(cartItemId) {
  // Enumerate all rows in the grid
  var rows = Zapatec.Shop.cartGrid.getRows();
  var rowCount = rows.length;
  for (var i = 0; i < rowCount; ++i) {
    var row = rows[i];

    var itemIndex = i + 1;
    if (row.cartItemId == cartItemId) {
      document.getElementById('quantity.'+i).value = 0;
      break;
    }
  }

  Zapatec.Shop.updateCart();

  return false;
}

/**
 * Converts a parsed xml response for a shopping cart operation to
 * something that the cart grid will understand
 *
 * @private
 * @param {array} objXmlSource parsed xml response from the proxy
 */
Zapatec.Shop.convertCartXmlToGrid = function(objXmlSource) {
  //Structure of the output(grid) object
  var objJsonGrid = {
    fields: [
    {title: "Title", dataType: "string", className: "zpTitle"},
    {title: "Price", dataType: "string"},
    {title: "Qty", dataType: "string"}
            ],
    rows: []
  };

  // Iterate all cart items
  for (var index = 0; index < objXmlSource.length; ++index) {
    var item = objXmlSource[index];

    // Push current cart item as a grid row
    objJsonGrid.rows.push({cells: [
    {v: item.title, className: "zpTitle"},
    {v: item.price},
    {v: item.quantity}
            ],
    asin: item.asin,
    cartItemId: item.itemId,
    quantity: item.quantity});
  }

  return objJsonGrid;
}

Zapatec.Shop.cartHtml = null;
Zapatec.Shop.cartHtmlItemCount = 0;

/**
 * Gets called by the cart grid to display headers.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.cartCallbackHeader = function(objGrid) {
  var cartOutput = document.getElementById("cartOutput");

  // Write <table> starting html element and begin table head
  Zapatec.Shop.cartHtml = '<table id="cartTable" style="width: 100%;"><thead>';
  Zapatec.Shop.cartHtmlItemCount = 0;

  // Enumerate all fileds in the grid (e.g. columns)
  var arrFields = objGrid.getFields();
  for (var iCol = 0; iCol < arrFields.length; iCol++) {
    var objField = arrFields[iCol];

    var style = null;
    // If this is the title header column
    if (0 == iCol) {
      style = 'width: 80%;';
    }
    else {
      style = 'width: 10%;';
    }

    // Write table header cell element
    Zapatec.Shop.cartHtml += '<td class="zpHeader" style="'+style;
    Zapatec.Shop.cartHtml += '">';
    Zapatec.Shop.cartHtml += '<a href="#" onclick="'+objGrid.getFieldOnclick(objField)+'; return false">'+objGrid.getFieldTitle(objField)+'</a>';
    Zapatec.Shop.cartHtml += '</td>';
  }
  // Write table head closing and begin table body
  Zapatec.Shop.cartHtml += '</thead><tbody>';
};

/**
 * Gets called by the cart grid to display rows.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.cartCallbackRow = function(objGrid, objRow) {
  Zapatec.Shop.cartHtml += '<tr>';

  var arrCells = objGrid.getRowCells(objRow);

  for (var iCol = 0; iCol < arrCells.length; iCol++) {
    var objCell = arrCells[iCol];
    var data = objGrid.getCellValueString(objCell);

    Zapatec.Shop.cartHtml += '<td ';

    if (objRow.cells[iCol].className) {
      Zapatec.Shop.cartHtml += ' class="' + objRow.cells[iCol].className + '"';
    }
    // If this is the title
    if (iCol == 0) {
      Zapatec.Shop.cartHtml += '><a href="#" ';
      Zapatec.Shop.cartHtml += ' onclick="return Zapatec.Shop.onTitleClick(\''+
                objRow.asin.toString()+'\');">';
      Zapatec.Shop.cartHtml += data;
      Zapatec.Shop.cartHtml += '</a';
    }

    Zapatec.Shop.cartHtml += '>';

    if (0 == iCol) {
    }
    else if (2 == iCol) {
      var input = '<input id="quantity.'+Zapatec.Shop.cartHtmlItemCount+
                  '" size="2" maxlength="3" value="'+objRow.quantity+
                  '" type="text">';

      Zapatec.Shop.cartHtml += input;
    }
    else {
      Zapatec.Shop.cartHtml += data;
    }

    Zapatec.Shop.cartHtml += '</td>';

  }

  // Write delete cart item anchor
  Zapatec.Shop.cartHtml += '<td ';
  Zapatec.Shop.cartHtml += '><a href="#" ';
  Zapatec.Shop.cartHtml += ' onclick="return Zapatec.Shop.deleteCartItem(\''+
            objRow.cartItemId.toString()+'\');">';
  Zapatec.Shop.cartHtml += "<span class=\"deleteItem\">delete</span>";
  Zapatec.Shop.cartHtml += '</a';
  Zapatec.Shop.cartHtml += '</td>';

  Zapatec.Shop.cartHtml += '</tr>';
  ++Zapatec.Shop.cartHtmlItemCount;

  if (Zapatec.Shop.cartHtmlItemCount == objGrid.getRows().length) {
    Zapatec.Shop.cartHtml += '</tbody></table>';

    var cartOutput = document.getElementById("cartOutput");

    cartOutput.innerHTML = Zapatec.Shop.cartHtml;

    Zapatec.Shop.cartHtml = null;
  }

};

/**
 * Gets called by the cart grid to display pagination.
 *
 * @private
 * @param {object} objGrid Grid object
 */
Zapatec.Shop.cartCallbackPagination = function(objGrid) {
};

/**
 * Create an html image tag from the specified src URL and given limits. If
 * image size is bigger than given limits appropriate width and height tags will
 * be produced so that it fits the specified boundaries.
 *
 * @private
 * @param {string} imageUrl image src URL
 * @param {number} origWidth image src width
 * @param {number} origHeight image src height
 * @param {number} maxWidth max image width to fit in
 * @param {number} maxHeight max image height to fir in
 * @param {string} class className to apply to image
 */
Zapatec.Shop.getFitImageHtml = function(imageUrl, origWidth, origHeight,maxWidth, maxHeight, className) {
	var width = origWidth;
	var height = origHeight;
	if (maxWidth < width) {
		var aspect = origWidth / origHeight;
	    var widthDiff = width - maxWidth;
		width -= widthDiff;
		height -= widthDiff / aspect;
	}
	if (maxHeight < height) {
		var aspect = origWidth / origHeight;
		var heightDiff = height - maxHeight;
		width -= heightDiff * aspect;
		height -= heightDiff;
	}
	var img = '<img src="' + imageUrl + '"';
	img += className ? ' class="'+className+'"' : '';
	if (width != origWidth || height != origHeight) {
		img += ' width="'+width+'" height="'+height+'"';
	}
	img += ' />';
	return img;
};

Zapatec Suite

Documentation generated by JSDoc on Thu May 21 12:20:07 2009