/**
 *                                                                            
 *  Copyright (c) 2011, 2016 - 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 v1.0       
 *  which accompanies this distribution, and is available at                  
 *  http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 */
package org.eclipse.osbp.utils.vaadin;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.osbp.ui.api.datamart.DerivedOlapException;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;
import org.eclipse.osbp.utils.blob.component.BlobUploadComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.server.Resource;

class DoubleComparator implements Comparator<Double> {
	@Override
	public int compare(Double arg0, Double arg1) {
		return arg0.compareTo(arg1);
	}
}

class BigDecimalComparator implements Comparator<BigDecimal> {
	@Override
	public int compare(BigDecimal arg0, BigDecimal arg1) {
		return arg0.compareTo(arg1);
	}
}

class DateComparator implements Comparator<Date> {
	@Override
	public int compare(Date o1, Date o2) {
		return o1.compareTo(o2);
	}
}

public class PropertyLookup {
	private final IThemeResourceService themeResourceService;
	private final IDSLMetadataService dslMetadataService;

	private static final Logger LOGGER = LoggerFactory.getLogger(PropertyLookup.class);
	// datatypes
	public final static int NOT_SET = -1;
	public final static int DATE = 0;
	public final static int NUMBER = 1;
	public final static int BIGDECIMAL = 2;
	public final static int STRING = 3;

	// infotype
	public final static int STYLE = 0;
	public final static int RESOURCE = 1;

	String format = null;
	String defaultStyle = null;

	boolean styleDiscreteValues = false;
	boolean resourceDiscreteValues = false;
	boolean tooltipDiscreteValues = false;
	boolean hideLabel = false;
	boolean collapseColumn = false;
	String tooltipPattern = null;
	private Map<Date, Resource> dateResourceMap = new TreeMap<Date, Resource>(new DateComparator());
	private Map<Date, String> dateStyleMap = new TreeMap<Date, String>(new DateComparator());
	private Map<Double, Resource> doubleResourceMap = new TreeMap<Double, Resource>(new DoubleComparator());
	private Map<Double, String> doubleStyleMap = new TreeMap<Double, String>(new DoubleComparator());
	private Map<String, Resource> stringResourceMap = new HashMap<String, Resource>();
	private Map<String, String> stringStyleMap = new HashMap<String, String>();
	private Map<Double, String> doubleTooltipMap = new TreeMap<Double, String>(new DoubleComparator());
	private Map<Date, String> dateTooltipMap = new TreeMap<Date, String>(new DateComparator());
	private Map<String, String> stringTooltipMap = new HashMap<String, String>();
	private Locale locale;
	private int defaultType = NOT_SET;
	private boolean isImage = false;
	private boolean isBlob = false;
	private StringToFormattedDateConverter dateConv = new StringToFormattedDateConverter();
	private StringToFormattedDoubleConverter numberConv = new StringToFormattedDoubleConverter();
	private StringToFormattedBigDecimalConverter bigDecimalConv = new StringToFormattedBigDecimalConverter();
	private String imagePath = null;
	private String imageParameterPattern = null;
	private String imageParameterFormat = null;
	private String resizeString = null;
	private Resource columnIcon = null;
	private int resolutionId = 0;

	public PropertyLookup(IThemeResourceService themeResourceService, IDSLMetadataService dslMetadataService, Locale locale) {
		this.themeResourceService = themeResourceService;
		this.dslMetadataService = dslMetadataService;
		this.locale = locale;
	}

	public PropertyLookup setLocale(Locale locale) {
		this.locale = locale;
		return this;
	}

	public Locale getLocale() {
		return locale;
	}

	public String getFormat() {
		return format;
	}

	public PropertyLookup setFormat(String format) {
		this.format = format;
		dateConv.setLookup(this);
		numberConv.setLookup(this);
		bigDecimalConv.setLookup(this);
		return this;
	}

	public String getTooltipPattern() {
		return tooltipPattern;
	}

	public PropertyLookup setTooltipPattern(String tooltipPattern) {
		this.tooltipPattern = tooltipPattern;
		return this;
	}

	public String getTooltip(Object value) {
		String tooltip = null;
		String item = "";
		switch (defaultType) {
		case DATE:
			item = dateConv.convertToPresentation((Date) value, String.class, locale);
			break;
		case NUMBER:
			try {
				item = numberConv.convertToPresentation(getDoubleValue(value), String.class, locale);
			} catch (ConversionException | DerivedOlapException e) {
				e.printStackTrace();
			}
			break;
		case BIGDECIMAL:
			try {
				item = bigDecimalConv.convertToPresentation(getBigDecimalValue(value), String.class, locale);
			} catch (ConversionException | DerivedOlapException e) {
				e.printStackTrace();
			}
			break;
		case STRING:
			item = (String) value;
			LOGGER.debug("getTooltip >" + item + "<");
			break;
		}
		if (tooltipPattern != null) {
			LOGGER.debug("getTooltip pattern >" + tooltipPattern + "< result:" + tooltip);
			tooltip = String.format(tooltipPattern, item);
		} else if (value != null) {
			tooltip = item;
		}
		return tooltip;
	}

	public Resource getColumnIcon() {
		return columnIcon;
	}

	public PropertyLookup setColumnIcon(String resourceName) {
		columnIcon = themeResourceService.getThemeResource(resourceName, ThemeResourceType.ICON);
		return this;
	}

	public boolean isBlob() {
		return isBlob;
	}

	public PropertyLookup setBlob(boolean isBlob, int resolutionId) {
		this.isBlob = isBlob;
		this.resolutionId = resolutionId;
		return this;
	}

	public String getResizeString() {
		return resizeString;
	}

	public PropertyLookup setResizeString(String resizeString) {
		this.resizeString = resizeString;
		return this;
	}

	public StringToFormattedDateConverter getDateConverter() {
		return dateConv;
	}

	public StringToFormattedDoubleConverter getNumberConverter() {
		return numberConv;
	}

	public StringToFormattedBigDecimalConverter getBigDecimalConverter() {
		return bigDecimalConv;
	}

	/**
	 * @param until
	 * @param resourceName
	 */
	public PropertyLookup addResourceInterval(Date until, String resourceName) {
		Resource resource = themeResourceService.getThemeResource(resourceName, ThemeResourceType.ICON);
		dateResourceMap.put(until, resource);
		isImage = true;
		defaultType = DATE;
		return this;
	}

	public PropertyLookup addStyleInterval(Date until, String styleName) {
		dateStyleMap.put(until, styleName);
		defaultType = DATE;
		return this;
	}

	public PropertyLookup addTooltipInterval(Date until, String tooltip) {
		dateTooltipMap.put(until, tooltip);
		defaultType = DATE;
		return this;
	}

	public PropertyLookup addResourceLookup(Date value, String resourceName) {
		resourceDiscreteValues = true;
		addResourceInterval(value, resourceName);
		return this;
	}

	public PropertyLookup addStyleLookup(Date value, String styleName) {
		styleDiscreteValues = true;
		addStyleInterval(value, styleName);
		return this;
	}

	public PropertyLookup addTooltipLookup(Date value, String tooltip) {
		tooltipDiscreteValues = true;
		addResourceInterval(value, tooltip);
		return this;
	}

	public PropertyLookup addResourceLookup(String value, String resourceName) {
		Resource resource = themeResourceService.getThemeResource(resourceName, ThemeResourceType.ICON);
		stringResourceMap.put(value, resource);
		isImage = true;
		defaultType = STRING;
		return this;
	}

	public PropertyLookup addStyleLookup(String value, String styleName) {
		stringStyleMap.put(value, styleName);
		defaultType = STRING;
		return this;
	}

	public PropertyLookup addTooltipLookup(String value, String tooltip) {
		stringTooltipMap.put(value, tooltip);
		defaultType = STRING;
		return this;
	}

	public PropertyLookup addResourceLookup(double value, String resourceName) {
		resourceDiscreteValues = true;
		addResourceInterval(value, resourceName);
		return this;
	}

	public PropertyLookup addStyleLookup(double value, String styleName) {
		styleDiscreteValues = true;
		addStyleInterval(value, styleName);
		return this;
	}

	public PropertyLookup addTooltipLookup(double value, String tooltip) {
		tooltipDiscreteValues = true;
		addTooltipInterval(value, tooltip);
		return this;
	}

	public PropertyLookup addResourceInterval(double until, String resourceName) {
		Resource resource = themeResourceService.getThemeResource(resourceName, ThemeResourceType.ICON);
		doubleResourceMap.put(until, resource);
		isImage = true;
		defaultType = NUMBER;
		return this;
	}

	public PropertyLookup addStyleInterval(double until, String styleName) {
		doubleStyleMap.put(until, styleName);
		defaultType = NUMBER;
		return this;
	}

	public PropertyLookup addTooltipInterval(double until, String tooltip) {
		doubleTooltipMap.put(until, tooltip);
		defaultType = NUMBER;
		return this;
	}

	public boolean isHideLabel() {
		return hideLabel;
	}

	public PropertyLookup setHideLabel(boolean hideLabel) {
		this.hideLabel = hideLabel;
		return this;
	}

	public boolean isCollapseColumn() {
		return collapseColumn;
	}

	public PropertyLookup setCollapseColumn(boolean collapseColumn) {
		this.collapseColumn = collapseColumn;
		return this;
	}

	protected double getDoubleValue(Object value) throws DerivedOlapException {
		if (value instanceof Double) {
			return (Double) value;
		} else if (value instanceof Float) {
			return (Float) value;
		} else if (value instanceof Long) {
			return (Long) value;
		} else if (value instanceof Integer) {
			return (Integer) value;
		}
		throw new DerivedOlapException("unsupported type conversion");
	}

	protected BigDecimal getBigDecimalValue(Object value) throws DerivedOlapException {
		if (value instanceof BigDecimal) {
			return (BigDecimal) value;
		}
		throw new DerivedOlapException("unsupported type conversion");
	}

	public int getType() {
		return defaultType;
	}

	public PropertyLookup setType(int type) {
		this.defaultType = type;
		return this;
	}

	public Object getValueObject(Object value) {
		if (value == null) {
			return null;
		}
		switch (defaultType) {
		case DATE:
			for (Date key : dateResourceMap.keySet()) {
				if ((resourceDiscreteValues && ((Date) value).equals(key)) || (!resourceDiscreteValues && ((Date) value).before(key))) {
					return new CellSetImage(value, dateConv.convertToPresentation((Date) value, String.class, locale), dateResourceMap.get(key), hideLabel, resizeString);
				}
			}
			// if it should be an image and no match was found, return an empty image to avoid complaints
			if (isImage) {
				return new CellSetImage(value, dateConv.convertToPresentation((Date) value, String.class, locale), null, hideLabel, resizeString);
			}
			break;
		case NUMBER:
			double doubleValue = 0;
			try {
				doubleValue = getDoubleValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleResourceMap.keySet()) {
				if ((resourceDiscreteValues && doubleValue == key) || (!resourceDiscreteValues && doubleValue <= key)) {
					return new CellSetImage(doubleValue, numberConv.convertToPresentation(doubleValue, String.class, locale), doubleResourceMap.get(key), hideLabel, resizeString);
				}
			}
			if (imagePath != null) {
				String path = imagePath;
				if (imageParameterPattern != null) {
					path = path.replace(imageParameterPattern, String.format(imageParameterFormat, doubleValue));
				}
				Resource res = themeResourceService.getThemeResource(path, ThemeResourceType.ICON);
				return new CellSetImage(doubleValue, numberConv.convertToPresentation(doubleValue, String.class, locale), res, hideLabel, resizeString);
			}
			// if it should be an image and no match was found, return an empty image to avoid complaints
			if (isImage) {
				return new CellSetImage(doubleValue, numberConv.convertToPresentation(doubleValue, String.class, locale), null, hideLabel, resizeString);
			}
			break;
		case BIGDECIMAL:
			BigDecimal bigValue = BigDecimal.ZERO;
			try {
				bigValue = getBigDecimalValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleResourceMap.keySet()) {
				BigDecimal bdKey = new BigDecimal(key);
				if ((resourceDiscreteValues && bigValue.equals(bdKey)) || (!resourceDiscreteValues && bigValue.compareTo(bdKey) <= 0)) {
					return new CellSetImage(bigValue, bigDecimalConv.convertToPresentation(bigValue, String.class, locale), doubleResourceMap.get(key), hideLabel, resizeString);
				}
			}
			if (imagePath != null) {
				String path = imagePath;
				if (imageParameterPattern != null) {
					path = path.replace(imageParameterPattern, String.format(imageParameterFormat, bigValue));
				}
				Resource res = themeResourceService.getThemeResource(path, ThemeResourceType.ICON);
				return new CellSetImage(bigValue, bigDecimalConv.convertToPresentation(bigValue, String.class, locale), res, hideLabel, resizeString);
			}
			// if it should be an image and no match was found, return an empty image to avoid complaints
			if (isImage) {
				return new CellSetImage(bigValue, bigDecimalConv.convertToPresentation(bigValue, String.class, locale), null, hideLabel, resizeString);
			}
			break;
		case STRING:
			for (String key : stringResourceMap.keySet()) {
				if (key.equals((String) value)) {
					return new CellSetImage(value, (String) value, stringResourceMap.get(key), hideLabel, resizeString);
				}
			}
			if (imagePath != null) {
				String path = imagePath;
				if (imageParameterPattern != null) {
					path = path.replace(imageParameterPattern, String.format(imageParameterFormat, (String) value));
				}
				Resource res = themeResourceService.getThemeResource(path, ThemeResourceType.ICON);
				return new CellSetImage(value, (String) value, res, hideLabel, resizeString);
			}
			if (isBlob) {
				BlobUploadComponent blobUploadComponent = BlobUploadComponent.initialize();
				blobUploadComponent.setValue((String) value);
				blobUploadComponent.setDisplayResolutionId(resolutionId);
				return blobUploadComponent;
			}
			// if it should be an image and no match was found, return an empty image to avoid complaints
			if (isImage) {
				return new CellSetImage(value, (String) value, null, hideLabel, resizeString);
			}
			break;
		}
		return value;
	}

	public String getValueTooltip(Object value) {
		switch (defaultType) {
		case DATE:
			for (Date key : dateTooltipMap.keySet()) {
				if ((tooltipDiscreteValues && ((Date) value).equals(key)) || (!tooltipDiscreteValues && ((Date) value).before(key))) {
					return dslMetadataService.translate(locale.toLanguageTag(), dateTooltipMap.get(key));
				}
			}
			break;
		case NUMBER:
			double doubleValue = 0;
			try {
				doubleValue = getDoubleValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleTooltipMap.keySet()) {
				if ((tooltipDiscreteValues && doubleValue == key) || (!tooltipDiscreteValues && doubleValue <= key)) {
					return dslMetadataService.translate(locale.toLanguageTag(), doubleTooltipMap.get(key));
				}
			}
			break;
		case BIGDECIMAL:
			BigDecimal bigValue = BigDecimal.ZERO;
			try {
				bigValue = getBigDecimalValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleTooltipMap.keySet()) {
				BigDecimal bdKey = new BigDecimal(key);
				if ((tooltipDiscreteValues && bigValue.equals(bdKey)) || (!tooltipDiscreteValues && bigValue.compareTo(bdKey) <= 0)) {
					return dslMetadataService.translate(locale.toLanguageTag(), doubleTooltipMap.get(key));
				}
			}
			break;
		case STRING:
			for (String key : stringTooltipMap.keySet()) {
				if (key.equals((String) value)) {
					return dslMetadataService.translate(locale.toLanguageTag(), stringTooltipMap.get(key));
				}
			}
			break;
		}
		return getTooltip(value);
	}

	public String getDefaultStyle() {
		return defaultStyle;
	}

	public PropertyLookup setDefaultStyle(Class<?> type, boolean isHeader) {
		if (isHeader) {
			defaultStyle = "rowheader";
		} else if (type.equals(double.class) || type.equals(Double.class) || type.equals(float.class) || type.equals(Float.class) || type.equals(int.class)
				|| type.equals(Integer.class) || type.equals(long.class) || type.equals(Long.class) || type.equals(BigDecimal.class)) {
			defaultStyle = "v-align-right";
		} else if (type.equals(String.class)) {
			defaultStyle = "v-align-left";
		} else if (type.equals(Date.class) || type.equals(Timestamp.class)) {
			defaultStyle = "v-align-left";
		} else if (type.equals(CellSetImage.class)) {
			defaultStyle = "v-align-center";
		}
		return this;
	}

	public String getValueStyle(Object value, int rowNumber) {
		switch (defaultType) {
		case DATE:
			if (dateStyleMap.size() == 0) {
				return defaultStyle;
			}
			for (Date key : dateStyleMap.keySet()) {
				if ((styleDiscreteValues && ((Date) value).equals(key)) || (!styleDiscreteValues && ((Date) value).before(key))) {
					return dateStyleMap.get(key);
				}
			}
			break;
		case NUMBER:
			if (doubleStyleMap.size() == 0) {
				return defaultStyle;
			}
			double doubleValue = 0;
			try {
				doubleValue = getDoubleValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleStyleMap.keySet()) {
				if ((styleDiscreteValues && doubleValue == key) || (!styleDiscreteValues && doubleValue <= key)) {
					return doubleStyleMap.get(key);
				}
			}
			break;
		case BIGDECIMAL:
			if (doubleStyleMap.size() == 0) {
				return defaultStyle;
			}
			BigDecimal bigDecimalValue = BigDecimal.ZERO;
			try {
				bigDecimalValue = getBigDecimalValue(value);
			} catch (DerivedOlapException e) {
				e.printStackTrace();
			}
			for (Double key : doubleStyleMap.keySet()) {
				BigDecimal bdKey = new BigDecimal(key);
				if ((styleDiscreteValues && bigDecimalValue.equals(bdKey)) || (!styleDiscreteValues && bigDecimalValue.compareTo(bdKey) <= 0)) {
					return doubleStyleMap.get(key);
				}
			}
			break;
		case STRING:
			if (stringStyleMap.size() == 0) {
				return defaultStyle;
			}
			for (String key : stringStyleMap.keySet()) {
				if (key.equals((String) value)) {
					return stringStyleMap.get(key);
				}
			}
			break;
		}
		return defaultStyle;
	}

	public Class<?> getPropertyType(Class<?> defaultType) {
		if (defaultType.equals(double.class) || defaultType.equals(Double.class) || defaultType.equals(float.class) || defaultType.equals(Float.class)
				|| defaultType.equals(int.class) || defaultType.equals(Integer.class) || defaultType.equals(long.class) || defaultType.equals(Long.class)) {
			this.defaultType = NUMBER;
		} else if (defaultType.equals(BigDecimal.class)) {
			this.defaultType = BIGDECIMAL;
		} else if (defaultType.equals(String.class)) {
			this.defaultType = STRING;
		} else if (defaultType.equals(Date.class) || defaultType.equals(Timestamp.class)) {
			this.defaultType = DATE;
		}
		if (isImage) {
			return CellSetImage.class;
		}
		if (isBlob) {
			return BlobUploadComponent.class;
		}
		return defaultType;
	}

	public PropertyLookup setImageService(String path, boolean hasParameter) {
		isImage = true;
		// defaultType = STRING;
		imagePath = path;
		if (hasParameter) {
			String[] token = path.split("%");
			// there must only be one parameter for the moment
			if (token.length == 3) {
				imageParameterPattern = "%" + token[1] + "%";
				imageParameterFormat = "%" + token[1];
			}
		}
		return this;
	}
}
