/* ChoiceFormat.java -- Format over a range of numbers
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public License. */


package java.text;

import java.util.Vector;

/**
 * This class allows a format to be specified based on a range of numbers.
 * To use this class, first specify two lists of formats and range terminators.
 * These lists must be arrays of equal length.  The format of index 
 * <code>i</code> will be selected for value <code>X</code> if 
 * <code>terminator[i] <= X < limit[i + 1]</code>.  If the value X is not
 * included in any range, then either the first or last format will be 
 * used depending on whether the value X falls outside the range.
 * <p>
 * This sounds complicated, but that is because I did a poor job of
 * explaining it.  Consider the following example:
 * <p>
 * <pre>
 * terminators = { 1, ChoiceFormat.nextDouble(1) }
 * formats = { "file", "files" }
 * </pre>
 * <p>
 * In this case if the actual number tested is one or less, then the word
 * "file" is used as the format value.  If the number tested is greater than
 * one, then "files" is used.  This allows plurals to be handled
 * gracefully.  Note the use of the method <code>nextDouble</code>.  This
 * method selects the next highest double number than its argument.  This
 * effectively makes any double greater than 1.0 cause the "files" string
 * to be selected.  (Note that all terminator values are specified as
 * doubles.
 * <p>
 * Note that in order for this class to work properly, the range terminator
 * array must be sorted in ascending order and the format string array
 * must be the same length as the terminator array.
 *
 * @author Tom Tromey <tromey@cygnus.com>
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @date March 9, 1999
 */
/* Written using "Java Class Libraries", 2nd edition, plus online
 * API docs for JDK 1.2 from http://www.javasoft.com.
 * Status:  Believed complete and correct to 1.1.
 */
public class ChoiceFormat extends NumberFormat
{
  /**
   * This method sets new range terminators and format strings for this
   * object based on the specified pattern. This pattern is of the form 
   * "term#string|term#string...".  For example "1#Sunday|2#Monday|#Tuesday".
   *
   * @param pattern The pattern of terminators and format strings.
   *
   * @exception IllegalArgumentException If the pattern is not valid
   */
  public void applyPattern (String newPattern)
  {
    // Note: we assume the same kind of quoting rules apply here.
    // This isn't explicitly documented.  But for instance we accept
    // '#' as a literal hash in a format string.
    int index = 0, max = newPattern.length();
    Vector stringVec = new Vector ();
    Vector limitVec = new Vector ();
    StringBuffer buf = new StringBuffer ();
    
    while (true)
      {
	// Find end of double.
	int dstart = index;
	while (index < max)
	  {
	    char c = newPattern.charAt(index);
	    if (c == '#' || c == '\u2064' || c == '<')
	      break;
	    ++index;
	  }
	
	if (index == max)
	  throw new IllegalArgumentException ("unexpected end of text");
	Double d = new Double (newPattern.substring(dstart, index));

	if (newPattern.charAt(index) == '<')
	  d = new Double (nextDouble (d.doubleValue()));

	limitVec.addElement(d);

	// Scan text.
	++index;
	buf.setLength(0);
	while (index < max)
	  {
	    char c = newPattern.charAt(index);
	    if (c == '\'' && index < max + 1
		&& newPattern.charAt(index + 1) == '\'')
	      {
		buf.append(c);
		++index;
	      }
	    else if (c == '\'' && index < max + 2)
	      {
		buf.append(newPattern.charAt(index + 1));
		index += 2;
	      }
	    else if (c == '|')
	      break;
	    else
	      buf.append(c);
	    ++index;
	  }

	stringVec.addElement(buf.toString());
	if (index == max)
	  break;
	++index;
      }

    choiceFormats = new String[stringVec.size()];
    stringVec.copyInto(choiceFormats);

    choiceLimits = new double[limitVec.size()];
    for (int i = 0; i < choiceLimits.length; ++i)
      {
	Double d = (Double) limitVec.elementAt(i);
	choiceLimits[i] = d.doubleValue();
      }
  }

  /**
   * This method initializes a new instance of <code>ChoiceFormat</code> that
   * generates its range terminator and format string arrays from the
   * specified pattern.  This pattern is of the form 
   * "term#string|term#string...".  For example "1#Sunday|2#Monday|#Tuesday".
   * This is the same pattern type used by the <code>applyPattern</code>
   * method.
   *
   * @param pattern The pattern of terminators and format strings.
   *
   * @exception IllegalArgumentException If the pattern is not valid
   */
  public ChoiceFormat (String newPattern)
  {
    super ();
    applyPattern (newPattern);
  }

  /**
   * This method initializes a new instance of <code>ChoiceFormat</code> that
   * will use the specified range terminators and format strings.
   *
   * @param choiceLimits The array of range terminators
   * @param choiceFormats The array of format strings
   */
  public ChoiceFormat (double[] choiceLimits, String[] choiceFormats)
  {
    super ();
    setChoices (choiceLimits, choiceFormats);
  }

  /**
   * This method tests this object for equality with the specified 
   * object.  This will be true if and only if:
   * <ul>
   * <li>The specified object is not <code>null</code>.
   * <li>The specified object is an instance of <code>ChoiceFormat</code>.
   * <li>The termination ranges and format strings are identical to
   *     this object's. 
   * </ul>
   *
   * @param obj The object to test for equality against.
   *
   * @return <code>true</code> if the specified object is equal to
   * this one, <code>false</code> otherwise. 
   */
  public boolean equals (Object obj)
  {
    if (! (obj instanceof ChoiceFormat))
      return false;
    ChoiceFormat cf = (ChoiceFormat) obj;
    if (choiceLimits.length != cf.choiceLimits.length)
      return false;
    for (int i = choiceLimits.length - 1; i >= 0; --i)
      {
	if (choiceLimits[i] != cf.choiceLimits[i]
	    || !choiceFormats[i].equals(cf.choiceFormats[i]))
	  return false;
      }
    return true;
  }

  /**
   * This method appends the appropriate format string to the specified
   * <code>StringBuffer</code> based on the supplied <code>long</code>
   * argument.
   *
   * @param number The number used for determine (based on the range
   *               terminators) which format string to append. 
   * @param sb The <code>StringBuffer</code> to append the format string to.
   * @param status Unused.
   *
   * @return The <code>StringBuffer</code> with the format string appended.
   */
  public StringBuffer format (long num, StringBuffer appendBuf,
			      FieldPosition pos)
  {
    return format ((double) num, appendBuf, pos);
  }

  /**
   * This method appends the appropriate format string to the specified
   * <code>StringBuffer</code> based on the supplied <code>double</code>
   * argument.
   *
   * @param number The number used for determine (based on the range
   *               terminators) which format string to append. 
   * @param sb The <code>StringBuffer</code> to append the format string to.
   * @param status Unused.
   *
   * @return The <code>StringBuffer</code> with the format string appended.
   */
  public StringBuffer format (double num, StringBuffer appendBuf,
			      FieldPosition pos)
  {
    if (choiceLimits.length == 0)
      return appendBuf;

    int index =  0;
    if (! Double.isNaN(num) && num >= choiceLimits[0])
      {
	for (; index < choiceLimits.length - 1; ++index)
	  {
	    if (choiceLimits[index] <= num
		&& index != choiceLimits.length - 2
		&& num < choiceLimits[index + 1])
	      break;
	  }
      }

    return appendBuf.append(choiceFormats[index]);
  }

  /**
   * This method returns the list of format strings in use.
   *
   * @return The list of format objects.
   */
  public Object[] getFormats ()
  {
    return (Object[]) choiceFormats.clone();
  }

  /**
   * This method returns the list of range terminators in use.
   *
   * @return The list of range terminators.
   */
  public double[] getLimits ()
  {
    return (double[]) choiceLimits.clone();
  }

  /**
   * This method returns a hash value for this object
   * 
   * @return A hash value for this object.
   */
  public int hashCode ()
  {
    int hash = 0;
    for (int i = 0; i < choiceLimits.length; ++i)
      {
	long v = Double.doubleToLongBits(choiceLimits[i]);
	hash ^= (v ^ (v >>> 32));
	hash ^= choiceFormats[i].hashCode();
      }
    return hash;
  }

  /**
   * This method returns the lowest possible double greater than the 
   * specified double.  If the specified double value is equal to
   * <code>Double.NaN</code> then that is the value returned.
   *
   * @param d The specified double
   *
   * @return The lowest double value greater than the specified double.
   */
  public static final double nextDouble (double d)
  {
    return nextDouble (d, true);
  }

  /**
   * This method returns a double that is either the next highest double
   * or next lowest double compared to the specified double depending on the
   * value of the passed boolean parameter.  If the boolean parameter is
   * <code>true</code>, then the lowest possible double greater than the 
   * specified double will be returned.  Otherwise the highest possible
   * double less than the specified double will be returned.
   *
   * @param d The specified double
   * @param positive <code>true</code> to return the next highest
   *                 double, <code>false</code> otherwise. 
   *
   * @return The next highest or lowest double value.
   */
  public static double nextDouble (double d, boolean next)
  {
    if (Double.isInfinite(d) || Double.isNaN(d))
      return d;

    long bits = Double.doubleToLongBits(d);

    long mantMask = (1L << mantissaBits) - 1;
    long mantissa = bits & mantMask;

    long expMask = (1L << exponentBits) - 1;
    long exponent = (bits >>> mantissaBits) & expMask;

    if (next ^ (bits < 0)) // Increment magnitude
      {
	if (mantissa == (1L << mantissaBits) - 1)
	  {
	    mantissa = 0L;
	    exponent++;
	     
	    // Check for absolute overflow.
	    if (exponent >= (1L << mantissaBits))
	      return (bits > 0) ? Double.POSITIVE_INFINITY 
		: Double.NEGATIVE_INFINITY;		      
	  }
	else
	  mantissa++;
      }
    else // Decrement magnitude
      {
	if (exponent == 0L && mantissa == 0L)
	  {
	    // The only case where there is a change of sign
	    return next ? Double.MIN_VALUE : -Double.MIN_VALUE;
	  }
	else
	  {
	    if (mantissa == 0L)
	      {
		mantissa = (1L << mantissaBits) - 1;
		exponent--;
	      }
	    else
	      mantissa--;
	  }
      }

    long result = bits < 0 ? 1 : 0;
    result = (result << exponentBits) | exponent;
    result = (result << mantissaBits) | mantissa;
    return Double.longBitsToDouble(result);
  }

  /**
   * I'm not sure what this method is really supposed to do, as it is
   * not documented.
   */
  public Number parse (String sourceStr, ParsePosition pos)
  {
    int index = pos.getIndex();
    for (int i = 0; i < choiceLimits.length; ++i)
      {
	if (sourceStr.startsWith(choiceFormats[i], index))
	  {
	    pos.setIndex(index + choiceFormats[i].length());
	    return new Double (choiceLimits[i]);
	  }
      }
    pos.setErrorIndex(index);
    return new Double (Double.NaN);
  }

  /**
   * This method returns the highest possible double less than the 
   * specified double.  If the specified double value is equal to
   * <code>Double.NaN</code> then that is the value returned.
   *
   * @param d The specified double
   *
   * @return The highest double value less than the specified double.
   */
  public static final double previousDouble (double d)
  {
    return nextDouble (d, false);
  }

  /**
   * This method sets new range terminators and format strings for this
   * object.
   *
   * @param choiceLimits The new range terminators
   * @param choiceFormats The new choice formats
   */
  public void setChoices (double[] choiceLimits, String[] choiceFormats)
  {
    if (choiceLimits == null || choiceFormats == null)
      throw new NullPointerException ();
    if (choiceLimits.length != choiceFormats.length)
      throw new IllegalArgumentException ();
    this.choiceFormats = (String[]) choiceFormats.clone();
    this.choiceLimits = (double[]) choiceLimits.clone();
  }

  private final void quoteString (StringBuffer dest, String text)
  {
    int max = text.length();
    for (int i = 0; i < max; ++i)
      {
	char c = text.charAt(i);
	if (c == '\'')
	  {
	    dest.append(c);
	    dest.append(c);
	  }
	else if (c == '#' || c == '|' || c == '\u2064' || c == '<')
	  {
	    dest.append('\'');
	    dest.append(c);
	    dest.append('\'');
	  }
	else
	  dest.append(c);
      }
  }

  /**
   * This method returns the range terminator list and format string list
   * as a <code>String</code> suitable for using with the 
   * <code>applyPattern</code> method.
   *
   * @return A pattern string for this object
   */
  public String toPattern ()
  {
    StringBuffer result = new StringBuffer ();
    for (int i = 0; i < choiceLimits.length; ++i)
      {
	result.append(choiceLimits[i]);
	result.append('#');
	quoteString (result, choiceFormats[i]);
      }
    return result.toString();
  }

  /**
   * This is the list of format strings.  Note that this variable is
   * specified by the serialization spec of this class.
   */
  private String[] choiceFormats;

  /**
   * This is the list of range terminator values.  Note that this variable is
   * specified by the serialization spec of this class.
   */
  private double[] choiceLimits;

  // Number of mantissa bits in double.
  private static final int mantissaBits = 52;
  // Number of exponent bits in a double.
  private static final int exponentBits = 11;

  private static final long serialVersionUID = 1795184449645032964L;
}
