/**
 *                                                                            
 * 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.dsl.dto.lib.services.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 EventHandler inputEventHandler;
	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);

		inputEventHandler = new EventHandler() {
			@Override
			public void handleEvent(Event event) {
				Object data = event.getProperty(IEventBroker.DATA);
				if (data instanceof EventBrokerMsg) {
					EventBrokerMsg msg = (EventBrokerMsg) data;
					String dtoClassFqn = getDtoName(msg.getName());
					if (dtoClassFqn.isEmpty()) {
						return;
					} else {

						Class<?> dtoClass = bundleSpaceTypeProvider.forName(
								null, dtoClassFqn);
						setInput(dtoClass, msg.getId());
					}
				} else if (data instanceof IDto) {
					String id = event.getTopic().split("/")[0];
					setInput(data.getClass(), id);
				}
			}
		};
		e4EventBroker.subscribe(EventBrokerMsg.AUTOWIRED_ENTITY_PREFIX + "*",
				inputEventHandler);
	}

	/**
	 * 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() {

		eventBroker.unsubscribe(inputEventHandler);
		inputEventHandler = null;

		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;
		}

	}

}
