/*
PShelper.com Commonly Used Javascript functions
For use with ProStores e-commerce platform
v1.0 published 03/25/2009
Derek Decker
*/

var d = document;

/* function to return common variables for functions to use

*/

var docLocation = d.location+'';
var globals = {
				'cartID':readCookie('CART'),	//obtained from the cookie saved by prostores
				'psrcv':readCookie('psrcv'), //actual cookie value of recently viewed products
				'psrav':readCookie('psrcv').split(':'), //array of recently viewed products
				'docLocation':docLocation,	 //get root location and convert to string format
				'rootUrl':docLocation.substring(0,docLocation.lastIndexOf('/')),	//remove the current servlet from the URL
				'currentServlet':docLocation.substring(docLocation.lastIndexOf('/'),docLocation.indexOf('?')),	//remove the current servlet from the URL
				'cartUrl':docLocation.substring(0,docLocation.lastIndexOf('/'))+'/Cart',
				'detailUrl':docLocation.substring(0,docLocation.lastIndexOf('/'))+'/Detail',
				'categoryUrl':docLocation.substring(0,docLocation.lastIndexOf('/'))+'/Categories',
				'storefrontUrl':docLocation.substring(0,docLocation.lastIndexOf('/'))+'/StoreFront',
				'checkoutUrl':docLocation.substring(0,docLocation.lastIndexOf('/'))+'/Checkout'
				};


/* remove spaces

@words = string input
*/
function trim(words){
     return words.replace(/\s+/g,'');
}

/* removes blank values from arrays */
function restack(array){
	var newArray = new Array();
	var newArrayIndex = 0;
	for(var i=0;i<array.length;i++){
		if(array[i]=='' || array[i]==null || array[i]==NaN || array[i]==false){
		}else{
			newArray[newArrayIndex] = array[i];
			newArrayIndex++;
		}
	}
	return newArray;
}


/* function to get a specific variable from the cookie group

*/
function getCookieVar(){
	
}

/*convert " and ' symbols to html friendly ascii code

@str = string input
*/
function convertquotes( str ) {
    return (str+'').replace(/([\\"'])/g, "&quot;").replace(/\0/g, "\\0");
}

/* builds and returns a querystring in format parameter=value&parameter2=value2

@postParameters = array of querystring parameters
@postParameterValues = array of associated parameter values
*/
function buildQuerystring(postParameters,postParameterValues){	
	  var poststr = '';
	  for(var i=0;i<postParameters.length;i++){
		poststr += escape(postParameters[i].replace(/[\$\.]/g,'')) + '=' + escape(postParameterValues[i]);
			if((postParameters.length-1)!=i){
				poststr += '&';
				}
		}
		return poststr;
}	

/* print a hidden image (used to post information to an off-domain external script)

@baseSrc = rootUrl of image
@postformid = form to gather variables from
@spantoprintimage = id attribute value of html tag to print the image in
*/
function printHiddenImage(baseSrc,postformid,spantoprintimage){
	var postedParameters=Array();
	var postedParameterValues=Array();
	var postedVars=false;
	var postform = d.getElementById(postformid);
	
	for(var i=0;i<postform.elements.length;i++){
		postedParameters[i]=postform.elements[i].name;
		postedParameterValues[i]=postform.elements[i].value;
	}
	postedVars = buildQuerystring(postedParameters,postedParameterValues);
    d.getElementById(spantoprintimage).innerHTML = '<img src="'+baseSrc+'?'+postedVars+'" style="display:none;"/>';
	//d.getElementById(spantoprintimage).innerHTML += baseSrc+'?'+postedVars;
	//alert(baseSrc+'?'+postedVars);
	return true;
}


/* disable the confirm button on invoice confirm page

@disableIt = boolean true false
@changeText = string change value to string
//@additionalFunctionsToCall [array] = array of additional functions to call upon click
*/
function modifyInvoiceButtonOnClick(disableIt,changeText){
   d.invoiceconfirm.elements[2].disabled=disableIt;
   d.invoiceconfirm.elements[2].value=changeText;
   return true;
}


/* for use with the terms agreement product
  disable/enables the checkout buttons on the modified Checkout template
  called as such  onClick="enableCheckoutButtons(Array('','',''),'')"
  
@idsOfButtons [array] = ids of the buttons to enable / disable based on the status of checkboxId
@checkboxId = the ids of the fields that control the buttons 
@eC = enabled classname (css) optional
@dC = disabled classname (css) optional
*/
function enableCheckoutButtons(idsOfButtons,idsToCheck,eC,dC){
 if(validateFields(idsToCheck)){
	for(var i in idsOfButtons)
  		if(d.getElementById(idsOfButtons[i])){
			d.getElementById(idsOfButtons[i]).disabled=false;
			if(eC) changeClass(d.getElementById(idsOfButtons[i]),eC);
		}
 }else{
	for(var i in idsOfButtons)
  		if(d.getElementById(idsOfButtons[i])){
			d.getElementById(idsOfButtons[i]).disabled=true;
			if(dC) changeClass(d.getElementById(idsOfButtons[i]),dC);
		}
 }
}

/* vanquish a cookie
  
@name = name of cookie to slay
*/
function killCookie(name){    
   d.cookie = name + "=; expires=Thu, 01-Jan-70 00:00:01 GMT; "; //kill the cookie
}

/* resurrect a cookie

@name = name of cookie to summon
@value = value of cookie being conjured
*/
function setCookie(name, value){
	killCookie();
	var path = '/';
	var today = new Date();
	var expires = new Date();
	expires.setTime(today.getTime() + 1000*60*60*24*30); // expires in a month
	d.cookie = name + "=" + value + "; expires=" + expires.toGMTString() + "; path="+path+";"; //set it anew
	return true;
}

/* access a cookies' value

@n = name of cookie being accessed
*/
function readCookie(n) {
var cookiecontent = new String();
if(d.cookie.length > 0) {
	var cookiename = n+ '=';
	var cookiebegin = d.cookie.indexOf(cookiename);
	var cookieend = 0;
	if(cookiebegin > -1) {
		cookiebegin += cookiename.length;
		cookieend = d.cookie.indexOf(";",cookiebegin);
		if(cookieend < cookiebegin) { cookieend = d.cookie.length; }
		cookiecontent = d.cookie.substring(cookiebegin,cookieend);
		}
	}
return cookiecontent;
} // function ReadCookie()


/* check for key being pressed onKeyPress="checkKeyPressed(event)"
return true if matched

@e = event
@code = numerical code to check for match (13 being enter)
*/
function checkKeyPressed(e,code){ //e is event object passed from function invocation
	var characterCode; //literal character code will be stored in this variable
	
	if(e && e.which){ //if which property of event object is supported (NN4)
		e = e;
		characterCode = e.which; //character code is contained in NN4's which property
	}else{
		e = event;
		characterCode = e.keyCode; //character code is contained in IE's keyCode property
	}
	
	if(characterCode == code){ //if generated character code is equal to ascii 13 (if enter key)
		return true;
	}else{
		return false;
	}
}


/* return the y px coordinate of the browsers current viewable area */
function getBrowserYPxLocation(){
	if (window.innerHeight) return window.pageYOffset+window.innerHeight;
	else if (d.documentElement.clientHeight){ return d.documentElement.scrollTop+d.documentElement.clientHeight; }
	return d.body.scrollTop+d.getElementsByTagName('body')[0].clientHeight;
}

/* PROCESSES THE FLOATING CART'S LOCATION FOR IE  */
if(d.getElementById('floatCartOverlayContainer')){ //if using the floatcart
	window.onscroll=function(){ //on window scroll move the floating cart
		d.getElementById('floatCartOverlayContainer').style.top=getBrowserYPxLocation()+'px';
	}
}


/* ultimate ajax object //hunlock.com */
function ajaxObject(url, callbackFunction) {
  var that=this;      
  this.updating = false;
  this.disableResponseText = false;
  this.abort = function() {
    if (that.updating) {
      that.updating=false;
      that.AJAX.abort();
      that.AJAX=null;
    }
  }
  this.update = function(passData,postMethod,postFunction) { 
    if (that.updating) { return false; }
    that.AJAX = null;                          
    if (window.XMLHttpRequest) {              
      that.AJAX=new XMLHttpRequest();              
    } else {                                  
      that.AJAX=new ActiveXObject("Microsoft.XMLHTTP");
    }                                             
    if (that.AJAX==null) {                             
      return false;                               
    } else {
      that.AJAX.onreadystatechange = function() {  
        if (that.AJAX.readyState==4) {             
          that.updating=false;                
          if(!that.disableResponseText) that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML,postFunction);       
          else that.callback(that.AJAX.status,postFunction);         
          that.AJAX=null;                                         
        }                                                      
      }                                                        
      that.updating = new Date();                              
      if (/post/i.test(postMethod)) {
        var uri=urlCall+'?'+that.updating.getTime();
        that.AJAX.open("POST", uri, true);
        that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        that.AJAX.setRequestHeader("Content-Length", passData.length);
        that.AJAX.send(passData);
      } else {
        var uri=urlCall+'?'+passData+'&timestamp='+(that.updating.getTime()); 
        that.AJAX.open("GET", uri, true);                             
        that.AJAX.send(null);                                         
      }              
      return true;                                             
    }                                                                           
  }
  var urlCall = url;        
  this.callback = callbackFunction || function () { };
}

/* build a div popup tooltip from any element
<div onmouseover="buildToolTip(this,'Tool tip text','style:info;','style:info')">Text</div>

@fromElement = typically (this), where the tooltip is being linked from
@toolTipInnerHtml = the text inside the tooltip
@textStyle = css style attribute list
@internalStyle = the external wrapper style attribute list
*/
function buildToolTip(fromElement,toolTipInnerHtml,textStyle,internalStyle){
	//set the toolTip wrapping div
		var baseStyle = 'display:inline-block;position:relative;';
		internalHtml = d.createTextNode(toolTipInnerHtml);
		fromElement.style.cssText=baseStyle;
		
	//set the toolTip internal div
		tooltipInternal = d.createElement('div');
		internalStyle += 'display:block;position:absolute;top:-16px;left:100%;padding:3px;z-index:990;';
		tooltipInternal.style.cssText=internalStyle;
		
	//set the toolTip internal span font formatting
		tooltipInternalSpan = d.createElement('span');
		tooltipInternalSpan.style.cssText=textStyle;		
		
		tooltipInternalSpan.appendChild(internalHtml);
		tooltipInternal.appendChild(tooltipInternalSpan);
		fromElement.appendChild(tooltipInternal);
		
		fromElement.onmouseout = function(){ fromElement.removeChild(tooltipInternal); };
}

/*print a dropdown list from the passed array of information
printDropdown(Array('option1','option2'),'selectName','option2','doSomething();','printSelectToHere');

@arrayInput = array of options for select menu
@selectName = name of select menu
@selectedValue = default selected value
@onChange = javascript code to execute when the menu is changed
@printToID = id to print the conjured select to
@selectStyle = styling css
@nameAsInitial = boolean (true,false), if true makes the first option 'Select a '+name of the select menu, otherwise it says 'Choose One'
*/
function printDropdown(arrayInput,selectName,selectedValue,onChange,printToID,selectStyle,nameAsInitial){
	var builtSelect = '';
	builtSelect = '<select name="'+selectName+'" id="'+selectName+'" onChange="'+onChange+'" style="'+selectStyle+'">';
	if(nameAsInitial) builtSelect += '<option value="">Select a '+selectName+'</option>';
	else builtSelect += '<option value="">Choose One</option>';
	
	
	for(var i in arrayInput){
		if(arrayInput[i]==selectedValue) selected = 'SELECTED';
		else  selected = '';
		selectOption = '<option value="'+arrayInput[i]+'" '+selected+'>'+arrayInput[i]+'</option>';
		builtSelect += selectOption;	
	}
	builtSelect += '</select>';
	
	if(printToID){
		d.getElementById(printToID).innerHTML = builtSelect;
	}else{
		d.write(builtSelect);
	}
}

/* check an element input for not being blank

@idArray = array of ids to check 
*/
function validateFields(idArray){
	for(var i in idArray){
		var elementObject = d.getElementById(idArray[i]);
		if(elementObject){
			if(elementObject.type=='checkbox'){ 
				if(!elementObject.checked) return false;
			}else if(elementObject.type=='select'){
				if(elementObject.selected.value=='') return false;
			}else{
				if(elementObject.value=='') return false;
			}
		}	
	}
	return true;
}

/* change a class name

@ie = input element
@ic = change to class
*/
function changeClass(ie,ic){
	ie.className=ic;	
}

/* limit a textarea element to a certain number of characters
onkeyup="limitTextarea(this,200,'remainId')"

@ie = input element
@nc = number of characters to limit to
@st = send to element id number of characters remaining, optional
*/
function limitTextarea(ie,nc,st){
	if(nc-ie.value.length<=0) ie.value=ie.value.substring(0,nc-1);
	if(st) d.getElementById(st).innerHTML = nc-ie.value.length;
}

/* function to set a recently viewed products in order of most recently viewed

Use to add a recently viewed product (Product Detail template)
<script>
setRecentlyViewed(<ss:value source="$product.productNumber"/>);
</script>

Use to display recently viewed products
<ss:foreach item="productNumber" within="$string.split($request.getCookieValue('psrcv'),':::')">
  <ss:value source="$store.products[$math.set($productNumber)].name"/><br>
</ss:foreach>

@productno = product number to add
*/
function setRecentlyViewed(productno){
		var recentlyViewedArray = globals['psrav'];
		var newCookieValue = '';
		
		for(var i in recentlyViewedArray){
			if(recentlyViewedArray[i]!=productno && recentlyViewedArray[i]){
				newCookieValue += recentlyViewedArray[i]+':';
			}
		}
		
		newCookieValue = productno+':'+newCookieValue;
		setCookie('psrcv',newCookieValue);
}

/* add a product (with quantity and attributes) to the cart with an ajax post

requires the ultimate ajax object, pshelper.js global variables, restack & readCookie functions

quickadd = new quickAddProduct();
quickadd.pushProduct(1234,1,Array('value1','value2',n....),function);
								  
PERFORMING FUNCTIONS BEFORE, AFTER ALL PUSHED, AND AFTER INDIVIDUAL PUSHED

###############

//BEFORE
disableButton();

//DURING NEED TO PASS THE FUNCTION TO PERFORM
quickadd = new quickAddProduct(wrapUpTheRequest); //AFTER ALL PUSHED
quickadd.pushProduct(1234,1,Array('value1','value2',n....),function); //AFTER INDIVIDUAL PUSHED

*/
function quickAddProduct(runAfter){
	
	var that = this;
	this.pRemain = 0;
	this.isCompleted = false;	
	this.ajaxCallback = function(responseStatus,postFunction){ 
		that.pRemain--;
		that.isComplete();
		if(postFunction) postFunction(); 
	}
	this.ajaxHandler = new ajaxObject(globals['cartUrl'],this.ajaxCallback);
	this.ajaxHandler.disableResponseText = true; //necessary for IE issues posting to prostores servlets via ajax... gives error if you retrieve the responseText
	this.isComplete = function(){ if(that.pRemain==0)runAfter(); }
	
	/* this method will hold onto the ajax request until the previous one is finished posting */
	this.productQueue = function(postFunction){
		if(!that.ajaxHandler.updating || that.pRemain==1){//wait for it to finish with the current product	
			that.ajaxHandler.update(that.queryString,'GET',postFunction);
		}else{
			window.setTimeout(function(){that.productQueue();},10);
		}
	}
	
	this.pushProduct = function(prodNumber,qty,attributes,postFunction){
			that.pRemain++;
			that.rootUrl = globals['rootUrl'];
			that.prodNumber = prodNumber; 
			that.attrInput = attributes;
			that.finalAttributes = that.buildAttributes();
			if(qty){ that.quantity=qty; }
			if(!that.quantity){ that.quantity=1; }
			if(!that.prodNumber){ alert('push product fail, you need to specify a product number');return; }
			that.queryString = that.buildQuerystring();
			if(that.finalAttributes!='&'){ that.queryString += that.finalAttributes; }
			that.productQueue(postFunction);
	}
	
	this.buildAttributes = function(){
		var finalAttributeList = '';
		that.attrInput = restack(that.attrInput);
		for(var i in that.attrInput){
			attrNumber = parseFloat(i)+1;
			finalAttributeList += '&attributevalue_'+attrNumber+'='+encodeURIComponent(that.attrInput[i]);	
		}
		return finalAttributeList;
	}
	
	this.buildQuerystring = function(){ 	
		that.queryParameters = Array('smode','product_no','qty');
		that.queryPValues = Array('add',that.prodNumber,that.quantity);
		return buildQuerystring(that.queryParameters,that.queryPValues);
	}
}


/* inserts a hidden field to any form, takes variable name and value, plus the form dom node

@va = variable name
@v = variable value
@dn = form DOM node
<form (@dn)>
<input type=hidden name=@va value=@v> <-------- This is what is inserted
</form>
*/
function addHiddenField(va,v,dn){
	//test for presence of field and update if already a field in the form
	for(var i=0;i<dn.elements.length;i++){ if(dn.elements[i].name==va){ dn.elements[i].value=v; var ud=1; break; }}
	if(ud!=1){
		var hi = d.createElement('input');
		hi.setAttribute('type','hidden');
		hi.setAttribute('name',va);
		hi.setAttribute('value',v);
		dn.appendChild(hi);
	}
}