/*
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,opacity[0-100])
eV.styleGet(obj,style)
eV.productRequireOptions();
eV.tableControl(elem)
eV.inlineFormTools()
eV.formElemValue(inputElem)
eV.formToQueryString(fElem)
eV.queryStringToForm(qString, fElem)

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/5/2009 mwexler: eV.tableControl Create
10/14/2009 mwexler: added eV.inlineFormTools, eV.formElemValue
10/17/2009 mwexler: added eV.formToQueryString, eV.queryStringToForm

12/14/2009 added calender functions ti inlineFormTools
12/15/2009 elemTween() - fixed height / width issue when jumped to negative amount
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
2/2/2010 mwexler: eV.productPriceGet: set quantity retreival to force base 10 to deal with leading 0 bug "010"
3/26/2010 mwexler: eV::productPriceGet: fixed bug where $0 base price would not work
9/14/2011 mwexler: eV.bannerZone_rotateInit: fixed IE9 bug where intervals where getting 2x created
*/

//alert('called getbanners');
// only create if not created already
// line 50

if(typeof eV == "undefined"){
	var eV = {
		test : function(){
			alert('test successful');
		},
		
		inlineFormTools : function(){
			
	
			// 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('ift_validate');
				//alert(vStr);
				var vArr = vStr.split(',');
				var isErr = false;
				elem.setAttribute('ift_isValid',false);
			
				for(var i in vArr){
					var vvStr = vArr[i];
					if(typeof vvStr == 'string' && vvStr.length > 0) {
						var vvArr = vvStr.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 "minNum":
								var vParam = vvArr[1];
								var vMsg = vvArr[2];
								if(parseFloat(value) < parseFloat(vParam) || parseFloat(value) == Nan) {
									elem.errorNode.innerHTML = vMsg;
									isErr = true;
								};
								break;
							case "num":
								var vMsg = vvArr[1];
								if(parseFloat(value) != value) {
									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;
						};
					// end if vvStr is valid
					};
				};
				if(!isErr){
					elem.errorNode.innerHTML = 'ok';
					elem.setAttribute('ift_isValid',true);
				};
				elem.errorNode.style.color = (isErr) ? elem.errorNode.getAttribute('ift_origColor') : '#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 helpMessageElemId = elem.getAttribute('ift_helpMessageElementId');
				var helpMessageElem = document.getElementById(helpMessageElemId);
				elem.helpMessageNode = helpMessageElem;
				helpMessageElem.displayHold = helpMessageElem.style.display;
				eV.eventAdd(elem,'click',function(){helpDisplay(this)});
				helpMessageElem.style.display = 'none'; //.visibility = 'hidden';
				//helpMessageElem.innerHTML = '<font color="#00F"><u>[x]</u></font> ' + helpMessageElem.innerHTML;
				eV.eventAdd(helpMessageElem,'click',function(){this.style.visibility = 'hidden';});
				/*
				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){
				if (elem.helpMessageNode.style.visibility == 'visible') {
					elem.helpMessageNode.style.visibility = 'hidden';
					elem.helpMessageNode.style.display = 'none';
				} else {
					elem.helpMessageNode.style.visibility = 'visible';
					elem.helpMessageNode.style.display = elem.helpMessageNode.displayHold;
				};
			};
			clearMessages = function(form){
				var elems = form.elements;
				for(var i=0;i<elems.length;i++){ // loop thru form elements
					var elem = elems[i];
					if(elem.getAttribute('ift_validateMessageElementId')) document.getElementById(elem.getAttribute('ift_validateMessageElementId')).style.visibility = 'hidden';
				};
				var as = form.getElementsByTagName('a');
				for(var i=0;i < as.length;i++){
					var a = as[i];
					if(typeof a.getAttribute('ift_helpMessageElementId') == 'string') document.getElementById(a.getAttribute('ift_helpMessageElementId')).style.display = 'none';
				};
			};
			// help elems
			var as = document.getElementsByTagName('a');
			for(var i=0;i < as.length;i++){
				var a = as[i];
				if(typeof a.getAttribute('ift_helpMessageElementId') == 'string') helpSet(a);
			};
			// apply form level classes to inputs
			var forms = document.forms;
			for(var i=0;i< forms.length;i++){ // loop thru forms
				var form = forms[i];
				var elems = form.elements;
				for(var ii=0;ii<elems.length;ii++){ // loop thru form elements
					var elem = elems[ii];
					
					if(elem.tagName.toLowerCase() == 'input' || elem.tagName.toLowerCase() == 'select' || elem.tagName.toLowerCase() == 'textarea'){ // is this an input, select or textarea field?
						// set validate behavior
						if(elem.getAttribute('ift_validate')) validateSet(elem); 
					
					}; // end if this is a input,select or textarea field
				}; // end form elements loop
				//eV.eventAdd(form,'submit',function(){validateAllExec(this)});
				//eV.methodChange(form,'submit',validateAllExec)
				//form.prototype.submit = function(){ alert(2); };
				form.inlineFormToolsSubmit = function(callback){
					var alertVal = '';
					//var forms = document.forms;
					var allValid = true;
					//for(var i=0;i< forms.length;i++){ // loop thru forms
						//var form = forms[i];
						var felems = this.elements; // this is returning only direct children  - we need all.
						for(var ii=0;ii<felems.length;ii++){ // loop thru form elements
							var felem = felems[ii];
							alertVal += '\n' + felem.name + ': ' + typeof felem.getAttribute('ift_isValid');
							if(typeof felem.getAttribute('ift_isValid') != 'object'){
								validateExec(felem);
								if(felem.getAttribute('ift_isValid') == 'false') allValid = false;
								alertVal += ': ' + felem.getAttribute('ift_isValid');
							};
						// end elems loop
						};
					// end forms loop
					//};
					// validate all items
					//alert(alertVal);
					document.getElementById(this.getAttribute('ift_validateMessageElementId')).style.visibility = (allValid) ? 'hidden' : 'visible';
					if(allValid) {
						clearMessages(this);
						callback();
					};
				// end form.inlineFormToolsSubmit
				};
				if(typeof form.getAttribute('ift_validateMessageElementId') == 'string') document.getElementById(form.getAttribute('ift_validateMessageElementId')).style.visibility = 'hidden';
				
			}; // end forms loop
		},
		
		methodChange : function(obj,method,func){
			// eV.methodChange(document.formName,'submit',newSubmitFunction)
			// make sure object is loaded before calling this function
			if(window.HTMLElement){
				// DOM-compliant Browsers 
				obj.prototype['_' + method] = obj.prototype[method]; // hold the original method
				obj.prototype[method] = func;
			} else {
				// IE does not expose it's HTMLElement object or its children
				obj['_' + method]= obj[method]; // hold the original method
				obj[method] = func;
			}
		},
		
		arrayToDOM : function(dataArr,prefix){
			if(!prefix) var prefix = '';
			//var alertVal = '';
			for(var i in dataArr) {
				//alertVal += '\n(' + i + '/' + i.replace(prefix,'') + ')';
				if((prefix == '' || i.indexOf(prefix) != -1) && document.getElementById(i.replace(prefix,''))) document.getElementById(i.replace(prefix,'')).innerHTML = dataArr[i];
			};
			//alert(alertVal);
		},
		
		arrayToForm : function(dataArr,fElem,prefix){
			if(!prefix) var prefix = '';
			var qString = eV.arrayToQueryString(dataArr);
			eV.queryStringToForm(qString,fElem,prefix);
		},
		
		queryStringToForm : function(qString,fElem,prefix){
			if(!prefix) var prefix = '';
			var alertVal = '';
			var qArr = qString.split('&');
			var dObj = new Object();
			for(var index in qArr){
				var eStr = qArr[index];
				if(typeof eStr == 'string' && eStr.length > 0) {
					var eArr = eStr.split('=');
					var eVar = eArr[0];
					var eVal = (eArr.length > 1) ? decodeURIComponent(eArr[1]) : '';
					//if(prefix == '' || aVar.indexOf(prefix) != -1) dObj[eVar.replace(prefix,'')] = eVal;
					if(prefix == '' || eVar.indexOf(prefix) != -1 && fElem[eVar.replace(prefix,'')]) {
						var elem = fElem[eVar.replace(prefix,'')];
						alertVal += '\n' + eVar.replace(prefix,'');
						eV.formElemSet(elem,eVal);
					}; // end if prefix
				}; // end if typeof
			}; // end qArr loop
			//alert(alertVal);
		},

		
		formToArray : function(fElem,valueList){
			var alertVal = 'valueList:' + valueList;
			var valueArr = (!valueList) ? new Array() : valueList.split(',');
			var arr = new Array();
			//var tagNameArr = new Array('input','textarea','select','text-area');
			for(index in fElem.elements){
				var elem = fElem.elements[index];
				alertVal += '\nindex:' + index + ' name:' + elem.name + ' type:' + elem.type + ' checked:' + elem.checked + ' selectedIndex:' + elem.selectedIndex;
				//) && eV.in_array(tagNameArr,elem.tagName.toLowerCase())
				if(valueArr.length == 0 || eV.in_array(valueArr,elem.name)){   
					var value = null;
					switch(elem.type){
						case "select-one":
							if(elem.selectedIndex >= 0) value = elem.options[elem.selectedIndex].value;
							break;
						case "checkbox":
						case "radio":
							if(elem.checked) value = elem.value;
							break;
						case "text":
						case "password":
						case "textarea":
						case "hidden":
							value = elem.value;
							break;
						default:
							break;
					};
					if(value != null && elem.name) arr[elem.name] = value;
				};
			};
			alertVal += '\narr: ' + eV.arrayToQueryString(arr);
			//alert(alertVal);
			return arr;
		},
		
		formToQueryString : function(fElem,valueList){
			var arr = eV.formToArray(fElem,valueList);
			var qString = eV.arrayToQueryString(arr);
			return qString;
		},
		
		
		formElemSet : function(elem,value){
			if(elem.type){
				switch(elem.type){
					case 'select-one':
						elem.selectedIndex = -1;
						for(var i in elem.options) if(elem.options[i].value == value) elem.selectedIndex = i;
						break;
					case 'checkbox':
					case 'radio':
						elem.checked = (elem.value == value) ? true : false;
						break;
					default:
						elem.value = value;
						break;
				}; // end swidth
			};
		},
		formElemValue : function(elem){
			return eV.formElemGet(elem);
		},
		formElemGet : 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;
		},
		
		
		tableControl : function(){
			/*
			example
			var x = new tableControl()
			x.divElem = document.getElementById('tableDiv');
			x.headerElam = document.getElementById('headerTable');
			x.dataElem = document.getElementById('dataTable');
			x.init();
			*/
			this.divElem = null;
			this.headerElem = null;
			this.dataElem = null;
			this.setColumnSort = false;
			this.setColumnResize = false;
			this.setColumnReorder = false;
			//// new model to support sep header table incoming
			
			this.init = function(callback){
				if(!callback) var callback = null;
				this.clear();
				// style outer div
				this.divElem.style.overflowY = 'auto';
				this.divElem.style.overflowX = 'hidden';		
				// style header table
				this.headerElem.style.borderCollapse = 'collapse';
				this.headerElem.style.border = '0';
				if(this.headerElem.style.position != 'absolute') {
					this.headerElem.style.tableLayout = 'absolute';
					this.headerElem.style.position = 'absolute';
					// necessary to lock in left, top position to maintain position, or it will move with reinitialization to the hidden top of the result table
					this.headerElem.style.left = this.headerElem.offsetLeft + 'px'; 
					this.headerElem.style.top = this.headerElem.offsetTop + 'px';
				};
							
				//document.write('<pre>' + divElem.innerHTML.replace(/\</g,'&lt;') + '</pre>');
				var tdElems = this.headerElem.getElementsByTagName('td');
				for(var i=0; i<tdElems.length;i++){
					//alertVal += '\n' + tdElems[i].tagName + ':' + tdElems[i].innerHTML;
					tdElems[i].style.textOverflow = 'ellipsis';
					tdElems[i].style.overflow = 'hidden';
					tdElems[i].style.whiteSpace = 'nowrap';
					
				};
		
				// style table
				this.dataElem.style.borderCollapse = 'collapse';
				this.dataElem.style.border = '0';
				this.dataElem.style.tableLayout = 'fixed';
				//elem.style.width = '100%';
				this.headerElem.holdWidth = this.dataElem.holdWidth = this.headerElem.offsetWidth;
			
				// column width holders
				this.currentColumnWidths = new Array();
				this.minColumnWidths = new Array();
				this.defaultMinColumnWidth = 30;
				this.columnHeaderCells = new Array();
				this.headerColElems = this.headerElem.getElementsByTagName('tr')[0].childNodes;
				var tdElems = this.dataElem.getElementsByTagName('td');
				alertVal = '';
				for(var i=0; i<this.headerColElems.length;i++){
					var headerColElem = this.headerColElems[i];
					if(headerColElem.tagName == 'TD' || headerColElem.tagName == 'TH'){
						var index = this.columnHeaderCells.length;
						this.columnHeaderCells[index] = headerColElem;
						this.currentColumnWidths[index] = headerColElem.offsetWidth;
						this.minColumnWidths[index] = (headerColElem.getAttribute('minWidth')) ? headerColElem.getAttribute('minWidth') : this.defaultMinColumnWidth;
						alertVal += '\nwidth:' + headerColElem.width + ' swidth:' + headerColElem.style.width + ' osWidth:' + headerColElem.offsetWidth + ' padleft:' + headerColElem.style.paddingLeft + ' padRight:' + headerColElem.style.paddingRight + ' borLeft:' + headerColElem.style.borderLeftWidth + ' borRight:' + headerColElem.style.borderRightWidth;
					};
				};
				//alertVal += '\nTOTAL width:' + headerElem.width + ' swidth:' + headerElem.style.width + ' osWidth:' + headerElem.offsetWidth;
				
				//alert(alertVal);
				// execute
				this.setControlTable(this.dataElem,this.headerElem);
				if(this.setColumnResize) this.initColumnResize();
				if(this.setColumnSort) this.initColumnSort();
				if(this.setColumnReorder) var t = new setDrag(this.dataElem.id,this.headerElem.id,this);
				if(callback) callback();
			// end init
			};
			
			this.clear = function(){
				this.clearControlTable();
				if(this.setColumnSort) this.clearSort();
				if(this.setColumnResize) this.clearResize();
			};
			
			
			this.initColumnSort = function() {
				//this.divElem = divElem;
				//this.headerElem = headerElem;
				//this.dataElem = dataElem;
				var tdElems = this.headerElem.getElementsByTagName('tr')[0].getElementsByTagName('td');
				//// end new model to suppot sep header table incoming
				this.sortASC = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.tableControl.sortRows(t.cellIndex,'ASC');
				};
				this.sortDESC = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.tableControl.sortRows(t.cellIndex,'DESC');
				};
				this.sortDESCover = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.src = '/sysimages/icon_sort_desc_active.gif';
				};
				this.sortDESCout = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.src = '/sysimages/icon_sort_desc_inactive.gif';
				};
				this.sortASCover = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.src = '/sysimages/icon_sort_asc_active.gif';
				};
				this.sortASCout = function(e){
					var e = e || window.event;
					var t = e.currentTarget || e.srcElement;
					t.src = '/sysimages/icon_sort_asc_inactive.gif';
				};
				
				this.sortRows = function(colIndex,direction){
					alertVal = '';
					// get rows
					var rElems = this.dataElem.getElementsByTagName('tr');
					var hrElems = this.headerElem.getElementsByTagName('tr');
					// set sort type
					var firstDataCell = rElems[0].getElementsByTagName('td')[colIndex];
					var firstVal = (typeof firstDataCell.getAttribute('sortValue') == 'string') ? firstDataCell.getAttribute('sortValue') : firstDataCell.innerHTML;
					var hSortCell = hrElems[0].getElementsByTagName('td')[colIndex];
					var sortType = (typeof hSortCell.getAttribute('sortType') == 'string') ? hSortCell.getAttribute('sortType') : ((parseFloat(firstVal) == firstVal) ? "NUM" : "STR");
					alertVal +='colIndex:' + colIndex + ' typeof fv:' + typeof(firstDataCell.getAttribute('sortValue')) + ' sortValue:' + firstDataCell.getAttribute('sortValue') + ' innerHTML:' + firstDataCell.innerHTML + ' typeof st:' + typeof hSortCell.getAttribute('sortType') + ' : ' + parseFloat(firstVal) + ' : ' + firstVal + ' : ' + (parseFloat(firstVal) == firstVal) + ' sortType:' + sortType;
					// guess sortType
					alertVal += '\ncolIndex:' + colIndex + ' rElems.length:' + rElems.length;
					for(var i=0;i<rElems.length;i++) {
						var cRow = rElems[i];
						var cCells = cRow.getElementsByTagName('td');
						alertVal += '\nrow:' + i + ' cellCount:' + cCells.length;
						if(cCells.length > colIndex){
							var cSortCell = cCells[colIndex];
							var cVal = (typeof cSortCell.getAttribute('sortValue') == 'string') ? cSortCell.getAttribute('sortValue') :cSortCell.innerHTML;
							alertVal += ' cVal:' + cVal + ' type:' + typeof cSortCell.getAttribute('sortValue');
							for(var ii=0;ii<i;ii++){
								var iRow = rElems[ii];
								var iCells = iRow.getElementsByTagName('td');
								if(iCells.length > colIndex) {
									var iSortCell = iCells[colIndex];
									var iVal = (typeof iSortCell.getAttribute('sortValue') == 'string') ? iSortCell.getAttribute('sortValue') : iSortCell.innerHTML;
									if(
									   (direction == 'DESC' && sortType == "NUM" && parseInt(cVal) < parseInt(iVal)) 
										|| (direction == 'DESC' && sortType != "NUM" && cVal < iVal)
										|| (direction != 'DESC' && sortType == "NUM" && parseInt(cVal) > parseInt(iVal)) 
										|| (direction != 'DESC' && sortType != "NUM" && cVal > iVal)
									) {
										cRow.parentNode.insertBefore(cRow.parentNode.removeChild(cRow),iRow);
										alertVal += '\n' + sortType + ' : ' + cVal +' vs ' + iVal + ' inserting ' + ii + ' before ' + i;
										break;
									};
								};
							};
						};
						//var q = document.getElementById('img1');
						//o.appendChild(q.parentNode.removeChild(q));
					};
					//alert(alertVal);
				};
				var tdElems = this.headerElem.getElementsByTagName('tr')[0].getElementsByTagName('td');
				for(var i=0; i<tdElems.length;i++){
					if(!tdElems[i].getAttribute('sort') || tdElems[i].getAttribute('sort') != 'off'){
						// remove sort buttons
						var btnASC = document.createElement('img');
						btnASC.width = '13';
						btnASC.height = '10';
						btnASC.src = '/sysimages/icon_sort_asc_inactive.gif';
						btnASC.style.cursor = "hand";
						btnASC.style.cursor = "pointer";
						btnASC.title = "Sort Ascending";
						btnASC.cellIndex = i;
						btnASC.tableControl = this;
						btnASC.identifier = 'sortButton';
						eV.eventAdd(btnASC,'click',this.sortASC);
						eV.eventAdd(btnASC,'mouseover',this.sortASCover);
						eV.eventAdd(btnASC,'mouseout',this.sortASCout);
						tdElems[i].appendChild(btnASC);
						
						var btnDESC = document.createElement('img');
						btnDESC.width = '13';
						btnDESC.height = '10';
						btnDESC.src = '/sysimages/icon_sort_desc_inactive.gif';
						btnDESC.style.cursor = "hand";
						btnDESC.style.cursor = "pointer";
						btnDESC.title = "Sort Descending";
						btnDESC.cellIndex = i;
						btnDESC.tableControl = this;
						btnDESC.identifier = 'sortButton';
						eV.eventAdd(btnDESC,'click',this.sortDESC);
						eV.eventAdd(btnDESC,'mouseover',this.sortDESCover);
						eV.eventAdd(btnDESC,'mouseout',this.sortDESCout);
						tdElems[i].appendChild(btnDESC);
					}; // end if
				}; // end loop
			
			// end initColumnSort	
			};
			this.initColumnResize = function(){
				// set data arrays to ref / hold table info
				
				
			};
			
			this.clearControlTable = function() {
				for (var i=0;i <this.divElem.childNodes.length;i++){
					var node = this.divElem.childNodes[i];
					if(node.identifier == 'grabber') {
						node.parentNode.removeChild(node);
						i--;
					};
				};
			};
			this.clearResize = function(){
				var childNodes = this.headerElem.getElementsByTagName('tr')[0].childNodes;
				//alert(childNodes.length + ' : ' + headerTable.innerHTML);
				for(var i=0;i<childNodes.length;i++){
					if(document.getElementById(dataElem.id + '_grabber_' + i)){
						//alert(i);
						var grabber = document.getElementById(dataElem.id + '_grabber_' + i);
						grabber.parentNode.removeChild(grabber);
					};
				};
			};
			this.clearSort = function(){
				var tdElems = this.headerElem.getElementsByTagName('tr')[0].getElementsByTagName('td');
				for(var i=0; i<tdElems.length;i++){
					for(var ii=0;ii<tdElems[i].childNodes.length;ii++){
						var node = tdElems[i].childNodes[ii];
						if(node.identifier == 'sortButton') {
							node.parentNode.removeChild(node);
							ii--;
						};
					};
				};
			};
			
			
			this.setControlTable = function() {
				// duplicat first row in remaining table - to pad for behind header row
				
				this.dataElem.style.marginTop = this.headerElem.offsetHeight + 'px';
				
				var alertVal = '';
				// style cells
				var tdElems = this.dataElem.getElementsByTagName('td');
				for(var i=0; i<tdElems.length;i++){
					var tdDiv = document.createElement('div');
					tdDiv.innerHTML = tdElems[i].innerHTML;
					tdElems[i].innerHTML = '';
					tdElems[i].appendChild(tdDiv);
					//alertVal += '\n' + tdElems[i].tagName + ':' + tdElems[i].innerHTML;
					tdDiv.style.textOverflow = 'ellipsis';
					tdDiv.style.overflow = 'hidden';
					tdDiv.style.whiteSpace = 'nowrap';
					
				};	
				
				this.columnBodyCells = new Array();
				this.headerColElems = this.headerElem.getElementsByTagName('tr')[0].childNodes;
				var tdElems = this.dataElem.getElementsByTagName('td');
				for(var i=0; i<this.headerColElems.length;i++){
					var headerColElem = this.headerColElems[i];
					if(headerColElem.tagName == 'TD' || headerColElem.tagName == 'TH'){
						var index = this.columnBodyCells.length;
						if(tdElems.length > index) {
							var tdDiv = tdElems[index].getElementsByTagName('div')[0];
							tdDiv.width = headerColElem.width;
							tdDiv.style.width = headerColElem.style.width;
							this.columnBodyCells[index] = tdElems[index];
						} else {
							this.columnBodyCells[index] = null;
						};
					};
				};
				
				this.UpdateColumns(true);
				// create the gabber divs
				this.currentGrabberOffset = 0;
				alertVal = '';
				/*
				for (var i=0; i < this.currentColumnWidths.length - 1; i++)
				{
					this.currentGrabberOffset += this.currentColumnWidths[i];
			
					var grabber = document.createElement("div");
					grabber.callerObj = this;
					grabber.identifier = 'grabber';
					grabber.minColumnWidth = this.minColumnWidths[i];
					grabber.nextMinColumnWidth = this.minColumnWidths[i+1];
					grabber.style.position = 'absolute'; //absolute
					grabber.style.top = this.divElem.offsetTop + 'px';
					grabber.style.width = '8px';
					grabber.style.height = this.divElem.offsetHeight + 'px';
					grabber.style.marginLeft = '6px';//'-4px';
					grabber.style.cursor = 'move';
					grabber.style.backgroundImage = 'url(/sysimages/columngrabber.gif)';
					grabber.style.backgroundPosition = 'bottom';
					grabber.style.backgroundRepeat = 'repeat-y';
					alertVal += '\nosl:' + this.dataElem.offsetLeft + ' cgo:' + this.currentGrabberOffset + ' sl:' + this.dataElem.style.left + ' sm:' + this.dataElem.style.marginLeft + ' bl:' + this.dataElem.style.borderLeft + ' pl:' + this.dataElem.style.paddingLeft;
					var left = (parseInt(this.dataElem.offsetLeft) + parseInt(this.currentGrabberOffset) - 9);
					grabber.style.left =  left + 'px';
					alertVal += '\n' + grabber.style.left;
					grabber.leftColumn = i;
					grabber.rightColumn = i + 1;
					grabber.inDrag = false;
					grabber.id = this.dataElem.id + '_grabber_' + i;
					
					grabber.onmousedown = function(event) {
						if (!event) event = window.event;
						var alertVal = '';
						if (this.inDrag) this.onmouseup(event);
						
						this.inDrag = true;
						
						this.totalWidth = parseInt(this.callerObj.dataElem.offsetWidth);
						alertVal += '\nTotal Width:' + this.totalWidth;
						
						alertVal += '\nsavedWidth:' + this.savedWidth + '\nsavedMaringLeft:' + this.savedMarginLeft + '\nsavedLeft:' + this.savedLeft + '\nsavedBackgroundPosition:' + this.savedBackgroundPosition;
						alertVal += '----------';
						// figure out how much we can go to the left and right
						this.minOffset = 0;
						for (var i=0; i < this.leftColumn; i++)
							this.minOffset += parseInt(this.callerObj.currentColumnWidths[i]);
							
						this.maxOffset = this.minOffset +
										 parseInt(this.callerObj.currentColumnWidths[this.leftColumn]) + 
										 parseInt(this.callerObj.currentColumnWidths[this.rightColumn]);
						this.minOffset += parseInt(this.minColumnWidth);
						this.maxOffset -= parseInt(this.nextMinColumnWidth);
						
						
						
						// widen the div so that the mouse doesn't escape even when moving quickly
						this.savedWidth = this.style.width;
						this.style.width = "100%";
						//this.style.backgroundColor = '#CCCCCC';
						this.savedMarginLeft = this.style.marginLeft;
						this.style.marginLeft = "0px";
						this.savedLeft = this.style.left;
						this.style.left = "0px";
						this.savedBackgroundPosition = this.style.backgroundPosition;
						alertVal += '\nsavedWidth:' + this.savedWidth + '\nsavedMaringLeft:' + this.savedMarginLeft + '\nsavedLeft:' + this.savedLeft + '\nsavedBackgroundPosition:' + this.savedBackgroundPosition;
						//alert(alertVal);
					
						this.onmousemove(event);
							
						return true;
					};
					grabber.onmouseup = function(){
						if (this.inDrag)
						{
							this.inDrag = false;
							
							this.style.width = this.savedWidth;
							this.style.marginLeft = this.savedMarginLeft;
							this.style.backgroundPosition = this.savedBackgroundPosition;
							this.style.left = this.savedLeft;
							
						
							this.callerObj.UpdateColumns(true);
						}
						
						return true;
					};
					grabber.onmousemove = function(event){
						
						if (!event) event = window.event;
					
						if (this.inDrag)
						{
							var newOffset = event.clientX;// /this.totalWidth;
							
							if (newOffset < this.minOffset || newOffset > this.maxOffset) return;
							
							var leftColumnOffset = 0;
							for (var i=0; i < this.leftColumn; i++)
								leftColumnOffset += this.callerObj.currentColumnWidths[i];
							var rightColumnOffset = leftColumnOffset +
													this.callerObj.currentColumnWidths[this.leftColumn] +
													this.callerObj.currentColumnWidths[this.rightColumn];
													
							this.callerObj.currentColumnWidths[this.leftColumn] = newOffset - leftColumnOffset;
							this.callerObj.currentColumnWidths[this.rightColumn] = rightColumnOffset - newOffset;
							
							this.style.backgroundPosition = newOffset + "px 0px";
							this.savedLeft = newOffset + "px";
							
							this.callerObj.UpdateColumns(false);
						}
						
						return true;
					};
					
					this.divElem.appendChild(grabber);
					//alert('L:' + grabber.style.left + ' T:' + grabber.style.top + ' W:' + grabber.style.width + ' H:' + grabber.style.height);
				}
				*/
				//alert(alertVal);
				this.DisableSelections(this.dataElem);
				this.UpdateColumns(true);
			// end setControlTable fuction
			}
			
			this.UpdateColumns = function(fullUpdate)
				{
					var alertVal = ''
					var total = 0;
					for (var i=0; i < this.currentColumnWidths.length - 1; i++)
					{
						//alertVal += '\nccw:' + this.currentColumnWidths[i] + ' osw:' + this.columnHeaderCells[i].offsetWidth + ' swidth:' + this.columnHeaderCells[i].style.width + ' width:' + this.columnHeaderCells[i].width + ' padLeft:' + this.columnHeaderCells[i].style.paddingLeft + ' borLeft:' + this.columnHeaderCells[i].style.borderLeftWidth + ' pad:' + this.columnHeaderCells[i].style.padding;
						var hWidthDif = this.columnHeaderCells[i].offsetWidth - this.columnHeaderCells[i].width;
						var width = this.currentColumnWidths[i];
						total += width;
						this.columnHeaderCells[i].width = (width - hWidthDif);
						//this.columnHeaderCells[i].width = width;
						if (fullUpdate && this.columnBodyCells[i]) {
							var dWidthDif = this.columnBodyCells[i].offsetWidth - this.columnBodyCells[i].width;
							this.columnBodyCells[i].width = (width - dWidthDif);
							this.columnBodyCells[i].getElementsByTagName('div')[0].style.width = (width - dWidthDif) + 'px';
						};
						//alert(columnBodyCells[i].style.width + '\n' + columnBodyCells[i].innerHTML);
					}
					//alert(alertVal);
					this.columnHeaderCells[this.columnHeaderCells.length - 1].width = (parseInt(this.headerElem.holdWidth) - total - hWidthDif);
					if (fullUpdate && this.columnBodyCells[this.columnBodyCells.length - 1])  this.columnBodyCells[this.columnBodyCells.length - 1].width = (parseInt(this.dataElem.holdWidth) - total - dWidthDif);
					
				}
				
			
				this.DisableSelections = function(node)
				{
					// CSS3 draft way
					if (typeof node.style.userSelect == "string")
						node.style.userSelect = "none";
					
					// mozilla extension
					if (typeof node.style.MozUserSelect == "string")
						node.style.MozUserSelect = "none";
						
					// msie/safari extension
					if(typeof node.onselectstart != "undefined")
						node.onselectstart = this.DisabledHandler;
				}
				
				this.DisabledHandler = function(){
					// do nothing
				};
			
			
			this.setDrag = function(tableId,headerTableId,callObj) {
				this.callObj = callObj;
				// store the cell that will be dragged
				this.draggedCell = null
				// true if ghostTd exists
				this.ghostCreated = false
				// store the table itselfs
				this.table = document.getElementById(tableId)
				this.headerTable = document.getElementById(headerTableId); // NEW
				// store every row of the table
				this.tableRows = this.table.getElementsByTagName("tr")
				this.headerTableRows = this.headerTable.getElementsByTagName("tr"); // NEW
				// create a handler array, usualy the ths in the thead, if not possible the first row of tds
				//this.handler = this.table.getElementsByTagName("th").length > 0 ? this.table.getElementsByTagName("th") : this.table.tBodies[0].rows[0].getElementsByTagName("td")
				this.handler = this.headerTable.getElementsByTagName("th").length > 0 ? this.headerTable.getElementsByTagName("th") : this.headerTable.tBodies[0].rows[0].getElementsByTagName("td"); // NEW
				// create a cell array
				this.cells = this.table.getElementsByTagName("td")
				// store the max index of the column when dropped
				this.maxIndex = this.handler.length
				// store the horizontal mouse position
				this.x;
				// store the vertical mouse position
				this.y;
				// store the index of the column that will be dragged
				this.oldIndex;
				// store the index of the destionation of the column
				this.newIndex;
				 
				for (x=0; x<this.handler.length; x++) {
					// associate the object with the cells
					this.handler[x].dragObj = this
					// override the default action when mousedown and dragging
					this.handler[x].onselectstart = function() { return false }
					// fire the drag action and return false to prevent default action of selecting the text
					this.handler[x].onmousedown = function(e) { this.dragObj.drag(this,e); return false }
					// visual effect
					this.handler[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
					this.handler[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
					this.handler[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
				// end handlerh loop
				}
				
				for (x=0; x<this.cells.length; x++) {
					this.cells[x].dragObj = this
					// visual effect
					 
					this.cells[x].onmouseover = function(e) { this.dragObj.dragEffect(this,e) }
					this.cells[x].onmouseout = function(e) { this.dragObj.dragEffect(this,e) }
					this.cells[x].onmouseup = function(e) { this.dragObj.dragEffect(this,e) }
					
				// end cells loop
				}
				
			// end dragTable function
			}
			 
			this.setDrag.prototype.dragEffect = function(cell,e) {
			// assign event to variable e
			
				if (!e) e = window.event
			 
					// return if the cell being hovered is the same as the one being dragged
					if (cell.cellIndex == this.oldIndex) return
			 
				else {
					// if there is a cell being dragged
					if (this.draggedCell) {
					// change class to give a visual effect
						if(e.type == "mouseover"){
							this.handler[cell.cellIndex].style.color = "#888"
							this.handler[cell.cellIndex].style.background = "#CCC"
						} else {
							this.handler[cell.cellIndex].style.color = "#000"
							this.handler[cell.cellIndex].style.background = "#FFF"
						};
					}
				}
				
			}
			 
			this.setDrag.prototype.drag = function(cell,e) {
				// reference of the cell that is being dragged
				this.draggedCell = cell
				 
				// change class for visual effect
				this.draggedCell.style.background = '#eeeeee';
				this.draggedCell.style.color = '#000';
				 
				// store the index of the cell that is being dragged
				this.oldIndex = cell.cellIndex
				 
				// create the ghost td
				this.createGhostTd(e)
				// start the engine
				this.dragEngine(true)
			}
			 
			this.setDrag.prototype.createGhostTd = function(e) {
				// if ghost exists return
				if (this.ghostCreated) return
				// assign event to variable e
				if (!e) e = window.event
				// horizontal position
				this.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
				// vertical position
				this.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
				 
					// create the ghost td (visual effect)
					this.ghostTd = document.createElement("div")
					this.ghostTd.className = "ghostTd"
					this.ghostTd.style.top = this.y + 5 + "px"
					this.ghostTd.style.left = this.x + 10 + "px"
					this.ghostTd.style.width = 'auto';
					this.ghostTd.style.padding = '2px 8px';
					this.ghostTd.style.border = '1px solid #000';
					this.ghostTd.style.position = 'absolute';
					this.ghostTd.style.background = '#eee';
			
					// ghost td receives the content of the dragged cell
					this.ghostTd.innerHTML = this.handler[this.oldIndex].innerHTML
					document.getElementsByTagName("body")[0].appendChild(this.ghostTd)
				 
				// assign a flag to see if ghost is created
				this.ghostCreated = true
			}
			 
			this.setDrag.prototype.drop = function(dragObj,e) {
				// assign event to variable e
				if (!e) e = window.event
				// store the target of the event - mouseup
				e.targElm = e.target ? e.target : e.srcElement
				 
				// end the engine
				dragObj.dragEngine(false,dragObj)
				 
				// remove the ghostTd
				dragObj.ghostTd.parentNode.removeChild(dragObj.ghostTd)
				 
				// remove ghost created flag
				this.ghostCreated = false
				 
					// store the index of the target, if it have one
					if (e.targElm.cellIndex !="undefined") {
					checkTable = e.targElm
				 
						// ascend in the dom beggining in the targeted element and ending in a table or the body tag
						while (checkTable.tagName.toLowerCase() !="table") {
						if (checkTable.tagName.toLowerCase() == "html") break
						checkTable = checkTable.parentNode
						}
				 
						// check if the table where the column was dropped is equal to the object table
						//checkTable == this.table ? this.newIndex = e.targElm.cellIndex : false
						checkTable == this.headerTable ? this.newIndex = e.targElm.cellIndex : false; // NEW
					}
				 
				// start the function to sort the column
				dragObj.sortColumn(this.oldIndex,this.newIndex)
				 
				// remove visual effect from column being dragged
				this.draggedCell.className = ""
				// clear the variable
				this.draggedCell = null
				
				// reset table columns
				this.callObj.clearControlTable();
				this.callObj.setControlTable();
			}
			 
			this.setDrag.prototype.sortColumn = function(o,d) {
				//alert(o + ' ' + d);
				// returns if destionation dont have a valid index
				if (d == null) return
				// returns if origin is equals to the destination
				if (o == d) return
			 
				// swap header row cells
				for (x=0; x<this.headerTableRows.length; x++) {
					tds = this.headerTableRows[x].cells
					// remove this cell from the row
					var cell = this.headerTableRows[x].removeChild(tds[o])
					// insert the cell in the new index
					if (d + 1 >= this.maxIndex) {
					this.headerTableRows[x].appendChild(cell)
					}
					else {
					this.headerTableRows[x].insertBefore(cell, tds[d])
					}
				};
				// loop through every row
				for (x=0; x<this.tableRows.length; x++) {
					// array with the cells of the row x
					tds = this.tableRows[x].cells
					// remove this cell from the row
					var cell = this.tableRows[x].removeChild(tds[o])
					// insert the cell in the new index
					if (d + 1 >= this.maxIndex) {
					this.tableRows[x].appendChild(cell)
					}
					else {
					this.tableRows[x].insertBefore(cell, tds[d])
					}
				}
			}
			 
			this.setDrag.prototype.dragEngine = function(boolean,dragObj) {
				var _this = this
				// fire the drop function
				document.documentElement.onmouseup = boolean ? function(e) { _this.drop(_this,e) } : null
				// capture the mouse coords
				document.documentElement.onmousemove = boolean ? function(e) { _this.getCoords(_this,e) } : null
			}
			 
			this.setDrag.prototype.getCoords = function(dragObj,e) {
				if (!e) e = window.event
				 
				// horizontal position
				dragObj.x = e.pageX ? e.pageX : e.clientX + document.documentElement.scrollLeft
				// vertical position
				dragObj.y = e.pageY ? e.pageY : e.clientY + document.documentElement.scrollTop
			 
				if (dragObj.ghostTd) {
				// make the ghostTd follow the mouse
				dragObj.ghostTd.style.top = dragObj.y + 5 + "px"
				dragObj.ghostTd.style.left = dragObj.x + 10 + "px"
				}
			}	
		},
		
		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.callback = 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.callback = 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
					if(!div.getAttribute('rotateIntervalId')) 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;
		},
		
		xHeight : function(e){
			
			var h = (e.style.height != '' ) ? parseInt(e.style.height) : 0;
			if(h == 0){
				var pt = (e.style.paddingTop != '') ? parseInt(e.style.paddingTop) : 0;
				var pb = (e.style.paddingBottom != '') ? parseInt(e.style.paddingBottom) : 0;
				var bt = (e.style.borderTop != '') ? parseInt(e.style.borderTop) : 0;
				var bb = (e.style.borderBottom != '') ? parseInt(e.style.borderBottom) : 0;
				h = e.offsetHeight - (pt+pb+bt+bb);
			};
		  return h;
		},
		
		elemTween : function (elem){
			//this.id = id;
			this.elem = (typeof elem == 'string') ? document.getElementById(elem) : elem;
			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.callback = 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;
				//alert(this.elem.style.height);
				if(this.targetWidth != null) this.startWidth = parseInt(this.elem.style.width);
				if(this.targetHeight != null) this.startHeight = eV.xHeight(this.elem);
				// 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(this.elem.style.left)+parseInt(this.elem.style.width);
						break;
					case 'center':
						this.startX = parseInt(this.elem.style.left)+(parseInt(this.elem.style.width)/2);
						break;
					default:
						this.startX = parseInt(this.elem.style.left);
						break;
				};
				switch(this.vanchor){
					case 'bottom':
						this.startY = parseInt(this.elem.style.top)+eV.xHeight(this.elem);
						break;
					case 'middle':
						this.startY = parseInt(this.elem.style.top)+(eV.xHeight(this.elem)/2);
						break;
					default:
						this.startY = parseInt(this.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.elem);
				this.currentOpacity = this.startOpacity;
				this.debug = '';
				//this.intervalId = setInterval(function(obj){
				this.intervalId = setInterval(function (obj){
					//var browser = eV.browserWindow(window);
					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{
							var newWidth = null;
							if(parseInt(obj.elem.style.width) != obj.targetWidth){
								newWidth = (parseInt(obj.elem.style.width) + ((obj.targetWidth-obj.startWidth)*adjustBy));
								obj.elem.style.width = (newWidth < 0) ? '0px' : (newWidth + 'px');
							};
							if(
								(parseInt(obj.elem.style.width) > obj.targetWidth && obj.targetWidth > obj.startWidth) 
								|| (parseInt(obj.elem.style.width) < obj.targetWidth && obj.targetWidth < obj.startWidth)
							) obj.elem.style.width = obj.targetWidth + 'px';
						} catch(e){
							wErr = true;
						};
						
					};
					
					// move height
					if(obj.targetHeight != null){
						//alert('theight:' + obj.targetHeight + 'cheight:' + eV.xHeight(obj.elem) + 'sheight:' + obj.startHeight);
						try{
							var newHeight = null;
							if(eV.xHeight(obj.elem) != obj.targetHeight){
								newHeight = (eV.xHeight(obj.elem) + ((obj.targetHeight-obj.startHeight)*adjustBy));
								obj.elem.style.height = (newHeight < 0) ? '0px' : (newHeight + 'px');
							};
							if(
								(eV.xHeight(obj.elem) > obj.targetHeight && obj.targetHeight > obj.startHeight)
								|| (eV.xHeight(obj.elem) < obj.targetHeight && obj.targetHeight < obj.startHeight)
							) obj.elem.style.height = obj.targetHeight + 'px';
							
							//debug('tween: elem:' + eV.xHeight(obj.elem) + ' : target:' + obj.targetHeight + ' : start:' + obj.startHeight + ' : adj:' + adjustBy + ' : new:' + newHeight);
						} 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(obj.elem.style.left){
						switch(obj.hanchor){
							
							case 'right':
								obj.elem.style.left = (obj.currentX-parseInt(obj.elem.style.width)) + 'px';
								break;
							case 'center':
								obj.elem.style.left = (obj.currentX-(parseInt(obj.elem.style.width)/2)) + 'px';
								break;
							default:
								obj.elem.style.left = obj.currentX + 'px';
								break;
						};
					};
					if(obj.elem.style.top){
						switch(obj.vanchor){
							case 'bottom':
								obj.elem.style.top = (obj.currentY-parseInt(obj.elem.style.height)) + 'px';
								break;
							case 'middle':
								obj.elem.style.top = (obj.currentY-(parseInt(obj.elem.style.height)/2)) + 'px';
								break;
							default:
								obj.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(obj.elem.style.width) == obj.targetWidth || wErr) 
						&& (!obj.targetHeight || parseInt(obj.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.callback) obj.callback();
							
					}; 
				},33,this);
			// end start function
			};
		},

		opacitySet : function (elem,opacity){
			elem = (typeof elem == 'string') ? document.getElementById(elem) : elem;
			elem.style.opacity = opacity / 10;
			elem.style.filter = 'alpha(opacity=' + (opacity * 10)+ ')';
			
			var children = null;
			if(elem.children) children = elem.children;
			if(elem.childNodes) children = elem.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(elem){
			elem = (typeof elem == 'string') ? document.getElementById(elem) : elem;
			var opacity = 10;
			if(elem.style.opacity) opacity = elem.style.opacity * 10;
			if(elem.style.filter && elem.style.filter.indexOf('opacity')) opacity = parseInt(elem.style.filter.substring(elem.style.filter.indexOf('opacity')+8,elem.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 = new 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;

		},
		
		arrayToQueryString : function(arr){
			var qArr = new Array();
			// look for string so not to include objects that are methods of array
			for(var i in arr) if(typeof arr[i] == 'string') qArr[qArr.length] = '' + encodeURIComponent(i) + '=' + encodeURIComponent(arr[i]);
			var qString = qArr.join('&');
			return qString;
		},
		
	
		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){
			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.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');
					});
					 // 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));
							});
							// 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);
					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));
					// 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){
				//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,10))) ? 0 : parseInt(quantityObj.value,10);// 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
				//alert('quantity:' + 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
				} 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);
					// 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 == 0)) basePrice = lowLevelP;
					// start outputPrice
					var outputPrice = (basePrice + groupOptionsPrice) * quantity;
					
					// assign the price
					// rounds to 2 dec places
					returnVal =  outputPrice.toFixed(2);
				// end quantity does not qualify
				};
			// end if productIndex == -1
			};
			//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() {
			if(c.apply) c.apply(this, a);                   // passes them to your function
		}, t);
	};
});
@*/

// intializations at load
// banner ads
eV.eventAdd(window,'load',eV.bannerZone_rotateInit);

