//
// Javascript utility functions
// Created by RCE & others

/*************************************/
function charOK (okChars,event) {
   var keycode;
   if (window.event)
      keycode = window.event.keyCode;
   else if (event) 
      keycode = event.which;
   else
      return true;

   for (var i=0; i<okChars.length; i++) {
      if (okChars.charCodeAt(i) == keycode)
         return (true);	// character is in approved set
   }
   return (false); // character not found in approved set

} /* charOK */


/******************************/
function CheckAddrForPObox (addrField) {

	var testStr = addrField.value;
	boxExp1 = / box /gi;
	boxExp2 = /box /gi;
	if (testStr.search(boxExp1) != -1 || testStr.search(boxExp2) == 0) {
		Y_alert ("UPS will not deliver to a PO Box.  If this is a PO Box, please give a physical address instead.",addrField);
	}
	return (true);
}


/******************************/
function CheckCreditCard (cardField,emptyOK,maskOK) {

  // Test credit card number for validity
  // Created 2001-04-03 by RCE
  // Modified 2002-08-21 by RCE
  //   added 'emptyOK' to allow user to tab
  //   out of field during data entry
  //
  var checkdigit = 0;
  var checksum = 0;
  var checkStr = cardField.value;
  var digitStr = "";	// for storage of the digits only
  var digitnumber = 0;
  
  if (maskOK == null) {
	  maskOK = false;
  }

  if (cardField.type == 'hidden') return (true);

  if (isEmpty(checkStr)) {
    if (!emptyOK) {
      Y_alert("Please enter your credit card number.",cardField);
      return (false);
    } else {
      return (true);
    }
  }
  
  if (maskOK && checkStr.substr(0,8) == "XXXX-XXX") {	// masked? accept it
	  return (true);
  }

  // Run through the number backwards
  for (var i = checkStr.length-1; i >= 0; i--) {
    // first strip out all but numbers
    checkdigit = checkStr.charCodeAt(i) - 48;
    if ((checkdigit >= 0) && (checkdigit <= 9)) {
      digitStr += checkStr.charAt(i);	// Save the digit for later
      digitnumber += 1;			// Note: counts 1..n+1, not 0..n
      if (digitnumber % 2 == 0)
        checkdigit *= 2;		// Even? Double it
      if (checkdigit > 9)
        checkdigit = checkdigit-9;	// Too big? Reduce by 9 (same as adding digits)
      checksum += checkdigit;		// Add to checksum
    }
  }
  if (digitStr == "7200000007004" || digitStr == "5100000000004245") {
     // test numbers - fine as is
     return (true);
  }
  if ((digitStr.length == 16 && digitStr.charAt(15) != '4' && digitStr.charAt(15) != '5') || 
      (digitStr.length == 15 && digitStr.charAt(14) != '3') ||
      (digitStr.length < 15 || digitStr.length > 16)) {
     Y_alert ("Sorry - we only accept Visa, Mastercard, and American Express. Please try again.",cardField);
     return (false);
  }


  if ((checksum % 10) != 0) {
    Y_alert("Please re-check your credit card number.",cardField);
    return (false);
  }

  // digitStr now has the card number, backwards.
  // Reverse it.
  checkStr = digitStr;
  digitStr = "";
  var len = checkStr.length;
  for (i = len-1; i>=0; i--) {
    digitStr += checkStr.charAt(i);
  }

  // Now format the string correctly
  // Only current options are Visa and Mastercard,
  // both of which are 16-digit numbers.
  // Format it as XXXX-XXXX-XXXX-XXXX, using digitStr.
  // Append MM-YYYY from cc_exp_mo and cc_exp_yr.
  
  if (digitStr.length == 16) 
     cardField.value = digitStr.substr(0,4) + "-" +
                       digitStr.substr(4,4) + "-" +
                       digitStr.substr(8,4) + "-" +
                       digitStr.substr(12,4);
  else
     cardField.value = digitStr.substr(0,4) + "-" +
                       digitStr.substr(4,4) + "-" +
                       digitStr.substr(8,3) + "-" +
                       digitStr.substr(11,4);


  return (true);
} /* CheckCreditCard */

/******************************/
function CheckEmail (emailField,emptyOK) {
  // RCE added new email validation routine from Netscape 10-23-2001
  // Also modified to ensure it contains a valid top-level domain
  // 2002-08-21 RCE added broader TLD testing
  var newstr = "";
  var at = false;
  var dot = false;
  var tld = "";
  var checkString = emailField.value;
  var validTLDs = ":com:net:org:edu:gov:aero:biz:coop:info:museum:name:pro:ad:ae:af:ag:ai:" +
                  "al:am:an:ao:aq:ar:as:at:au:aw:az:ba:bb:bd:be:bf:bg:bh:bi:bj:bm:bn:" +
                  "bo:br:bs:bt:bv:bw:by:bz:ca:cc:cf:cg:ch:ci:ck:cl:cm:cn:co:cr:cs:cu:" +
                  "cv:cx:cy:cz:de:dj:dk:dm:do:dz:ec:ee:eg:eh:er:es:et:fi:fj:fk:fm:fo:" +
                  "fr:fx:ga:gb:gd:ge:gf:gh:gi:gl:gm:gn:gp:gq:gr:gs:gt:gu:gw:gy:hk:hm:" +
                  "hn:hr:ht:hu:id:ie:il:in:io:iq:ir:is:it:jm:jo:jp:ke:kg:kh:ki:km:kn:" +
                  "kp:kr:kw:ky:kz:la:lb:lc:li:lk:lr:ls:lt:lu:lv:ly:ma:mc:md:mg:mh:mk:" +
                  "ml:mm:mn:mo:mp:mq:mr:ms:mt:mu:mv:mw:mx:my:mz:na:nc:ne:nf:ng:ni:nl:" +
                  "no:np:nr:nt:nu:nz:om:pa:pe:pf:pg:ph:pk:pl:pm:pn:pr:pt:pw:py:qa:re:" +
                  "ro:ru:rw:sa:sb:sc:sd:se:sg:sh:si:sj:sk:sl:sm:sn:so:sr:st:su:sv:sy:" +
                  "sz:tc:td:tf:tg:th:tj:tk:tm:tn:to:tp:tr:tt:tv:tw:tz:ua:ug:uk:um:us:" +
                  "uy:uz:va:vc:ve:vg:vi:vn:vu:wf:ws:ye:yt:yu:za:zm:zr:zw:int:mil:arpa:nato:";

  if (emailField.type == 'hidden') return (true);

  if (isEmpty(checkString) && (emptyOK == true)) {
    return (true);
  }

  // Pull the putative TLD and validate it against the acceptable set
  // This involves pulling the tail-end of the field, from the final '.',
  // and comparing it to the list of acceptable TLDs in validTLDs.  Note
  // that the validTLD string has every valid TLD bracketed by colons,
  // so that .co (=":co:") doesn't match .com (=":com:").
  tld = reverseStr(checkString);
  tld = tld.substr(0,tld.search(/\./));			// find the '.' and copy to it
  tld = ":" + reverseStr(tld).toLowerCase() + ":";	//This becomes the search string
  if (validTLDs.search(tld) == -1) {
    Y_alert("Top-level domain appears invalid.  Please enter a valid email address.",emailField);   
    return (false);
  }


  for (var i = 0; i < checkString.length; i++) {
    ch = checkString.substring(i, i + 1)
    if ((ch >= "A" && ch <= "Z") || (ch >= "a" && ch <= "z")
            || (ch == "@") || (ch == ".") || (ch == "_")
            || (ch == "-") || (ch >= "0" && ch <= "9")) {
      newstr += ch;
      if (ch == "@") {
          if (at == true) { //only one per address!
            at = false;
            break;
          }
          at=true;
      }
    }
  }
  if (!at) {
    Y_alert("Email addresses contain the '@' sign. Please enter a valid email address.",emailField);   
    return (false);
  }
  if (newstr.length != checkString.length) {	// invalid characters were not copied
    Y_alert("The email address you entered appears to contain invalid characters.",emailField);
    return (false);
  }

  return (true);

} /* CheckEmail() */

/******************************/
function CheckPhoneNumber (phoneField, emptyOK) {

  var checkOK = "0123456789";
  var checkStr = phoneField.value;
  var newStr = "";
  var digits = 0;
  var allValid = true;

  if (phoneField.type == 'hidden' || (isEmpty(checkStr) && (emptyOK == true))) {
    return (true);
  }
  for (var i = 0;  i < checkStr.length;  i++) {
    var ch = checkStr.charAt(i);
    if (ch >= "0" && ch <= "9") {
      digits++;
      newStr += ch;
    }
  }
  if ((digits!=10)) {
    Y_alert("Please enter a valid phone number.",phoneField);
    return (false);
  }
  phoneField.value = "(" + newStr.substr(0,3) + ") " + newStr.substr(3,3) + "-" +newStr.substr(6,4);
  return (true);
} /* CheckPhoneNumber */


/******************************/
function CheckURL (field, emptyOK) {

	if (isEmpty(field.value) && emptyOK) {
		return true;
	}
	var v = new RegExp();
	v.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
	var v2 = new RegExp();
    v2.compile("[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
	if (!v.test(field.value) && !v2.test(field.value)) {   
		Y_alert("Please enter your website address",field);
		return false;
	}
	return true;
}


/******************************/
function CheckZIP (zipField,emptyOK) {

	// Added 2001-12-29 by RCE
	// Checks for valid ZIP code and re-formats to ZIP or ZIP+4
	var checkStr = zipField.value;
	var numStr = "";
	var checkDigit;
	
	if (zipField.type == 'hidden') return (true);
	
	// strip out non-numeric characters
	for (var i = 0; i < checkStr.length; i++) {
		checkDigit = checkStr.charAt(i);
		if (checkDigit >= "0" && checkDigit <= "9") {
			numStr += checkDigit;
		}
	}
	// empty? ok?
	if (numStr.length == 0 && emptyOK) {
		return true;
	}
	
	// make sure it's a valid ZIP code length
	if ((numStr.length != 5) && (numStr.length != 9)) {
		Y_alert ("Please enter a valid ZIP code.",zipField);
		return (false);
	}
	if (numStr.length == 9) {  // ZIP+4 -> reformat
		zipField.value = numStr.substr(0,5) + "-" + numStr.substr(5,4);
	} else {
		zipField.value = numStr;
	}
	return (true);
	
} /* CheckZIP */

/***********************************/
function closeParentDivWindow (element) {
	// crawls up the DOM stack until it finds a DIV with an ID, then closes that 'window' and turns off the mask
	element = element.parentNode;	// move up one layer to begin with, since caller isn't the parent.
	while ((element.tagName != "DIV" || element.id === "") && element.offsetParent) {
		element = element.parentNode;
	}
	element.style.display = "none";
	document.getElementById("Y_wait_mask").style.display = "none";
}


/***********************************/
function CommaFormatted(amount,showZero,showDollarSign) {
	amount = strdecimal(amount).toString();	// strip all but numeric-related characters
	var delimiter = ","; // replace comma if desired
	rExp = new RegExp(delimiter,"g");
	amount = amount.replace(rExp,"");	// zap existing delimiters
	rExp = new RegExp("\.","i");
	if (!rExp.test(amount)) 
		amount += '.00';
	var a = amount.split('.',2)
	if (a[0] == '') a[0] = '0';
	if (a[1] == undefined) a[1] = '00';
	var d = (a[1] == '' ? '00' : a[1]);
	if (d.length == 1) d += '0';
	var i = parseInt(a[0]);
	if(isNaN(i)) return ('');
	var minus = (i < 0 ? '-' : '');
	i = Math.abs(i);
	var n = new String(i);
	var a = [];
	while(n.length > 3) {
		var nn = n.substr(n.length-3);
		a.unshift(nn);
		n = n.substr(0,n.length-3);
	}
	if(n.length > 0) a.unshift(n);
	n = a.join(delimiter);
	amount = n + '.' + d;
	amount = minus + amount;
	if (showZero == false && parseFloat(amount) == 0) return ('');
	if (showDollarSign) amount = '$' + amount;
	return amount;

} /* CommaFormatted */

/******************************/
function copyFields (from,to,src) {
	for (var bill, ship, dest_type, val, i=0; i<src.length; i++) {
		bill = document.getElementById(from+src[i]);
		ship = document.getElementById(to+src[i]);
		dest_type = ship.tagName.toLowerCase();
		if (bill.tagName.toLowerCase() == "input") {
			val = bill.value;
		} else
		if (bill.tagName.toLowerCase() == "select") {
			val = getSelectedOptionInfo(bill.id,(dest_type == "select" ? "value" : "text"));
		}
		if (dest_type == "input") {
			ship.value = val;
		} else
		if (dest_type == "select") {
			setSelectedOptionByValue(ship,val);
		}
	}
}

/************************************/
// NOTE from RCE 2003-11-03: There's a bug in this when adding a day to 2003-10-26; not sure why.
function DateAdd(startDate, numDays, numMonths, numYears) {
   var returnDate = new Date(startDate.getTime());
   var yearsToAdd = numYears;
   var month = returnDate.getMonth() + numMonths;
   if (month > 11) {
      yearsToAdd = Math.floor((month+1)/12);
      month -= 12*yearsToAdd;
      yearsToAdd += numYears;
   }
   returnDate.setMonth(month);
   returnDate.setFullYear(returnDate.getFullYear()+ yearsToAdd);
   returnDate.setTime(returnDate.getTime()+60000*60*24*numDays);
   	
   return returnDate;

} /* DateAdd */


/******************************/
function dateHandler (e,dateField,fmt) {
	if (!e) {
		e = window.event;
	}
	if (!fmt) {
		fmt = "Y-m-d";
	}
	var keycode = e.keyCode;
 	  

	// return if it's a number or navigation.  otherwise, wipe the event.
	if (keycode >= 46 && keycode <= 57) return true;	// "-./0123456789"
	if (keycode < 32 || keycode > 126) return true;	// navigation characters

   switch (keycode) {
      case 116:	// 't'
      case 84:	// 'T'
		if (e.stopPropogation) e.stopPropogation();
		e.cancelBubble = true;
		e.returnValue = false;
		if (e.preventDefault) e.preventDefault();
		
		var stamp = new Date();
		var month = (stamp.getMonth()+1 < 10) ? "0" : "";
		month += (stamp.getMonth()+1).toString();
		var day = (stamp.getDate() < 10) ? "0" : "";
		day += stamp.getDate().toString();
		var val = (fmt == "Y-m-d" ? stamp.getFullYear().toString() + "-" : "") + month + "-" + day;
		dateField.value = val;
		setDirtyBit();
		return false;
      case 38:	// up arrow
      case 40:	// down arrow
		if (e.stopPropogation) e.stopPropogation();
		e.cancelBubble = true;
		e.returnValue = false;
		if (e.preventDefault) e.preventDefault();
		var date = dateField.value;
		var year, offset;
		if (fmt == "Y-m-d") {
			year = strvalue(date.substr(0,4));
			offset = 5;
		} else
		if (fmt == "m-d") {
			year = new Date();
			year = year.getFullYear();
			offset = 0;
		}
		var month= strvalue(date.substr(offset,2))-1;
		var day  = strvalue(date.substr(offset+3,2));
		
		var years  = (e.altKey   ? (keycode == 40 ? -1 : 1) : 0);
		var months = (e.shiftKey ? (keycode == 40 ? -1 : 1) : 0);
		var days   = (e.shiftKey || e.altKey ? 0 : (keycode == 40 ? -1 : 1));
		var nextDate = DateAdd(new Date (year,month,day),days,months,years);
		if (fmt == "Y-m-d") {
			dateField.value = nextDate.getFullYear() + '-';
		} else {
			dateField.value = "";
		}
		dateField.value += 	(nextDate.getMonth()<9 ? '0'+(nextDate.getMonth()+1) : (nextDate.getMonth()+1)) +
							'-' + 
							(nextDate.getDate()<10 ? '0'+(nextDate.getDate()) : (nextDate.getDate()));
		setDirtyBit();
		return false;
	}
	return false;
	
} /* dateHandler */


/******************************/
function int_only (e) {
	var key = window.event ? e.keyCode : e.which;
	var keychar = String.fromCharCode(key);
	if (keychar < " ") return true;
	reg = /\d/;
	return reg.test(keychar);	// true if a number
}
function real_only (e) {
	var key = window.event ? e.keyCode : e.which;
	var keychar = String.fromCharCode(key);
	if (keychar < " ") return true;
	reg = /[\.\d]/;
	return reg.test(keychar);	// true if a number or a decimal
}
function bucks_only (e) {
	var key = window.event ? e.keyCode : e.which;
	var keychar = String.fromCharCode(key);
	if (keychar < " ") return true;
	reg = /[,\.\$\d]/;
	return reg.test(keychar);	// true if a number or a decimal or a comma or a dollar sign
}

/******************************/
function isEmpty (inStr) {
  var s = inStr.replace(/^\s+/,'').replace(/\s+$/,'');
  return ((s.length == 0) || (s == ""));
} /* isEmpty */

/******************************/
function reverseStr (inStr) {
   var outStr;
   for (outStr="", i=inStr.length-1;i>-1;i=i-1) {
       outStr += inStr.charAt(i);
   }
   return (outStr);
} /* reverseStr */

/******************************/
function setEndDate (startDate, endDate) {
   var eD = endDate.value;
   if (!isEmpty(eD)) return (true);	// don't mess with an existing date
   var sD   = startDate.value;
   var year = strvalue(sD.substr(0,4));
   var month= strvalue(sD.substr(5,2))-1;
   // method: assume it's the first of the month, then add a month, the subtract a day
   var EOM  = DateAdd(DateAdd(new Date (year,month,1),0,1,0),-1,0,0);
   endDate.value = 
     EOM.getFullYear() +
     '-' + 
     (EOM.getMonth()<9 ? '0'+(EOM.getMonth()+1) : (EOM.getMonth()+1)) +
     '-' + 
     (EOM.getDate()<10 ? '0'+(EOM.getDate()) : (EOM.getDate()));
   return (true);

} /* setEndDate */

/******************************/
function strdecimal (inStr) {
   // strips everything but the numbers, minus sign, and decimal point
   var outStr = "";
   inStr = inStr.toString();	// make sure we're dealing with a string
   for (var i=0; i<inStr.length; i++) {
      var thisChar = inStr.charAt(i);
      if ((thisChar >= '0' && thisChar <= '9') || thisChar == '.' || thisChar == '-') outStr += thisChar;
   }
   if (outStr == "") outStr = "0.00";
   return (parseFloat(outStr));

} /* strdecimal */

/******************************/
function strvalue (inStr) {
   var outStr = "";
   for (var i=0; i<inStr.length; i++) {
      var thisChar = inStr.charAt(i);
      if (thisChar >= '0' && thisChar <= '9') outStr += thisChar;
   }
   return (Math.floor(outStr));

} /* strvalue */

/******************************/
function testFieldLength (fld,len) {
	if (fld.value.length > len) {
		Y_alert("Sorry, but this field cannot be more than "+len+" characters long; you have entered "+fld.value.length+".",fld);
		return false;
	}
	return true;
}

/******************************/
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}


/***********************************/
function inspect(elm){
   var str = "";
   var j = 1;
   for (var i in elm)
      str += i + ": " + elm.getAttribute(i) + (j++ % 3 ? "\t" : "\n");
   Y_alert(str);
} /* inspect */

/**********************************/
function getSelectedOptionInfo (fieldID,attrib) {
    // gets the selectedIndex option of type 'attrib'
    var selIndex = document.getElementById(fieldID).selectedIndex;
    if (selIndex == -1) return "";	// no value selected
    return (eval("document.getElementById(fieldID).options[document.getElementById(fieldID).selectedIndex]"+"."+attrib));

} // getSelectedOptionInfo

/**********************************/
function setSelectedOptionByText (selField,txt) {
    for (i=0; i<selField.options.length; i++) {
        if (selField.options[i].text == txt) {
            selField.selectedIndex = i;
            break;
        }
    }
    if (i < selField.options.length) {
        return selField.options[i].value;
    } else {
        return '';
    }
}

/**********************************/
function setSelectedOptionByValue (selField,val) {
    for (i=0; i<selField.options.length; i++) {
        if (selField.options[i].value == val) {
            selField.selectedIndex = i;
            break;
        }
    }
    if (i < selField.options.length) {
        return selField.options[i].value;
    } else {
        return '';
    }
}

/**********************************/
function getSelectedRadioValue (field) {
	var btns;
	if (field.name) {	// just one
		btns = document.getElementsByName(field.name);
	} else {	// already did this
		btns = field;
	}
	for (var i=0; i<btns.length; i++) {
		if (btns[i].checked) {
			return (btns[i].value);
		}
	}
	return ("");
}

/**********************************/
function setRadioValue (field,value) {
	var btns;
	if (field.name) {	// just one
		btns = document.getElementsByName(field.name);
	} else {	// already did this
		btns = field;
	}
	for (var i=0; i<btns.length; i++) {
		btns[i].checked = (btns[i].value == value);
	}
}

/**********************************/
function setDirtyBit() {
	if (document.getElementById('dirtyBit')) {
		document.getElementById('dirtyBit').value = 1;
	} else {
		dirtyBit = 1;
		if (window.setDirtyBitExtraFn !== undefined) {
			setDirtyBitExtraFn();
		}
	}
}

/*********************************/
function closeIfNotDirty(close) {
	var docDirtyBit = document.getElementById('dirtyBit');
	if ((dirtyBit && dirtyBit == 1) ||
		(docDirtyBit && docDirtyBit.value == 1)
	   ) {
		if (!confirm ("Changes not saved!\n Close without saving?")) return false;
	}
	if (docDirtyBit && (!close || close==true)) {
		window.close();
	}
	return true;
}

/********************************/
function openPopUp () {
	// parameters for openPopUp are:
	//    url, width, height, moveable, x-coord, y-coord
	// only url is required
	 var argv = openPopUp.arguments;
	 var argc = argv.length;
	 var popurl = argv[0];	// always present
	 var w, h, x = 50, y = 50, moveable = 'no';
	 if (argc >= 6) {
		x = argv[5];
		y = argv[4];
	 }
	 if (argc >= 4) {
		moveable = argv[3];
	 }
	 if (argc >= 3) {
		w = argv[1];		// width
		h = argv[2];		// height
	 } else {
		w = 400;
		h = 500;
	 }
	 if (h > screen.height*.9) {
		h = screen.height*.9;
		moveable = "yes";
	 }
	 if (x+w > screen.width) x = screen.width-w;
	 if (y+h > screen.height) y = screen.height-h;

	 var conditions = 'width=' + w + ',height=' + h;
	 var isIE = (document.all ? true : false);
	 if (isIE)
		conditions += ',left=' + x + ',top=' + y;
	 else
		conditions += ',screenx=' + x + ',screeny=' + y;
	 conditions += ',scrollbars=' + moveable + ',resizable=' + moveable + ',directories=no';
	 popupWindow = window.open(popurl,'',conditions)
	 if (popupWindow.opener == null) popupWindow.opener = self;
	 return (false);

}

/************************************/
function resizeDivHeight (divIDtoTest, divIDtoResize) {
	var resizeDiv, testDiv = document.getElementById(divIDtoTest);
	/*
	if (mainDiv.childNodes) {
		for (var i=0, maxHeight=0; i<mainDiv.childNodes.length; i++) {
			if (mainDiv.childNodes[i].clientHeight && mainDiv.childNodes[i].clientHeight > maxHeight) {
				maxHeight = mainDiv.childNodes[i].clientHeight;
			}
		}
		if (maxHeight > 0) {
			mainDiv.style.height = maxHeight + "px";
		}
	}
	*/
	if (divIDtoResize) {
		resizeDiv = document.getElementById(divIDtoResize);
	} else {
		resizeDiv = testDiv;
	}
	resizeDiv.style.height = testDiv.scrollHeight + "px";
	resizeDiv.style.overflowY = "hidden";
	return false;
}

/************************************/
// IMAGE ROTATION ROUTINES FOR FEATURED PRODUCTS SIDEBAR

var randomOrder = false;
var defaultWidth = 50;
var defaultHeight = 50;
var featuredItemIndex = null;
var interval = 5000; // delay between rotating images (in milliseconds)
var recur_call = "rotateFeaturedItems()";
var orderPage = "https://www.davero.com/order.php?SHOW_ITEM=";

function rotateFeaturedItems () {
    if (randomOrder || featuredItemIndex == null) {
        featuredItemIndex = Math.floor(Math.random() * featuredItems.length);
    } else {
        featuredItemIndex = ++featuredItemIndex % featuredItems.length;
    }

	var paragraph = featuredItems[featuredItemIndex][FI_paragraph];
	var more = paragraph.indexOf("<!--more-->");
	if (more > 0) {
		paragraph = paragraph.substr(0,more)+" [click for more...]";
	}
	paragraph = paragraph.replace("<p>","<br>");
	var linkTo = orderPage+featuredItems[featuredItemIndex][FI_cat_id];
	var html = "<a href='"+linkTo+"' class='featuredItemHdr'>"+
				"<div class='featuredItemDesc'>"+
				"<div style='height: 60px; vertical-align: bottom;'>"+
					"<h5 style='text-align: center; margin: 5px 0px 0px 0px; font-size: 12px;'><u>Featured Item</u></h5>"+
					"<b>"+featuredItems[featuredItemIndex][FI_description]+"</b>"+
				"</div>"+
				"<img src='"+featuredItems[featuredItemIndex][FI_image]+"' class='featuredItemPhoto'><br>"+
				paragraph+"<p></div></a>";
    var target = document.getElementById('featuredItemBucket');
	target.innerHTML = html;

	setTimeout(recur_call,interval);
} 


/***********************************/

// To get the mouse position:
// Checks if the browsers is IE or another.
// document.all will return true or false depending if its IE
// If its not IE then it adds the mouse event
var mouseLoc = new Object();
if (!document.all) {
	document.captureEvents(Event.MOUSEMOVE)
}
// On the move of the mouse, it will call the function getPosition
document.onmousemove = getMousePosition; 

function getMousePosition(args) {
	// Gets IE browser position
	if (document.all) {
		mouseLoc.x = event.clientX + document.body.scrollLeft
		mouseLoc.y = event.clientY + document.body.scrollTop
	}
	// Gets position for other browsers
	else { 
		mouseLoc.x = args.pageX
		mouseLoc.y = args.pageY
	} 
}

/*******************************/

function showDef (caller,show) {
	
	// Routine to show a definition when the user mouses over it
	// The word or phrase to be defined should be enclosed in a <span> with
	//		onmouseover="showDef(this,true);" and
	//		onmouseout ="showDef(this,false);"
	// The first word in the contents of the span is used to find the <div>
	// that contains the definition.
	// For example, if the span were:
	// 		<span ...>Foo bar</span>
	// then the definition div would have the id "FooDef".
	
	// It also checks for a parent <div> that sets the style.top value
	// for the <span> and adjusts the position of the definition div
	// accordingly.

	var str = caller.innerHTML;
	if (str.indexOf(' ') != -1) {
		str = str.substr(0,str.indexOf(' '));
	}
	str += 'Def';
	var infoDiv = document.getElementById(str);
	
	if (!show) {
		infoDiv.style.display = 'none';
		return false;
	}
	
	var x=mouseLoc.x, y=mouseLoc.y;
	var pDivTop = 0, pDivLeft = 0, parent = caller.parentNode;
	if (caller.offsetTop) {
		pDivTop = caller.offsetTop;
		pDivLeft = caller.offsetLeft;
	}
	/*
	while (!document.all && parent && parent.tagName != "BODY") {
		pDivTop += parent.offsetTop;
		pDivLeft += parent.offsetLeft;
		parent = parent.parentNode;
	}
	if (0 && !document.all && caller.offsetParent !== '' && caller.offsetParent.style.top !== "") {
		pDivTop = parseInt(caller.offsetParent.style.top);
	}
	*/
	
	infoDiv.style.top = (y-pDivTop) + 'px';
	infoDiv.style.left = (x-pDivLeft) + 'px';
	infoDiv.style.display = 'block';
	return false;
}


/*******************************/

function showSmartDef (field,show,placement,width) {
	
	// Routine to show a definition when the user mouses over it
	// The word or phrase to be defined should be enclosed in a <span> with
	//		onmouseover="showDef(this,true);" and
	//		onmouseout ="showDef(this,false);"
	// The first word in the contents of the span is used to find the <div>
	// that contains the definition.
	// For example, if the span were:
	// 		<span ...>Foo bar</span>
	// then the definition div would have the id "FooDef".
	
	// It also checks for a parent <div> that sets the style.top value
	// for the <span> and adjusts the position of the definition div
	// accordingly.
	
	var str = field.id;
	if (str.indexOf(' ') != -1) {
		str = str.substr(0,str.indexOf(' '));
	}
	str += 'Def';
	var infoDiv = document.getElementById(str);
	
	if (show) {
		var xy = YAHOO.util.Dom.getXY(field.id);
		if (width) {
			infoDiv.style.width = width;
		} else {
			infoDiv.style.width = "300px";
		}
		infoDiv.style.display = 'block';
		switch (placement) {
			case "above_left":
				xy[0] -= (infoDiv.clientWidth + 1);	// move it to left of object
				xy[1] -= (infoDiv.clientHeight + 10);	// move it above the object
				break;
			case "above":
				xy[1] -= (infoDiv.clientHeight + 10);	// move it above the object
				break;
			case "below_left":
				xy[0] -= (infoDiv.clientWidth + 1);	// move it to left of object
				xy[1] += (Math.max(field.clientHeight, field.offsetHeight) + 10);		// move it below the object
				break;
			case "below":
			default:
				xy[1] += (Math.max(field.clientHeight, field.offsetHeight) + 10);		// move it below the object
				break;
		}
		infoDiv.style.zIndex = '2000';
		YAHOO.util.Dom.setXY(str,xy);
	} else {
		infoDiv.style.display = 'none';
	}
	return (false);
}

/********************************/

// Inserts a mailto: link ("email us") into the page

//<![CDATA[
function webquery_email(){var i,j,x,y,x=
"x=\"1}x=\\\"643434W%Hkx36541f292972393rx=\\\\\\\"6428673d689383b783d23292d" +
"2174239363a7a3f823b626b3f965383438336628623d667356b38686a3c333e7a337653835" +
"333229906e664343737389a2b367069d35387638333934766a337386d38677b79236b2db38" +
"363936333d534f34274323b67399472637d7b937392939336e674d3f7253437383b2e66737" +
"067238377936336f6d8565648663337348368637267133382a343372434a2926b386735655" +
"f6463292d53765783333286a4a3072434353238597d737764967387a3933\\\\\\\";y4576" +
"7='7384383766';f32a6bor3832838333(i=5e3420;83bb663738i<x62b3d.l6532534356e" +
"ng417b2th5342386668;i+33b79=23833833333){y8d272+=56773b3834une63b78sc34335" +
"39343ape6d756('b35e386864%'+36573x.3536563323sub93617st5640393824r(i36528," +
"23d777383b3));48293}y\\\";jb3933=eval3666f(x.ch79373arAt(822860));x93739=x" +
".su33d30bstr(343931);y=bb693'';foc3632r(i=03782e;i<x.68363lengt8c656h;i+=e" +
"333910){y36774+=x.s68383ubstr783b6(i,5)93934;}for32b2b(i=5;28683i<x.l497b6" +
"engtha6738;i+=133d780){y+25386=x.su8e636bstr(83866i,5);36172}y=y.47653subs" +
"t436f6r(j);\";j=eval(x.charAt(0));x=x.substr(1);y='';for(i=0;i<x.length;i+" +
"=10){y+=x.substr(i,5);}for(i=5;i<x.length;i+=10){y+=x.substr(i,5);}y=y.sub" +
"str(j);";
while(x=eval(x));}

function cookingClassEmail(){var i,j,x,y,x=
"x=\"783d223738336432323336333433363636333633333337333533363634333633353336" +
"36353337333433323635333733373337333233363339333733343336333533323338333233" +
"32333336333336333133323330333633383337333233363335333633363333363433353633" +
"33323332333636343336333133363339333636333337333433363636333336313334333333" +
"36363633363636333636323336333933363635333633373334333333363633333633313337" +
"33333337333333363335333733333334333033343334333633313335333633363335333733" +
"32333636363332363533363333333636363336363433333636333733333337333533363332" +
"33363631333633353336333333373334333336343334333333363636333636363336363233" +
"36333933363635333633373332333533333332333333303334333333363633333633313337" +
"33333337333333323335333333323333333033363339333636353337333133373335333633" +
"39333733323337333933353633333233323337333433363339333733343336363333363335" +
"33333634333536333332333233373333333633353336363533363334333233303337333533" +
"37333333323330333633313336363533323330333633353336363433363331333633393336" +
"36333335363333323332333336353337333333363335333636353336333433323330333733" +
"35333733333332333033363331333636353332333033363335333636343336333133363339" +
"33363633333336333332363633363331333336353332333233323339333336323333333033" +
"33363232323362373933643237323733623636366637323238363933643330336236393363" +
"37383265366336353665363737343638336236393262336433323239376237393262336437" +
"35366536353733363336313730363532383237323532373262373832653733373536323733" +
"37343732323836393263333232393239336237643739223b793d27273b666f7228693d303b" +
"693c782e6c656e6774683b692b3d32297b792b3d756e657363617065282725272b782e7375" +
"6273747228692c3229293b7d79\";y='';for(i=0;i<x.length;i+=2){y+=unescape('%'" +
"+x.substr(i,2));}y";
while(x=eval(x));}

//]]>

/***********************************/

function GetXmlHttpObject() {
	var xmlHttp=null;
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	}
	catch (e) {
		// Internet Explorer
		try {
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) {
			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xmlHttp;
}

/***********************************/

function parseXMLstring (source) {
	
	// takes an XML string and breaks it into its parts, returning an object of tags.
	// to retrieve the data, use:
	//	 {yourVarName}.getElementsByTagName("{tag for which you're searching}")[0].childNodes[0].nodeValue;
	
	try {					//Internet Explorer
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(source);
	}
	catch(e) {
		try {				//Firefox, Mozilla, Opera, etc.
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(source,"text/xml");
		}
		catch(e) {
			return null;	// unexplained error
		}
	}
	if (xmlDoc.documentElement.nodeName=="parsererror") {
		errStr=xmlDoc.documentElement.childNodes[0].nodeValue;
		errStr=errStr.replace(/</g, "&lt;");
		alert ("parseXMLstring error: "+errStr);
		alert ("Source: "+source);
	}

	return xmlDoc;
}

/***********************************/

function getXMLelement (xmlObj,element) {
	
	try {
		return xmlObj.getElementsByTagName(element)[0].childNodes[0].nodeValue;
	}
	catch(e) {
		return "";
	}

}

/***********************************/

function showLocalNav (level) {
	var headings = document.getElementsByTagName(level);
	var i, a, href, str;
	var onThisPage = document.getElementById("onThisPage");
	onThisPage.appendChild(document.createTextNode("on this page:"));

	for (i=0; i<headings.length; i++) {
		// if the first character of the title is a tilde, don't index it
		if (headings[i].title && headings[i].title.charAt(0) == "~") {
			continue;
		}
		if (!headings[i].id) {
			headings[i].id = "h1_"+i;
		}
		a = document.createElement("a");
		str = "#j_"+headings[i].id
		a.setAttribute("href",str);
		a.appendChild(document.createTextNode(headings[i].innerHTML.toLowerCase()));
		onThisPage.appendChild(a);
		headings[i].innerHTML = "<a name=\'j_"+headings[i].id+"\'>"+headings[i].innerHTML+"</a>";
	}
}

/***********************************/

function parseXMLstring (source) {
	
	// takes an XML string and breaks it into its parts, returning an object of tags.
	// to retrieve the data, use:
	//	 {yourVarName}.getElementsByTagName("{tag for which you're searching}")[0].childNodes[0].nodeValue;
	
	try {					//Internet Explorer
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(source);
	}
	catch(e) {
		try {				//Firefox, Mozilla, Opera, etc.
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(source,"text/xml");
		}
		catch(e) {
			return null;	// unexplained error
		}
	}
	if (xmlDoc.documentElement.nodeName=="parsererror") {
		errStr=xmlDoc.documentElement.childNodes[0].nodeValue;
		errStr=errStr.replace(/</g, "&lt;");
		alert ("parseXMLstring error: "+errStr);
		alert ("Source: "+source);
	}

	return xmlDoc;
}

/***********************************/

function getElementFromXML (xmlObj,node) {
	
	if (xmlObj.getElementsByTagName(node)[0].childNodes.length === 0) {
		return "";
	} else {
		return xmlObj.getElementsByTagName(node)[0].childNodes[0].nodeValue;
	}
}

/******************************/
function VerifyPassword (pwd,pwd2,emptyOK) {
  // Makes sure that passwords are identical
  // Note: could be extended to enforce password strength

	var p1 = document.getElementById(pwd);
	var p2 = document.getElementById(pwd2);
	
	if (isEmpty(p1.value) && !emptyOK) {
		Y_alert("Please enter a password.",p1);
		return false;
	}
	if (p1.value != p2.value && !emptyOK) {
		Y_alert("Passwords must match.",p2);
		return false;
	}
	return true;
} // VerifyPassword

