/*******************************************************************************
 * Copyright (c) 2013 CEA LIST.
 * 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:
 *     Cedric Dumoulin - cedric.dumoulin@lifl.fr
 ******************************************************************************/
package org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime;

import static org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime.Activator.log;

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

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack;
import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication;
import org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime.model.ILayersModelRootEventListener;
import org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime.model.LayersModelEventRootNotifier;
import org.eclipse.papyrus.internal.infra.gmfdiag.layers.runtime.model.LayersModelResource;


/**
 *
 * Listen to:
 * - LayerStack added
 * - application added/removed in LayerModel
 *
 * <br>
 * The class has an internal state machine with two states: ApplicationExist and NoApplication. <br>
 * In the ApplicationExist state, the class listen to {@link LayersStack} added/removed and to the Diagrams deletion. <br>
 * In the NoApplication state, the class listen on the LayerModel to be informed when the application is created.
 * When application is created, we change the state to ApplicationExist.
 *
 * There is an UML sm diagram of this in architecture.di.
 *
 *
 *
 * @author cedric dumoulin
 *
 */
public class LayerStackApplicationSynchronizer implements ILayersModelRootEventListener, ILayersStackApplicationEventListener, INotationDiagramRemovedEventListener {

	/**
	 * States used in the state machine.
	 */
	protected enum State {
		NoApplication, ApplicationCreated, disposed
	};

	protected State state;

	protected LayersModelResource layersModel;
	protected NotationModel notationModel;

	/**
	 * All registered synchronizers.
	 */
	protected Map<Diagram, LayerStackSynchronizer> synchronizers = new HashMap<Diagram, LayerStackSynchronizer>();

	/**
	 * Notifier on Diagram removed event.
	 */
	protected NotationDiagramRemovedFromResourceEventNotifier notationDiagramRemovedNotifier;

	/**
	 * Notifier on LayerSTackApplication events
	 */
	protected LayersStackApplicationEventNotifier layersStackApplicationEventNotifier;

	/**
	 * Notifier on {@link LayersModelResource} events.
	 */
	protected LayersModelEventRootNotifier layersModelEventRootNotifier;

	/**
	 * Constructor.
	 *
	 */
	public LayerStackApplicationSynchronizer(LayersModelResource layersModel, NotationModel notationModel) {

		this.layersModel = layersModel;
		this.notationModel = notationModel;

		initState();
	}

	/**
	 * Init the state of the object
	 */
	private void initState() {

		if (layersModel.lookupLayerStackApplication() != null) {
			transitionInitToApplicationCreatedState();
		} else {
			transitionInitToNoApplicationState();
		}
	}

	/**
	 * Initialize the class for the NoApplication state:
	 * - listen on LayersModel notifiers for application creation
	 */
	private void transitionInitToApplicationCreatedState() {
		activateLayersModelAndDiagramDeletionNotifiers();
		activateLayersModelRootNotifier();
		createSynchronizerForExistingStacks();
		state = State.ApplicationCreated;
	}

	/**
	 * Initialize the class for the NoApplication state:
	 * - listen on LayersModel notifiers for application creation
	 */
	private void transitionNoApplicationToApplicationCreatedState() {
		activateLayersModelAndDiagramDeletionNotifiers();
		activateLayersModelRootNotifier();
		state = State.ApplicationCreated;
	}

	/**
	 * Initialize the class for the ApplicationCreated state:
	 * - listen on appropriate notifiers
	 * - check if some LayerStack are already there.
	 */
	private void transitionInitToNoApplicationState() {
		activateLayersModelRootNotifier();
		state = State.NoApplication;
	}

	/**
	 * Initialize the class for the ApplicationCreated state:
	 * - listen on appropriate notifiers
	 * - check if some LayerStack are already there.
	 */
	private void transitionApplicationCreatedToNoApplicationState() {
		deactivateLayersModelAndDiagramDeletionNotifiers();
		state = State.NoApplication;
	}

	/**
	 * Create synchronizer for already created stack.
	 * The application object must exist.
	 */
	private void createSynchronizerForExistingStacks() {

		LayersStackApplication application = layersModel.lookupLayerStackApplication();
		if (application == null) {
			// Application is not set, skip.
			return;
		}

		for (LayersStack stack : application.getLayersStacks()) {
			if (stack.getDiagram() != null) {
				addLayerStackSynchronizer(stack);
			}
		}

	}



	/**
	 * @return the synchronizers
	 */
	public Map<Diagram, LayerStackSynchronizer> getSynchronizers() {
		return synchronizers;
	}


	/**
	 * @return the layersModel
	 */
	public LayersModelResource getLayersModel() {
		return layersModel;
	}


	/**
	 * @return the notationModel
	 */
	public NotationModel getNotationModel() {
		return notationModel;
	}

	/**
	 * Activate the listeners.
	 *
	 */
	protected void activate() {
		initState();
	}

	/**
	 * Activate the listeners.
	 *
	 */
	private void activateLayersModelRootNotifier() {
		/**
		 * Listen on layersModel to be inform when the application object is created.
		 * When it is created, we can listen on it.
		 */

		layersModelEventRootNotifier = new LayersModelEventRootNotifier(layersModel);
		layersModelEventRootNotifier.addEventListener(this);
	}


	/**
	 * Activate the listeners.
	 *
	 */
	private void deactivateLayersModelRootNotifier() {
		/**
		 * Listen on layersModel to be inform when the application object is created.
		 * When it is created, we can listen on it.
		 */
		if (layersModelEventRootNotifier != null) {
			layersModelEventRootNotifier.removeEventListener(this);
			layersModelEventRootNotifier = null;
		}
	}

	/**
	 * Deactivate the listeners.
	 *
	 */
	private void activateLayersModelAndDiagramDeletionNotifiers() {
		/**
		 * Listen on layersModel to be inform when the application object is created.
		 * When it is created, we can listen on it.
		 */
		notationDiagramRemovedNotifier = new NotationDiagramRemovedFromResourceEventNotifier(notationModel);
		notationDiagramRemovedNotifier.addLayersModelEventListener(this);

		layersStackApplicationEventNotifier = new LayersStackApplicationEventNotifier(layersModel);
		layersStackApplicationEventNotifier.addLayersModelEventListener(this);
	}

	/**
	 * Deactivate listeners
	 */
	protected void deactivateLayersModelAndDiagramDeletionNotifiers() {
		if (notationDiagramRemovedNotifier != null) {
			notationDiagramRemovedNotifier.removeLayersModelEventListener(this);
			notationDiagramRemovedNotifier = null;
		}

		if (layersStackApplicationEventNotifier != null) {
			layersStackApplicationEventNotifier.removeLayersModelEventListener(this);
			layersStackApplicationEventNotifier = null;
		}
	}

	/**
	 * Deactivate listeners
	 */
	protected void deactivate() {
		deactivateLayersModelAndDiagramDeletionNotifiers();
		deactivateLayersModelRootNotifier();
	}

	/**
	 * Dispose the synchronizer
	 */
	public void dispose() {
		// Deactivate listeners
		deactivate();
		layersModel = null;
		notationModel = null;
		state = State.disposed;
	}

	/**
	 * Return true if the object is disposed.
	 *
	 * @return
	 */
	public boolean isDisposed() {
		return state == State.disposed;
	}

	/**
	 * Called by events when a {@link LayersStack} is added to the {@link LayersStackApplication}
	 *
	 * @param msg
	 */
	@Override
	public void layerStackAdded(Notification msg) {

		if (log.isDebugEnabled()) {
			log.debug("LayerStackApplicationSynchronizer.layerStackAdded : " + msg.getNewValue());
		}

		// Find the LayerStack
		LayersStack stack = LayersStackApplicationEventNotifier.getAddedLayerStack(msg);

		addLayerStackSynchronizer(stack);
	}


	/**
	 * Create and add a {@link LayerStackSynchronizer} for the stack.
	 * Do nothing if the stack has already a synchronizer.
	 *
	 * @param stack
	 */
	private void addLayerStackSynchronizer(LayersStack stack) {
		// Check if already exist
		if (lookupLayersStackSynchronizer(stack.getDiagram()) != null) {
			return;
		}

		// Create a new synchronizer
		LayerStackSynchronizer layerStackSynchronizer = new LayerStackSynchronizer(stack);
		putLayersStackSynchronizer(layerStackSynchronizer);
	}

	/**
	 * Lookup a {@link LayerStackSynchronizer} by its diagram.
	 *
	 * @param diagram
	 * @return
	 */
	protected LayerStackSynchronizer lookupLayersStackSynchronizer(Diagram diagram) {
		return synchronizers.get(diagram);
	}

	/**
	 * Lookup a {@link LayerStackSynchronizer} by its diagram.
	 *
	 * @param diagram
	 * @return
	 */
	protected void putLayersStackSynchronizer(LayerStackSynchronizer layerStackSynchronizer) {

		synchronizers.put(layerStackSynchronizer.getDiagram(), layerStackSynchronizer);
	}


	/**
	 * Called by events when a {@link LayersStack} is removed from the {@link LayersStackApplication}
	 *
	 * @param msg
	 */
	@Override
	public void layerStackRemoved(Notification msg) {
		if (log.isDebugEnabled()) {
			log.debug("LayerStack is removed" + msg.getOldValue());
		}

		// Find the LayerStack
		LayersStack stack = LayersStackApplicationEventNotifier.getRemovedLayerStack(msg);

		LayerStackSynchronizer synchronizer = synchronizers.remove(stack.getDiagram());
		synchronizer.dispose();

		// Also remove from application

	}

	/**
	 * Called by events when a {@link Diagram} is removed from the {@link NotationModel}
	 *
	 * @param msg
	 */
	@Override
	public void diagramRemoved(Notification msg) {

		if (log.isDebugEnabled()) {
			log.debug(this.getClass().getSimpleName() + ".diagramRemoved() - " + msg.getOldValue());
		}

		if (state != State.ApplicationCreated) {
			return;
		}

		// Find the diagram
		Diagram diagram = NotationDiagramRemovedFromResourceEventNotifier.getRemovedDiagram(msg);

		// Remove from application
		// This should in turn remove the LayerStackSynchronizer from
		// this class (LayerStackApplicationSynchronizer).
		getLayersModel().lookupLayerStackApplication().removeLayersStackFor(diagram);

		// check if really removed from this object
		LayerStackSynchronizer synchronizer = synchronizers.remove(diagram);
		if (synchronizer != null) {
			// Should not happen
			log.info(this.getClass().getSimpleName() + ".diagramRemoved() - synchronizer not completly cleaned. Finish the job.");
			synchronizer.dispose();
		}
	}


	@Override
	public void layersModelRootAdded(Notification msg) {
		if (state == State.NoApplication) {
			transitionNoApplicationToApplicationCreatedState();
		}

	}


	@Override
	public void layersModelRootRemoved(Notification msg) {
		if (state == State.ApplicationCreated) {
			transitionApplicationCreatedToNoApplicationState();
		}
	}
}
