/**
 * Copyright (c) 2005, 2013, Werner Keil 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:
 *    Werner Keil - initial API and implementation
 */
package org.eclipse.uomo.units;

import java.math.BigDecimal;
import java.math.MathContext;

import org.unitsofmeasurement.quantity.Dimensionless;
import org.unitsofmeasurement.quantity.Quantity;
import org.unitsofmeasurement.unit.IncommensurableException;
import org.unitsofmeasurement.unit.UnconvertibleException;
import org.unitsofmeasurement.unit.Unit;
import org.unitsofmeasurement.unit.UnitConverter;

import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;

/**
 * An amount of quantity, consisting of a Number and a Unit. QuantityAmount
 * objects are immutable.
 * 
 * @see java.lang.Number
 * @see MeasureUnit
 * @author <a href="mailto:uomo@catmedia.us">Werner Keil</a>
 * @param <Q>
 *            The type of the quantity.
 * @version 1.3.4 ($Revision: 212 $), $Date: 2011-09-12 01:20:44 +0200 (Mo, 12
 *          Sep 2011) $ XXX rename to Amount, AbstractAmount or MeasureAmount?
 *          FIXME Bug 338334 overwrite equals()
 */
public abstract class QuantityAmount<Q extends Quantity<Q>> extends Measure
		implements IMeasure<Q> {

	/**
	 * Holds a dimensionless measure of one (exact).
	 */
	public static final Quantity<Dimensionless> ONE =
			QuantityFactory.getInstance(Dimensionless.class).create(
					BigDecimal.ONE, AbstractUnit.ONE);
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.icu.util.Measure#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if (obj == this)
			return true;
		if (this.getClass() == obj.getClass()) {
			return super.equals(obj);
		} else {
			if (obj instanceof Measure) {
				Measure m = (Measure) obj;
				if (m.getNumber().getClass() == this.getNumber().getClass()
						&& m.getUnit().getClass() == this.unit().getClass()) {
					return super.equals(obj);
				} else {
					// if (this.getQuantityUnit() instanceof AbstractUnit<?>) {
					// if
					// }
					return super.equals(obj);
				}
			}
			return false;
		}
	}

	/**
	 * Indicates if this measure is exact.
	 */
	private boolean isExact;

	/**
	 * Holds the exact value (when exact) stated in this measure unit.
	 */
	// private long _exactValue;

	/**
	 * Holds the minimum value stated in this measure unit. For inexact
	 * measures: _minimum < _maximum
	 */
	// private double _minimum;

	/**
	 * Holds the maximum value stated in this measure unit. For inexact
	 * measures: _maximum > _minimum
	 */
	// private double _maximum;

	protected QuantityAmount(Number number, MeasureUnit unit) {
		super(number, unit);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.uomo.units.IMeasure#doubleValue(org.unitsofmeasurement.unit
	 * .Unit)
	 */
	@Override
	public double doubleValue(Unit<Q> unit) {
		Unit<Q> myUnit = unit();
		try {
			UnitConverter converter = unit.getConverterTo(myUnit);
			return converter.convert(getNumber().doubleValue());
		} catch (UnconvertibleException e) {
			throw e;
		} // catch (IncommensurableException e) {
		// throw new IllegalArgumentException(e.getMessage());
		// }
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.uomo.units.IMeasure#longValue(org.unitsofmeasurement.unit
	 * .Unit)
	 */
	@Override
	public long longValue(Unit<Q> unit) {
		Unit<Q> myUnit = unit();
		try {
			UnitConverter converter = unit.getConverterToAny(myUnit);
			return (converter.convert(
					BigDecimal.valueOf(getNumber().longValue()),
					MathContext.DECIMAL128)).longValue();
		} catch (UnconvertibleException e) {
			throw e;
		} catch (IncommensurableException e) {
			throw new IllegalArgumentException(e.getMessage());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.unitsofmeasurement.quantity.Quantity#unit()
	 */
	@Override
	public Unit<Q> unit() {
		return internalUnit();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.unitsofmeasurement.quantity.Quantity#value()
	 */
	@Override
	public Number value() {
		return getNumber();
	}

	/**
	 * Indicates if this measure amount is exact. An exact amount is guarantee
	 * exact only when stated in this measure unit (e.g.
	 * <code>this.longValue()</code>); stating the amount in any other unit may
	 * introduce conversion errors.
	 * 
	 * @return <code>true</code> if this measure is exact; <code>false</code>
	 *         otherwise.
	 */
	public boolean isExact() {
		return isExact;
	}

	// ////////////////////
	// Factory Creation //
	// ////////////////////
	
//	private static <Q extends Quantity<Q>> QuantityAmount<Q> create(Number value, Unit<Q> unit) {
//		
//	}
	

//	@SuppressWarnings("unchecked")
//	protected static <Q extends Quantity<Q>> QuantityAmount<Q> newInstance(
//			Number value, Unit<?> unit) {
//		QuantityAmount<Q> measure = FACTORY.create(value, unit);
//
//		measure._unit = (Unit<Q>) unit;
//
//		return measure;
//	}

	/**
	 * Get the unit (convenience to avoid cast).
	 * 
	 * @provisional This API might change or be removed in a future release.
	 */
	@SuppressWarnings("unchecked")
	private final AbstractUnit<Q> internalUnit() {
		return (AbstractUnit<Q>) super.getUnit();
	}
}
