/*
 * 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 flex.messaging.io.amf.translator.decoder;

import java.math.BigDecimal;
import java.math.BigInteger;

import flex.messaging.io.SerializationContext;

/**
 * Decode an ActionScript type (a string or a double) to a Java number (of any type).
 */
public class NumberDecoder extends ActionScriptDecoder {
    public Object decodeObject(Object shell, Object encodedObject, Class desiredClass) {
        Object result = null;

        if (encodedObject != null && encodedObject instanceof String) {
            String str = ((String) encodedObject).trim();
            try {
                // Short-ciruit String -> BigInteger,BigDecimal to avoid loss
                // of precision that occurs if we go through Double
                if (!SerializationContext.getSerializationContext().legacyBigNumbers) {
                    if (BigInteger.class.equals(desiredClass)) {
                        result = new BigInteger(str);
                        return result;
                    } else if (BigDecimal.class.equals(desiredClass)) {
                        result = new BigDecimal(str);
                        return result;
                    }
                }

                Double dbl = new Double(str);
                encodedObject = dbl;
            } catch (NumberFormatException nfe) {
                DecoderFactory.invalidType(encodedObject, desiredClass);
            }
        }

        if (encodedObject instanceof Number || encodedObject == null) {
            Double dbl;

            if (desiredClass.isPrimitive()) {
                if (encodedObject == null)
                    dbl = new Double(0);
                else
                    dbl = new Double(((Number) encodedObject).doubleValue());

                if (Object.class.equals(desiredClass) || Double.TYPE.equals(desiredClass))
                    result = dbl;
                else if (Integer.TYPE.equals(desiredClass))
                    result = new Integer(dbl.intValue());
                else if (Long.TYPE.equals(desiredClass))
                    result = new Long(dbl.longValue());
                else if (Float.TYPE.equals(desiredClass))
                    result = new Float(dbl.floatValue());
                else if (Short.TYPE.equals(desiredClass))
                    result = new Short(dbl.shortValue());
                else if (Byte.TYPE.equals(desiredClass))
                    result = new Byte(dbl.byteValue());
            } else if (encodedObject != null) {
                dbl = new Double(((Number) encodedObject).doubleValue());

                if (Object.class.equals(desiredClass) || Number.class.equals(desiredClass) ||
                        Double.class.equals(desiredClass))
                    result = dbl;
                else if (Integer.class.equals(desiredClass))
                    result = dbl.isNaN() ? null : new Integer(dbl.intValue());
                else if (Long.class.equals(desiredClass))
                    result = dbl.isNaN() ? null : new Long(dbl.longValue());
                else if (Float.class.equals(desiredClass))
                    result = new Float(dbl.floatValue());
                else if (Short.class.equals(desiredClass))
                    result = dbl.isNaN() ? null : new Short(dbl.shortValue());
                else if (Byte.class.equals(desiredClass))
                    result = dbl.isNaN() ? null : new Byte(dbl.byteValue());
                else if (BigDecimal.class.equals(desiredClass)) {
                    // Though this is a little slower than using the
                    // double constructor for BigDecimal, it yields a rounded
                    // result which is more predicable (see the Javadoc for
                    // BigDecimal and bug: 182378).
                    if (SerializationContext.getSerializationContext().legacyBigNumbers)
                        result = new BigDecimal(dbl.doubleValue());
                    else
                        result = new BigDecimal(String.valueOf(dbl));
                } else if (BigInteger.class.equals(desiredClass)) {
                    // Must have no special characters or whitespace
                    String val = null;
                    long l = dbl.longValue();
                    if (l > Integer.MAX_VALUE) {
                        Long lo = new Long(dbl.longValue());
                        val = lo.toString().toUpperCase();
                        int suffix = val.indexOf('L');
                        if (suffix != -1)
                            val = val.substring(0, suffix);
                    } else {
                        Integer i = new Integer(dbl.intValue());
                        val = i.toString();
                    }
                    result = new BigInteger(val.trim());
                }
            } else {
                result = null;
            }
        } else {
            DecoderFactory.invalidType(encodedObject, desiredClass);
        }

        return result;
    }
}
