/*
eV.trim(string);
eV.bookmark(title,url)
eV.in_array(array,itemtomatch) = bool
eV.array_search(array,itemtomatch) = int (-1 = not found)
eV.queryStringToArray(querystring) = array
eV.AJAXgetData(dataSource,functionOnComplete) = calls [functionOnComplete](output)
eV.CSVtoArray(data,maxRows) = array
eV.layerPopUpClose(parent,child)
eV.layerPopUp(title,content,id)
eV.mdArrElemToArr(arr,key) = array
eV.arrayToTable(array) = tableString
eV.productPriceInit(formNameRE,elementIdRE,priceDataArr);
eV.productPriceGet(productId)
eV.eventAdd(obj,type,fn); // crossbrowser add event to object
eV.eventRemove(obj,type,fn); // cross browser remove event from object
eV.exitTriggerSet(func); // sets a pop up to display when leaving the site
eV.exitPopUp(file);
eV.browserWindow(targetWindow) // returns object crossbrowser x,y,innerWidth,innerHeight of targetWindow
eV.elemTween(id)
eV.opacityGet(id)
eV.opacitySet(id)
eV.styleGet(obj,style)
eV.productRequireOptions();
eV.inlineFormTools()
eV.formElemValue(formElement)

eV.bannerZone_bannerChange(zoneId,bannerIndex)
eV.bannerZone_rotateInit()
eV.bannerZone_rotateInterval(zoneId)
eV.bannerZone_changeManual(zoneId,bannerIndex)

eV.drag.init(); // once on script
eV.drag.set(buttonElementId,movingElementId); // to set each draggable element


////////// HISTORY ////////////
2/10/2009 mwexler added exitTriggerSet function
2/11/2009 mwexler added exitPopUp, browserWindow functions
3/6/2009 mwexler added elemTween, opacityGet, opacitySet, browser correction for setTimeout, setInterval
3/8/2009 mwexler added styleGet
3/17/2009 mwexler added bannerZone_bannerChange, bannerZone_rotateInit, bannerZone_rotateInterval, bannerZone_changeManual
5/21/2009 mwexler: eV.productPriceGet: added quantity qualifier that compares against incremetns, minQuantity and maxQuantity
5/21/2009 mwexler: eV.prodPriceInit: adjusted to show '-' when producePriceGet return val is false
8/14/2009 mwexler: eV.ajaxGetData: added pass thru arguments
10/14/2009 mwexler: added eV.inlineFormTools, eV.formElemValue
12/22/2009 mwexler: eV.productPriceInit: added support for per item price element
1/10/2010 mwexler: eV.productPriceGet, ev.productPriceInit - added support for quantity# fields
1/15/2010 mwexler: eV.priductPriceInit: added chainfunction support
*/

//alert('called getbanners');
// only create if not created already
// line 50

if(typeof eV == "undefined"){
	var eV = {
		test : function(){
			alert('test successful');
		},
		inlineFormTools : function(){
		
			// set private functions
			// sets a field to validate
		
			
			validateSet = function(elem){
				// creates error message div
				var eElem = document.createElement('div');
				eElem.innerHTML = '&nbsp;';
				elem.parentNode.appendChild(eElem);
				if(elem.getAttribute('validateMessageClass')) eElem.className = elem.getAttribute('validateMessageClass');
				
				// elem type specific settings
				switch(elem.type.toLowerCase()){
					case "select-one":
						eV.eventAdd(elem,'change',function(){validateExec(this)});
						elem.errorNode = eElem;
						break;
					case "checkbox":
						eV.eventAdd(elem,'click',function(){validateExec(this)});
						elem.errorNode = eElem;
						break;
					case "radio":
						for(var i=0;i<elem.form.elements.length;i++){
							var fElem = elem.form.elements[i];
							if(fElem.name == elem.name && fElem.type == elem.type) { 
								eV.eventAdd(fElem,'click',function(){validateExec(this)});
								fElem.errorNode = eElem;
								fElem.setAttribute('validate',elem.getAttribute('validate'));
							};
						};
						
						break;
					default:
						eV.eventAdd(elem,'keyup',function(){validateExec(this)});
						elem.errorNode = eElem;
						break;
				};
				
				//eV.eventAdd(elem,'focus',function(){this.setAttribute('validationTimer',0);});
		
			};
			// executed as field changes to check for check validation
			validateExec = function(elem){
				
				//var date = new Date();
				//var ms = date.getTime();
				//if(elem.getAttribute('validationTimer') == 0) elem.setAttribute('validationTimer',ms);
				
				var vStr = elem.getAttribute('validate');
				var vArr = vStr.split(',');
				var isErr = false;
			
				for(var i in vArr){
					var vvArr = vArr[i].split(':');
					var vCom = vvArr[0];
					// get value, depending on element
					var value = eV.formElemValue(elem);
					switch(vCom){
						case "min":
							//alert(elem.value.length + ' vs ' + vParam);
							var vParam = vvArr[1];
							var vMsg = vvArr[2];
							if(parseInt(value.length) < parseInt(vParam)) {
								elem.errorNode.innerHTML = vMsg;
								isErr = true;
							};
							break;
						case "email":
							var vMsg = vvArr[1];
							//alert(elem.value.length + ' vs ' + vParam);
							var regex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
							if(!regex.test(value)) {
								elem.errorNode.innerHTML = vMsg;
								isErr = true;	
							};
							break;
						case "match":
							var vParam = vvArr[1];
							var vMsg = vvArr[2];
							if(eV.formElemValue(elem.form[vParam]) != eV.formElemValue(elem)) {
								elem.errorNode.innerHTML = vMsg;
								isErr = true;	
							};
							break;
						case "unique":
							var vMsg = vvArr[1];
							var datasource = 'index.php?fa=COMMON.validate&type=unique&field=u.emailAddress&value=' + encodeURI(value);
							eV.AJAXgetData(dataSource,functionOnComplete);
							break;
					};
				};
				if(!isErr) elem.errorNode.innerHTML = 'ok';
				elem.errorNode.style.color = (isErr) ? '#FF0000' : '#999999';
			// end validateExec
			};
			// handles returns of async validation requests
			validateAsync = function(data){
			
			};
			// sets up help for form element
			helpSet = function(elem){
				// elem = input field
				// setup button
				var aElem = document.createElement('a');
				aElem.innerHTML = "?";
				aElem.inputNode = elem;
				elem.helpButtonNode = aElem;
				aElem.setAttribute('helpMessage',elem.getAttribute('help'));
				eV.eventAdd(aElem,'click',function(){helpDisplay(this)});
				elem.parentNode.appendChild(aElem);
				if(elem.getAttribute('helpButtonClass')) aElem.className = elem.getAttribute('helpButtonClass');
				
				// setup message
				var dElem = document.createElement('div');	
				dElem.innerHTML = aElem.getAttribute('helpMessage');
				elem.parentNode.appendChild(dElem);
				elem.helpMessageNode = dElem;
				if(elem.getAttribute('helpMessageClass')) dElem.className = elem.getAttribute('helpMessageClass');
				dElem.style.visibility = 'hidden';
			};
			// executes when help button is pressed
			helpDisplay = function(elem){
				//alert(elem.inputNode.helpMessageNode.innerHTML);
				elem.inputNode.helpMessageNode.style.visibility = 'visible';
			};
			
			
			// apply form level classes to inputs
			var formElems = document.forms;
			for(var i=0;i< formElems.length;i++){
				var formElem = formElems[i];
				var formChildren = formElem.elements; // this is returning only direct children  - we need all.
				for(var ii=0;ii<formChildren.length;ii++){
					var formChild = formChildren[ii];
					if(formChild.tagName.toLowerCase() == 'input' || formChild.tagName.toLowerCase() == 'select' || formChild.tagName.toLowerCase() == 'textarea'){
						var inputElem = formChild;
						if(formElem.getAttribute('helpButtonClass') && !inputElem.getAttribute('helpButtonClass')) inputElem.setAttribute('helpButtonClass',formElem.getAttribute('helpButtonClass'));
						if(formElem.getAttribute('helpMessageClass') && !inputElem.getAttribute('helpMessageClass')) inputElem.setAttribute('helpMessageClass',formElem.getAttribute('helpMessageClass'));
						if(formElem.getAttribute('validateMessageClass') && !inputElem.getAttribute('validateMessageClass')) inputElem.setAttribute('validateMessageClass',formElem.getAttribute('validateMessageClass'));
						
						if(inputElem.getAttribute('help')) helpSet(inputElem);
						if(inputElem.getAttribute('validate')) validateSet(inputElem); 
					};
				};
			};
			
		// end inline form tools
		},

		formElemValue : function(elem){
			var value = null;
			switch(elem.type.toLowerCase()){
				case "select-one":
					if(elem.selectedIndex >= 0) value = elem.options[elem.selectedIndex].value;
					break;
				case "checkbox":
					if(elem.checked) value = elem.value;
					break;
				case "radio":
					var rName = elem.name;
					var form = elem.form;
					for(var ii=0;ii<form.elements.length;ii++){
						var fElem = form.elements[ii];
						if(fElem.name == rName && fElem.checked) value = fElem.value;
					};
					break;
				default:
					value = elem.value;
					break;
			};
			return value;
		},
		alertBox : function(title,content,attribs){
		 	var attribs = attribs || {};
			attribs.titleId = attribs.titleId || null;
			attribs.contentId = attribs.contentId || null;
			attribs.boxId = attribs.boxId || 'alertBox';
			attribs.closeId = attribs.closeId || null;
			//attribs.x = attribs.x || null;
			//attribs.y = attribs.y || null;

			eV.screenDisable();
			var disableElem = document.getElementById('screenDisable');
			
			var tbody = document.getElementsByTagName("body")[0];

			var alertBoxHolder = document.createElement('div');
			alertBoxHolder.style.width = disableElem.style.width;
			alertBoxHolder.style.height = disableElem.style.height;
			alertBoxHolder.style.top = '0px';
			alertBoxHolder.style.left = '0px';
			alertBoxHolder.style.position = 'absolute';
			alertBoxHolder.setAttribute('id','alertBoxHolder');
			alertBoxHolder.setAttribute('align','center');
			//if(attribs.y == null) alertBoxHolder.setAttribute('valign','middle');
			tbody.appendChild(alertBoxHolder);
			alertBoxHolder.style.zIndex = 51;
			
			var alertBox = document.createElement('div');
			
			//if(attribs.x != null) alertBox.style.left = attribs.x + 'px';
			//if(attribs.y != null) alertBox.style.top = attribs.y + 'px';		
			alertBox.setAttribute('id',attribs.boxId);
			//disableElem.setAttribute('align','center');
			alertBoxHolder.appendChild(alertBox);

			var titleElem = document.createElement('div');
			
			titleElem.style.width = '100%';
			//titleElem.innerHTML = title;
			if(attribs.titleId) titleElem.setAttribute('id',attribs.titleId);
			alertBox.appendChild(titleElem);
			

			var closeElem = document.createElement('div');
			closeElem.innerHTML = '<a href="javascript:eV.alertBoxClose();">X</a>';
			if(attribs.closeId) closeElem.setAttribute('id',attribs.closeId);
			titleElem.appendChild(closeElem);

			
			var titleTextElem = document.createElement('div');
			titleTextElem.innerHTML = title;
			titleElem.appendChild(titleTextElem);
			

			var contentElem = document.createElement('div');
			contentElem.innerHTML = content;
			contentElem.style.width = '100%';
			if(attribs.contentId) contentElem.setAttribute('id',attribs.contentId);
			alertBox.appendChild(contentElem);

			var targetHeight = parseInt(alertBox.offsetHeight);
			alertBox.style.position = 'absolute';
			alertBox.style.top = (alertBoxHolder.offsetHeight/2 - alertBox.offsetHeight/2) + 'px';
			alertBox.style.left = (alertBoxHolder.offsetWidth/2 - alertBox.offsetWidth/2) + 'px';
			//alert(alertBox.style.top);
			alertBox.style.height = '10px';
			
			var alertBoxTween = new eV.elemTween(attribs.boxId);
			alertBoxTween.seconds = .5;
			//alertBoxTween.targetWidth = 100; // in pixels
			alertBoxTween.targetHeight = targetHeight// in pixels
			//this.targetX = null; // in pixels
			//this.targetY = null; // in pixels
			alertBoxTween.hanchor = 'center'; // left, center, right
			alertBoxTween.vanchor = 'top'; // top, middle, bottom
			//this.targetOpacity = null; // 0 thru 10
			alertBoxTween.ease = 0; // -100 (ease in) thru 100 (ease out). 0 for none
			//this.chainFunction = null;
			alertBoxTween.start();
			
		},
		alertBoxClose : function() {
			if(document.getElementById('alertBoxHolder')) {
				var tBody = document.getElementsByTagName('body')[0];
				tBody.removeChild(document.getElementById('alertBoxHolder'));
			};
			eV.screenEnable(); 
		},
		screenDisable : function() {
  		
  			var zindex = 50;
  			var opacity = 70;
  			var opaque = (opacity / 100);
  			var bgcolor = '#000000';
   			var tbody = document.getElementsByTagName("body")[0];
			
    			var tnode = document.createElement('div');           // Create the layer.
        		tnode.style.position='absolute';                 // Position absolutely
        		tnode.style.top='0px';                           // In the top
       		tnode.style.left='0px';                          // Left corner of the page
        		tnode.style.overflow='hidden';                   // Try to avoid making scroll bars            
        		tnode.style.display='none';                      // Start out Hidden
        		tnode.id='screenDisable';                   // Name it so we can find it later
   			tbody.appendChild(tnode);                            // Add it to the web page
	
    			// Calculate the page width and height 
    				if(document.body && (document.body.clientWidth || document.body.clientHeight) ) {
					var pageHeight = document.body.clientHeight;
					var pageWidth = document.body.clientWidth;
				} else if ( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
       			 		var pageWidth = document.body.scrollWidth+'px';
        				var pageHeight = document.body.scrollHeight+'px';
   			 	} else if( document.body.offsetWidth ) {
     			 		var pageWidth = document.body.offsetWidth+'px';
      			 		var pageHeight = document.body.offsetHeight+'px';
    				} else {
      			 		var pageWidth='100%';
       		  	 		var pageHeight='100%';
    				} 
    			//set the shader to cover the entire page and make it visible.
    			tnode.style.opacity=0;                      
    			tnode.style.MozOpacity=0;                   
    			tnode.style.filter='alpha(opacity=0)'; 
    			tnode.style.zIndex=zindex;        
    			tnode.style.backgroundColor=bgcolor;  
    			tnode.style.width= pageWidth;
    			tnode.style.height= pageHeight;
    			tnode.style.display='block'; 
			tnode.interval = setInterval(eV.screenDisableRepos, 10);  

			tnode.bodyOverflow = tbody.style.overflow;  
			tbody.style.overflow = 'hidden'; 
			var tnodeTween = new eV.elemTween('screenDisable');
			tnodeTween.targetOpacity = opacity / 10;
			tnodeTween.seconds = .5;
			tnodeTween.start();
			                     
		},
		screenEnable : function(){
			if(document.getElementById('screenDisable')) {
				var tnodeTween = new eV.elemTween('screenDisable');
				tnodeTween.targetOpacity = 0;
				tnodeTween.seconds = .5;
				tnodeTween.chainFunction = function(){ 
					var tbody = document.getElementsByTagName("body")[0];
					tbody.style.overflow = document.getElementById('screenDisable').bodyOverflow;
					clearInterval(document.getElementById('screenDisable').interval);
					tbody.removeChild(document.getElementById('screenDisable'));
				};
				tnodeTween.start();
				
				
			};
		},
		screenDisableRepos : function(){
			if(document.getElementById('screenDisable')) {
				var screenDisable = document.getElementById('screenDisable');
				screenDisable.style.top = '0px';
				screenDisable.style.left = '0px';
				
				if(document.body && (document.body.clientWidth || document.body.clientHeight) ) {
					var pageHeight = document.body.clientHeight;
					var pageWidth = document.body.clientWidth;
				} else if ( document.body && ( document.body.scrollWidth || document.body.scrollHeight ) ) {
       			 		var pageWidth = document.body.scrollWidth+'px';
        				var pageHeight = document.body.scrollHeight+'px';
   			 	} else if( document.body.offsetWidth ) {
     			 		var pageWidth = document.body.offsetWidth+'px';
      			 		var pageHeight = document.body.offsetHeight+'px';
    				} else {
      			 		var pageWidth='100%';
       		  	 		var pageHeight='100%';
    				}  
				
			
				screenDisable.style.height = pageHeight;
				screenDisable.style.width = pageWidth;
			};
			eV.alertBoxRepos();
		},
		alertBoxRepos : function(){
			if(document.getElementById('alertBoxHolder')) {
				var disableElem = document.getElementById('screenDisable');
				var alertBoxHolder = document.getElementById('alertBoxHolder');
				alertBoxHolder.style.width = disableElem.style.width;
				alertBoxHolder.style.height = disableElem.style.height;
				alertBoxHolder.setAttribute('align','center');
			};
		},
		menuExpander : function(elem,params){
			// incoming params 
			params.controlTag = params.controlTag || 'span';
			//params.controlClass = params.controlClass || null;
			
			// elem should be the top <ul> around the entire menu
			var debugVal = 'li length:' + elem.getElementsByTagName('li').length;
			for(childIndex in elem.getElementsByTagName('li')){
				//debugVal += '\n childIndex:' + childIndex;
				var child = elem.getElementsByTagName('li')[childIndex];

				if(typeof child.childNodes != 'undefined'){
					var menuElem = null;
					var controlElem = null;
					var menuElemParent = null;
					for(subChildIndex in child.childNodes) {
						//debugVal += '\nsubChildIndex:' + subChildIndex;
						var subChild = child.childNodes[subChildIndex];
						//debugVal += '\nsubChild.tagName:' + subChild.tagName + ' nodeName:' + subChild.nodeName;
						if(typeof subChild.tagName != 'undefined' && subChild.tagName.toLowerCase() == 'ul' && menuElem == null) menuElem = subChild;
						if(typeof subChild.tagName != 'undefined' && subChild.tagName.toLowerCase() == params.controlTag.toLowerCase() && controlElem == null) controlElem = subChild;

					};
					if(menuElem) menuElemParent = menuElem.parentNode.parentNode;
					if(!menuElem && controlElem){
						// debugVal += '\ntrying for outside ul';
						// try for ul outside of li
						var menuElemPossible = false;
						// loop thru elem children
						for(subChildIndex in controlElem.parentNode.parentNode.childNodes){
							var subChild = controlElem.parentNode.parentNode.childNodes[subChildIndex];
							// if this is a ul and menuELem is possible, mark this as menuElem
							if(typeof subChild.tagName != 'undefined' && subChild.tagName.toLowerCase() == 'ul' && menuElem == null && menuElemPossible == true) menuElem = subChild;
							// if passed first item following matching subChild and menuElemPossible, mark as not possible
							// this is because only the ul immediatly following the current subChild can possible qualify
							if(typeof subChild.tagName != 'undefined' && menuElemPossible) menuElemPossible = false;
							// we are at element matching the current child, next element could be menuElem, lets flag as possible
							if(subChild == child) menuElemPossible = true;
							//debugVal += '\nend loop menuElemPossible:' + menuElemPossible + ' menuElem:' + menuElem;
							//debugVal += '\nlooping tagName:' + subChild.tagName + ' menuElem:' + menuElem + ' menuElemPossible:' + menuElemPossible;
							
						};
					};
					if(menuElem && !menuElemParent) menuElemParent = menuElem.parentNode;
					

					if(menuElem && controlElem) {
						
						eV.eventAdd(controlElem,'click',eV.expandMenu);
						menuElem.setAttribute('fullHeight',menuElem.offsetHeight);
						menuElem.setAttribute('currentHeight',menuElem.offsetHeight);
						var menuHeight = parseInt(menuElem.offsetHeight);
						if(menuElemParent.getAttribute('currentHeight')) menuElemParent.setAttribute('currentHeight',parseInt(menuElemParent.getAttribute('currentHeight')) - menuHeight);
							
		
						menuElem.style.height = '0px';
						menuElem.style.overflow = 'hidden';
						menuElem.setAttribute('targetHeight',0);
						debugVal += '\nSetting Expanded Menu for:' + controlElem.innerHTML + '. offsetHeight:' + menuElem.offsetHeight + ' height:' + menuElem.style.height + ' currentHeight:' + menuElem.getAttribute('currentHeight') + ' parent.currentHeight:' + menuElemParent.getAttribute('currentHeight');
					};
				};
				// set all to hide
				

			}; // line 75
			
			for(childIndex in elem.getElementsByTagName('ul')){
				var child = elem.getElementsByTagName('ul')[childIndex]; // line 100
				if(typeof child.currentHeight != 'undefined') {
					child.style.display = 'none';
					debugVal += '\nsetting display:' + child.style.display;
				};
				// set all to hide
			}; 
			
			
			//alert(debugVal);
		},

		expandMenu : function(e){
			
			e = e || window.event;
			var currentTarget = e.currentTarget || e.srcElement;
			var alertVal = 'expand: ' + currentTarget.parentNode.tagName;
			var menuElem = null;
			var menuParentCount = null;
			var debugVal = '';
			// child ul
			for(subChildIndex in currentTarget.parentNode.childNodes) {
				var subChild = currentTarget.parentNode.childNodes[subChildIndex];
				if(typeof subChild.tagName != 'undefined' && subChild.tagName.toLowerCase() == 'ul' && menuElem == null) menuElem = subChild;

			};
			if(menuElem) menuParentCount = 2;
			
			if(!menuElem){
				//inline ul
				var menuElemPossible = false;
				for(subChildIndex in currentTarget.parentNode.parentNode.childNodes) {
					var subChild = currentTarget.parentNode.parentNode.childNodes[subChildIndex];
					// if this is a ul and menuELem is possible, mark this as menuElem
					if(typeof subChild.tagName != 'undefined' && subChild.tagName.toLowerCase() == 'ul' && menuElem == null && menuElemPossible == true) menuElem = subChild;
					// if passed first item following matching subChild and menuElemPossible, mark as not possible
					// this is because only the ul immediatly following the current subChild can possible qualify
					if(typeof subChild.tagName != 'undefined' && menuElemPossible) menuElemPossible = false;
					// we are at element matching the current child, next element could be menuElem, lets flag as possible
					if(subChild == currentTarget.parentNode) menuElemPossible = true;
					//debugVal += '\nend loop menuElemPossible:' + menuElemPossible + ' menuElem:' + menuElem;
					//debugVal += '\nlooping tagName:' + subChild.tagName + ' menuElem:' + menuElem + ' menuElemPossible:' + menuElemPossible;
							
				};

			};
			
			if(!menuParentCount && menuElem) menuParentCount = 1;
			var heightChange = (menuElem.getAttribute('targetHeight') == 0) ? parseInt(menuElem.getAttribute('currentHeight')) : (-1*parseInt(menuElem.getAttribute('currentHeight')));

			menuElem.setAttribute('targetHeight',parseInt(menuElem.getAttribute('targetHeight')) + heightChange);
			menuElem.interval = window.setInterval(function(){eV.expandMenuTimer(menuElem)},1);
			alertVal += '\n setting interval ' + menuElem.interval + ' for targetHeight:' + menuElem.getAttribute('targetHeight') + ' currentHeight:' + menuElem.getAttribute('currentHeight');
			thisMenuElem = menuElem;
			thisMenuParentElem = (menuParentCount == 2) ? menuElem.parentNode.parentNode : menuElem.parentNode;
			while(thisMenuParentElem.getAttribute('currentHeight')){
				thisMenuElem = thisMenuParentElem;
				thisMenuElem.setAttribute('currentHeight',parseInt(thisMenuElem.getAttribute('currentHeight')) + heightChange);
				
				thisMenuElem.setAttribute('targetHeight',thisMenuElem.getAttribute('currentHeight'));
				//thisMenuElem.interval = window.setInterval(function(){eV.expandMenuTimer(thisMenuElem)},1);
				//alertVal += '\n setting interval ' + thisMenuElem.interval + ' for targetHeight:' + thisMenuElem.getAttribute('targetHeight') + ' currentHeight:' + thisMenuElem.getAttribute('currentHeight');
				thisMenuParentElem = (menuParentCount == 2) ? thisMenuElem.parentNode.parentNode : thisMenuElem.parentNode;
			};
			
			//alert(alertVal);
		},
		expandMenuTimer : function(menuElem){
			var tH = menuElem.getAttribute('targetHeight');
			var cH = parseInt(menuElem.style.height);
			menuElem.style.height = (tH > cH) ? (''+(cH+2)+'px') : (''+(cH-2)+'px');
			
			var allDone = true;
			if(tH >= cH-1 && tH <= cH+1) {
				menuElem.style.height = tH+'px';				
			} else {
				allDone = false;
			};
			menuElem.style.display = (parseInt(menuElem.style.height) > 0) ? "block" : "none"; 
			var thisMenuElem = menuElem;
			while(thisMenuElem.parentNode.parentNode.getAttribute('currentHeight')){
				thisMenuElem = thisMenuElem.parentNode.parentNode;
				var tH = thisMenuElem.getAttribute('targetHeight');
				var cH = parseInt(thisMenuElem.style.height); // line 150
				if(cH != tH){
					thisMenuElem.style.height = (tH > cH) ? (''+(cH+1)+'px') : (''+(cH-1)+'px');
					if(tH >= cH-1 && tH <= cH+1) {
						thisMenuElem.style.height = tH+'px';				
					} else {
						allDone = false;
					};
					thisMenuElem.style.display = (parseInt(thisMenuElem.style.height) > 0) ? "block" : "none"; 
				};
			};
			if(allDone) window.clearInterval(menuElem.interval);
		},

		productRequireOptions : function(formObj) {
			// call function as onSubmit for product forum
			// <form action='index.php' method = 'post' onSubmit='eV.productRequireOptions();'>
			var optionsSet = true;
			for(var i in formObj.elements) {
				var elem = formObj.elements[i];
				try{
					if((elem.name.indexOf('group') === 0 || elem.name.indexOf('option') === 0)
						&& elem.options[elem.selectedIndex].value == ''){
						alert('We are sorry, but more information is needed to order this item. Please select all options for this item and then continue your order.');
						optionsSet = false;
						break;
					// end if this is an option group
					};
				} catch (err){
					// do nothing
				};
			// end elements loop
			};
			return optionsSet;	
		},
		// changes banner. called on by BOTH the automatic interval AND manual button presses
		bannerZone_bannerChange : function(zoneId,bannerIndex) {
			// get the elem from the zoneId
			var div = document.getElementById('eV_bannerZone' + zoneId);
			// accomidate the "+" and "-" command to go back / forward in rotation
			switch(bannerIndex){
				case "+":
					// increment
					div.setAttribute('rotateIndex',parseInt(div.getAttribute('rotateIndex'))+1);
					break;
				case "-":
					// decrement
					div.setAttribute('rotateIndex',parseInt(div.getAttribute('rotateIndex'))-1);
					break;
				default:
					// pinpoint specific banner
					div.setAttribute('rotateIndex',bannerIndex);
					break;
			};
			//alert(':' + div.rotateIndex + ':' + bannerIndex);
			// lets build arrays of the banners AND the buttons for this bannerZone
			var banners = new Array();
			var buttons = new Array();
			var zoneDivs = div.getElementsByTagName('div');
			for(var i=0;i<zoneDivs.length;i++) if(zoneDivs[i].getAttribute('bannerId')) banners[banners.length] = zoneDivs[i];
			var zoneAnchors = div.getElementsByTagName('a');
			for(var i=0;i<zoneAnchors.length;i++) if(zoneAnchors[i].getAttribute('bannerId')) buttons[buttons.length] = zoneAnchors[i];
			
			// error check - make sure zone is trying to show banner that is available
			if(parseInt(div.getAttribute('rotateIndex')) >= banners.length || isNaN(parseInt(div.getAttribute('rotateIndex')))) div.setAttribute('rotateIndex',0);
			if(parseInt(div.getAttribute('rotateIndex')) < 0) div.setAttribute('rotateIndex',banners.length-1);
			//alert(div.getAttribute('rotateIndex'));
			
			// ok loop thru ALL banners and buttons for this zone
			// and display, hide or reformat accordingly
			for(var i=0;i<banners.length;i++){
				banners[i].style.display = (i == div.getAttribute('rotateIndex')) ? 'block' : 'none';
				if(buttons.length && buttons[i]) buttons[i].className = (i == div.getAttribute('rotateIndex')) ? 'eV_bannerZoneButtonSelected' : 'eV_bannerZoneButton';
			};
		},
		
		
		// this function initializes all rotating banner zones on the page
		// to act as rotating banners
		bannerZone_rotateInit : function(){
			// loop thru all the Divs in the entire page, find those that are bannerZnes
			var divs = document.getElementsByTagName('div');
			//var alertVal = '';
			for(var i=0;i<divs.length;i++){
				var div = divs[i];
				if(div.getAttribute('zoneId') && div.getAttribute('rotateDelay')){
					//alertVal .= '\nzoneId:' + div.getAttribute('zoneId') + ' rotateDelay:' + 
					// this is a banner zone, we know because it has the zoneId attrib
					// preset some variables
		
					// rotate interval - this sets the the timer that rotates the banner
					div.setAttribute('rotateIntervalId',setInterval(eV.bannerZone_rotateInterval, div.getAttribute('rotateDelay')*1000,div.getAttribute('zoneId')));
					
					eV.eventAdd(div,'mouseover',function(e){
						this.setAttribute('isRotating',0);
						//alert(this.getAttribute('isRotating'));
					});
					eV.eventAdd(div,'mouseout',function(e){
						this.setAttribute('isRotating',1);
					});
					
					div.style.width = div.offsetWidth + 'px';
					div.style.height = div.offsetHeight + 'px';
					div.style.overflow="hidden";
		
				
				};
			};
		},
		
		// the rotate interval function that is called on at the banner zones specified rotation interval
		bannerZone_rotateInterval : function(zoneId){
			var div = document.getElementById('eV_bannerZone' + zoneId);
			// call on the banner change function and tell it to "+" increment the passed zone
			if(div.getAttribute('isRotating') == 1) eV.bannerZone_bannerChange(zoneId,'+');
		},
		
		// the manual change function is triggered when a button is clicked
		bannerZone_changeManual : function(zoneId,bannerIndex){
			// get the zone element
			var div = document.getElementById('eV_bannerZone' + zoneId);
			// stop the timed interval change - once a manual button is clicked, auto rotation is off
			clearInterval(div.getAttribute('rotateIntervalId'));
			// call on the banner change function and tell it to target a specific banner
			eV.bannerZone_bannerChange(zoneId,bannerIndex);
		},

		
		styleGet : function(obj,cAttribute){
			// browser independent style retrieval function
			// works even when they are not set
			//if ie
			if (obj.currentStyle){
				var curVal=eval('obj.currentStyle.'+cAttribute)
			}else{
				//if Mozilla/FF
				var curVal=eval('document.defaultView.getComputedStyle(obj, null).'+cAttribute)
			}
			return curVal;
		},
		
		elemTween : function (id){
			this.id = id;
			this.seconds = null;
			this.targetWidth = null; // in pixels
			this.targetHeight = null; // in pixels
			this.targetX = null; // in pixels
			this.targetY = null; // in pixels
			this.hanchor = null; // left, center, right
			this.vanchor = null; // top, middle, bottom
			this.targetOpacity = null; // 0 thru 10
			this.ease = 0; // -100 (ease in) thru 100 (ease out). 0 for none
			this.chainFunction = null;
		
			this.start = function() {
				var hErr = false;
				var wErr = false;
				var xErr = false;
				var yErr = false;
				var oErr = false;
				var now = new Date();
				this.startTime = now.getTime();
				//this.lastTime = this.startTime;
				this.lastEase = 0;
				var elem = document.getElementById(this.id);
				this.startWidth = parseInt(elem.style.width);
				this.startHeight = parseInt(elem.style.height);
				// get coords
				/*
				var coords = this.getCoords(this);
				this.startX = coords.x;
				this.startY = coords.y;
				*/
				this.startX = null;
				this.startY = null;
				switch(this.hanchor){
					
					case 'right':
						this.startX = parseInt(elem.style.left)+parseInt(elem.style.width);
						break;
					case 'center':
						this.startX = parseInt(elem.style.left)+(parseInt(elem.style.width)/2);
						break;
					default:
						this.startX = parseInt(elem.style.left);
						break;
				};
				switch(this.vanchor){
					case 'bottom':
						this.startY = parseInt(elem.style.top)+parseInt(elem.style.height);
						break;
					case 'middle':
						this.startY = parseInt(elem.style.top)+(parseInt(elem.style.height)/2);
						break;
					default:
						this.startY = parseInt(elem.style.top);
						break;
				};
		
				
				this.currentX = this.startX;
				this.currentY = this.startY;
				if(!this.targetX) this.targetX = this.startX;
				if(!this.targetY) this.targetY = this.startY;
				this.startOpacity = eV.opacityGet(this.id);
				this.currentOpacity = this.startOpacity;
				this.debug = '';
				//this.intervalId = setInterval(function(obj){
				this.intervalId = setInterval(function (obj){
					//var browser = eV.browserWindow(window);
					// shortcut elem
					var elem = document.getElementById(obj.id);
					var now = new Date();
					var thisTime = now.getTime();
					//var percTimeSinceLast = (thisTime - obj.lastTime) / (obj.seconds*1000);
					var percTimePassed = (thisTime - obj.startTime) / (obj.seconds*1000);
					
					// tween adjustment
					if(obj.ease < 0) {
						var thisEase = 1- Math.pow (1-percTimePassed, -(obj.ease-1));
					} else if(obj.ease > 0) {
						var thisEase = Math.pow (percTimePassed, (obj.ease+1));
					} else {
						var thisEase = percTimePassed;
					};
					
					var adjustBy = thisEase - obj.lastEase;
					// just in case we overshoot parabola
					if(adjustBy < 0) adjustBy = 1;
					
					obj.lastEase = thisEase;
					//this.debug += '\nsec:' + obj.seconds + ' ltime:' + obj.lastTime + ' ttime:' + obj.thisTime + ' ptime:' + adjustBy + ' twid:' + obj.targetWidth + ' swid:' + obj.startWidth + ' cwid:' + elem.style.width;
					//obj.lastTime = thisTime;
					obj.lastPercTimePassed = percTimePassed;
					// move width
					if(obj.targetWidth != null){
						try{
							if(parseInt(elem.style.width) != obj.targetWidth){
								elem.style.width = (parseInt(elem.style.width) + ((obj.targetWidth-obj.startWidth)*adjustBy)) + 'px';
							};
							if(
								(parseInt(elem.style.width) > obj.targetWidth && obj.targetWidth > obj.startWidth) 
								|| (parseInt(elem.style.width) < obj.targetWidth && obj.targetWidth < obj.startWidth)
							) elem.style.width = obj.targetWidth + 'px';
						} catch(e){
							wErr = true;
						};
						
					};
					
					// move height
					if(obj.targetHeight != null){
						try{
							if(parseInt(elem.style.height) != obj.targetHeight){
								elem.style.height = (parseInt(elem.style.height) + ((obj.targetHeight-obj.startHeight)*adjustBy)) + 'px';
							};
							if(
								(parseInt(elem.style.height) > obj.targetHeight && obj.targetHeight > obj.startHeight)
								|| (parseInt(elem.style.height) < obj.targetHeight && obj.targetHeight < obj.startHeight)
							) elem.style.height = obj.targetHeight + 'px';
						} catch(e){
							hErr = true;
						};
					};
				
					// set new x and y
					if(obj.targetX != obj.currentX) {
						try{
							obj.currentX = obj.currentX + ((obj.targetX-obj.startX)*adjustBy);
						
						// adj x and y
							if(
								(obj.currentX > obj.targetX && obj.targetX > obj.startX)
								|| (obj.currentX < obj.targetX && obj.targetX < obj.startX)
							) obj.currentX = obj.targetX;
						} catch(e){
							xErr = true;
						};
					};
					
					if(obj.targetY != obj.currentY) {
						try{
							obj.currentY = obj.currentY + ((obj.targetY-obj.startY)*adjustBy);
							if(
								(obj.currentY > obj.targetY && obj.targetY > obj.startY)
								|| (obj.currentY < obj.targetY && obj.targetY < obj.startY)
							) obj.currentY = obj.targetY;
						} catch(e){
							yErr = true;
						};
					};
					// move elem
					if(elem.style.left){
						switch(obj.hanchor){
							
							case 'right':
								elem.style.left = (obj.currentX-parseInt(elem.style.width)) + 'px';
								break;
							case 'center':
								elem.style.left = (obj.currentX-(parseInt(elem.style.width)/2)) + 'px';
								break;
							default:
								elem.style.left = obj.currentX + 'px';
								break;
						};
					};
					if(elem.style.top){
						switch(obj.vanchor){
							case 'bottom':
								elem.style.top = (obj.currentY-parseInt(elem.style.height)) + 'px';
								break;
							case 'middle':
								elem.style.top = (obj.currentY-(parseInt(elem.style.height)/2)) + 'px';
								break;
							default:
								elem.style.top = obj.currentY + 'px';
								break;
						};
					};
					
					// opacity;
					if(obj.targetOpacity != null && obj.currentOpacity != obj.targetOpacity){
						try{
							obj.currentOpacity = (obj.currentOpacity + ((obj.targetOpacity-obj.startOpacity)*adjustBy));
							if(
								(obj.currentOpacity > obj.targetOpacity && obj.targetOpacity > obj.startOpacity) 
								|| (obj.currentOpacity < obj.targetOpacity && obj.targetOpacity < obj.startOpacity)
							) obj.currentOpacity = obj.targetOpacity;
						
							eV.opacitySet(obj.id,obj.currentOpacity);
						} catch(e){
							oErr = true;
						};
					};
						
				
					
					// clear interval if we are done
					if(
						(!obj.targetWidth || parseInt(elem.style.width) == obj.targetWidth || wErr) 
						&& (!obj.targetHeight || parseInt(elem.style.height) == obj.targetHeight || hErr) 
						&& (!obj.targetX || obj.targetX == obj.currentX || xErr) 
						&& (!obj.targetY || obj.targetY == obj.currentY || yErr) 
						&& (obj.targetOpacity == null || obj.targetOpacity == obj.currentOpacity || oErr)
					)
					{
							//alert(this.debug);
							clearInterval(obj.intervalId);
							if(obj.chainFunction) obj.chainFunction();
							
					}; 
				},33,this);
			// end start function
			};
		},

		opacitySet : function (id,opacity){
			document.getElementById(id).style.opacity = opacity / 10;
			document.getElementById(id).style.filter = 'alpha(opacity=' + (opacity * 10)+ ')';
			
			var children = null;
			if(document.getElementById(id).children) children = document.getElementById(id).children;
			if(document.getElementById(id).childNodes) children = document.getElementById(id).childNodes;
			if(children){
				for(var i=0; i<children.length;i++){
					if(children[i].style) {
						children[i].style.opacity = opacity / 10;
						children[i].style.filter = 'alpha(opacity=' + (opacity * 10)+ ')';
						children[i].style.MozOpacity = opacity / 10;                   
					};
				};
			};
		},
		
		opacityGet : function(id){
			var opacity = 10;
			if(document.getElementById(id).style.opacity) opacity = document.getElementById(id).style.opacity * 10;
			if(document.getElementById(id).style.filter && document.getElementById(id).style.filter.indexOf('opacity')) opacity = parseInt(document.getElementById(id).style.filter.substring(document.getElementById(id).style.filter.indexOf('opacity')+8,document.getElementById(id).style.filter.length))/10;
			return opacity;
		},

		
		eventAdd: function(obj,type,fn) {
			//eV.eventAdd(window.document.formName.fieldName,'mouseover',function() { alert(true); });
	
			if (obj.attachEvent) {
				obj['e'+type+fn] = fn;
				obj[type+fn] = function() { obj['e'+type+fn](window.event); }
				obj.attachEvent('on'+type,obj[type+fn]);
			} else
			obj.addEventListener(type,fn,false);
		},
		eventRemove: function(obj,type,fn) {
			if (obj.detachEvent) {
				obj.detachEvent('on'+type,obj[type+fn]);
				obj[type+fn] = null;
			} else
			obj.removeEventListener(type,fn,false);
		},
	
		
		trim : function(str) {
			return str.replace(/^\s+|\s+$/,"");
			/*
			str = str.replace(/^\s+/, '');
			for (var i = str.length - 1; i >= 0; i--) {
				if (/\S/.test(str.charAt(i))) {
					str = str.substring(0, i + 1);
					break;
				}
			}
			*/
			return str;
		},
	
		
		bookmark : function(title,url){
			if (window.sidebar) // firefox
				window.sidebar.addPanel(title, url, "");
			else if(window.opera && window.print){ // opera
				var elem = document.createElement('a');
				elem.setAttribute('href',url);
				elem.setAttribute('title',title);
				elem.setAttribute('rel','sidebar');
				elem.click();
			} 
			else if(document.all)// ie
				window.external.AddFavorite(url, title);
		},
		
		in_array : function(arr,matchObj){
			var isInArray = false;
			for(var i=0;i<arr.length;i++){
				if(arr[i] == matchObj){
					isInArray = true;
					break;
				};
			};
			return isInArray;
		},
		
		array_search : function(arr,matchObj){
			var index = -1;
			for(var i=0;i<arr.length;i++){
				if(arr[i] == matchObj){
					index = i;
					break;
				};
			};
			return index;
		},
		
		queryStringToArray : function(querystring){
			var returnArr = Array();
			var qsArr = querystring.split('&');
			for(var i=0;i<qsArr.length;i++){
				var valuePair = qsArr[i];
				var valuePairArr = valuePair.split('=');
				if(valuePairArr.length > 1 && valuePairArr[0].length > 0) returnArr[valuePairArr[0]] = decodeURIComponent(valuePairArr[1]);
			};
			return returnArr;
		},
	
		AJAXgetData : function(dataSource,functionOnComplete){
			// additional arguments can be appended and will be passed back, following the content variable, to the functionOnComplete
			var XMLHttpRequestObject = false;
			var returnVal = 'No file';
			if(window.XMLHttpRequest){
				XMLHttpRequestObject = new XMLHttpRequest();
			} else if (window.ActiveXObject){
				XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
			};
			if(XMLHttpRequestObject){
				XMLHttpRequestObject.open("GET", dataSource);
				XMLHttpRequestObject.argumentHolder = arguments;
				XMLHttpRequestObject.onreadystatechange = function(e){
					//if(window.event) {target = window.event.srcElement; alert('window.event.srcElement');};
					//if(event) {target = event.srcElement; alert('event.srcElement');};
					//if(e && e.target) {target = e.target; alert('e.target');};
					//ev = e.target || event.srcElement || window.event;
					//var alertVal = '';
					//for(i in this.argumentHolder) alertVal += '\n' + i;
					//for(i=2;i<arguments.length;i++) alertVal += '\n' + arguments[i];
					//alert(this.argumentHolder[2]);
					//alert('onreadystatechange readystate:' + XMLHttpRequestObject.readyState + ' status:' + XMLHttpRequestObject.status);
					if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200){
						returnVal = XMLHttpRequestObject.responseText;
						var functionToEval = functionOnComplete + '(returnVal';
						for(var i=2;i<this.argumentHolder.length;i++) functionToEval += ',this.argumentHolder[' + i +']';
						functionToEval += ');'
						//alert(functionToEval);
						eval(functionToEval);
					// end check ready state and status 
					// end if readystate = 4 or 200
					};
				// end onreadystatechange function
				};
				XMLHttpRequestObject.send(null);
			// end if XMLHttpRequestObject
			};
		// end function
		},
		
		CSVtoArray : function(data,maxRows){
			/* expects new line delim rows, comma delim fields, dquote as text identifier
			returns 2 dim array, first dim = rows, 2nd dim = values */
			// convert "" escapes to \" escapes
			//data= data.replace(/""/g,'\\"');
			var csvArray = Array();
			// c solution: ,(?=([^\"]*"[^"]*")*(?![^"]*"))
			/*
				,						// loop for comma
					(?=					// positive lookahead
						(
							[^\"]*"		// anything but quote repeated, until quote
							[^"]*"		// anything but quote repeated, until quote
						)
						*				// repeated
						(?!				// negative lookahead
								[^"]*"	// anything but quote repeated, until quote
						)
					)
			
			*/
			//var regex = /,(?=([^\"]*"[^"]*")*(?![^"]*"))/;
			//var regex = /(,|,(?=([^\"]*"[^"]*")*(?![^"]*")))/;
			
			//var regex = /,(?=([^"]*"[^"]*")*(?![^"]*"))/;
			
			//var regex = /,(?="[^"]*")/; // working only for quote
			//var regex = /((,(?="[^"]*"))|(,?!"))/;
			// var regex = /,(?=([^']*'[^']*')*(?![^']*'))/; // 4 guys from rolla 
			//var regex = /[ \t\r\n]*(.*?)[ \t\r\n]*=[ \t\r\n]*(\'[^\']*\'|\"[^\"]*\"|[^;]*?)[\t\r\n]*(;|$)/
			
			
			//eval('var regex = /,(?=' + textQualifier + '[^' + textQualifier + ']*' + textQualifier + ')/'); // working only for quote
			
			// start line split by enter
			/*
			var regex = /\n(?<!(\n|,)"[^"]*)/;
			
			//qualify \n that is not preceded by a (  ',"' or '\n"' ) that isnt followed by a '"'"
			
			*/
			// split to array of lines
			var csvArray = (maxRows == null) ? data.split('\n') : data.split('\n',maxRows);
			// begin looping thru lines
			for(i=0;i<csvArray.length;i++){
				// start field split by ,
				var regex = /,(?="[^"]*")/;
				
				var recordArray = csvArray[i].split(regex);
				var newRecordArray = Array();
				
				// now lets split up the remaining items
				for(var ii=0;ii<recordArray.length;ii++){
					var elem = recordArray[ii];
				//	document.writeln('<br>elem:' + elem);
					if(elem.indexOf('"') == 0 && elem.indexOf('"',1) == elem.length-1){
						// this is already a quoted item, just append to array and move on
						newRecordArray[newRecordArray.length] = elem;
						//document.writeln('<br>Fully enclosed quotes:' . elem);
						continue;
					};
					var elemArr = elem.split(',');
					var newElemArr = Array();
					// work backwords and gather all fields until we identify the end of a quoted text identifier field
					for(var iii=elemArr.length-1;iii>=0;iii--){
						var elemItem = elemArr[iii];
						//document.writeln('<br>checking elemItem:' + elemItem);
						if(elemItem.indexOf('"') == elemItem.length-1 && elemArr[0].indexOf('"') == 0 && elemItem.length > 0){
							// found quoted end and quoted beginning
							// last item = quoted string
							//document.writeln('<br>sliced item:' + elemArr.slice(0,iii+1).join(","));
							newElemArr[newElemArr.length] = elemArr.slice(0,iii+1).join(",");
							break;
						} else {
							// not quoted, this is its own element
							//document.writeln('<br>own:' + elemItem);
							newElemArr[newElemArr.length] = elemItem;
						};
					// end elemArr loop
					};
					
					newRecordArray = newRecordArray.concat(newElemArr.reverse());
					
				// end csvArray loop
				};
				// end lfield split by ,
				csvArray[i] = newRecordArray;
			// end of line loop
			};
			return csvArray;
		},
		layerPopUpClose : function(parent,child){
			parent.removeChild(child);
		},
		layerPopUp : function(title,content,id,leftX,topY){
			if(leftX == null) leftX = window.mouseX;
			if(topY == null) topY = window.mouseY;
			// dont double do same id
			if(!document.getElementById('eV_popUp' + id)) {
				var bodytag = document.getElementsByTagName('body')[0];
				var popup = document.createElement('div');
				popup.setAttribute('id','eV_popUp' + id);
				popup.className = 'eV_popUp';
				//popup.setAttribute('id','customPopUp__' + id);
				
				popup.style.position = "absolute";
				popup.style.zIndex = 999999;
				
				var popuptitle = document.createElement('div');
				popuptitle.className = 'eV_popUp_title';
				popuptitle.setAttribute('id','eV_popUp_title' + id);
				popup.appendChild(popuptitle);
				
				var popuptitletext = document.createElement('div');
				popuptitletext.className = 'eV_popUp_titleText';
				popuptitletext.setAttribute('id','eV_popUp_titleText' + id);
				popuptitle.appendChild(popuptitletext);
				
				var popuptitletextnode = document.createTextNode(title);
				popuptitletext.appendChild(popuptitletextnode);
				
				var popupcloselink = document.createElement('a');
				popupcloselink.setAttribute('href','javascript:eV.layerPopUpClose(document.getElementsByTagName(\'body\')[0],window.document.getElementById(\'eV_popUp' + id + '\'));');
				popupcloselink.className = 'eV_popUp_close';
				popupcloselink.setAttribute('id','eV_popUp_close' + id);
				popuptitle.appendChild(popupcloselink);
				
				var popupcloselinktext = document.createTextNode('x');
				popupcloselink.appendChild(popupcloselinktext);
				
				var popupcontent =document.createElement('div');
				popupcontent.className = 'eV_popUp_content';
				popupcontent.setAttribute('id','eV_popUp_content' + id);
				popupcontent.innerHTML = content;
				popup.appendChild(popupcontent);
				
				//alert(htmlOutput);
				//popup.innerHTML = htmlOutput;
				bodytag.appendChild(popup);
				
				// set as dragable
				eV.drag.init(); // once on script
				eV.drag.set('eV_popUp_title' + id,'eV_popUp' + id); // to set each draggable element
				
				// set location
				popup.style.left = leftX + 'px';
				popup.style.top = topY + 'px';
				//popup.style.left = event.clientX;
				//popup.style.top = event.clientY;
	
				
			};
			return 'customPopUp__' + id;
		},
		
		mdArrElemToArr : function(arr,key){
			var newArr = Array();
			for(var i=0;i<arr.length;i++){
				newArr[i] = arr[i][key];
			};
			return newArr;
		},
		
		
		arrayToTable : function(array){
			// loop thru rows
			var output = '<table border=2>';
			for(var i=0;i<array.length;i++){
				var row = array[i];
				var output = output + '<tr>';
				for(var ii=0;ii<row.length;ii++){
					var cell = row[ii];
					var output = output + '<td valign=top><font size=1>' + cell + '</font></td>';
				};
				var output = output + '</tr>'; 
			};
			output = output + '</table>';
			return output;
		},
		
		
		exitTriggerSet: function(func){
		
			eV.exitTriggerTest = true;
			eV.exitTriggerExec = func;
			eV.eventAdd(window,'unload',function(){if(eV.exitTriggerTest) eV.exitTriggerExec();});
			//eV.eventAdd(document.getElementsByTagName('body')[0],'click',function(e){eV.exitTriggerTest = false;});
			
			eV.eventAdd(window,'load',function(e){
				// set data array for tags. functions
				var tagArr = [
						{tagname : 'a', eventname : 'click'},
						{tagname : 'form', eventname : 'submit'}
				];
				
				
				//alert('-----\nappName:\n' + navigator.appName + '\n-------\nappVersion:\n' + navigator.appVersion + '\n------\nappMinorVersion:\n' + navigator.appMinorVersion + '\n------\nuserAgent:\n' + navigator.userAgent + '\n------\nappCodeName:\n' + navigator.appCodeName + '\n------\nplatform:\n' + navigator.platform);
				
				for(i=0;i<tagArr.length;i++){
					var tag = tagArr[i];
					var as=document.getElementsByTagName(tag.tagname);
					// loop thru tags
					for (ii=0;ii<as.length;ii++) eV.eventAdd(as[ii],tag.eventname,function(e){eV.exitTriggerTest = false;});
				// end for i loop 
				};
				
					// fix forms so submit method can envoke onsubmit functions.
					
				for( var i = 0; i < document.forms.length; i++ ) {
					var theForm = document.forms[i];
					theForm.originalSubmit = theForm.submit;
					theForm.submit = function() {
					  if ( this.onsubmit ) {
						if ( this.onsubmit() != false ) this.originalSubmit();
					  } else {
						this.originalSubmit();
					  }
					 // end submit function
					};
				// end for loop
				};
			// end eV.eventAdd(window,'load',function(e)
			});
		// end function
		},
		
		exitPopUp: function(file){
			// exit pop up that close if calling window doesnt land on same domain
			eV.exitTriggerSet(function(){
				// ? trick to circumvent some pop up blockers?
				document.domain = document.domain.substring(document.domain.indexOf('.')+1);
				var eVexitPopUp = window.open(file,'eVexitPopUp','width=10,height=10,resizable=0,menubar=0,status=0,directories=0,location=0,toolbar=0,top=' + (screen.height+20) + ', left=' + (screen.width+20));
				window.focus();
			 });
		},
		
		exitPopUpTest: function(){
			//alert('exitPopUpTest start');
			setTimeout(function(){
				//alert("exitPopUpTest timer");
				//alert(window.location.hostname + '\nvs\n' + window.opener.location.hostname);
				var hostMatch = false;
				try{
					if(window.location.hostname == window.opener.location.hostname) hostMatch = true;
					else hostMatch = false;	
				}
				catch(err) {
					hostMatch = false;
				};
				if(hostMatch){
					// same domain, close
					//alert('exitPopUpTest closing');
					window.close();
				} else {
					//alert('exitPopUpTest sizing');
					// new domain, size and move
					//window.document.write(eV.exitPopUpData.content);
					//window.moveTo(window.popUpData.parentx+100,window.popUpData.parenty+100);
					window.moveTo(100,100);
					window.resizeTo(eV.exitPopUpData.width,eV.exitPopUpData.height); 
					window.focus();
				};
			},100);
		},
		browserWindow : function(){
			var x = false;
			var y = false;
			var innerHeight = false;
			var innerWidth = false;
			var windowObj = window;
			// location
			if (typeof windowObj.screenLeft != "undefined"){ //IE
				x = windowObj.screenLeft;
				y =  windowObj.screenTop;
			}
				else if (typeof windowObj.screenX != "undefined"){ //NS/Moz
				x = windowObj.screenX;
				y = windowObj.screenY;
			};
			
			// dimensions
			if( typeof( windowObj.innerWidth ) == 'number' ) {
				 //Non-IE
					innerWidth = windowObj.innerWidth;
					innerHeight = windowObj.innerHeight;
			  } else if( windowObj.document.documentElement && ( windowObj.document.documentElement.clientWidth || windowObj.document.documentElement.clientHeight ) ) {
					//IE 6+ in 'standards compliant mode'
					innerWidth = windowObj.document.documentElement.clientWidth;
					innerHeight = windowObj.document.documentElement.clientHeight;
			  } else if( windowObj.document.body && ( windowObj.document.body.clientWidth || windowObj.document.body.clientHeight ) ) {
					//IE 4 compatible
					innerWidth = windowObj.document.body.clientWidth;
					innerHeight = windowObj.document.body.clientHeight;
			  };
			  
			  return {'x' : x, 'y' : y, 'innerWidth' : innerWidth, 'innerHeight' : innerHeight};

		},
	
		
		productPriceInit : function(formNameRE,elementIdRE,priceData,elementIdREper,chainFunctionName){
			if(!chainFunctionName) chainFunctionName = '';
			if(!elementIdREper) elementIdREper = '';
			// send formNameRE as xxx#yyy where # is the productId of the form
			// send targetIdRE as xxx#yyy where # is the productId of the target
			// incoming test
		//alert('\nformNameRE:' + formNameRE + '\nelementIdRE:' + elementIdRE + '\npriceData:' + priceData.length);
			for(var i in priceData){
				var productId = priceData[i].productId;
				var formName = formNameRE.replace('#',productId);
				var elementId = elementIdRE.replace('#',productId);
				var elementPerId = (elementIdREper.length > 0) ? elementIdREper.replace('#',productId) : '';
				if(document[formName] && (document[formName].quantity || document[formName]['quantity' + productId])){
					// test
					//alert('form found: ' + formName);
					var formObj = document[formName];
					formObj.elementIdHolder = elementId;
					formObj.elementPerIdHolder = elementPerId;
					formObj.formNameHolder = formName;
					formObj.productIdHolder = productId;
					formObj.priceDataHolder = priceData;
					formObj.chainFunctionName = chainFunctionName;
					formObj.quantityObj = (formObj.quantity) ? formObj.quantity : formObj['quantity' + productId];
					//alert('formObj.quantityObj' + formObj.quantityObj.value;
					eV.eventAdd(formObj.quantityObj,'keyup',function(e){
						//var debug = '';
						//for(var i in e.srcElement) debug += '\n' + i + ':' + e.srcElement[i];
						//alert(debug);
						var formObj = null;
						if(e.target) formObj = e.target.form; // FF
						if(e.srcElement) formObj = e.srcElement.form; // IE
						var price =  eV.productPriceGet(formObj.priceDataHolder,formObj.formNameHolder,formObj.productIdHolder);
						document.getElementById(formObj.elementIdHolder).innerHTML = (price === false) ? '-' : ('$' + price);
						if(formObj.elementPerIdHolder.length > 0 && document.getElementById(formObj.elementPerIdHolder)) document.getElementById(formObj.elementPerIdHolder).innerHTML = (price === false) ? '-' : ('$' + (parseFloat(price)/parseInt(formObj.quantityObj.value)).toFixed(2));
						// test
						//alert('quantity for form ' + formObj.formNameHolder + ' called');
						if(formObj.chainFunctionName.length > 0) window[formObj.chainFunctionName](formObj);
					});
					 // loop thru options and apply
					 for(var ii in priceData[i].optionGroupArray){
						 var groupId = priceData[i].optionGroupArray[ii].groupId;
						 var selectName = null;
						 if(formObj['option' + groupId]) selectName = 'option' + groupId;
						 if(formObj['group' + groupId]) selectName = 'group' + groupId;
						 if(selectName){
							 eV.eventAdd(formObj[selectName],'change',function(e){
								//alert('targetHolder:' + e.target.targetHolder + '\n' + 'formNameHolder:' + e.target.formNameHolder + '\n' + 'quantity:' + e.target.value);
								var formObj = null;
								if(e.target) formObj = e.target.form;
								if(e.srcElement) formObj = e.srcElement.form;
								var price =  eV.productPriceGet(formObj.priceDataHolder,formObj.formNameHolder,formObj.productIdHolder);
								document.getElementById(formObj.elementIdHolder).innerHTML = (price === false) ? '-' : ('$' + price);
								if(formObj.elementPerIdHolder.length > 0 && document.getElementById(formObj.elementPerIdHolder)) document.getElementById(formObj.elementPerIdHolder).innerHTML = (price === false) ? '-' : ('$' + (parseFloat(price)/parseInt(formObj.quantityObj.value)).toFixed(2));
								if(formObj.chainFunctionName.length > 0) window[formObj.chainFunctionName](formObj);
							});
							// end if selecName
						 };
						// end optionGroupArray loop
					 };
					 // ok lets call this once to set our price
					var price =  eV.productPriceGet(formObj.priceDataHolder,formObj.formNameHolder,formObj.productIdHolder);
					//alert(price);
					document.getElementById(formObj.elementIdHolder).innerHTML = (price === false) ? '-' : ('$' + price);
					if(formObj.elementPerIdHolder.length > 0 && document.getElementById(formObj.elementPerIdHolder)) document.getElementById(formObj.elementPerIdHolder).innerHTML = (price === false) ? '-' : ('$' + (parseFloat(price)/parseInt(formObj.quantityObj.value)).toFixed(2));
					
					if(formObj.chainFunctionName.length > 0) window[formObj.chainFunctionName](formObj);
					// end if formName && quantity exist 
				};
			// end priceData loop
			};
		// end function
		},
		
		productPriceGet : function(priceData,formName,productId){
			// gathers data from a product form and returns the price
			// must have productPriceGet object set on page via php function eV.productPriceGetJS
			/* 
			---------priceData structure:--------------
			{
				productIndex : {
						productId,
						lowPrice,
						lowFlatPrice,
						priceLevelArray {
							priceLevelIndex : {
								quantity
								price
								price2
								price3
								price4
							};
						};
						optionGroupArray : {
							optionGroupIndex : {
								groupId
								optionArray : {
									optionIndex : {
										price
										value
										priceOption
									};
								};
							};
						};
						increments,
						minQuantity,
						maxQuantity
				};
			};
			-------form structure:----------------
			priceData[priceIndex].optionGroupArray[optionGroupIndex].optionArray[optionIndex].value = 
			form.option#.options[form.option#.selectedIndex].value
			-- OR --
			form.group#.group[form.group#.selectedIndex].value
			form.quantity
			form.productId
			*/
			var alertData = '';
			
			var formObj = window.document[formName];
			//var target = document.getElementById[targetId];
			
			// find product data in priceData
			var productIndex = -1;
			for(var i in priceData){
				//alertData += '\npriceData[i].productId:' + priceData[i].productId + ' productId:' + productId;
				if(priceData[i].productId == productId){
					productIndex = i;
					break;
				};
			};
			alertData += '\nproductIndex:' + productIndex;
			
			// preset return val
			returnVal =  false;
			
			// test product index;
			if(productIndex == -1){
				alertData += '\ninvalid productId';
				//alert('invalid productId');
				// leaving returnval as false;
			} else {
				// shortcut pricedata for product
				var prodData = priceData[productIndex];
				// get quantity
				var quantityObj = (formObj.quantity) ? formObj.quantity : formObj['quantity' + productId];
				var quantity = (isNaN(parseInt(quantityObj.value))) ? 0 : parseInt(quantityObj.value);
				// validate quantity added 5/21/2009 by mwexler
				// clean up comparison vars
				var increments = (isNaN(parseInt(prodData['increments'])) || parseInt(prodData['increments']) <= 1) ? 1 : parseInt(prodData['increments']);
				var minQuantity = (isNaN(parseInt(prodData['minQuantity'])) || parseInt(prodData['minQuantity']) <= 1) ? 1 : parseInt(prodData['minQuantity']);
				var maxQuantity = (isNaN(parseInt(prodData['maxQuantity'])) || parseInt(prodData['maxQuantity']) <= 1) ? 0 : parseInt(prodData['maxQuantity']);
				// test quantity
				alertData += '\nquantity:' + quantity + ' mod:' + (quantity % increments) + ' minQ:' + minQuantity + ' maxQ:' + maxQuantity;
				if(quantity % increments != 0 || quantity < minQuantity || (maxQuantity > 0 && quantity > maxQuantity)){
					// quantity does not yet qualify, return false
					alertData += '\nquantity does not qualify, return false';
				} else {
					/////// part 1: group options prices /////////////////
					// start groupOptionsPrice
					var groupOptionsPrice = 0;
					// set priceOption - later used to SELECT which price to use in matched price level
					var priceOption = ''; // empty means first price option 'price', all others appended with integer 'price2','price3','price4'
					// get group options prices
					for(var i in prodData.optionGroupArray){
						var optionGroup = prodData.optionGroupArray[i];
						//alertData += '\noption group:' + optionGroup.groupId;
						for(var ii in optionGroup.optionArray){ 
							var loopOptionValue = optionGroup.optionArray[ii].value;
							var loopOptionPriceOption = optionGroup.optionArray[ii].priceOption;
							var loopOptionPrice = optionGroup.optionArray[ii].price;
							var formOptionValue= false;
							if(formObj['option' + optionGroup.groupId]) formOptionValue = formObj['option' + optionGroup.groupId].options[formObj['option' + optionGroup.groupId].selectedIndex].value;
							if(formObj['group' + optionGroup.groupId]) formOptionValue = formObj['group' + optionGroup.groupId].options[formObj['group' + optionGroup.groupId].selectedIndex].value;
							alertData += '\noption:' + loopOptionValue + ' vs ' + formOptionValue;
							// if this is a currently selected options, effect prices accordingly
							if(formOptionValue == loopOptionValue && !isNaN(loopOptionPrice)) {
								// increment groupOptionsPrice
								groupOptionsPrice += loopOptionPrice;
								// set priceOption
								if(!isNaN(parseInt(loopOptionPriceOption)) && parseInt(loopOptionPriceOption) > 1) priceOption = loopOptionPriceOption;	
							};
								
						};
					};
					
					///////// part 2: base price ///////////////
					// start basePrice as lowFlatPrice
					var basePrice = (isNaN(parseFloat(prodData.lowFlatPrice))) ? 999999 : parseFloat(prodData.lowFlatPrice);
					alertData += '\nlowFlatPrice:' + prodData.lowFlatPrice;
					// qualify bulk price
					var lowLevelQ = 0;
					var priceLevelIndex = -1;
					var lowLevelP = 999999;
					for(var i in prodData.priceLevelArray){
						var priceLevel = prodData.priceLevelArray[i];
						alertData += '\npriceLevel quantity:' + priceLevel.quantity + ' vs ' + quantity;
						if(!isNaN(parseInt(priceLevel.quantity)) && parseInt(priceLevel.quantity) <= quantity && parseInt(priceLevel.quantity) > lowLevelQ){
							lowLevelQ = parseInt(priceLevel.quantity);
							// set low level price, pull from correct price option considering the priceOption set from optionGroups
							// first fix price option
							if(!eV.in_array(['2','3','4'],priceOption)) priceOption = ''; 
							// now set lowLevelP to the correct price
							lowLevelP = parseFloat(priceLevel['price' + priceOption]);
							priceLevelIndex = i;
						};
					};
					alertData += '\nlowLevelP:' + lowLevelP;
					// set basePrice to level price, if matched
					if(priceLevelIndex > -1 && !isNaN(lowLevelP) && lowLevelP > 0 && lowLevelP < basePrice) basePrice = lowLevelP;
					// start outputPrice
					var outputPrice = (basePrice + groupOptionsPrice) * quantity;
					alertData += '\nbasePrice:' + basePrice + ' groupOptionsPrice:' + groupOptionsPrice + ' quantity:' + quantity;
					// assign the price
					// rounds to 2 dec places
					returnVal =  outputPrice.toFixed(2);
				// end quantity does not qualify
				};
			// end if productIndex == -1
			};
			alertData += '\nreturnVal:' + returnVal;
			//alert(alertData);

			return returnVal;
		// end function
		},
		
		drag : {
			/* to use drag
			eV.drag.init(); // once on script
			eV.drag.set(buttonElementId,movingElementId); // to set each draggable element
			
			buttonElementId= id of element that when clicked on drags
			movingElementId= id of element that moves when button is clicked on
			movingElement should contain buttonElement
			buttonElement and movingElement could be the same
			*/
			movemouse : function(e)
			{
			  if (eV.drag.isDrag)
			  {
				//document.getElementById(eV.drag.dobj.moveElemId).style.left = '' + (eV.drag.tx + window.mouseX - eV.drag.x) + 'px';
				//document.getElementById(eV.drag.dobj.moveElemId).style.top  = '' + (eV.drag.ty + window.mouseY - eV.drag.y) + 'px';
				document.getElementById(eV.drag.dobj.moveElemId).style.left = '' + (eV.drag.nn6 ? eV.drag.tx + e.clientX - eV.drag.x : eV.drag.tx + event.clientX - eV.drag.x) + 'px';
				document.getElementById(eV.drag.dobj.moveElemId).style.top  = '' + (eV.drag.nn6 ? eV.drag.ty + e.clientY - eV.drag.y : eV.drag.ty + event.clientY - eV.drag.y) + 'px';
				//alert('movemouse setting :' + eV.drag.dobj.moveElemId + ' x:' + document.getElementById(eV.drag.dobj.moveElemId).style.left + ' y:' + document.getElementById(eV.drag.dobj.moveElemId).style.top);
				return false;
			  }
			},
			
			selectmouse : function(e) 
			{
			
			  var fobj       = eV.drag.nn6 ? e.target : event.srcElement;
			  var topelement = eV.drag.nn6 ? "HTML" : "BODY";
			
			  while (fobj.tagName != topelement && fobj.dragMe != true)
			  {
				fobj = eV.drag.nn6 ? fobj.parentNode : fobj.parentElement;
			  }
	
			  if (fobj.dragMe)
			  {
				eV.drag.isDrag = true;
				eV.drag.dobj = fobj;
				eV.drag.tx = parseInt(document.getElementById(eV.drag.dobj.moveElemId).style.left+0);
				eV.drag.ty = parseInt(document.getElementById(eV.drag.dobj.moveElemId).style.top+0);
				eV.drag.x = eV.drag.nn6 ? e.clientX : event.clientX;
				eV.drag.y = eV.drag.nn6 ? e.clientY : event.clientY;
				document.onmousemove=eV.drag.movemouse;
				//alert('selectmouse called: tx:' + eV.drag.tx + ' ty:' + eV.drag.ty + ' x:' + eV.drag.x + ' y:' + eV.drag.y);
				return false;
			  }
			},
			
			init : function(){
				eV.drag.isDrag = false;
				eV.drag.x = null;
				eV.drag.y = null;
				eV.drag.tx = null;
				eV.drag.ty = null;
				eV.drag.dobj = null;
				eV.drag.ie=document.all;
				eV.drag.nn6=document.getElementById&&!document.all;
				onmousedown=eV.drag.selectmouse;
				onmouseup=new Function("eV.drag.isDrag=false");
			},
			
			set : function(clickElementId,moveElementId){
				clickelem = document.getElementById(clickElementId);
				moveelem = document.getElementById(moveElementId);
				clickelem.dragMe = true;
				clickelem.moveElemId = moveElementId;
				//elem.moveElemId = clickElementId;
				//moveelem.style.position = 'relative';
				moveelem.style.position = 'absolute';
				//alert('set complete');
			}
		// end drag
		},
		mousePosition : function(evt){
			/*
			evt = evt || window.event;
			var posArr = new Array(null,null);
			
			//if(evt == null) alert('test');
			if (evt.pageX != null) posArr[0] = evt.pageX;
			else if (evt.clientX != null)
			   posArr[0] =  evt.clientX + (document.documentElement.scrollLeft ?
			   document.documentElement.scrollLeft :
			   document.body.scrollLeft);
			else posArr[0] = null;
			
			if (evt.pageY != null) posArr[1] = evt.pageY;
			else if (evt.clientY != null)
			   posArr[1] = evt.clientY + (document.documentElement.scrollTop ?
			   document.documentElement.scrollTop :
			   document.body.scrollTop);
			else posArr[1] = null;
			*/
			evt = evt || window.event;
			var cursor = {x:0, y:0};
			if (evt.pageX || evt.pageY) {
				cursor.x = evt.pageX;
				cursor.y = evt.pageY;
			} 
			else {
				try{
				var de = document.documentElement;
				var b = document.body;
				cursor.x = evt.clientX + 
					(de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
				cursor.y = evt.clientY + 
					(de.scrollTop || b.scrollTop) - (de.clientTop || 0);
				} catch(e) {
					// do nothing
				};
			}
	 
			window.mouseX = cursor.x;
			window.mouseY = cursor.y;
		}
	
	};
	
	window.mouseX = 0;
	window.mouseY = 0;
	document.onmousemove = eV.mousePosition;
	

// end if(typeof eV == "undefined")
};

///////////////////////////////////////
//////// BROWSER CORRECTIONS //////////
///// get IE, Mozilla, others to work the same ////
////////////////////////////////////////

// setInterval in IE to accept arguements
 /*@cc_on
(function(f) {
	window.setTimeout = f(window.setTimeout);   // overwrites the global function!
	window.setInterval = f(window.setInterval); // overwrites the global function!
})(function(f) {
	return function(c, t) {
		var a = [].slice.call(arguments, 2);    // gathers the extra args
		return f(function() {
			c.apply(this, a);                   // passes them to your function
		}, t);
	};
});
@*/

// intializations at load
// banner ads
eV.eventAdd(window,'load',eV.bannerZone_rotateInit);
