/*******************************************************************************
 * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
 *
 * 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:
 * Lucas Koehler- initial API and implementation
 ******************************************************************************/
package org.eclipse.emfforms.internal.core.services.controlmapper;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecp.common.spi.UniqueSetting;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener;
import org.eclipse.emf.ecp.view.spi.model.ModelChangeNotification;
import org.eclipse.emf.ecp.view.spi.model.VControl;
import org.eclipse.emf.ecp.view.spi.model.VDomainModelReference;
import org.eclipse.emf.ecp.view.spi.model.VElement;
import org.eclipse.emfforms.spi.core.services.controlmapper.EMFFormsSettingToControlMapper;
import org.eclipse.emfforms.spi.core.services.mappingprovider.EMFFormsMappingProviderManager;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener;
import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;

/**
 * Implementation of {@link EMFFormsSettingToControlMapper}.
 *
 * @author Lucas Koehler
 *
 */
public class SettingToControlMapperImpl implements EMFFormsSettingToControlMapper, EMFFormsContextListener {
	/**
	 * Used to get View model changes.
	 *
	 * @author Eugen Neufeld
	 *
	 */
	private final class ModelChangeAddRemoveListenerImplementation implements ModelChangeAddRemoveListener {
		@Override
		public void notifyChange(ModelChangeNotification notification) {
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener#notifyAdd(org.eclipse.emf.common.notify.Notifier)
		 */
		@Override
		public void notifyAdd(Notifier notifier) {
			if (VDomainModelReference.class.isInstance(notifier)
				&& !VDomainModelReference.class.isInstance(EObject.class.cast(notifier).eContainer())) {
				final VDomainModelReference domainModelReference = VDomainModelReference.class.cast(notifier);

				// FIXME remove
				SettingToControlExpandHelper.resolveDomainReferences(domainModelReference,
					viewModelContext.getDomainModel(),
					viewModelContext);

				final VControl control = findControl(domainModelReference);
				if (control != null) {
					vControlAdded(control);
				}
			}
		}

		private VControl findControl(VDomainModelReference dmr) {
			EObject parent = dmr.eContainer();
			while (!VControl.class.isInstance(parent) && parent != null) {
				parent = parent.eContainer();
			}
			return (VControl) parent;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.emf.ecp.view.spi.model.ModelChangeAddRemoveListener#notifyRemove(org.eclipse.emf.common.notify.Notifier)
		 */
		@Override
		public void notifyRemove(Notifier notifier) {
			if (VControl.class.isInstance(notifier)) {
				vControlRemoved((VControl) notifier);
			}
		}
	}

	private final EMFFormsViewContext viewModelContext;
	private final ViewModelListener viewModelListener;

	private final Map<EObject, Set<UniqueSetting>> eObjectToMappedSettings = new LinkedHashMap<EObject, Set<UniqueSetting>>();

	/**
	 * A mapping between settings and controls.
	 */
	private final Map<UniqueSetting, Set<VControl>> settingToControlMap = new LinkedHashMap<UniqueSetting, Set<VControl>>();
	private final EMFFormsMappingProviderManager mappingManager;
	private final Map<VElement, Set<EMFFormsSettingToControlMapper>> childMappers = new LinkedHashMap<VElement, Set<EMFFormsSettingToControlMapper>>();

	/**
	 * Creates a new instance of {@link SettingToControlMapperImpl}.
	 *
	 * @param mappingManager The {@link EMFFormsMappingProviderManager}
	 * @param viewModelContext The {@link EMFFormsViewContext} that created this instance
	 */
	public SettingToControlMapperImpl(EMFFormsMappingProviderManager mappingManager,
		EMFFormsViewContext viewModelContext) {
		this.mappingManager = mappingManager;
		this.viewModelContext = viewModelContext;
		viewModelContext.registerEMFFormsContextListener(this);
		viewModelContext.registerViewChangeListener(new ModelChangeAddRemoveListenerImplementation());
		viewModelListener = new ViewModelListener(viewModelContext, this);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Set<VControl> getControlsFor(Setting setting) {
		return settingToControlMap.get(UniqueSetting.createSetting(setting));
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Set<VElement> getControlsFor(UniqueSetting setting) {
		final Set<VElement> elements = new LinkedHashSet<VElement>();
		final Set<VControl> currentControls = settingToControlMap.get(setting);
		if (currentControls != null) {
			for (final VElement control : currentControls) {
				if (!control.isEffectivelyEnabled() || !control.isEffectivelyVisible()
					|| control.isEffectivelyReadonly()) {
					continue;
				}
				elements.add(control);
			}
		}
		for (final VElement parentElement : childMappers.keySet()) {
			for (final EMFFormsSettingToControlMapper childMapper : childMappers.get(parentElement)) {
				final Set<VElement> controlsFor = childMapper.getControlsFor(setting);
				elements.addAll(controlsFor);
				if (!controlsFor.isEmpty()) {
					elements.add(parentElement);
				}
			}
		}
		return elements;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void updateControlMapping(VControl vControl) {
		if (vControl == null) {
			return;
		}
		// delete old mapping
		final Set<UniqueSetting> keysWithEmptySets = new LinkedHashSet<UniqueSetting>();
		for (final UniqueSetting setting : settingToControlMap.keySet()) {
			final Set<VControl> controlSet = settingToControlMap.get(setting);
			controlSet.remove(vControl);
			if (controlSet.isEmpty()) {
				keysWithEmptySets.add(setting);
			}
		}
		for (final UniqueSetting setting : keysWithEmptySets) {
			settingToControlMap.remove(setting);
			handleRemoveForEObjectMapping(setting);
		}
		// update mapping
		final Set<UniqueSetting> map = mappingManager.getAllSettingsFor(vControl.getDomainModelReference(),
			viewModelContext.getDomainModel());
		for (final UniqueSetting setting : map) {
			if (!settingToControlMap.containsKey(setting)) {
				settingToControlMap.put(setting, new LinkedHashSet<VControl>());
				handleAddForEObjectMapping(setting);
			}
			settingToControlMap.get(setting).add(vControl);
		}
	}

	private void handleAddForEObjectMapping(UniqueSetting setting) {
		if (!eObjectToMappedSettings.containsKey(setting.getEObject())) {
			eObjectToMappedSettings.put(setting.getEObject(), new LinkedHashSet<UniqueSetting>());
		}
		eObjectToMappedSettings.get(setting.getEObject()).add(setting);
	}

	private void handleRemoveForEObjectMapping(UniqueSetting setting) {
		final Set<UniqueSetting> settings = eObjectToMappedSettings.get(setting.getEObject());
		settings.remove(setting);
		if (settings.isEmpty()) {
			eObjectToMappedSettings.remove(setting.getEObject());
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void vControlRemoved(VControl vControl) {
		if (vControl.getDomainModelReference() == null) {
			return;
		}

		final Set<UniqueSetting> map = mappingManager.getAllSettingsFor(vControl.getDomainModelReference(),
			viewModelContext.getDomainModel());
		for (final UniqueSetting setting : map) {
			if (settingToControlMap.containsKey(setting)) {
				settingToControlMap.get(setting).remove(vControl);
				if (settingToControlMap.get(setting).size() == 0) {
					settingToControlMap.remove(setting);
					handleRemoveForEObjectMapping(setting);
				}
			}
		}

		viewModelListener.removeVControl(vControl);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void vControlAdded(VControl vControl) {
		if (vControl.getDomainModelReference() == null) {
			return;
		}

		checkAndUpdateSettingToControlMapping(vControl);

		viewModelListener.addVControl(vControl);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void checkAndUpdateSettingToControlMapping(EObject eObject) {
		if (VControl.class.isInstance(eObject)) {
			final VControl vControl = (VControl) eObject;
			if (vControl.getDomainModelReference() == null) {
				return;
			}

			updateControlMapping(vControl);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextAdded(org.eclipse.emf.ecp.view.spi.model.VElement,
	 *      org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
	 */
	@Override
	public void childContextAdded(VElement parentElement, EMFFormsViewContext childContext) {
		final EMFFormsSettingToControlMapper childSettingToControlMapper = childContext
			.getService(EMFFormsSettingToControlMapper.class);
		if (!childMappers.containsKey(parentElement)) {
			childMappers.put(parentElement, new LinkedHashSet<EMFFormsSettingToControlMapper>());
		}
		childMappers.get(parentElement).add(childSettingToControlMapper);

	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#childContextDisposed(org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext)
	 */
	@Override
	public void childContextDisposed(EMFFormsViewContext childContext) {
		final EMFFormsSettingToControlMapper childSettingToControlMapper = childContext
			.getService(EMFFormsSettingToControlMapper.class);
		for (final VElement vElement : childMappers.keySet()) {
			childMappers.get(vElement).remove(childSettingToControlMapper);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextInitialised()
	 */
	@Override
	public void contextInitialised() {
		// do nothing
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.emfforms.spi.core.services.view.EMFFormsContextListener#contextDispose()
	 */
	@Override
	public void contextDispose() {
		viewModelContext.unregisterEMFFormsContextListener(this);
		viewModelListener.dispose();
		settingToControlMap.clear();
		childMappers.clear();
	}

	@Override
	public boolean hasControlsFor(EObject eObject) {
		if (eObjectToMappedSettings.containsKey(eObject)) {
			return true;
		}

		for (final VElement parentElement : childMappers.keySet()) {
			for (final EMFFormsSettingToControlMapper childMapper : childMappers.get(parentElement)) {
				if (childMapper.hasControlsFor(eObject)) {
					return true;
				}
			}
		}

		return false;
	}

	@Override
	public Collection<EObject> getEObjectsWithSettings() {
		final Set<EObject> result = new LinkedHashSet<EObject>();
		result.addAll(eObjectToMappedSettings.keySet());
		for (final VElement parentElement : childMappers.keySet()) {
			for (final EMFFormsSettingToControlMapper childMapper : childMappers.get(parentElement)) {
				result.addAll(childMapper.getEObjectsWithSettings());
			}
		}
		return result;
	}
}
