//PShelper Advanced Search Object
//Written and maintained by Derek Decker - PShelper.com
//For use with the ProStores e-commerce Platform

var prodName = 'PRODNAME';  
var prodStock = 'PRODSTOCK';  
var prodUrl = 'PRODLINK';    
var prodPrice = 'PRODPRICE';  
var prodImage = 'PRODIMAGE';

var almostGoneAmount = 5; //must have less then this quantity

function convertQuotes( str ) {
    return (str+'').replace(/([\\"'])/g, "&quot;").replace(/\0/g, "\\0");
}

function Product(){
	this.setProduct = function(productArray)
	{
		this.productName = productArray[prodName];
		this.productStock = productArray[prodStock];
		this.productPrice = productArray[prodPrice];
		this.productImage = productArray[prodImage];
		this.productUrl = productArray[prodUrl];
	}
}

/* need to take in all the product listings and build into a sortable array 
then sort based on passed in variables
*/
function productSearch(){
	
	this.rootNode = document.getElementById('productResults');
	this.currentProduct = new Product();
	this.layoutContainer = null;
	this.debug = false;
	

	/*
	@printOptions = array of options for printing
		{	'pageNum' : 1, 
			'perPage' : 5,
			'sortBy' : prodName,
			'sortDir' : asc,
			'layoutContainerClass' : 'className',
			'layoutContainerID' : 'uniqueId',
			'header' : 'Short Supply!', 
			'alternateColor' : '#d8d8d8', 
			'limitAlmostGone' : true,
			'printOutOfStock' : false,
			'showPaging' : true,
			'removeSortFieldZeroes' : false,
			
			'showFields' : {
				'productStock' : true, 
				'productNew' : false
			}
		}
	*/
	this.printPagedProducts = function(printOptions)
	{	
		//gather up the variables from the printOptions
		var currentPageNumber = printOptions['pageNum'];
		var amountPerPage = printOptions['perPage'];
		var sortByField = printOptions['sortBy'];
		var sortDirection = printOptions['sortDir'];
		var containerClass = printOptions['layoutContainerClass'];
		var containerID = printOptions['layoutContainerID']; //required for paging and filtering multiple searches on one page
		var headerText = printOptions['header'];
		var rowAltColor = printOptions['alternateColor'];
		var limitAlmostGone = printOptions['limitAlmostGone'];
		var printOutOfStock = printOptions['printOutOfStock'];
		var showPaging = printOptions['showPaging'];
		var removeSortFieldZeroes = printOptions['removeSortFieldZeroes']; //remove indexes where the sorted by field is null or 0
		var printFields = printOptions['showFields']; //array of fields
		var printArray = this.initiateProductArray();
	
		//first sort the product array
		//recreate for out of stock settings
		printArray = this.productSorter(sortByField,sortDirection,printArray);
		if(!printOutOfStock) printArray = this.removeOutOfStockFromArray(printArray);
		if(limitAlmostGone) printArray = this.removeHigherQuantities(printArray);	
		if(removeSortFieldZeroes) printArray = this.removeSortFieldZeroes(printArray,sortByField);	
		
		//calculate paging information
		pageStartIndex = (currentPageNumber==1) ? 0 : ((currentPageNumber*amountPerPage)-amountPerPage);
		pageEndIndex = (amountPerPage>printArray.length) ? printArray.length : pageStartIndex+amountPerPage;
		pageEndIndex = (pageEndIndex>printArray.length) ? printArray.length : pageEndIndex;
		containerClass = (containerClass) ? containerClass : this.layoutContainer;
		
		//actual printing
		if(printArray.length>0){
			productContainer = (document.getElementById(containerID)) ? '' : '<div class="'+containerClass+'" id="'+containerID+'">';
			
			if(this.debug){
			productContainer += 'Total Products: '+printArray.length+'<br>'+
								'Current Page: '+currentPageNumber+'<br>'+
								'Per Page: '+amountPerPage+'<br>'+
								'Page Start Index: '+pageStartIndex+'<br>'+
								'Page End Index: '+pageEndIndex+'<br>'+
								'Sort By: '+sortByField+'<br>'+
								'Sort Direction: '+sortDirection+'<br>'+
								'containerClass: '+containerClass+'<br>'+
								'containerID: '+containerID+'<br>'+
								'limitAlmostGone: '+limitAlmostGone+'<br>'+
								'printOutOfStock: '+printOutOfStock+'<br>'+
								'showPaging: '+showPaging+'<br>';
			}
			
			productContainer += (headerText) ? '<div class="resultHeader">'+headerText+'</div>' : '';
			productContainer += '<div class="resultContainer">';
			for(var i=pageStartIndex;i<pageEndIndex;i++)//print only the current page of products
			{ 
				this.currentProduct.setProduct(printArray[i]);
				productContainer += (rowAltColor && i%2) ? '<div class="productResultWrapper" style="background-color:'+rowAltColor+';">' : '<div class="productResultWrapper">';
				productContainer += (printFields['productImage']) ? '<div class="productImage">'+this.currentProduct.productImage+'</div>' : '';
			//	productContainer += '<div class="productUrl">'+this.currentProduct.productUrl+'</div>';
				productContainer += '<div class="productName"> '+this.currentProduct.productName+'</div>';
				productContainer += (printFields['productStock']) ? '<div class="productStock">'+this.currentProduct.productStock+' left </div>' : '';
				productContainer += (printFields['productPrice']) ? '<div class="productPrice">'+this.currentProduct.productPrice+'</div>' : '';
				productContainer += '</div>'; 
			}
			productContainer += '</div><div style="clear:both;height:5px;"></div>';
			productContainer += (showPaging) ? this.addPageLinks(printOptions,printArray.length)+'<div style="clear:both;height:15px;"></div>' : '';
			productContainer += (document.getElementById(containerID)) ? '' : '</div>';
			if(document.getElementById(containerID)) document.getElementById(containerID).innerHTML = productContainer; else document.write(productContainer);
		}
	}
	


	this.printOptionsAsString = function(printOptions){
			linkOptions = '{';
			loop1 = 0;
			loop2 = 0;
			for(var j in printOptions){ 
				linkOptions += (loop1==0) ? '' : ','; 
				linkOptions += '\''+j+'\':';
				
				//different variable types testing
				if(typeof(printOptions[j])=='string') //string
					linkOptions += '\''+convertQuotes(printOptions[j])+'\''; 
				if(typeof(printOptions[j])=='boolean') //boolean
					linkOptions += printOptions[j]; 
				if(typeof(printOptions[j])=='number') //number
					linkOptions += printOptions[j]; 
				if(j=='showFields'){
					linkOptions += '{';
					for(var k in printOptions[j]){
						linkOptions += (loop2==0) ? '' : ','; 
						linkOptions += '\''+k+'\':'+printOptions[j][k];
						loop2++;
					}
					linkOptions += '}';					
				}
				loop1++;
			}
			linkOptions += '}';
			return linkOptions;
	}
	
	this.addPageLinks = function(printOptions,totalProducts){
		//calculate paging information
		var currentPageNumber = printOptions['pageNum'];
		var amountPerPage = printOptions['perPage'];
		var pageReturn = '<div class="pageLinks">';
		pageStartIndex = (currentPageNumber==1) ? 0 : ((currentPageNumber*amountPerPage)-1);
		pageEndIndex = (amountPerPage>totalProducts) ? totalProducts : pageStartIndex+amountPerPage;
		pageEndIndex = (pageEndIndex>totalProducts) ? totalProducts : pageEndIndex;
		totalPages = Math.ceil(totalProducts/amountPerPage);
		
		if(totalPages>1){
			/*
			if(currentPageNumber!=1){
				printOptions['pageNum'] = currentPageNumber-1;
				linkOptions = this.printOptionsAsString(printOptions);
				pageReturn += '<a href="javascript:;" onClick="productSearch.printPagedProducts('+linkOptions+');"><</a> ';
			}
			*/
			for(var i=0;i<totalPages;i++){
				printOptions['pageNum'] = i+1;
				linkOptions = this.printOptionsAsString(printOptions);
				pageReturn += (i+1!=currentPageNumber) ? '<a href="javascript:;" onClick="productSearch.printPagedProducts('+linkOptions+');">'+(i+1)+'</a> ' : '<span class="currentPage">'+(i+1)+'</span> ';
			}	
			if(currentPageNumber<totalPages){
				printOptions['pageNum'] = currentPageNumber+1;
				linkOptions = this.printOptionsAsString(printOptions);
				pageReturn += '<a href="javascript:;" onClick="productSearch.printPagedProducts('+linkOptions+');">></a>';
			}
		}
		pageReturn += '</div>';
		return pageReturn;
	}
	
	this.productSorter = function(sortIndex,sortDirection,sortArray)
	{
		numericSortField = (isNaN(parseInt(sortArray[0][sortIndex]))) ? false : true;		
		sortAscending = (sortDirection=='asc') ? true : false;
		
		if(numericSortField){ funcNumber = 0;
			sortFunction = function(a,b){ return (parseInt(a[sortIndex]) - parseInt(b[sortIndex])); }
		}else if(!numericSortField){ funcNumber = 1;
			sortFunction = function(a,b){ return (a[sortIndex] < b[sortIndex]) ? -1 : 1; }
		}
		if(sortIndex=='random'){ funcNumber = 2;
			sortFunction = function(a,b){ return (0.5 - Math.random()); }
		}
		//if(this.debug) document.write('Sort Field: '+sortIndex+'<br>'+'Sort Field is Numeric? '+numericSortField+' ('+parseInt(this.productArray[0][sortIndex])+') <br>'+'Sort Function Chosen: '+funcNumber+'<br>'+'Sort Ascending? '+sortAscending+'<br><br>'); 
		sortArray.sort(sortFunction);
		if(!sortAscending) sortArray.reverse();
		return sortArray;
	}
	
	this.removeSortFieldZeroes = function(printArray,sortByField)
	{
		tempArray = new Array();
		useArray = printArray;
		reIndex = 0;
		for(var i=0;i<useArray.length;i++){
			if(useArray[i][sortByField]!=0){ tempArray[reIndex] = useArray[i];reIndex++; }
		}
		return tempArray;			
	}
	
	this.removeOutOfStockFromArray = function(printArray)
	{
		tempArray = new Array();
		useArray = printArray;
		reIndex = 0;
		for(var i=0;i<useArray.length;i++){
			if(useArray[i][prodStock]!=0){ tempArray[reIndex] = useArray[i];reIndex++; }
		}
		return tempArray;
	}
	
	this.removeHigherQuantities = function(printArray)
	{
		tempArray = new Array();
		useArray = printArray;
		reIndex = 0;
		for(var i=0;i<useArray.length;i++){
			if(useArray[i][prodStock]<=almostGoneAmount){ tempArray[reIndex] = useArray[i];reIndex++; }
		}
		return tempArray;
	}	
	
	
	this.printProductArray = function()
	{	
		for(var i in productArray)
		{
			document.write(i+'. {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
		
			for(var j in productArray[i])
			{
				document.write(j+':'+productArray[i][j]+', <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;');
			}
			
			document.write(' } <br>');
		}
	}
	
	this.initiateProductArray = function()
	{
		arrayCount = 0;
		productArray = new Array();
		for(var i in this.rootNode.childNodes) //foreach top-level LI (top-level product group node)
		{	
			workingProductLI = (this.isLInode(this.rootNode.childNodes[i])) ? this.rootNode.childNodes[i] : false;	
			if(workingProductLI)
			{
				for(var j in workingProductLI.childNodes) //foreach bottom-level UL (product group node)
				{
					workingProductUL = (this.getProductULgroup(workingProductLI.childNodes[j])) ? workingProductLI.childNodes[j] : false;
					if(workingProductUL)
					{
						productArray[arrayCount] = new Array();
						for(var k in workingProductUL.childNodes) //foreach bottom-level LI (detail information node)
						{
							if(this.isDetailLInode(workingProductUL.childNodes[k]))
							{ 
								attributeName = workingProductUL.childNodes[k].getAttribute('id');
								productArray[arrayCount][attributeName] = workingProductUL.childNodes[k].innerHTML;
							}
						}
						arrayCount++;
					}
				}
			}
		}
		return productArray;
	}

	this.getProductULgroup = function(nd){
		return (this.isULnode(nd)) ? nd : false;
	}
	
	this.isULnode = function(nd){
		return (nd.nodeType==1 && nd.tagName=='UL') ? true : false; 
	}
	
	this.isLInode = function(nd){
		return (nd.nodeType==1 && nd.tagName=='LI') ? true : false;
	}
	
	this.isDetailLInode = function(nd){
		return (nd.tagName=='LI' && nd.getAttribute('id')) ? true : false;
	}
	
	this.printMatchingProducts = function(field,value){
		if(!field) field = prodName;
		if(!value) value = '*';		
	}	
}//end class