/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: XNumber.java,v 1.2.4.2 2005/09/14 20:34:46 jeffsuttor Exp $
 */
package com.sun.org.apache.xpath.internal.objects;

import com.sun.org.apache.xpath.internal.ExpressionOwner;
import com.sun.org.apache.xpath.internal.XPathContext;
import com.sun.org.apache.xpath.internal.XPathVisitor;

/**
 * This class represents an XPath number, and is capable of
 * converting the number to other types, such as a string.
 * @xsl.usage general
 */
public class XNumber extends XObject
{
    static final long serialVersionUID = -2720400709619020193L;

  /** Value of the XNumber object.
   *  @serial         */
  double m_val;

  /**
   * Construct a XNodeSet object.
   *
   * @param d Value of the object
   */
  public XNumber(double d)
  {
    super();

    m_val = d;
  }

  /**
   * Construct a XNodeSet object.
   *
   * @param num Value of the object
   */
  public XNumber(Number num)
  {

    super();

    m_val = num.doubleValue();
    setObject(num);
  }

  /**
   * Tell that this is a CLASS_NUMBER.
   *
   * @return node type CLASS_NUMBER
   */
  public int getType()
  {
    return CLASS_NUMBER;
  }

  /**
   * Given a request type, return the equivalent string.
   * For diagnostic purposes.
   *
   * @return type string "#NUMBER"
   */
  public String getTypeString()
  {
    return "#NUMBER";
  }

  /**
   * Cast result object to a number.
   *
   * @return the value of the XNumber object
   */
  public double num()
  {
    return m_val;
  }

  /**
   * Evaluate expression to a number.
   *
   * @return 0.0
   *
   * @throws javax.xml.transform.TransformerException
   */
  public double num(XPathContext xctxt)
    throws javax.xml.transform.TransformerException
  {

    return m_val;
  }

  /**
   * Cast result object to a boolean.
   *
   * @return false if the value is NaN or equal to 0.0
   */
  public boolean bool()
  {
    return (Double.isNaN(m_val) || (m_val == 0.0)) ? false : true;
  }

//  /**
//   * Cast result object to a string.
//   *
//   * @return "NaN" if the number is NaN, Infinity or -Infinity if
//   * the number is infinite or the string value of the number.
//   */
//  private static final int PRECISION = 16;
//  public String str()
//  {
//
//    if (Double.isNaN(m_val))
//    {
//      return "NaN";
//    }
//    else if (Double.isInfinite(m_val))
//    {
//      if (m_val > 0)
//        return "Infinity";
//      else
//        return "-Infinity";
//    }
//
//    long longVal = (long)m_val;
//    if ((double)longVal == m_val)
//      return Long.toString(longVal);
//
//
//    String s = Double.toString(m_val);
//    int len = s.length();
//
//    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
//    {
//      return s.substring(0, len - 2);
//    }
//
//    int exp = 0;
//    int e = s.indexOf('E');
//    if (e != -1)
//    {
//      exp = Integer.parseInt(s.substring(e + 1));
//      s = s.substring(0,e);
//      len = e;
//    }
//
//    // Calculate Significant Digits:
//    // look from start of string for first digit
//    // look from end for last digit
//    // significant digits = end - start + (0 or 1 depending on decimal location)
//
//    int decimalPos = -1;
//    int start = (s.charAt(0) == '-') ? 1 : 0;
//    findStart: for( ; start < len; start++ )
//    {
//      switch (s.charAt(start))
//      {
//      case '0':
//        break;
//      case '.':
//        decimalPos = start;
//        break;
//      default:
//        break findStart;
//      }
//    }
//    int end = s.length() - 1;
//    findEnd: for( ; end > start; end-- )
//    {
//      switch (s.charAt(end))
//      {
//      case '0':
//        break;
//      case '.':
//        decimalPos = end;
//        break;
//      default:
//        break findEnd;
//      }
//    }
//
//    int sigDig = end - start;
//
//    // clarify decimal location if it has not yet been found
//    if (decimalPos == -1)
//      decimalPos = s.indexOf('.');
//
//    // if decimal is not between start and end, add one to sigDig
//    if (decimalPos < start || decimalPos > end)
//      ++sigDig;
//
//    // reduce significant digits to PRECISION if necessary
//    if (sigDig > PRECISION)
//    {
//      // re-scale BigDecimal in order to get significant digits = PRECISION
//      BigDecimal num = new BigDecimal(s);
//      int newScale = num.scale() - (sigDig - PRECISION);
//      if (newScale < 0)
//        newScale = 0;
//      s = num.setScale(newScale, BigDecimal.ROUND_HALF_UP).toString();
//
//      // remove trailing '0's; keep track of decimalPos
//      int truncatePoint = s.length();
//      while (s.charAt(--truncatePoint) == '0')
//        ;
//
//      if (s.charAt(truncatePoint) == '.')
//      {
//        decimalPos = truncatePoint;
//      }
//      else
//      {
//        decimalPos = s.indexOf('.');
//        truncatePoint += 1;
//      }
//
//      s = s.substring(0, truncatePoint);
//      len = s.length();
//    }
//
//    // Account for exponent by adding zeros as needed
//    // and moving the decimal place
//
//    if (exp == 0)
//       return s;
//
//    start = 0;
//    String sign;
//    if (s.charAt(0) == '-')
//    {
//      sign = "-";
//      start++;
//    }
//    else
//      sign = "";
//
//    String wholePart = s.substring(start, decimalPos);
//    String decimalPart = s.substring(decimalPos + 1);
//
//    // get the number of digits right of the decimal
//    int decimalLen = decimalPart.length();
//
//    if (exp >= decimalLen)
//      return sign + wholePart + decimalPart + zeros(exp - decimalLen);
//
//    if (exp > 0)
//      return sign + wholePart + decimalPart.substring(0, exp) + "."
//             + decimalPart.substring(exp);
//
//    return sign + "0." + zeros(-1 - exp) + wholePart + decimalPart;
//  }

  /**
   * Cast result object to a string.
   *
   * @return "NaN" if the number is NaN, Infinity or -Infinity if
   * the number is infinite or the string value of the number.
   */
  public String str()
  {

    if (Double.isNaN(m_val))
    {
      return "NaN";
    }
    else if (Double.isInfinite(m_val))
    {
      if (m_val > 0)
        return "Infinity";
      else
        return "-Infinity";
    }

    double num = m_val;
    String s = Double.toString(num);
    int len = s.length();

    if (s.charAt(len - 2) == '.' && s.charAt(len - 1) == '0')
    {
      s = s.substring(0, len - 2);

      if (s.equals("-0"))
        return "0";

      return s;
    }

    int e = s.indexOf('E');

    if (e < 0)
    {
      if (s.charAt(len - 1) == '0')
        return s.substring(0, len - 1);
      else
        return s;
    }

    int exp = Integer.parseInt(s.substring(e + 1));
    String sign;

    if (s.charAt(0) == '-')
    {
      sign = "-";
      s = s.substring(1);

      --e;
    }
    else
      sign = "";

    int nDigits = e - 2;

    if (exp >= nDigits)
      return sign + s.substring(0, 1) + s.substring(2, e)
             + zeros(exp - nDigits);

    // Eliminate trailing 0's - bugzilla 14241
    while (s.charAt(e-1) == '0')
      e--;

    if (exp > 0)
      return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "."
             + s.substring(2 + exp, e);

    return sign + "0." + zeros(-1 - exp) + s.substring(0, 1)
           + s.substring(2, e);
  }


  /**
   * Return a string of '0' of the given length
   *
   *
   * @param n Length of the string to be returned
   *
   * @return a string of '0' with the given length
   */
  static private String zeros(int n)
  {
    if (n < 1)
      return "";

    char[] buf = new char[n];

    for (int i = 0; i < n; i++)
    {
      buf[i] = '0';
    }

    return new String(buf);
  }

  /**
   * Return a java object that's closest to the representation
   * that should be handed to an extension.
   *
   * @return The value of this XNumber as a Double object
   */
  public Object object()
  {
    if(null == m_obj)
      setObject(new Double(m_val));
    return m_obj;
  }

  /**
   * Tell if two objects are functionally equal.
   *
   * @param obj2 Object to compare this to
   *
   * @return true if the two objects are equal
   *
   * @throws javax.xml.transform.TransformerException
   */
  public boolean equals(XObject obj2)
  {

    // In order to handle the 'all' semantics of
    // nodeset comparisons, we always call the
    // nodeset function.
    int t = obj2.getType();
    try
    {
            if (t == XObject.CLASS_NODESET)
              return obj2.equals(this);
            else if(t == XObject.CLASS_BOOLEAN)
              return obj2.bool() == bool();
                else
               return m_val == obj2.num();
    }
    catch(javax.xml.transform.TransformerException te)
    {
      throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te);
    }
  }

  /**
   * Tell if this expression returns a stable number that will not change during
   * iterations within the expression.  This is used to determine if a proximity
   * position predicate can indicate that no more searching has to occur.
   *
   *
   * @return true if the expression represents a stable number.
   */
  public boolean isStableNumber()
  {
    return true;
  }

  /**
   * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor)
   */
  public void callVisitors(ExpressionOwner owner, XPathVisitor visitor)
  {
        visitor.visitNumberLiteral(owner, this);
  }


}
