/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Matt Carter - bug 180392
 ******************************************************************************/

package org.eclipse.core.databinding.conversion;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;

import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.NumberFormat;

/**
 * Converts a Number to a String using <code>NumberFormat.format(...)</code>.
 * This class is thread safe.
 * 
 * @since 1.0
 */
public class NumberToStringConverter extends Converter {
	private final NumberFormat numberFormat;
	private final Class fromType;
	private boolean fromTypeFitsLong;
	private boolean fromTypeIsDecimalType;
	private boolean fromTypeIsBigInteger;
	private boolean fromTypeIsBigDecimal;

	static Class icuBigDecimal = null;
	static Constructor icuBigDecimalCtr = null; 
	
	{
		/*
		 * If the full ICU4J library is available, we use the ICU BigDecimal
		 * class to support proper formatting and parsing of java.math.BigDecimal.
		 * 
		 * The version of ICU NumberFormat (DecimalFormat) included in eclipse excludes 
		 * support for java.math.BigDecimal, and if used falls back to converting as
		 * an unknown Number type via doubleValue(), which is undesirable.
		 * 
		 * See Bug #180392.
		 */
		try {
			icuBigDecimal = Class.forName("com.ibm.icu.math.BigDecimal"); //$NON-NLS-1$
			icuBigDecimalCtr = icuBigDecimal.getConstructor(new Class[] {BigInteger.class, int.class});
//			System.out.println("DEBUG: Full ICU4J support state: icuBigDecimal="+(icuBigDecimal != null)+", icuBigDecimalCtr="+(icuBigDecimalCtr != null)); //$NON-NLS-1$ //$NON-NLS-2$
		} 
		catch(ClassNotFoundException e) {}
		catch(NoSuchMethodException e) {}
	}	
	
	/**
	 * Constructs a new instance.
	 * <p>
	 * Private to restrict public instantiation.
	 * </p>
	 * 
	 * @param numberFormat
	 * @param fromType
	 */
	private NumberToStringConverter(NumberFormat numberFormat, Class fromType) {
		super(fromType, String.class);

		this.numberFormat = numberFormat;
		this.fromType = fromType;

		if (Integer.class.equals(fromType) || Integer.TYPE.equals(fromType)
				|| Long.class.equals(fromType) || Long.TYPE.equals(fromType)
				|| Short.class.equals(fromType) || Short.TYPE.equals(fromType)
				|| Byte.class.equals(fromType) || Byte.TYPE.equals(fromType)) {
			fromTypeFitsLong = true;
		} else if (Float.class.equals(fromType) || Float.TYPE.equals(fromType)
				|| Double.class.equals(fromType)
				|| Double.TYPE.equals(fromType)) {
			fromTypeIsDecimalType = true;
		} else if (BigInteger.class.equals(fromType)) {
			fromTypeIsBigInteger = true;
		} else if (BigDecimal.class.equals(fromType)) {
			fromTypeIsBigDecimal = true;
		}
	}

	/**
	 * Converts the provided <code>fromObject</code> to a <code>String</code>.
	 * If the converter was constructed for an object type, non primitive, a
	 * <code>fromObject</code> of <code>null</code> will be converted to an
	 * empty string.
	 * 
	 * @param fromObject
	 *            value to convert. May be <code>null</code> if the converter
	 *            was constructed for a non primitive type.
	 * @see org.eclipse.core.databinding.conversion.IConverter#convert(java.lang.Object)
	 */
	public Object convert(Object fromObject) {
		// Null is allowed when the type is not primitve.
		if (fromObject == null && !fromType.isPrimitive()) {
			return ""; //$NON-NLS-1$
		}

		Number number = (Number) fromObject;
		String result = null;
		if (fromTypeFitsLong) {
			synchronized (numberFormat) {
				result = numberFormat.format(number.longValue());
			}
		} else if (fromTypeIsDecimalType) {
			synchronized (numberFormat) {
				result = numberFormat.format(number.doubleValue());
			}
		} else if (fromTypeIsBigInteger) {
			synchronized (numberFormat) {
				result = numberFormat.format((BigInteger) number);
			}
		} else if (fromTypeIsBigDecimal) {
			if(icuBigDecimal != null && icuBigDecimalCtr != null && numberFormat instanceof DecimalFormat) {
				// Full ICU4J present. Convert java.math.BigDecimal to ICU BigDecimal to format. Bug #180392.
				BigDecimal o = (BigDecimal) fromObject;
				try {
					fromObject = icuBigDecimalCtr.newInstance(new Object[] {o.unscaledValue(), new Integer(o.scale())});
				}
				catch(InstantiationException e) {}
				catch(InvocationTargetException e) {}
				catch(IllegalAccessException e) {}
				// Otherwise, replacement plugin present and supports java.math.BigDecimal.
			}
			synchronized (numberFormat) {
				result = numberFormat.format(fromObject);
			}
		}
		

		return result;
	}

	/**
	 * @param primitive
	 *            <code>true</code> if the type is a double
	 * @return Double converter for the default locale
	 */
	public static NumberToStringConverter fromDouble(boolean primitive) {
		return fromDouble(NumberFormat.getNumberInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Double converter with the provided numberFormat
	 */
	public static NumberToStringConverter fromDouble(NumberFormat numberFormat,
			boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Double.TYPE : Double.class);
	}

	/**
	 * @param primitive
	 *            <code>true</code> if the type is a long
	 * @return Long converter for the default locale
	 */
	public static NumberToStringConverter fromLong(boolean primitive) {
		return fromLong(NumberFormat.getIntegerInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Long convert with the provided numberFormat
	 */
	public static NumberToStringConverter fromLong(NumberFormat numberFormat,
			boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Long.TYPE : Long.class);
	}

	/**
	 * @param primitive
	 *            <code>true</code> if the type is a float
	 * @return Float converter for the default locale
	 */
	public static NumberToStringConverter fromFloat(boolean primitive) {
		return fromFloat(NumberFormat.getNumberInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Float converter with the provided numberFormat
	 */
	public static NumberToStringConverter fromFloat(NumberFormat numberFormat,
			boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Float.TYPE : Float.class);
	}

	/**
	 * @param primitive
	 *            <code>true</code> if the type is a int
	 * @return Integer converter for the default locale
	 */
	public static NumberToStringConverter fromInteger(boolean primitive) {
		return fromInteger(NumberFormat.getIntegerInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Integer converter with the provided numberFormat
	 */
	public static NumberToStringConverter fromInteger(
			NumberFormat numberFormat, boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Integer.TYPE : Integer.class);
	}

	/**
	 * @return BigInteger convert for the default locale
	 */
	public static NumberToStringConverter fromBigInteger() {
		return fromBigInteger(NumberFormat.getIntegerInstance());
	}

	/**
	 * @param numberFormat
	 * @return BigInteger converter with the provided numberFormat
	 */
	public static NumberToStringConverter fromBigInteger(
			NumberFormat numberFormat) {
		return new NumberToStringConverter(numberFormat, BigInteger.class);
	}
	
	/**
	 * @return BigDecimal convert for the default locale
	 * @since 1.2
	 */
	public static NumberToStringConverter fromBigDecimal() {
		return fromBigDecimal(NumberFormat.getNumberInstance());
	}

	/**
	 * @param numberFormat
	 * @return BigDecimal converter with the provided numberFormat
	 * @since 1.2
	 */
	public static NumberToStringConverter fromBigDecimal(
			NumberFormat numberFormat) {
		return new NumberToStringConverter(numberFormat, BigDecimal.class);
	}
	
	/**
	 * @param primitive
	 *            <code>true</code> if the type is a short
	 * @return Short converter for the default locale
	 * @since 1.2
	 */
	public static NumberToStringConverter fromShort(boolean primitive) {
		return fromShort(NumberFormat.getIntegerInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Short converter with the provided numberFormat
	 * @since 1.2
	 */
	public static NumberToStringConverter fromShort(
			NumberFormat numberFormat, boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Short.TYPE : Short.class);
	}
	
	/**
	 * @param primitive
	 *            <code>true</code> if the type is a byte
	 * @return Byte converter for the default locale
	 * @since 1.2
	 */
	public static NumberToStringConverter fromByte(boolean primitive) {
		return fromByte(NumberFormat.getIntegerInstance(), primitive);
	}

	/**
	 * @param numberFormat
	 * @param primitive
	 * @return Byte converter with the provided numberFormat
	 * @since 1.2
	 */
	public static NumberToStringConverter fromByte(
			NumberFormat numberFormat, boolean primitive) {
		return new NumberToStringConverter(numberFormat,
				(primitive) ? Byte.TYPE : Byte.class);
	}
	
}
