    function FormatNumber(num, decimals, mask, leading_zeros_ok)
    {
      var pos;
      var str = "";
      var masklen = 0;
      var formatted_str = "";
      var numbers = "0123456789";
      var padchr = " ";
      var tmp;
      var tmp1 = "";
      var onechar;
  
      tmp1 = num + "";
      // round decimal places
      str = getRounded(tmp1, decimals);
      if (decimals > 0)
        str = preserveZeros(str, decimals); // this step makes nNum into a string. v1.0.1 Math.abs
      for (i=0; i<mask.length; i++)
      {
        if (mask.charAt(i) == "#") ++masklen;
      }
      if (decimals > 0) ++masklen; // add one for the decimal point
      while (str.length < masklen) 
      {
        if (decimals > 0) 
          str = padchr + str 
        else
          str = str + padchr;
      }
      var i1 = 0;
      var maskchar;
      var strchar;
      nonblankprinted = false;
      for (i=0; i<mask.length; i++)
      {
        maskchar = mask.charAt(i);
        if (maskchar == "#") 
        {
          strchar = str.charAt(i1++);
          if (strchar == " ")
            if (!nonblankprinted) strchar = "";
          if  (strchar == "0")
          {
            if ((!nonblankprinted) && (!leading_zeros_ok)) strchar = ""
          }
          if ((!nonblankprinted) && (strchar == "-"))
            nonblankprinted = false
          else
            if (strchar != "") nonblankprinted = true;
        }
        else
        {
          strchar = maskchar;
        }
        if ((maskchar == ",") && (nonblankprinted == false)) strchar = "";
        if (maskchar == "." && decimals > 0)
        {
          while ((str.charAt(i1) != ".") && (i1 < str.length)) ++i1;
          ++i1; // going to print from mask so just move to the char after the decimal
          nonblankprinted = true;
        }
        formatted_str = formatted_str + strchar;
      }
      // now, go backwards through the formatted string and remove any characters
      // that aren't numbers. This keeps me from getting a zipcode that looks like "92109-    "
      for (i=formatted_str.length - 1; i>=0; i--)
      {
        onechar = formatted_str.charAt(i);
        tmp = numbers.indexOf(formatted_str.charAt(i));
        if (tmp != -1) break; // first numeric character
      }
      formatted_str = formatted_str.substr(0, i+1);
      return (formatted_str);
    }

    /*
     * getRounded - Used internally to round a value
     * val - The number to be rounded
     */
    function getRounded(val, places)
    {
      var factor;
      var i;

      if (places == 0) return val;
      // round to a certain precision
      factor = 1;
      for (i=0; i<places; i++)
      {
        factor *= 10; 
      }
      val *= factor;
      val = Math.round(val);
      val /= factor;
      return (val);
    }

    /*
     * preserveZeros - Used internally to make the number a string
     * 	that preserves zeros at the end of the number
     * val - The number
     */
    function preserveZeros(val, places)
    {
      var i;

      // make a string - to preserve the zeros at the end
      if (places <= 0) return val; // leave now. no zeros are necessary - v1.0.1 less than or equal
      val = val + '';
      var decimalPos = val.indexOf('.');
      if (decimalPos == -1)
      {
        val += '.';
        for (i=0; i<places; i++)
        {
          val += '0';
        }
        return val;
      }
      var actualDecimals = (val.length - 1) - decimalPos;
      var difference = places - actualDecimals;
      if (difference >= 0)
      {
        for (i=0; i<difference; i++)
        {
          val += '0';
        }
        return val;
      }
      var tmp = "";
      var size = decimalPos + places;
      for (i=0; i<=size; i++)
      {
        tmp = tmp + val.charAt(i);
      }
      return tmp;
    }
