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

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.eclipse.e4.core.contexts.Active;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.impl.DtoServiceAccess;
import org.eclipse.osbp.runtime.common.filter.IDTOService;
import org.eclipse.osbp.runtime.common.types.ITypeProviderService;
import org.eclipse.osbp.infogrid.api.IGridSourceDescriptor;
import org.eclipse.osbp.infogrid.api.IGridSourceFacade;
import org.eclipse.osbp.infogrid.model.gridsource.CxGridSource;
import org.eclipse.osbp.infogrid.vaadin.GridComponent;
import org.eclipse.osbp.vaaclipse.common.ecview.api.IECViewSessionHelper;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.VerticalLayout;

import org.eclipse.osbp.eventbroker.EventBrokerMsg;

public class InfoGridView {

	@Inject
	private IEventBroker eventBroker;
	@Inject
	IEclipseContext context;
	@Inject
	private VerticalLayout parentLayout;
	@Inject
	private org.eclipse.e4.core.services.events.IEventBroker e4EventBroker;
	@Inject
	private IGridSourceFacade gridSourceService;
	@Inject
	private IECViewSessionHelper ecviewPropsProvider;
	@Inject
	private EModelService modelService;
	@Inject
	private ITypeProviderService bundleSpaceTypeProvider;

	private ContentCache cache;

	protected CssLayout layout;
	protected MPart activeMPart;
	protected String activeContentID;
	protected Component activeContent;
	private Class<?> inputClass;
	private GridComponent currentComponent;

	// snapshots of perspectives state to reset
	private Map<MPerspective, StateSnapshot> stateSnapshots = new HashMap<MPerspective, InfoGridView.StateSnapshot>();

	@PostConstruct
	protected void setup() {
		cache = new ContentCache();

		layout = new CssLayout();
		layout.setSizeFull();
		parentLayout.setMargin(true);
		parentLayout.setSpacing(true);
		parentLayout.addComponent(layout);
	}

	/**
	 * Converts the entity name to the dto name.
	 * 
	 * @param entityName
	 * @return TODO NamingConventions replace me later!
	 */
	private String getDtoName(String entityName) {
		String dtoName = null;
		if (entityName == null) {
			return "";
		}
		if (entityName.contains("entities")) {
			dtoName = entityName.replace("entities", "dtos");
		} else {
			dtoName = entityName + ".dtos";
		}

		dtoName = dtoName.concat("Dto");

		return dtoName;
	}

	/**
	 * Perspective was switches. Return to last state of perspective.
	 * 
	 * @param perspective
	 */
	@Inject
	protected void activatePerspective(
			@Optional @Active MPerspective perspective) {
		restoreForSnapshot(perspective);
	}

	/**
	 * Sets the new input value.
	 * 
	 * @param dtoClass
	 * @param id
	 */
	private void setInput(Class<?> dtoClass, Object id) {
		Class<?> oldInputClass = this.inputClass;
		inputClass = dtoClass;

		if (oldInputClass != inputClass) {

			// reset layout
			layout.removeAllComponents();
			currentComponent = null;

			if (inputClass != null) {
				currentComponent = getGridComponent(inputClass);
				if (currentComponent != null) {
					layout.addComponent(currentComponent);
				}
			}
		}

		if (currentComponent != null) {
			Object dtoInstance = getDTO(dtoClass, (String) id);
			currentComponent.setValue(dtoInstance);

			// create a snapshot for later use on perspective switch
			MPerspective activePerspective = findActivePerspective();
			// update snapshot info for restore on perspective switch
			updateSnapshot(dtoClass, id, activePerspective, currentComponent);
		} else {
			MPerspective activePerspective = findActivePerspective();
			resetSnapshot(activePerspective);
		}
	}

	/**
	 * Returns the dto for the given class and id.
	 * 
	 * @param dtoClass
	 * @param id
	 * @return
	 */
	@SuppressWarnings("restriction")
	private Object getDTO(Class<?> dtoClass, String id) {
		IDTOService<?> dtoService = DtoServiceAccess.getService(dtoClass);
		Object dtoInstance = null;
		if (id != null) {
			try {
				dtoInstance = dtoService.get((int) Double.parseDouble(id));
			} catch (NumberFormatException e) {
				dtoInstance = dtoService.get(id);
			}
		}
		// Object dtoInstance = id != null ? dtoService.get(id) : null;
		return dtoInstance;
	}

	private MPerspective findActivePerspective() {
		// EObject part = (EObject) partService.getActivePart();
		// if (part == null) {
		// return null;
		// }
		// EObject current = part;
		// while (current.eContainer() != null) {
		// current = current.eContainer();
		// if (current instanceof MPerspective) {
		// return (MPerspective) current;
		// }
		// }
		return modelService.getActivePerspective(context.get(MWindow.class));
	}

	/**
	 * Updates the snapshot info.
	 * 
	 * @param dtoClass
	 * @param id
	 * @param activePerspective
	 * @param currentComponent
	 */
	private void updateSnapshot(Class<?> dtoClass, Object id,
			MPerspective activePerspective, GridComponent currentComponent) {
		// update the snapshot
		stateSnapshots.put(activePerspective, new StateSnapshot(
				activePerspective, dtoClass, id, currentComponent));
	}

	/**
	 * Restores UI for the given activePerspective.
	 * 
	 * @param activePerspective
	 */
	private void restoreForSnapshot(MPerspective activePerspective) {
		StateSnapshot snapshot = stateSnapshots.get(activePerspective);
		if (snapshot != null) {

			inputClass = snapshot.dtoClass;
			currentComponent = snapshot.component;
			layout.removeAllComponents();
			layout.addComponent(currentComponent);
			currentComponent.setValue(getDTO(snapshot.dtoClass,
					(String) snapshot.id));
			setInput(snapshot.dtoClass, snapshot.id);

		} else {
			if (layout != null) {
				layout.removeAllComponents();
			}
			inputClass = null;
			currentComponent = null;
		}
	}

	/**
	 * Removes the snapshot information.
	 * 
	 * @param activePerspective
	 */
	private void resetSnapshot(MPerspective activePerspective) {
		stateSnapshots.remove(activePerspective);
	}

	/**
	 * Returns the grid component for the given inputclass.
	 * 
	 * @param inputClass
	 * @return
	 */
	protected GridComponent getGridComponent(Class<?> inputClass) {
		if (inputClass == null) {
			return null;
		}

		GridComponent component;
		if (cache.containsContent(inputClass)) {
			component = cache.getActiveContent(inputClass);
		} else {
			component = createComponent(inputClass);
		}
		return component;
	}

	private GridComponent createComponent(Class<?> inputClass) {
		// create the component and register it at the cache
		//
		GridComponent component = new GridComponent();
		component.setSizeFull();
		cache.putActiveContent(inputClass, component);

		// set the descriptors to the component
		//
		List<IGridSourceDescriptor> descriptors = createGridSourceDescriptors(inputClass);
		component.setSourceDescriptors(descriptors);

		return component;
	}

	/**
	 * Uses the IGridSourceService to create the descriptors that should be used
	 * for the input class.
	 * 
	 * @param inputClass
	 * @return
	 */
	protected List<IGridSourceDescriptor> createGridSourceDescriptors(
			Class<?> inputClass) {
		List<IGridSourceDescriptor> descriptors = gridSourceService
				.getDescriptors(inputClass,
						new IGridSourceDescriptor.ConfigCallback() {
							@Override
							public Map<String, Object> getProperties(
									IGridSourceDescriptor descriptor) {
								CxGridSource cxSource = descriptor.getSource();
								if (cxSource.getKind().equals(
										IGridSourceDescriptor.KIND_ECVIEW)) {
									return createECViewProperties(descriptor);
								}
								return null;
							}
						});
		return descriptors;
	}

	/**
	 * Creates the ecview properties to properly config the descriptor.
	 * 
	 * @param descriptor
	 * @return
	 */
	protected Map<String, Object> createECViewProperties(
			IGridSourceDescriptor descriptor) {
		return ecviewPropsProvider.createBasicProperties();
	}

	@PreDestroy
	protected void destroy() {
		stateSnapshots.clear();
		stateSnapshots = null;

		if (cache != null) {
			cache.dispose();
			cache = null;
		}

	}

	protected BundleContext getBundleContext() {
		return FrameworkUtil.getBundle(getClass()).getBundleContext();
	}

	private static class StateSnapshot {
		private final MPerspective perspective;
		private final Class<?> dtoClass;
		private final Object id;
		private final GridComponent component;

		public StateSnapshot(MPerspective perspective, Class<?> dtoClass,
				Object id, GridComponent component) {
			super();
			this.perspective = perspective;
			this.dtoClass = dtoClass;
			this.id = id;
			this.component = component;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result
					+ ((perspective == null) ? 0 : perspective.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;
			StateSnapshot other = (StateSnapshot) obj;
			if (perspective == null) {
				if (other.perspective != null)
					return false;
			} else if (!perspective.equals(other.perspective))
				return false;
			return true;
		}

	}

}
