
  // find all the option fields in the form and compile an option set string from them
  // calling convention
  //   from a form field : onchange=\"AddCartCompileOptions(this.form);\"
  //   from a form       : onchange=\"AddCartCompileOptions(this);\"
  function AddCartCompileOptions(FormObject)
  {
    var Idx;
    var groupset = "";

    for (Idx = 0; Idx < FormObject.length; Idx++)
    {
      // option fields look like this : OPTION_P101-G2
      //       if (/OPTION_P\d+_G\d+/.test(FormObject.elements[Idx].name))
      if (/OPTION_P\w+_G\d+/.test(FormObject.elements[Idx].name))
      {
        // if its a select list, use its value, if its a radio button make sure its checked
        if ( (FormObject.elements[Idx].type != "radio") ||
            ((FormObject.elements[Idx].type == "radio") && (FormObject.elements[Idx].checked)))
        {
          var startIdx = FormObject.elements[Idx].name.indexOf("_G",1) + 2; // first digit of group
          var endIdx = FormObject.elements[Idx].name.length;
          var Group_ID = FormObject.elements[Idx].name.substring(startIdx, endIdx);

          // update the option set string with option group ID and selected option group value
          groupset = groupset + ".G" + Group_ID + "-" + FormObject.elements[Idx].value;
        }
      }
    }

    FormObject.optionset.value = groupset;
  }

 // find all the option fields in the form and update the price based on their sum total
  // calling convention
  //   from a form field : onchange=\"AddCartCompileOptions(this.form, this.form.returnField);\"
  //   from a form       : onchange=\"AddCartCompileOptions(this, this.form.returnField);\"
  function AddCartCompileOptionPrice(FormObject, ReturnFieldObject)
  {
    var Idx;
    var groupset = "";
    var base_price = 0;
    var options_price = 0;
    var final_price = 0;
    var priceDiv;
    var ReturnFieldDiv = ReturnFieldObject;

    for (Idx = 0; Idx < FormObject.length; Idx++)
    {
      // option fields look like this : OPTION_P101-G2
      // option price arrays look like this : OptionPrices_P101-G2[]
      // find all option fields and use their names to grab their cost from the array with the matching name
      //       if (/OPTION_P\d+_G\d+/.test(FormObject.elements[Idx].name))
      if (/OPTION_P\w+_G\d+/.test(FormObject.elements[Idx].name))
      {
        // if its a select list, use its value, if its a radio button make sure its checked
        if ( (FormObject.elements[Idx].type != "radio") ||
            ((FormObject.elements[Idx].type == "radio") && (FormObject.elements[Idx].checked)))
        {
          if (FormObject.elements[Idx].type != "radio")
          {
            var startIdx = FormObject.elements[Idx].name.indexOf("_P",1); // first character of product-group signature
            var endIdx = FormObject.elements[Idx].name.length;
            var ProdGroupID = FormObject.elements[Idx].name.substring(startIdx, endIdx);

             // get a reference to the product-option group price array based on the variables name
            var arrayRef = window['OptionPrices' + ProdGroupID];

            // select the option groups price value based on the currently selected item in the dropdown (*1 to force numeric)
            options_price = options_price + (arrayRef[FormObject.elements[Idx].selectedIndex] * 1);
          }
          else
          {
            var startIdx = FormObject.elements[Idx].id.indexOf("_P",1); // first character of product-group signature
            var endIdx = FormObject.elements[Idx].id.length;
            var ProdGroupID = FormObject.elements[Idx].id.substring(startIdx, endIdx);

             // get a reference to the product-option item price variable based on the radio button id name
            var varRef = window['OptionPrices' + ProdGroupID];

            // select the option groups price value on the variable value
            options_price = options_price + (varRef * 1);
          }
        }
      }
      else if (FormObject.elements[Idx].name == 'baseprice')
      {

        base_price = (FormObject.elements[Idx].value * 1);  // * 1 to force numeric
      }

    }

    // set up final price, force two decimal places in formatting
    final_price = (base_price + options_price);
    final_price = final_price.toFixed(2);

    // check to see if price update needs to happen for a div
    priceDiv = document.getElementById(ReturnFieldDiv)
    if (priceDiv)
    {
      // return field is an ID name for a div, update its contents
      priceDiv.innerHTML = (final_price);
    }

    // check to see if price update needs to happen for a form object
    if (ReturnFieldObject.value)
    {
      // final unitprice is base price + cost of all options
      ReturnFieldObject.value = (final_price);
    }
  }


  function AddCartRecalcPerCost(FormObject, ReturnField, SumField, QuantityField)
  {
    var Result = (Math.round((SumField.value / QuantityField.value) * 100)) / 100;
    if (!(isNaN(Result)))
    {
        ReturnField.value = Result;
    }
  }

  function AddCartRecalcSumCost(FormObject, ReturnField, PerField, QuantityField)
  {
    var Result = (Math.round((PerField.value * QuantityField.value) * 100)) / 100;
    if (!(isNaN(Result)))
    {
        ReturnField.value = Result;
    }
  }




  function ShowExtraInput(id)
  {
    var e = document.getElementById(id);

    if(e.style.display == 'none')
      e.style.display = 'block';
    else
      e.style.display = 'none';
  }




   // ********** STORE POPUP FUNCTIONS **********


    var storePopupOffsetX = -5;    //Customize x offset of tooltip
    var storePopupOffsetY = 0;     //Customize y offset of tooltip
    var storePopupIE=document.all;
    var storePopupNS6=document.getElementById && !document.all;
    var storePopupEnabled=false;
    var storePopupObj;

    function storePopupFindElement()
    {
      if (storePopupIE || storePopupNS6)
        storePopupObj=document.all? document.all["storePopup"] : document.getElementById? document.getElementById("storePopup") : ""
    }

    function storePopupevalScriptsGlobal(htmlContent)
    {
         // find all script elements in the HTML and eval them globally
          var scriptText = htmlContent;
          var VstartIdx;
          var VendIdx;

          // convert all script tags to lowercase
          scriptText = scriptText.replace(/script/gi,"script");


          VstartIdx = scriptText.indexOf("<script");
          while (VstartIdx != -1)
          {
            VstartIdx = scriptText.indexOf(">", VstartIdx) + 1; // seek to end of tag a nd one char after
            VendIdx = scriptText.indexOf("</script", VstartIdx) - 1; // search for close tag and one char before

            var strData = scriptText.substring(VstartIdx, VendIdx);
            if (strData.length > 0)
            {
              // need to eval in a global context
              // otherwise variables defined will exist only within this function

              // IE =exectScript, FF/chrome/etc =wind.eval
              if (window.execScript)
                { window.execScript(strData); }
              else
                { window.eval(strData); }
            }

            VstartIdx = scriptText.indexOf("<script", VendIdx); // search for next opening tag
          }
    }

    function storePopupietruebody()
    {
      return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
    }

    function storePopupShow(thetext, thecolor, thewidth)
    {
      storePopupFindElement();

      if (storePopupNS6 || storePopupIE)
      {
        if (typeof thewidth != "undefined") storePopupObj.style.width = thewidth + "px";
        if (typeof thecolor != "undefined" && thecolor != "") storePopupObj.style.backgroundColor = thecolor;
        storePopupObj.innerHTML = thetext;

        // eval the javascript to make sure it gets loaded into the DOM
        storePopupevalScriptsGlobal(thetext);

        return false;
      }
    }


    // preferX = 'left' or 'right'
    // pregerY = 'top' or 'bottom'
    function storePopupPositionByID(IDName, preferX, preferY, buttonclass)
    {
      storePopupFindElement();

      // toggle popup state
      storePopupEnabled = !(storePopupEnabled);

      // hide if its not visible, otherwise show the tip and move it to the desired location
      if ( !(storePopupEnabled) )
      {
        // hide popup
        storePopupHide(IDName, buttonclass);
      }
      else
      {
        var parentObj = document.getElementById(IDName);

        if (parentObj)
        {
          parentObj.className = buttonclass + 'gray';

          var parentObj_x, parentObj_y, parentObj_w , parentObj_h;

            // get width and height first
            parentObj_w = parentObj.offsetWidth;
            parentObj_h = parentObj.offsetHeight;

            // then loop through the object and all its parents to accumulate its x,y position
            parentObj_x = 0;
            parentObj_y = 0;
            while( parentObj != null )
            {
              parentObj_x += parentObj.offsetLeft;
              parentObj_y += parentObj.offsetTop;
              parentObj = parentObj.offsetParent;
            }

          // adjust target x and y locations by global offsets
          parentObj_x = parentObj_x + storePopupOffsetX;
          parentObj_y = parentObj_y + storePopupOffsetY;


          // get the edges of the page visible to the user
          var windowLeftEdge = storePopupIE ? storePopupietruebody().scrollLeft : window.pageXOffset;
          var windowTopEdge = storePopupIE ? storePopupietruebody().scrollTop : window.pageYOffset;
          var windowRightEdge = storePopupIE && !window.opera ? storePopupietruebody().clientWidth + windowLeftEdge : window.innerWidth + windowLeftEdge;
          var windowBottomEdge = storePopupIE && !window.opera ? storePopupietruebody().clientHeight + windowTopEdge : window.innerHeight + windowTopEdge;

          if (preferX == 'right')
          {
            // Check to see if the poup will spill over the right edge of the window.
            //   If it fits, set its left edge to the left edge of the parent object,
            //   otherwise align its right edge to the right edge of the parent object
            if ((parentObj_x + storePopupObj.offsetWidth) <= windowRightEdge)
              storePopupObj.style.left = parentObj_x + "px";
            else
              storePopupObj.style.left = (parentObj_x + parentObj_w - storePopupObj.offsetWidth)+ "px";
          }
          else
          {
            // prefer left alignment instead, reverse test order above
            // make sure the left edge of the popup doesn't spill beyond the left edge of the window
            if ((parentObj_x + parentObj_w - storePopupObj.offsetWidth) >= windowLeftEdge)
              storePopupObj.style.left = (parentObj_x + parentObj_w - storePopupObj.offsetWidth)+ "px";
            else
              storePopupObj.style.left = parentObj_x + "px";
          }

          if (preferY == 'bottom')
          {
            // Check to see if the poup will spill over the bottom edge of the window.
            //   If it fits, set its top edge to the bottom edge of the parent object,
            //   otherwise align its bottom edge to the top edge of the parent object
            if (((parentObj_y + parentObj_h) + storePopupObj.offsetHeight) <= windowBottomEdge)
              storePopupObj.style.top = (parentObj_y + parentObj_h) + "px";
            else
              storePopupObj.style.top = (parentObj_y - storePopupObj.offsetHeight) + "px";
          }
          else
          {
            // prefer top alignment instead, reverse test order above
            // make sure the top edge of the popup doesn't spill beyond the top edge of the window
            if ((parentObj_y - storePopupObj.offsetHeight) > windowTopEdge)
              storePopupObj.style.top = (parentObj_y - storePopupObj.offsetHeight) + "px";
            else
              storePopupObj.style.top = (parentObj_y + parentObj_h) + "px";
          }

          // make the popup visible
          storePopupObj.style.visibility="visible";
        }
      }
    }

    function storePopupHide(IDName, buttonclass)
    {
      // restore the parent button to its normal class
      var parentObj = document.getElementById(IDName);
      if (parentObj)
        { parentObj.className = buttonclass; }

      storePopupFindElement();

      if (storePopupNS6 || storePopupIE)
      {
        storePopupEnabled=false;
        storePopupObj.style.visibility="hidden";
        storePopupObj.style.left="-1000px";
        storePopupObj.style.backgroundColor='';
        storePopupObj.style.width='';
      }
    }


  function cartoptionsPopupRequest(urlParams)
  {
    var remoteURL;
    // form base lookup URL
    remoteURL = '/cart/store/change_options_popup_2009.cgi?' + urlParams;

    //alert(remoteURL);
    store_dynRemoteJSStartEvalGlobal(remoteURL);
  }

