package org.eclipse.osbp.runtime.common.event;

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

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;

public class SelectionStore {
	private Map<String, Object> selections = new HashMap<>();
	
	public void setSelection(String fqn, Object id) {
		if(id != null) {
			selections.put(fqn, id);
		} else {
			selections.remove(fqn);
		}
	}
	
	public Object getSelection(String fqn) {
		if(selections.containsKey(fqn)) {
			return selections.get(fqn);
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	private void addSelection(String fqn, Object id) {
		if(!selections.containsKey(fqn) || !(selections.get(fqn) instanceof List<?>)) {
			selections.put(fqn, new ArrayList<Object>());
		}
		((List<Object>)selections.get(fqn)).add(id);
	}
	
	@SuppressWarnings("unchecked")
	private void removeSelection(String fqn, Object id) {
		if(selections.containsKey(fqn) && selections.get(fqn) instanceof List<?>) {
			((List<Object>)selections.get(fqn)).remove(id);
			if(((List<Object>)selections.get(fqn)).isEmpty()) {
				selections.remove(fqn);
			}
		}
	}

	private static IEclipseContext getContext(MPart part) {
		MUIElement element = part;
		while(element != null && !(element instanceof MPerspective)) {
			element = element.getParent();
		}
		if(element != null) {
			return ((MPerspective)element).getContext(); 
		}
		return null;
	}
	
	/**
	 * Adds a selection to perspective context.
	 *
	 * @param part the part
	 * @param fqn the fqn
	 * @param id the id
	 * @return true, if successful
	 */
	public static boolean addSelectionToPerspectiveContext(MPart part, String fqn, Object id) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).addSelection(fqn, id);
			return true;
		}
		return false;
	}
	
	/**
	 * Removes a selection from perspective context.
	 *
	 * @param part the part
	 * @param fqn the fqn
	 * @param id the id
	 * @return true, if successful
	 */
	public static boolean removeSelectionFromPerspectiveContext(MPart part, String fqn, Object id) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).removeSelection(fqn, id);
			return true;
		}
		return false;
	}

	/**
	 * Store a selection by id to perspective context.
	 *
	 * @param key the fully qualified name of the id field
	 * @param value the id object
	 * @return true, if successful
	 */
	public static boolean putSelectionToPerspectiveContext(MPart part, String key, Object value) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).setSelection(key, value);
			return true;
		}
		return false;
	}
	
	/**
	 * Gets a selection by id from perspective context.
	 *
	 * @param key the fully qualified name of the id field
	 * @return the selected id object from perspective context
	 */
	public static Object getSelectionFromPerspectiveContext(MPart part, String key) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) != null) {
				return context.get(SelectionStore.class).getSelection(key);
			}
		}
		return null;
	}
}
