// Error handler for the asynchronous functions.
var myErrorHandler = function(statusCode, statusMsg) {
	alert('Status: ' + statusCode + ', ' + statusMsg);
}

// Hides errors produced by asynchronous functions.
var SuppressError = function(statusCode, statusMsg) {
	// Do nothing
}

var IsNumeric = function(strString) {
   var strValidChars = "0123456789";
   var strChar;
   var blnResult = true;

   if (strString.length == 0) return false;

   //  test strString consists of valid characters listed above
   for (var i = 0; i < strString.length && blnResult == true; i++) {
      strChar = strString.charAt(i);
      if (strValidChars.indexOf(strChar) == -1) {
         blnResult = false;
      }
   }
   return blnResult;
}

var IsFloat = function(strString) {
   var strValidChars = "0123456789.";
   var strChar;
   var blnResult = true;
   var DecimalCnt = 0;

   if (strString.length == 0) return false;

   //  test strString consists of valid characters listed above
   for (var i = 0; i < strString.length && blnResult == true; i++) {
      strChar = strString.charAt(i);
      if (strValidChars.indexOf(strChar) == -1) {
         blnResult = false;
      }
	  // Keep track of how many decimal points we find
	  if (strChar=='.') {
		  DecimalCnt++;
	  }
   }
   
   // Make sure we didn't find more than one decimal point
   if (DecimalCnt > 1)
     blnResult = false;
	 
   return blnResult;
}

// Given a string representation of what is supposed to be a float value, returns the same string with any commas removed
var CleanFloatStr = function(strString) {
   var strChar;
   var Result = '';

   if (strString.length == 0) 
     return '';

   //  Loop through strString
   for (var i = 0; i < strString.length; i++) {
      strChar = strString.charAt(i);
      if (strChar!=',') {
         Result = Result + strChar;
      }
   }
   
   return Result;
}

var CurrencyFormat = function(num) {
	var sign, cents;
	
	num = num.toString().replace(/\$|\,/g,'');
	if(isNaN(num))
		num = "0";
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num*100+0.50000000001);
	cents = num%100;
	num = Math.floor(num/100).toString();
	if(cents < 10)
		cents = "0" + cents;
	for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
		num = num.substring(0,num.length-(4*i+3))+','+
		num.substring(num.length-(4*i+3));
	return (((sign)?'':'-') + num + '.' + cents);
}

var Left = function(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}

var Right = function(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

// Trims a string
var Trim = function(stringToTrim) {
	return stringToTrim.replace(/^\s+|\s+$/g,"");
}

// Removes an arbitrary element by id
var removeEl = function(idEl){
	var t = document.getElementById(idEl);
	t.parentNode.removeChild(t);
}

// Removes a row from a table by using ids
var removeRowByIDs = function(idTable, idRow){
	var table = document.getElementById(idTable);
	var row = document.getElementById(idRow);
	var tbody = table.getElementsByTagName("tbody")[0];
	
	tbody.removeChild(row);
}

var MM_openBrWindow = function(theURL,winName,features){ 
  window.open(theURL,winName,features);
}

var MM_displayStatusMsg = function(msgStr) { 
  status=msgStr;
  document.MM_returnValue = true;
}

var MM_callJS = function(jsStr) { 
  return eval(jsStr);
}

var GoToLoginPage = function(){
	window.location.href = 'index.cfm';
}

var getSelectedRadio = function(buttonGroup) {
   // returns the array number of the selected radio button or -1 if no button is selected
   if (buttonGroup[0]) { // if the button group is an array (one button is not an array)
      for (var i=0; i<buttonGroup.length; i++) {
         if (buttonGroup[i].checked) {
            return i
         }
      }
   } else {
      if (buttonGroup.checked) { return 0; } // if the one button is checked, return zero
   }
   // if we get to this point, no radio button is selected
   return -1;
} // Ends the "getSelectedRadio" function

var getSelectedRadioValue = function(buttonGroup) {
   // returns the value of the selected radio button or "" if no button is selected
   var i = getSelectedRadio(buttonGroup);
   if (i == -1) {
      return "";
   } else {
      if (buttonGroup[i]) { // Make sure the button group is an array (not just one button)
         return buttonGroup[i].value;
      } else { // The button group is just the one button, and it is checked
         return buttonGroup.value;
      }
   }
} // Ends the "getSelectedRadioValue" function

// Selects the specified option value in the select list
var SetSelectOption = function(selectID, optionValue){
	var list = document.getElementById(selectID);
	for (var intI = 0; intI < list.options.length; intI++) {
	  if (list.options[intI].value == optionValue) {
		list.options[intI].selected = true;
	  }
	}
}

// Changes the specified option text and value in the select list
var ChangeSelectOption = function(selectID, optionValueOld, optionTextNew, optionValueNew){
	var list = document.getElementById(selectID);
	for (var intI = 0; intI < list.options.length; intI++) {
	  if (list.options[intI].value == optionValueOld) {
		list.options[intI].text = optionTextNew;
		list.options[intI].value = optionValueNew;
	  }
	}
}

var errors='';

function MM_validateForm() { //v4.0
  if (document.getElementById){
    var i,p,q,nm,test,num,min,max,args=MM_validateForm.arguments;
    for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=document.getElementById(args[i]);
      if (val) { nm=val.name; if ((val=val.value)!="") {
        if (test.indexOf('isEmail')!=-1) { p=val.indexOf('@');
          if (p<1 || p==(val.length-1)) errors+='- '+nm+' must contain an e-mail address.\n';
        } else if (test!='R') { num = parseFloat(val);
          if (isNaN(val)) errors+='- '+nm+' must contain a number.\n';
          if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
            min=test.substring(8,p); max=test.substring(p+1);
            if (num<min || max<num) errors+='- '+nm+' must contain a number between '+min+' and '+max+'.\n';
      } } } else if (test.charAt(0) == 'R') errors += '- '+nm+' is required.\n'; }
    } if (errors) alert('The following error(s) occurred:\n'+errors);
    document.MM_returnValue = (errors == '');
} }

var SetAllCheckBoxes = function(FormName, FieldName, CheckValue){
	if(!document.forms[FormName])
		return;
	var objCheckBoxes = document.forms[FormName].elements[FieldName];
	if(!objCheckBoxes)
		return;
	var countCheckBoxes = objCheckBoxes.length;
	if(!countCheckBoxes)
		objCheckBoxes.checked = CheckValue;
	else
		// set the check value for all check boxes
		for(var i = 0; i < countCheckBoxes; i++)
			objCheckBoxes[i].checked = CheckValue;
}

var MenuShowing = true;

var ToggleMenuDisplay = function() {
	var LeftMenu = document.getElementById('LeftMenu');
	var ShowHideArrow = document.getElementById('ShowHideArrow');
	
	if (MenuShowing) {
		LeftMenu.style.display = 'none';
		ShowHideArrow.src = 'images/expand.gif';
		MenuShowing = false;
	} else {
		LeftMenu.style.display = '';
		ShowHideArrow.src = 'images/collapse.gif';
		MenuShowing = true;
	}
}

// Find the x position of an object
function myFindPosX(obj) {
	var curleft = 0;
	if(obj.offsetParent)
		while(1) 
		{
		  curleft += obj.offsetLeft;
		  if(!obj.offsetParent)
			break;
		  obj = obj.offsetParent;
		}
	else if(obj.x)
		curleft += obj.x;
	return curleft;
}

// Find the y position of an object
function myFindPosY(obj) {
	var curtop = 0;
	if(obj.offsetParent)
		while(1)
		{
		  curtop += obj.offsetTop;
		  if(!obj.offsetParent)
			break;
		  obj = obj.offsetParent;
		}
	else if(obj.y)
		curtop += obj.y;
	return curtop;
}

function FindPosById(idCtrl) { 
	var pos = {x:0, y:0};
	var ctrl = document.getElementById(idCtrl);
	
	if (ctrl.offsetParent) {
		while(ctrl) {
			pos.x += ctrl.offsetLeft;
			pos.y += ctrl.offsetTop;
			ctrl = ctrl.offsetParent;
		}
	} else if (ctrl.x && ctrl.y) {
		pos.x += ctrl.x;
		pos.y += ctrl.y;
	}
	
	return pos;
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

// Find the x position of an object
function findPosX(obj) {
	var curleft = 0;
	if(obj.offsetParent)
		while(1) 
		{
		  curleft += obj.offsetLeft;
		  if(!obj.offsetParent)
			break;
		  obj = obj.offsetParent;
		}
	else if(obj.x)
		curleft += obj.x;
	return curleft;
}

// Find the y position of an object
function findPosY(obj) {
	var curtop = 0;
	if(obj.offsetParent)
		while(1)
		{
		  curtop += obj.offsetTop;
		  if(!obj.offsetParent)
			break;
		  obj = obj.offsetParent;
		}
	else if(obj.y)
		curtop += obj.y;
	return curtop;
}

// Moves an absolutely positioned object to a position relative to another object
function relPosition(moveID, relID, dX, dY, SubtractWidth) {
	var moveObj = MM_findObj(moveID);
	var relObj = MM_findObj(relID);
	var relObjX = findPosX(relObj);
	var relObjY = findPosY(relObj);
	// Move the obj left it's own width
	if (SubtractWidth) {
		// Show the obj - need to do this first to get it's width
		moveObj.style.display = '';
		// Move the obj
		moveObj.style.left = (relObjX + dX - moveObj.offsetWidth) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
	} else {
		// Move the obj
		moveObj.style.left = (relObjX + dX) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
		// Show the obj
		moveObj.style.display = '';
	}
	
}

// Moves an absolutely positioned object to a position relative to another object, but based on object
function relPositionObj(moveID, relObj, dX, dY, SubtractWidth) {
	var moveObj = MM_findObj(moveID);
	var relObjX = myFindPosX(relObj);
	var relObjY = myFindPosY(relObj);
	
	// Move the obj left it's own width
	if (SubtractWidth) {
		// Show the obj - need to do this first to get it's width
		moveObj.style.display = '';
		// Move the obj
		moveObj.style.left = (relObjX + dX - moveObj.offsetWidth) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
	} else {
		// Move the obj
		moveObj.style.left = (relObjX + dX) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
		// Show the obj
		moveObj.style.display = '';
	}
	
}

// Moves an absolutely positioned object to a position relative to another object, but based on object
// This version uses JQuery to get the coordinates of the relObj because JQuery's function to do that
// supports the object being in a scrolling div container
function relPositionObjJQ(moveID, relObj, dX, dY, SubtractWidth) {
	var moveObj = MM_findObj(moveID);
	var relObjPos = $(relObj).offset();
	var relObjX = relObjPos.left;
	var relObjY = relObjPos.top;
	
	// Move the obj left it's own width
	if (SubtractWidth) {
		// Show the obj - need to do this first to get it's width
		moveObj.style.display = '';
		// Move the obj
		moveObj.style.left = (relObjX + dX - moveObj.offsetWidth) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
	} else {
		// Move the obj
		moveObj.style.left = (relObjX + dX) + 'px';
		moveObj.style.top = (relObjY + dY) + 'px';
		// Show the obj
		moveObj.style.display = '';
	}
	
}

function getCursorXY(e) {
	var x = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
	var y = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
	return [x,y];
}

/*
   name - name of the cookie
   value - value of the cookie
   [expires] - expiration date of the cookie
     (defaults to end of current session)
   [path] - path for which the cookie is valid
     (defaults to path of calling document)
   [domain] - domain for which the cookie is valid
     (defaults to domain of calling document)
   [secure] - Boolean value indicating if the cookie transmission requires
     a secure transmission
   * an argument defaults when it is assigned null as a placeholder
   * a null placeholder is not required for trailing omitted arguments
*/

function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
      ((expires) ? "; expires=" + expires.toGMTString() : "") +
      ((path) ? "; path=" + path : "") +
      ((domain) ? "; domain=" + domain : "") +
      ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}

/*
  name - name of the desired cookie
  return string containing value of specified cookie or null
  if cookie does not exist
*/

function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

var SubmitOnEnter = function(myfield,e) {
	var keycode;
	if (window.event) 
		keycode = window.event.keyCode;
	else 
		if (e) 
			keycode = e.which;
	else 
		return true;
	
	if (keycode == 13) {
	   myfield.form.Submit.click();
	   return false;
	} else
	   return true;
}

// Used like this: <input type=text onkeyup="getKey(event, 13, 'myjsfunc();')">
var getKey = function(e, keyCode, jscode) {
	if(e.keyCode == keyCode) {
		eval(jscode);
	}
}

var SortListBox = function(id) {
  var box = document.getElementById(id);
  var tmp  = new Array();
  var len = box.options.length;
  for (i = 0; i < len; i++) {
    tmp[i] = new Array(box.options[i].text.toLowerCase(), new Object(box.options[i]));
  }
  tmp.sort();

  box.options.length = 0;

  for (i = 0; i < len; i++) box.options.add(tmp[i][1]);
}

var MoveListItem = function(idSource, idTarget) {
	var Source = document.getElementById(idSource);
	var Target = document.getElementById(idTarget);

	if ((Source != null) && (Target != null)) {
		while ( Source.options.selectedIndex >= 0 ) {
			var newOption = new Option(); // Create a new instance of ListItem
			newOption.text = Source.options[Source.options.selectedIndex].text;
			newOption.value = Source.options[Source.options.selectedIndex].value;
		   
			Target.options[Target.length] = newOption; //Append the item in Target
			Source.remove(Source.options.selectedIndex);  //Remove the item from Source
		}
	}
	
	SortListBox(idTarget);
}

var selectAllListOptions = function(idSelect) {
	var ref = document.getElementById(idSelect);
	
	for(var i=0; i < ref.options.length; i++)
		ref.options[i].selected = true;
}

var GoToURL = function(URL){
	window.location.href = URL;
}

var OverCallout = false;
var HideCalloutTimer;
var idTblCallout = 'tblCallout';
var arrCalloutsToHide = new Array();

// Adds a callout id to the array of callouts to hide, but only if it isn't already in the array
var AddCalloutIdToArray = function(idCallout){
	var posCalloutId = -1;
	//Check to see if the callout id is already in the array
	for(var i=0; i < arrCalloutsToHide.length; i++)
		if (arrCalloutsToHide[i] == idCallout)
			posCalloutId = i;
	// If it's not already in the array, add it
	arrCalloutsToHide.splice(0,0,idCallout);
}

// Removes a callout id from the array of callouts to hide
var RemoveCalloutIdFromArray = function(idCallout){
	var posCalloutId = -1;
	//Find the callout id in the array of callouts that are showing
	for(var i=0; i < arrCalloutsToHide.length; i++)
		if (arrCalloutsToHide[i] == idCallout)
			posCalloutId = i;
	// Remove the callout id from the array
	if (posCalloutId > -1)
		arrCalloutsToHide.splice(posCalloutId,1);
}

var OnMouseOverCallout = function(idCallout){
	//if (HideCalloutTimer)
		//clearTimeout(HideCalloutTimer);
	// Add the callout id to the array of callouts that are showing
	//AddCalloutIdToArray(idCallout);
	
	// Remove the callout id from the array of callouts to hide, if it is in the list
	RemoveCalloutIdFromArray(idCallout);
	// Set the flag that the mouse is over the callout
	OverCallout = true;
}

var OnMouseOutCallout = function(idCallout){
	// Hide the callout
	// HideCallout(idCallout);
	// If no callouts are showing, clear the OverCallout flag
	//if (arrCallouts.length == 0)
		//OverCallout = false;
		
	// Set the flag that the mouse is not over the callout
	OverCallout = false;
	// Set the hide callout timer
	SetHideCallout(idCallout);
}

var ShowCallout = function(Desc, idPos) {
	//if (HideCalloutTimer)
		//clearTimeout(HideCalloutTimer);
	idTblCallout = 'tblCallout';
	var CalloutDescTD = document.getElementById('tdCalloutDesc');

	if (CalloutDescTD) {
		// Put the description in place
		CalloutDescTD.innerHTML = Desc;
		// Move the layer
		relPosition(idTblCallout, idPos, 5, -10, true);
	}
}

var ShowCalloutObj = function(Desc, objPos, dX, dY, CallOutWidth) {
	if (HideCalloutTimer){
		clearTimeout(HideCalloutTimer);
		HideCalloutTimer = null;
	}
	var CalloutDescTD = document.getElementById('tdCalloutDesc');
	
	if (CalloutDescTD) {
		// If we have a width value and it's greater than 0, set the width
		if (CallOutWidth && CallOutWidth > 0)
			CalloutDescTD.style.width = CallOutWidth + 'px';
		// Put the description in place
		CalloutDescTD.innerHTML = Desc;
		// Move the layer
		relPositionObj(idTblCallout, objPos, dX, dY, true);
	}
}

var ShowFeaItemCalloutObj = function(idFeaItemCallout, objPos, dX, dY, CallOutWidth) {
	//if (HideCalloutTimer)
		//clearTimeout(HideCalloutTimer);
	idTblCallout = idFeaItemCallout;
	// Remove the callout id from the array of callouts to hide, if it is in the list
	RemoveCalloutIdFromArray(idTblCallout);
	relPositionObj(idTblCallout, objPos, dX, dY, true);
}

var ShowRecommProdCalloutObj = function(idRecommProdCallout, objPos, dX, dY, CallOutWidth) {
	//if (HideCalloutTimer)
		//clearTimeout(HideCalloutTimer);
	idTblCallout = idRecommProdCallout;
	// Remove the callout id from the array of callouts to hide, if it is in the list
	RemoveCalloutIdFromArray(idTblCallout);
	relPositionObjJQ(idTblCallout, objPos, dX, dY, false);
}

var HideCallout = function() {
	// Loop through the array of callouts to hide
	for(var i=0; i < arrCalloutsToHide.length; i++){
		if (document.getElementById(arrCalloutsToHide[i])) {
			// Hide the callout
			document.getElementById(arrCalloutsToHide[i]).style.display='none';
			// Remove the callout id from the array of callouts to hide
			RemoveCalloutIdFromArray(arrCalloutsToHide[i]);
		}
	}
}

var SetHideCallout = function(idCallout) {
	// Add the callout id to the array of callouts to hide
	AddCalloutIdToArray(idCallout);
	HideCalloutTimer = setTimeout(HideCallout, 100);
}

var returnDocument = function() {
	var file_name = document.location.href;
	var end = (file_name.indexOf("?") == -1) ? file_name.length : file_name.indexOf("?");
	return file_name.substring(file_name.lastIndexOf("/")+1, end);
}

var DHTMLSound = function(idAudioSpan, surl) {
  document.getElementById(idAudioSpan).innerHTML=
    "<embed src='"+surl+"' hidden=true autostart=true loop=false>";
}

// Scrolls the contents of a div up
var ScrollUp = function() {
	document.getElementById(ScrollUpDivID).scrollTop -= 10;
}
  
// Scrolls the contents of a div down
var ScrollDn = function() {
	document.getElementById(ScrollDnDivID).scrollTop += 10;
}

// Starts repeated scrolling up - generally called in onmousedown
var StartScrollUp = function(idDiv){
	// Purposely not a var so it's global
	ScrollUpDivID = idDiv;
	ScrollUp();
	ScrollUpTimeout = setInterval(ScrollUp,50);
}

// Stops repeated scrolling up - generally called in onmouseup
var StopScrollUp = function(){
	if (typeof(ScrollUpTimeout) != "undefined") clearTimeout(ScrollUpTimeout);
}

// Starts repeated scrolling down - generally called in onmousedown
var StartScrollDn = function(idDiv){
	// Purposely not a var so it's global
	ScrollDnDivID = idDiv;
	ScrollDn();
	ScrollDnTimeout = setInterval(ScrollDn,50);
}

// Stops repeated scrolling down - generally called in onmouseup
var StopScrollDn = function(){
	if (typeof(ScrollDnTimeout) != "undefined") clearTimeout(ScrollDnTimeout);
}

var callback = function(text){
	//alert("Callback: " + text);
}


