/*******************************************************************************
 *  Copyright (c) 2012-2014 SAP SE.
 *  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:
 *  SAP SE - initial API and implementation and/or initial documentation
 *
 *******************************************************************************/
package org.eclipse.ogee.designer.utils;

import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.ogee.designer.Activator;
import org.eclipse.ogee.designer.contextmenu.IArtifactSelection;
import org.eclipse.ogee.designer.contextmenu.UIElementType;
import org.eclipse.ogee.model.odata.Association;
import org.eclipse.ogee.model.odata.ComplexType;
import org.eclipse.ogee.model.odata.EntitySet;
import org.eclipse.ogee.model.odata.EntityType;
import org.eclipse.ogee.model.odata.FunctionImport;
import org.eclipse.ogee.utils.logger.Logger;

/**
 * This class will be used for to retrieve all
 * implementations of artifact selection extension point.
 * 
 * 
 */
public class ODataArtifactSelectionUtil {
	private static String[][] artifactSelectionOption = null;
	
	public enum SelectionStatus {
		SELECTED , DELETED;
	 
	}

	public static IConfigurationElement[] getArtifactSelectionExtensions() {

		IConfigurationElement[] extensionMenuConfigElems = Platform
				.getExtensionRegistry().getConfigurationElementsFor(
						IODataEditorConstants.ODATA_ARTIFACT_SELECTION_ATTRIBUTE_NAME );
		
		return extensionMenuConfigElems;
	}

	/**
	 * Returns Current current selection.
	 * 
	 * @param artifactSelectionId
	 * 
	 * @return IArtifactSelection Instance.
	 */
	public static IArtifactSelection getCurrentSelection(String artifactSelectionId) {
		IArtifactSelection currentSelection = null;
		String id = null;
		String currentSelectionID = artifactSelectionId;

		try {
			IConfigurationElement[] contextMenuConfigElems = getArtifactSelectionExtensions();
			for (IConfigurationElement iConfigurationElement : contextMenuConfigElems) {
				id = iConfigurationElement
						.getAttribute(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_ID );
				if (id.equals(currentSelectionID)) {
					currentSelection = (IArtifactSelection) iConfigurationElement
							.createExecutableExtension(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_CLASS);
					break;
				}

			}
		} catch (CoreException e) {
			Logger.getLogger(Activator.PLUGIN_ID).logError(e);
		}

		return currentSelection;
	}

	/**
	 * This method is used in creating UI in Editor Context Menu. Creates a
	 * String Array with name,id,parent_name,icon & key_binding with all
	 * available context menus
	 * 
	 * 
	 * @return String Array.
	 */
	public static String[][] getCurrentSelectionOption() {
		String id = null;
		String className = null;
		String plugin_id = null;
		IArtifactSelection currentSelection = null;

		if (artifactSelectionOption == null) {
			IConfigurationElement[] contextMenuExtensions = getArtifactSelectionExtensions();
			Map<String, IConfigurationElement> filteredExtensions = new LinkedHashMap<String, IConfigurationElement>();
			for (IConfigurationElement iConfigurationElement : contextMenuExtensions) {
				id = iConfigurationElement
						.getAttribute(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_ID);
				className = iConfigurationElement
						.getAttribute(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_CLASS);
				if (id != null && !id.isEmpty() && className != null
						&& !className.isEmpty()) {
					try {
						currentSelection = (IArtifactSelection) iConfigurationElement
								.createExecutableExtension(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_CLASS);
						if (currentSelection != null) {
							filteredExtensions.put(id, iConfigurationElement);
						}

					} catch (CoreException e) {
						Logger.getLogger(Activator.PLUGIN_ID).logError(e);
					}

				}
			}
			int counter = 0;
			Collection<String> filteredKeys = filteredExtensions.keySet();
			artifactSelectionOption = new String[filteredKeys.size()][2];
			IConfigurationElement iConfigurationElement = null;
			for (String key : filteredKeys) {
				iConfigurationElement = filteredExtensions.get(key);
				id = iConfigurationElement
						.getAttribute(IODataEditorConstants.ARTIFACT_SELECTION_ATTRIBUTE_ID);
				artifactSelectionOption[counter][0] = id;
				plugin_id = iConfigurationElement.getContributor().getName();
				artifactSelectionOption[counter++][1] = plugin_id;
			}
		}
		return artifactSelectionOption;
	}
	
	public static void notifyRegisteredSubscribers( PictogramElement pe, EObject eo , SelectionStatus status){
		String[][] selectionOptions = ODataArtifactSelectionUtil.getCurrentSelectionOption();
		String contextMenuId = null;
		if (selectionOptions .length > 0){
			for (int i = 0; i < selectionOptions.length; i++) {
				contextMenuId = selectionOptions[i][0];
				IArtifactSelection artifactSelectionFeature = ODataArtifactSelectionUtil.getCurrentSelection(contextMenuId);
				EnumSet<UIElementType> uiElementTypeSet = artifactSelectionFeature
						.getApplicableElements();
				if(uiElementTypeSet != null){
					for (UIElementType uiElementType : uiElementTypeSet) {
						if(isArtifactSelectedApplicable(uiElementType,eo) && status == SelectionStatus.SELECTED){
							artifactSelectionFeature.setSelectedEObjectElement(eo);
							artifactSelectionFeature.setSelectedPictogramElement(pe);
						}
						if(!isArtifactSelectedApplicable(uiElementType,eo) && status == SelectionStatus.SELECTED){
							artifactSelectionFeature.setSelectedEObjectElement(null);
							artifactSelectionFeature.setSelectedPictogramElement(null);
						}
						if(isArtifactSelectedApplicable(uiElementType,eo) && status == SelectionStatus.DELETED){
							artifactSelectionFeature.setDeletedEObjectElement(eo);
							artifactSelectionFeature.setDeletedPictogramElement(pe);
						}
					}
				}
				
				
			}
		}
			
	}
	
	public static boolean isArtifactSelectedApplicable(UIElementType elementType , EObject elementEObject){
		boolean isRequiredElement = false;
		switch(elementType){
		case ENTITY_TYPE:
			isRequiredElement = (elementEObject instanceof EntityType) ? true : false;
			break;
		case ASSOCIATION:
			isRequiredElement = (elementEObject instanceof Association) ? true : false;
			break;
		case COMPLEX_TYPE:
			isRequiredElement = (elementEObject instanceof ComplexType) ? true : false;
			break;
		case FUNCTION_IMPORT:
			isRequiredElement = (elementEObject instanceof FunctionImport) ? true : false;
			break;
		case ENTITY_SET:
			isRequiredElement = (elementEObject instanceof EntitySet) ? true : false;
			break;
		default:
			isRequiredElement = false;
		}
		return isRequiredElement ;
		
	}

}
