/**
 *                                                                            
 * 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.infogrid.api;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.osbp.ecview.core.common.model.core.YCompare;
import org.eclipse.osbp.ecview.core.common.model.core.YConverter;
import org.eclipse.osbp.runtime.common.types.IBundleSpace;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridProperty;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSource;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceEQFilter;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSourceInput;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridCompare;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropButtonStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropDateStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropImageStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropIndicatorStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropNumberStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropPriceStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropProgressbarStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridPropQuantityStyle;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfig;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfigNumericToResource;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStyleConfigStringToResource;
import org.eclipse.osbp.infogrid.model.gridsource.style.CxGridStylePackage;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.osbp.ecview.extension.grid.CxGrid;
import org.eclipse.osbp.ecview.extension.grid.CxGridColumn;
import org.eclipse.osbp.ecview.extension.grid.CxGridFactory;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridButtonRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridDateRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridImageRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridIndicatorRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridNumberRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridPriceRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridProgressBarRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridQuantityRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRenderer;
import org.eclipse.osbp.ecview.extension.grid.renderer.CxGridRendererFactory;
import org.eclipse.osbp.ecview.extension.model.converter.YConverterFactory;
import org.eclipse.osbp.ecview.extension.model.converter.YNumericToResourceConfig;
import org.eclipse.osbp.ecview.extension.model.converter.YNumericToResourceConverter;
import org.eclipse.osbp.ecview.extension.model.converter.YStringToResourceConfig;
import org.eclipse.osbp.ecview.extension.model.converter.YStringToResourceConverter;

// TODO put to different bundle
public class DefaultECViewGridFactory implements IECViewGridFactory {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(DefaultECViewGridFactory.class);

	private CxGridFactory gridFactory = CxGridFactory.eINSTANCE;

	public DefaultECViewGridFactory() {

	}

	@Override
	public CxGrid createGrid(Class<?> inputType, CxGridSource gridSource) {

		BundleContext bc = FrameworkUtil.getBundle(getClass())
				.getBundleContext();
		ServiceReference<IBundleSpace> bsRef = bc
				.getServiceReference(IBundleSpace.class);
		if (bsRef == null) {
			LOGGER.error("No BundleSpace available.");
			return gridFactory.createCxGrid();
		}
		IBundleSpace bundleSpace = bc.getService(bsRef);

		Class<?> rootType = null;
		try {
			rootType = bundleSpace.forName(gridSource.getRootTypeFQN());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		bc.ungetService(bsRef);

		CxGrid grid = gridFactory.createCxGrid();
		grid.setId(GRID_ID);
		grid.getProperties().put(GRIDSOURCE_ID, gridSource.getId());
		grid.setEditorEnabled(false);
		grid.setHeaderVisible(true);
		grid.setUseBeanService(!gridSource.getTags().contains(IECViewGridSourceDescriptor.PROP_MANUAL_BEANS));
		grid.setColumnReorderingAllowed(true);
		if( rootType != null ) {
			grid.setType(rootType);
			grid.setTypeQualifiedName(rootType.getName());
		}
		
		for (CxGridProperty prop : gridSource.getProperties()) {
			CxGridColumn column = gridFactory.createCxGridColumn();
			column.setPropertyPath(prop.getDotPath());
			column.setPropertyId(prop.getDotPath());

			Class<?> propertyType = BeanProperties
					.value(rootType, prop.getDotPath()).getPropertyDescriptor()
					.getPropertyType();
			Pair pair = createRendererPair(prop, propertyType);
			column.setRenderer(pair.renderer);
			column.setConverter(pair.converter);
			grid.getColumns().add(column);
		}

		for (CxGridSourceInput input : gridSource.getInputs()) {
			if (inputType.getName().equals(input.getInputTypeFQN())) {
				for (CxGridSourceEQFilter filter : input.getFilters()) {
					// take the filter value from the input
					filter.getInputTypePropertyPath();
				}
			}
		}

		return grid;
	}

	/**
	 * Creates a renderer for the given property.
	 * 
	 * @param prop
	 * @param propertyType
	 * @return
	 */
	protected Pair createRendererPair(CxGridProperty prop, Class<?> propertyType) {

		if ( prop == null ) {
			return null;
		}
		
		Pair pair = new Pair();

		CxGridRendererFactory factory = CxGridRendererFactory.eINSTANCE;
		if (prop.getStyle() == null) {
			return createBadRenderer();
		}

		EClass styleClass = prop.getStyle().eClass();
		switch (styleClass.getClassifierID()) {
		case CxGridStylePackage.CX_GRID_PROP_BOOLEAN_STYLE:
			pair.renderer = factory.createCxGridBooleanRenderer();
			break;
		case CxGridStylePackage.CX_GRID_PROP_DATE_STYLE: {
			CxGridPropDateStyle style = (CxGridPropDateStyle) prop.getStyle();
			CxGridDateRenderer renderer = factory.createCxGridDateRenderer();
			renderer.setDateFormat(style.getDateFormat());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_NUMBER_STYLE: {
			if (!isNumeric(propertyType)) {
				return createBadRenderer();
			}
			CxGridPropNumberStyle style = (CxGridPropNumberStyle) prop
					.getStyle();
			CxGridNumberRenderer renderer = factory
					.createCxGridNumberRenderer();
			renderer.setNumberFormat(style.getNumberFormat());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_BUTTON_STYLE: {
			CxGridPropButtonStyle style = (CxGridPropButtonStyle) prop
					.getStyle();
			CxGridButtonRenderer renderer = factory
					.createCxGridButtonRenderer();
			renderer.setEventTopic(style.getEventTopic());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_IMAGE_STYLE: {
			CxGridPropImageStyle style = (CxGridPropImageStyle) prop.getStyle();
			YConverter converter = toConverter(style.getConfigs());
			CxGridImageRenderer renderer = factory.createCxGridImageRenderer();
			renderer.setEventTopic(style.getEventTopic());
			pair.renderer = renderer;
			pair.converter = converter;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_HTML_STYLE:
			pair.renderer = factory.createCxGridHtmlRenderer();
			break;
		case CxGridStylePackage.CX_GRID_PROP_PROGRESSBAR_STYLE: {
			CxGridPropProgressbarStyle style = (CxGridPropProgressbarStyle) prop
					.getStyle();
			CxGridProgressBarRenderer renderer = factory
					.createCxGridProgressBarRenderer();
			renderer.setMaxValue(style.getMaxValue());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_INDICATOR_STYLE: {
			CxGridPropIndicatorStyle style = (CxGridPropIndicatorStyle) prop
					.getStyle();
			CxGridIndicatorRenderer renderer = factory
					.createCxGridIndicatorRenderer();
			renderer.setGreenStarts(style.getGreenStarts());
			renderer.setRedEnds(style.getRedEnds());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_SPARKLINE_STYLE:
			pair.renderer = factory.createCxGridHtmlRenderer();
			break;
		case CxGridStylePackage.CX_GRID_PROP_TEXT_STYLE:
			pair.renderer = factory.createCxGridHtmlRenderer();
			break;
		case CxGridStylePackage.CX_GRID_PROP_QUANTITY_STYLE: {
			CxGridPropQuantityStyle style = (CxGridPropQuantityStyle) prop
					.getStyle();
			CxGridQuantityRenderer renderer = factory
					.createCxGridQuantityRenderer();
			renderer.setHtmlPattern(style.getHtmlPattern());
			renderer.setNullRepresentation("");
			renderer.setNumberFormat(style.getValueNumberFormat());
			renderer.setUomPropertyPath(style.getUomPropertyDotPath());
			renderer.setValuePropertyPath(style.getValuePropertyDotPath());
			pair.renderer = renderer;
		}
			break;
		case CxGridStylePackage.CX_GRID_PROP_PRICE_STYLE: {
			CxGridPropPriceStyle style = (CxGridPropPriceStyle) prop.getStyle();
			CxGridPriceRenderer renderer = factory.createCxGridPriceRenderer();
			renderer.setHtmlPattern(style.getHtmlPattern());
			renderer.setNullRepresentation("");
			renderer.setNumberFormat(style.getValueNumberFormat());
			renderer.setCurrencyPropertyPath(style.getCurrencyPropertyDotPath());
			renderer.setValuePropertyPath(style.getValuePropertyDotPath());
			pair.renderer = renderer;
		}
			break;
		}

		return pair;
	}

	protected boolean isNumeric(Class<?> propertyType) {
		boolean result = propertyType.isAssignableFrom(Number.class);
		if (!result) {
			if (propertyType.isPrimitive() && propertyType != Boolean.TYPE
					&& propertyType != Void.TYPE) {
				result = true;
			}
		}
		return result;
	}

	protected YConverter toConverter(EList<CxGridStyleConfig> configs) {
		if (configs.isEmpty()) {
			return null;
		}

		CxGridStyleConfig cxConfig = configs.get(0);
		if (cxConfig instanceof CxGridStyleConfigStringToResource) {
			List<YStringToResourceConfig> newConfigs = toStringToResourceConfig(configs);
			YStringToResourceConverter converter = YConverterFactory.eINSTANCE
					.createYStringToResourceConverter();
			converter.getConfigs().addAll(newConfigs);
			return converter;
		} else if (cxConfig instanceof CxGridStyleConfigNumericToResource) {
			List<YNumericToResourceConfig> newConfigs = toNumberToResourceConfig(configs);
			YNumericToResourceConverter converter = YConverterFactory.eINSTANCE
					.createYNumericToResourceConverter();
			converter.getConfigs().addAll(newConfigs);
			return converter;
		}

		return null;
	}

	private List<YNumericToResourceConfig> toNumberToResourceConfig(
			EList<CxGridStyleConfig> configs) {
		List<YNumericToResourceConfig> result = new ArrayList<>(configs.size());
		for (CxGridStyleConfig config : configs) {
			if (!(config instanceof CxGridStyleConfigNumericToResource)) {
				LOGGER.warn("you mixed up different style configs!");
				continue;
			}

			CxGridStyleConfigNumericToResource givenConfig = (CxGridStyleConfigNumericToResource) config;
			YNumericToResourceConfig newConfig = YConverterFactory.eINSTANCE
					.createYNumericToResourceConfig();
			newConfig.setResourceThemePath(givenConfig.getResourceThemePath());
			newConfig.setValue(givenConfig.getValue());
			newConfig.setCompare(toGridCompare(givenConfig.getCompare()));
			result.add(newConfig);
		}

		return result;
	}

	private YCompare toGridCompare(CxGridCompare compare) {
		switch (compare) {
		case EQUAL:
			return YCompare.EQUAL;
		case GREATER_EQUAL:
			return YCompare.GREATER_EQUAL;
		case GREATER_THAN:
			return YCompare.GREATER_THAN;
		case LOWER_EQUAL:
			return YCompare.LOWER_EQUAL;
		case LOWER_THAN:
			return YCompare.LOWER_THAN;
		case NOT_EQUAL:
			return YCompare.NOT_EQUAL;
		}
		return null;
	}

	private List<YStringToResourceConfig> toStringToResourceConfig(
			EList<CxGridStyleConfig> configs) {
		List<YStringToResourceConfig> result = new ArrayList<>(configs.size());
		for (CxGridStyleConfig config : configs) {
			if (!(config instanceof CxGridStyleConfigStringToResource)) {
				LOGGER.warn("you mixed up different style configs!");
				continue;
			}

			CxGridStyleConfigStringToResource givenConfig = (CxGridStyleConfigStringToResource) config;
			YStringToResourceConfig newConfig = YConverterFactory.eINSTANCE
					.createYStringToResourceConfig();
			newConfig.setResourceThemePath(givenConfig.getResourceThemePath());
			newConfig.setValue(givenConfig.getValue());
			newConfig.setCompare(toGridCompare(givenConfig.getCompare()));
			result.add(newConfig);
		}

		return result;
	}

	protected Pair createBadRenderer() {
		Pair pair = new Pair();
		pair.renderer = CxGridRendererFactory.eINSTANCE
				.createCxGridTextRenderer();
		return pair;
	}

	protected static class Pair {
		public CxGridRenderer renderer;
		public YConverter converter;
	}
}
