/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */

package org.apache.harmony.luni.util;


/**
 * Used to parse a string and return either a single or double precision
 * floating point number.
 */
public final class FloatingPointParser {

	private static final class StringExponentPair {
		String s;

		int e;

		boolean negative;

		StringExponentPair(String s, int e, boolean negative) {
			this.s = s;
			this.e = e;
			this.negative = negative;
		}
	}

	/**
	 * Takes a String and an integer exponent. The String should hold a positive
	 * integer value (or zero). The exponent will be used to calculate the
	 * floating point number by taking the positive integer the String
	 * represents and multiplying by 10 raised to the power of the of the
	 * exponent. Returns the closest double value to the real number
	 * 
	 * @param s
	 *            the String that will be parsed to a floating point
	 * @param e
	 *            an int represent the 10 to part
	 * @return the double closest to the real number
	 * 
	 * @exception NumberFormatException
	 *                if the String doesn't represent a positive integer value
	 */
	private static native double parseDblImpl(String s, int e);

	/**
	 * Takes a String and an integer exponent. The String should hold a positive
	 * integer value (or zero). The exponent will be used to calculate the
	 * floating point number by taking the positive integer the String
	 * represents and multiplying by 10 raised to the power of the of the
	 * exponent. Returns the closest float value to the real number
	 * 
	 * @param s
	 *            the String that will be parsed to a floating point
	 * @param e
	 *            an int represent the 10 to part
	 * @return the float closest to the real number
	 * 
	 * @exception NumberFormatException
	 *                if the String doesn't represent a positive integer value
	 */
	private static native float parseFltImpl(String s, int e);

	/**
	 * Takes a String and does some initial parsing. Should return a
	 * StringExponentPair containing a String with no leading or trailing white
	 * space and trailing zeroes eliminated. The exponent of the
	 * StringExponentPair will be used to calculate the floating point number by
	 * taking the positive integer the String represents and multiplying by 10
	 * raised to the power of the of the exponent.
	 * 
	 * @param s
	 *            the String that will be parsed to a floating point
	 * @param length
	 *            the length of s
	 * @return a StringExponentPair with necessary values
	 * 
	 * @exception NumberFormatException
	 *                if the String doesn't pass basic tests
	 */
	private static StringExponentPair initialParse(String s, int length) {
		boolean negative = false;
		char c;
		int start, end, decimal;
		int e = 0;

		start = 0;
		if (length == 0)
			throw new NumberFormatException(s);

		c = s.charAt(length - 1);
		if (c == 'D' || c == 'd' || c == 'F' || c == 'f') {
			length--;
			if (length == 0)
				throw new NumberFormatException(s);
		}

		end = Math.max(s.indexOf('E'), s.indexOf('e'));
		if (end > -1) {
			if (end + 1 == length)
				throw new NumberFormatException(s);

                        int exponent_offset = end + 1;
                        if (s.charAt(exponent_offset) == '+') {
                                if (s.charAt(exponent_offset + 1) == '-') {
                                        throw new NumberFormatException(s);
                                }
                                exponent_offset++; // skip the plus sign
                        }
			try {
				e = Integer.parseInt(s.substring(exponent_offset,
                                                                 length));
                        } catch (NumberFormatException ex) {
                                // ex contains the exponent substring
                                // only so throw a new exception with
                                // the correct string
				throw new NumberFormatException(s);
                        }                            
                                    
		} else {
			end = length;
		}
		if (length == 0)
			throw new NumberFormatException(s);

		c = s.charAt(start);
		if (c == '-') {
			++start;
			--length;
			negative = true;
		} else if (c == '+') {
			++start;
			--length;
		}
		if (length == 0)
			throw new NumberFormatException(s);

		decimal = s.indexOf('.');
		if (decimal > -1) {
			e -= end - decimal - 1;
			s = s.substring(start, decimal) + s.substring(decimal + 1, end);
		} else {
			s = s.substring(start, end);
		}

		if ((length = s.length()) == 0)
			throw new NumberFormatException();

		end = length;
		while (end > 1 && s.charAt(end - 1) == '0')
			--end;

		start = 0;
		while (start < end - 1 && s.charAt(start) == '0')
			start++;

		if (end != length || start != 0) {
			e += length - end;
			s = s.substring(start, end);
		}

        // Trim the length of very small numbers, natives can only handle down
        // to E-309
        final int APPROX_MIN_MAGNITUDE = -359;
        final int MAX_DIGITS = 52;
        length = s.length();
        if (length > MAX_DIGITS && e < APPROX_MIN_MAGNITUDE) {
            int d = Math.min(APPROX_MIN_MAGNITUDE - e, length - 1);
            s = s.substring(0, length - d);
            e += d;
        }

		return new StringExponentPair(s, e, negative);
	}

	/*
	 * Assumes the string is trimmed.
	 */
	private static double parseDblName(String namedDouble, int length) {
		// Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
		// -Infinity.
		if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
			throw new NumberFormatException();
		}

		boolean negative = false;
		int cmpstart = 0;
		switch (namedDouble.charAt(0)) {
		case '-':
			negative = true; // fall through
		case '+':
			cmpstart = 1;
		default:
		}

		if (namedDouble.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
			return negative ? Double.NEGATIVE_INFINITY
					: Float.POSITIVE_INFINITY;
		}

		if (namedDouble.regionMatches(false, cmpstart, "NaN", 0, 3)) {
			return Double.NaN;
		}

		throw new NumberFormatException();
	}

	/*
	 * Assumes the string is trimmed.
	 */
	private static float parseFltName(String namedFloat, int length) {
		// Valid strings are only +Nan, NaN, -Nan, +Infinity, Infinity,
		// -Infinity.
		if ((length != 3) && (length != 4) && (length != 8) && (length != 9)) {
			throw new NumberFormatException();
		}

		boolean negative = false;
		int cmpstart = 0;
		switch (namedFloat.charAt(0)) {
		case '-':
			negative = true; // fall through
		case '+':
			cmpstart = 1;
		default:
		}

		if (namedFloat.regionMatches(false, cmpstart, "Infinity", 0, 8)) {
			return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
		}

		if (namedFloat.regionMatches(false, cmpstart, "NaN", 0, 3)) {
			return Float.NaN;
		}

		throw new NumberFormatException();
	}

	/**
	 * Returns the closest double value to the real number in the string.
	 * 
	 * @param s
	 *            the String that will be parsed to a floating point
	 * @return the double closest to the real number
	 * 
	 * @exception NumberFormatException
	 *                if the String doesn't represent a double
	 */
	public static double parseDouble(String s) {
		s = s.trim();
		int length = s.length();

		if (length == 0) {
			throw new NumberFormatException(s);
		}

		// See if this could be a named double
		char last = s.charAt(length - 1);
		if ((last == 'y') || (last == 'N')) {
			return parseDblName(s, length);
		}
        
        // See if it could be a hexadecimal representation
        if (s.toLowerCase().indexOf("0x") != -1) { //$NON-NLS-1$
            return HexStringParser.parseDouble(s);
        }
        
		StringExponentPair info = initialParse(s, length);

		double result = parseDblImpl(info.s, info.e);
		if (info.negative)
			result = -result;

		return result;
	}

	/**
	 * Returns the closest float value to the real number in the string.
	 * 
	 * @param s
	 *            the String that will be parsed to a floating point
	 * @return the float closest to the real number
	 * 
	 * @exception NumberFormatException
	 *                if the String doesn't represent a float
	 */
	public static float parseFloat(String s) {
		s = s.trim();
		int length = s.length();

		if (length == 0) {
			throw new NumberFormatException(s);
		}

		// See if this could be a named float
		char last = s.charAt(length - 1);
		if ((last == 'y') || (last == 'N')) {
			return parseFltName(s, length);
		}
        
        // See if it could be a hexadecimal representation
        if (s.toLowerCase().indexOf("0x") != -1) { //$NON-NLS-1$
            return HexStringParser.parseFloat(s);
        }
        
		StringExponentPair info = initialParse(s, length);

		float result = parseFltImpl(info.s, info.e);
		if (info.negative)
			result = -result;

		return result;
	}
}
