/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */

package org.eclipse.osbp.ecview.core.databinding.emf.common;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.databinding.BindingException;
import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.util.Policy;
import org.eclipse.core.internal.databinding.Activator;
import org.eclipse.core.internal.databinding.conversion.NumberToBigDecimalConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToBigIntegerConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToByteConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToDoubleConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToFloatConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToIntegerConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToLongConverter;
import org.eclipse.core.internal.databinding.conversion.NumberToShortConverter;
import org.eclipse.core.internal.databinding.conversion.ObjectToStringConverter;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.databinding.EMFUpdateValueStrategy;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EDataType;

import com.ibm.icu.text.NumberFormat;

@SuppressWarnings("restriction")
public class ECViewUpdateValueStrategy extends EMFUpdateValueStrategy {

	private static final Map<ConverterKey, IConverter> converterMap = new HashMap<ConverterKey, IConverter>();
	static {

		NumberFormat integerFormat = NumberFormat.getIntegerInstance();
		NumberFormat numberFormat = NumberFormat.getNumberInstance();

		converterMap.put(new ConverterKey(Number.class, BigDecimal.class),
				new NumberToBigDecimalConverter(numberFormat, Number.class));
		converterMap.put(new ConverterKey(Number.class, BigInteger.class),
				new NumberToBigIntegerConverter(integerFormat, Number.class));

		converterMap.put(new ConverterKey(Number.class, Byte.class),
				new NumberToByteConverter(integerFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Byte.TYPE),
				new NumberToByteConverter(integerFormat, Number.class, true));

		converterMap.put(new ConverterKey(Number.class, Double.class),
				new NumberToDoubleConverter(numberFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Double.TYPE),
				new NumberToDoubleConverter(numberFormat, Number.class, true));

		converterMap.put(new ConverterKey(Number.class, Float.class),
				new NumberToFloatConverter(numberFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Float.TYPE),
				new NumberToFloatConverter(numberFormat, Number.class, true));

		converterMap.put(new ConverterKey(Number.class, Integer.class),
				new NumberToIntegerConverter(integerFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Integer.TYPE),
				new NumberToIntegerConverter(integerFormat, Number.class, true));

		converterMap.put(new ConverterKey(Number.class, Long.class),
				new NumberToLongConverter(integerFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Long.TYPE),
				new NumberToLongConverter(integerFormat, Number.class, true));

		converterMap.put(new ConverterKey(Number.class, Short.class),
				new NumberToShortConverter(integerFormat, Number.class, false));
		converterMap.put(new ConverterKey(Number.class, Short.TYPE),
				new NumberToShortConverter(integerFormat, Number.class, true));

	}

	public ECViewUpdateValueStrategy() {
		super();
	}

	public ECViewUpdateValueStrategy(boolean provideDefaults, int updatePolicy) {
		super(provideDefaults, updatePolicy);
	}

	public ECViewUpdateValueStrategy(int updatePolicy) {
		super(updatePolicy);
	}

	@Override
	protected IConverter createConverter(Object fromType, Object toType) {

		/*
		 * Try to find an number converter for EAttributes
		 */
		if (fromType instanceof EAttribute && toType instanceof EAttribute) {
			final EAttribute fromEAttribute = (EAttribute) fromType;
			final EAttribute toEAttribute = (EAttribute) toType;

			if (isNumber(fromEAttribute) && isNumber(toEAttribute)) {
				final EDataType fromEDataType = fromEAttribute.getEAttributeType();
				final Class<?> fromTypeClass = fromEDataType.getInstanceClass();

				final EDataType toEDataType = toEAttribute.getEAttributeType();
				final Class<?> toTypeClass = toEDataType.getInstanceClass();

				IConverter converter = findNumberToNumberConverter(toTypeClass, fromTypeClass);
				if (converter != null) {
					return converter;
				}
			}
		}

		/*
		 * Try to find further converters
		 */
		if (toType instanceof EAttribute) {
			final EAttribute eAttribute = (EAttribute) toType;
			final EDataType eDataType = eAttribute.getEAttributeType();
			final Class<?> toTypeClass = eDataType.getInstanceClass();
			if (isNumber(fromType)) {
				if (isNumber(toTypeClass)) {
					final Class<?> fromTypeClass = (Class<?>) fromType;
					IConverter converter = findNumberToNumberConverter(toTypeClass, fromTypeClass);
					if (converter != null) {
						return converter;
					}
				} else if (toTypeClass == String.class) {
					return new ObjectToStringConverter();
				}
			} else if (isBoolean(eAttribute)) {
				return new BooleanConverter((Boolean) eAttribute.getDefaultValue());
			} else if (fromType == String.class && (toTypeClass == String.class || toTypeClass == Object.class)) {
				return null;
			}
		} else if (fromType instanceof EAttribute) {
			final EAttribute eAttribute = (EAttribute) fromType;
			final EDataType eDataType = eAttribute.getEAttributeType();
			final Class<?> fromTypeClass = eDataType.getInstanceClass();
			if (isNumber(toType)) {
				// if eAttribute == number
				if (isNumber(fromTypeClass)) {
					final Class<?> toTypeClass = (Class<?>) toType;
					IConverter converter = findNumberToNumberConverter(toTypeClass, fromTypeClass);
					if (converter != null) {
						return converter;
					}
				}
			} else if (toType == String.class && (fromTypeClass == String.class || fromTypeClass == Object.class)) {
				return null;
			}
		}
		return super.createConverter(fromType, toType);
	}

	/**
	 * Converts the value from the source type to the destination type.
	 * <p>
	 * Default implementation will use the setConverter(IConverter), if one
	 * exists. If no converter exists no conversion occurs.
	 * </p>
	 *
	 * @param value
	 * @return the converted value
	 */
	public Object convert(Object value) {
		if (converter != null) {
			try {
				return converter.convert(value);
				// TODO We should think about validators in ECView
			} catch (BindingException ex) {
				return null;
			} catch (Exception ex) {
				Policy.getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex));
				return null;
			}
		}
		return value;
	}

	/**
	 * Tries to find a proper number converter.
	 * 
	 * @param toTypeClass
	 * @param fromTypeClass
	 * @return
	 */
	private IConverter findNumberToNumberConverter(final Class<?> toTypeClass, final Class<?> fromTypeClass) {
		// if (toTypeClass == BigDecimal.class)
		// return new NumberToBigDecimalConverter(
		// NumberFormat.getNumberInstance(), fromTypeClass);
		// if (toTypeClass == BigInteger.class)
		// return new NumberToBigIntegerConverter(
		// NumberFormat.getNumberInstance(), fromTypeClass);
		// if (toTypeClass == Byte.class || toTypeClass == Byte.TYPE)
		// return new NumberToByteConverter(NumberFormat.getNumberInstance(),
		// fromTypeClass, toTypeClass.isPrimitive());
		// if (toTypeClass == Double.class || toTypeClass == Double.TYPE)
		// return new NumberToDoubleConverter(
		// NumberFormat.getNumberInstance(), fromTypeClass,
		// toTypeClass.isPrimitive());
		// if (toTypeClass == Float.class || toTypeClass == Float.TYPE)
		// return new NumberToFloatConverter(NumberFormat.getNumberInstance(),
		// fromTypeClass, toTypeClass.isPrimitive());
		// if (toTypeClass == Integer.class || toTypeClass == Integer.TYPE)
		// return new NumberToIntegerConverter(
		// NumberFormat.getNumberInstance(), fromTypeClass,
		// toTypeClass.isPrimitive());
		// if (toTypeClass == Long.class || toTypeClass == Long.TYPE)
		// return new NumberToLongConverter(NumberFormat.getNumberInstance(),
		// fromTypeClass, toTypeClass.isPrimitive());
		// if (toTypeClass == Short.class || toTypeClass == Short.TYPE)
		// return new NumberToShortConverter(NumberFormat.getNumberInstance(),
		// fromTypeClass, toTypeClass.isPrimitive());

		return converterMap.get(new ConverterKey(Number.class, toTypeClass));
	}

	/**
	 * Returns true, if the given type is a number.
	 * 
	 * @param type
	 * @return
	 */
	private boolean isNumber(Object type) {
		if(type instanceof Class<?>) {
			Class<?> clazz = (Class<?>) type;
			return Number.class.isAssignableFrom(clazz) || isPrimitiveNumber((Class<?>) type);
		}
		return false;
	}

	private boolean isBoolean(Object type) {
		return type == Boolean.class || type == Boolean.TYPE;
	}

	private boolean isNumber(EAttribute eAttribute) {
		final EDataType eDataType = eAttribute.getEAttributeType();
		final Class<?> fromTypeClass = eDataType.getInstanceClass();
		return isNumber(fromTypeClass);
	}

	private boolean isBoolean(EAttribute eAttribute) {
		final EDataType eDataType = eAttribute.getEAttributeType();
		final Class<?> fromTypeClass = eDataType.getInstanceClass();
		return isBoolean(fromTypeClass);
	}

	/**
	 * Returns true, if the given type is a date.
	 * 
	 * @param type
	 * @return
	 */
	@SuppressWarnings("unused")
	private boolean isDate(Object type) {
		return type instanceof Class && (Date.class.isAssignableFrom((Class<?>) type));
	}

	/**
	 * Returns true, if the given type is a string.
	 * 
	 * @param type
	 * @return
	 */
	@SuppressWarnings("unused")
	private boolean isString(Object type) {
		return type == String.class;
	}

	/**
	 * Returns true, if the given type is a primitive number.
	 * 
	 * @param type
	 * @return
	 */
	private boolean isPrimitiveNumber(Class<?> type) {
		if (type.isPrimitive()) {
			return type == Short.TYPE || type == Byte.TYPE || type == Double.TYPE || type == Float.TYPE
					|| type == Integer.TYPE || type == Long.TYPE;
		}
		return false;
	}

	/**
	 * A key to access the converter map.
	 */
	private static final class ConverterKey {

		private final Class<?> fromType;
		private final Class<?> toType;

		public ConverterKey(Class<?> fromType, Class<?> toType) {
			super();
			this.fromType = fromType;
			this.toType = toType;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((fromType == null) ? 0 : fromType.hashCode());
			result = prime * result + ((toType == null) ? 0 : toType.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ConverterKey other = (ConverterKey) obj;
			if (fromType == null) {
				if (other.fromType != null)
					return false;
			} else if (!fromType.equals(other.fromType))
				return false;
			if (toType == null) {
				if (other.toType != null)
					return false;
			} else if (!toType.equals(other.toType))
				return false;
			return true;
		}

	}

	private static class BooleanConverter implements IConverter {

		final Boolean defaultValue;

		public BooleanConverter(Boolean defaultValue) {
			this.defaultValue = defaultValue;
		}

		@Override
		public Object getFromType() {
			return Boolean.class;
		}

		@Override
		public Object getToType() {
			return Boolean.class;
		}

		@Override
		public Object convert(Object fromObject) {
			return fromObject != null ? fromObject : toDefault();
		}

		private Boolean toDefault() {
			return defaultValue != null ? defaultValue : Boolean.FALSE;
		}

	}

}
