//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.epf.library.configuration.ConfigurationData;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.configuration.DefaultElementRealizer;
import org.eclipse.epf.library.configuration.ElementRealizer;
import org.eclipse.epf.library.configuration.SupportingElementData;
import org.eclipse.epf.library.edit.configuration.PracticeSubgroupItemProvider;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropUtil;
import org.eclipse.epf.library.edit.util.MethodElementPropertyHelper;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.BrowsingLayoutSettings;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.layout.IElementLayout;
import org.eclipse.epf.library.layout.elements.AbstractElementLayout;
import org.eclipse.epf.library.layout.elements.AbstractProcessElementLayout;
import org.eclipse.epf.library.layout.elements.ElementLayoutExtender;
import org.eclipse.epf.library.layout.elements.SummaryPageLayout;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.realization.RealizationManagerFactory;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodElementProperty;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.epf.uma.util.Scope;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;

/**
 * Delegate class used in ConfigurationHelper
 * 
 * @author Weiping Lu 
 * @since 1.5
 */
public class ConfigHelperDelegate {

	private boolean publishingMode = false;
	private boolean authoringPerspective = false;
	private MethodConfiguration config;
	private boolean loadForBrowsingNeeded = true;
	private boolean autoSyncedByBrowsing = false;
	private Map<MethodElement, Set<CustomCategory>> dynamicCustomCategoriesMap; 	
	
	public ConfigHelperDelegate() {
		LibraryService.getInstance().addListener(libServiceListener);		
		IRealizationManager mgr = RealizationManagerFactory.getInstance().newRealizationManager(null);
		LibraryEditUtil.getInstance().setDefaultRealizationManager(mgr);
	}

	protected boolean hasDynamicElements(CustomCategory cc) {
		MethodElementProperty prop = MethodElementPropertyHelper.getProperty(
				cc,
				MethodElementPropertyHelper.CUSTOM_CATEGORY__INCLUDED_ELEMENTS);
		return prop != null;
	}
	
	public void buildDynamicCustomCategoriesMap(MethodConfiguration config) {
		try {
		if (config == null) {
			return;
		}
		ConfigurationHelper.getDelegate().loadUserDefinedType();
		dynamicCustomCategoriesMap = new HashMap<MethodElement, Set<CustomCategory>>();		
		ElementRealizer realizer = DefaultElementRealizer.newElementRealizer(config);		
		Set<CustomCategory> set = new HashSet<CustomCategory>();
		MethodElementPropUtil propUtil = MethodElementPropUtil.getMethodElementPropUtil();
		for (MethodPlugin plugin : config.getMethodPluginSelection()) {		
			for (CustomCategory cc : TngUtil.getAllCustomCategories(plugin)) {
				cc = (CustomCategory) ConfigurationHelper.getCalculatedElement(cc, realizer);
				if (cc != null && hasDynamicElements(cc)) {
					set.add(cc);
				}
			}			
		}
		
		for (CustomCategory cc : set) {
			for (MethodElement element : (List<MethodElement>) ConfigurationHelper
					.calc0nFeatureValue(cc, UmaPackage.eINSTANCE
							.getCustomCategory_CategorizedElements(), realizer)) {
				Set<CustomCategory> ccSet = dynamicCustomCategoriesMap.get(element);
				if (ccSet == null) {
					ccSet = new HashSet<CustomCategory>();
					dynamicCustomCategoriesMap.put(element, ccSet);
				}
				ccSet.add(cc);				
			}
		}
		} catch (Throwable e) {
			LibraryPlugin.getDefault().getLogger().logError(e);
		}
	}
	
	public void clearDynamicCustomCategoriesMap() {
		dynamicCustomCategoriesMap = null;
	}		
	
	public Set<CustomCategory> getDynamicCustomCategories(MethodElement element) {
		return dynamicCustomCategoriesMap == null ? null : dynamicCustomCategoriesMap.get(element);
	}
	
	/**
	 * Test if pkg is a system package of plugin
	 * @param plugin
	 * @param pkg
	 * @return
	 */
	public boolean isSystemPackage(MethodPlugin plugin, MethodPackage pkg) {
		return TngUtil.getAllSystemPackages(plugin).contains(pkg);
	}
	
	public void loadOppositeFeatures(ILibraryResourceSet resouceSet,
			List<OppositeFeature> oppositeFeatures,  MethodElement element) {
		Set<String> GUIDs = new HashSet<String>();
		GUIDs.add(element.getGuid());
		resouceSet.loadOppositeFeatures(oppositeFeatures, GUIDs);
	}
	
	public boolean isOwnerSelected(MethodElement element,
			MethodConfiguration config, boolean checkSubtracted) {
		if (config instanceof Scope) {
			return ((Scope)config).inScope(element);
		}
		MethodLibrary library = LibraryServiceUtil.getMethodLibrary(config);
		ILibraryManager libraryManager = library == null? null : LibraryService.getInstance().getLibraryManager(library);
		if (libraryManager != null) {
			return LibraryService.getInstance()
						.getConfigurationManager(config)
							.getConfigurationData()
								.isOwnerSelected(element, checkSubtracted);
		}
				
		if (element == null) {
			return false;
		}

		if (config == null || ConfigurationHelper.isDescriptionElement(element)) {
			return true;
		}

		// since UMA 1.0.4, configuration can have added categories 
		// and subtracted categories. The order of filtering is:
		// 1. any element in the subtracted categories should be excluded
		// 2. any element in the added categories should be included
		// 3. any element not in the selected package or plugin should be excluded.
		
		if ( checkSubtracted ) {
			// first check subtracted elements
			List subtractedCategories = config.getSubtractedCategory();
			if ( subtractedCategories.size() > 0 ) {
				for ( Iterator it = subtractedCategories.iterator(); it.hasNext(); ) {
					ContentCategory cc = (ContentCategory)it.next();
					if ( cc == element ) {
						return false;
					}
					
					// need to check all content category types and sub-categories
					// we need to have an efficient algorithm for this checking.
					// for now, only check the custom category's categorised elements
					// TODO. Jinhua Xi, 11/27/2006
					if ( cc instanceof CustomCategory ) {
						if ( ((CustomCategory)cc).getCategorizedElements().contains(element) ) {
							return false;
						}
					} else {
						// TODO, not implemented yet
						System.out.println("TODO, isOwnerSelected: not implemented yet"); //$NON-NLS-1$
					}
				}
			}
		}
		
		// then check added categories
		// TODO
		
		// elements beyond configuration scope should be always visible
		if ((element instanceof MethodLibrary)
				|| (element instanceof MethodConfiguration)) {
			return true;
		} else if (element instanceof MethodPlugin) {
			List plugins = config.getMethodPluginSelection();
			return (plugins != null) && plugins.contains(element);
		} else {
			// if the ownerprocess can't show, can't accept
			if (element instanceof Activity) {
				Activity base = (Activity) ((Activity) element)
						.getVariabilityBasedOnElement();
				if (base != null && base != element) {
					MethodElement owningProc = TngUtil.getOwningProcess(base);
					if ( owningProc != null && owningProc != element 
							&& !ConfigurationHelper.inConfig(owningProc, config, checkSubtracted)) {
						return false;
					}
				}
			}

			EObject pkg = LibraryUtil.getSelectable(element);

			// accept global package if the plugin is in the configuration
			if (pkg instanceof MethodPackage
					&& ConfigurationHelper.isGlobalPackage((MethodPackage) pkg)) {
				MethodPlugin plugin = LibraryUtil.getMethodPlugin(pkg);
				return ConfigurationHelper.inConfig(plugin, config, checkSubtracted);
			}

			List pkgs = config.getMethodPackageSelection();
			if (pkgs == null) {
				return false;
			}

			// per Phong's request, for ProcessPackage, check the
			// ProcessComponent parent instead
			if (pkg instanceof ProcessPackage) {
				while ((pkg != null) && !(pkg instanceof ProcessComponent)
						&& !pkgs.contains(pkg)) {
					pkg = pkg.eContainer();
				}
			}

			// if package not selected, return false
			if ((pkg == null) || !pkgs.contains(pkg)) {
				return false;
			}

			return true;
		}
	}
	
	public void loadOppositeFeatures(Map map, List oppositeFeatures, Set deletedGUIDs) {
		int max = oppositeFeatures.size() - 1;
		if (max < 0) {
			return;
		}
		Collection elements = new HashSet(map.values());
		HashSet loadedElements = new HashSet();
		while (!elements.isEmpty()) {
			for (Iterator iter = elements.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof MethodElement) {
					MethodElement element = (MethodElement) obj;
					MultiResourceEObject mrEObject = ((MultiResourceEObject) element);
					for (int i = max; i > -1; i--) {
						OppositeFeature oppositeFeature = ((OppositeFeature) oppositeFeatures
								.get(i));
						EStructuralFeature eFeature = oppositeFeature.getTargetFeature();
						if (eFeature.getContainerClass().isInstance(element)) {
							if (eFeature.isMany()) {
								InternalEList list = (InternalEList) element
										.eGet(eFeature);
								if (!list.isEmpty()) {
									boolean resolve = false;
									check_resolve: for (Iterator iterator = list
											.basicIterator(); iterator
											.hasNext();) {
										InternalEObject e = (InternalEObject) iterator
												.next();
										if (e.eIsProxy()) {
											String guid = e.eProxyURI()
													.fragment();
											if (deletedGUIDs.contains(guid)) {
												resolve = true;
												break check_resolve;
											}
										}
									}
									if (resolve) {
										Collection<Object> deletedElements = new HashSet<Object>();
										for (Iterator iterator = list
												.iterator(); iterator.hasNext();) {
											Object o = iterator.next();
											if(o instanceof MethodElement && deletedGUIDs.contains(((MethodElement) o).getGuid())) {
												deletedElements.add(o);
											}
										}
										for (Object e : deletedElements) {
											if(oppositeFeature.isMany()) {
												mrEObject.oppositeAdd(oppositeFeature, e);
											}
											else {
												mrEObject.getOppositeFeatureMap().put(oppositeFeature, e);
											}
										}										
									}
								}
							} else {
								Object value = element.eGet(eFeature, false);
								if (value instanceof InternalEObject) {
									InternalEObject e = (InternalEObject) value;
									if (e.eIsProxy()) {
										String guid = e.eProxyURI().fragment();
										if (deletedGUIDs.contains(guid)) {
											Object o = element.eGet(eFeature);
											if(oppositeFeature.isMany()) {
												mrEObject.oppositeAdd(oppositeFeature, o);
											}
											else {
												mrEObject.getOppositeFeatureMap().put(oppositeFeature, o);
											}
										}
									}
								}
							}
						}
					}
				}
			}
			// gets the newly loaded elements to load their opposite features
			//
			loadedElements.addAll(elements);
			elements = new HashSet(map.values());
			elements.removeAll(loadedElements);
		}
	}
	
	public String generateHtml(Object raw_element, HtmlBuilder htmlBuilder) {
		loadForBrowsing(raw_element);
		
		IElementLayout layout = null;
		String file_url = "about:blank"; //$NON-NLS-1$
		Object element = LibraryUtil.unwrap(raw_element);
		if ( raw_element instanceof ActivityWrapperItemProvider ) {
			ActivityWrapperItemProvider wrapper = (ActivityWrapperItemProvider)raw_element;
			Object proc = wrapper.getTopItem();
			if ( element instanceof MethodElement && proc instanceof org.eclipse.epf.uma.Process ) {
				String path = AbstractProcessElementLayout.getPath(wrapper);
				//System.out.println(topItem);
				layout = htmlBuilder.getLayoutManager()
					.createLayout((MethodElement)element, 
							(org.eclipse.epf.uma.Process)proc, path);
				file_url = htmlBuilder.generateHtml(layout);
			}
		} else if (raw_element instanceof PracticeSubgroupItemProvider) {
			PracticeSubgroupItemProvider provider = (PracticeSubgroupItemProvider) raw_element;
			layout = new SummaryPageLayout(htmlBuilder.getLayoutManager(),
					provider.getPractice(), provider.getPrefix(),
					provider.getText(null), (List) provider.getChildren(null),
					provider.getText(null));
			((SummaryPageLayout) layout).setHtmlBuilder(htmlBuilder);
			file_url = htmlBuilder.generateHtml(layout);
		} else if (element instanceof MethodElement) {
				file_url = htmlBuilder.generateHtml((MethodElement)element);
		}
		
		if ( file_url == null ) {
			file_url = "about:blank"; //$NON-NLS-1$
		}
		// on linux, the file path need to be specified as file, otherwise it will be treated as url
		// and casuign encoding/decoding issue
		// Linux: Configuration names containing accented characters cannot be browsed.
		else {			
			if (!SWT.getPlatform().equals("win32") && !file_url.startsWith("file://") && //$NON-NLS-1$ //$NON-NLS-2$
				!file_url.equals("about:blank")) //$NON-NLS-1$
			{
				file_url = "file://" + file_url; //$NON-NLS-1$
			}
			
			// Bug 201335 - Refresh does not work correctly for process pages in browsing mode
			// need to append the query string
			if ( layout instanceof AbstractProcessElementLayout ) {
				file_url += ((AbstractProcessElementLayout)layout).getQueryString();
			}
		}
		return file_url;
	}
	
	//Should be overriden by sub classes
	public ElementLayoutExtender newElementLayoutExtender(AbstractElementLayout layout) {
		return null;
	}
	
	public void configViewRefreshNotified() {		
	}
	
	public void debugDump(String msg) {
		System.out.println("LD> " + getClass() + ".debugDump: " + msg);	//$NON-NLS-1$//$NON-NLS-2$
	}

	public boolean isPublishingMode() {
		return publishingMode;
	}

	public void setPublishingMode(boolean publishingMode) {
		this.publishingMode = publishingMode;
	}

	public boolean isAuthoringPerspective() {
		return authoringPerspective;
	}

	public void setAuthoringPerspective(boolean authoringPerspective) {
		this.authoringPerspective = authoringPerspective;
	}
	
	public boolean isAuthoringMode() {
		return isAuthoringPerspective();
	}
	
	private boolean supportingInAuthoringMode = false;
	
	public boolean isSupportingInAuthoringMode() {
		return supportingInAuthoringMode;
	}

	public void setSupportingInAuthoringMode(boolean supportingInAuthoringMode) {
		this.supportingInAuthoringMode = supportingInAuthoringMode;
	}

	private IPerspectiveListener perspectiveListener;

	private void addPerspectiveListener() {
		if (perspectiveListener != null) {
			return;
		}
		
		IWorkbenchWindow window = LibraryUtil.getActiveWorkbenchWindow();
		if (window != null) {
			perspectiveListener = new IPerspectiveListener() {
				public void perspectiveActivated(IWorkbenchPage page,
						IPerspectiveDescriptor desc) {
					handleConfigOrPersepctiveChange();
				}

				public void perspectiveChanged(IWorkbenchPage page,
						IPerspectiveDescriptor desc, String id) {
					handleConfigOrPersepctiveChange();
				}
				
			};
			window.addPerspectiveListener(perspectiveListener);
		}

	}
	
	private ILibraryServiceListener libServiceListener = new LibraryServiceListener() {

		public void configurationSet(MethodConfiguration newConfig) {
			addPerspectiveListener();
			
			if (config == newConfig) {
				return;
			}			
			
			handleConfigOrPersepctiveChange();				
			config = newConfig;
		}

	};
	
	protected void loadForBrowsing(Object raw_element) {
		if (!loadForBrowsingNeeded) {
			return;
		}

		MethodConfiguration config = LibraryService.getInstance()
		.getCurrentMethodConfiguration();
		if (config != null && ! BrowsingLayoutSettings.INSTANCE.isIgnoreDynamicParents()) {
			buildDynamicCustomCategoriesMap(config);
		}
		if (raw_element instanceof BreakdownElement
				|| raw_element instanceof ActivityWrapperItemProvider) {

			if (config == null) {
				LibraryUtil.loadAll(LibraryService.getInstance()
						.getCurrentMethodLibrary());
			} else {
				LibraryUtil.loadAllPlugins(config);
				IRealizationManager mgr = getRealizationManager(config);
				if (mgr != null) {
					mgr.updateAllProcesseModels();
					setAutoSyncedByBrowsing(true);
				}
			}
		}
		
		loadForBrowsingNeeded = false;
	}
	
	public IRealizationManager getRealizationManager(MethodConfiguration config) {
		if (config == null || config instanceof Scope) {
			return null;
		}
		IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config);
		return configMgr == null ? null : configMgr.getRealizationManager();
	}
	
	private void handleConfigOrPersepctiveChange() {
		loadForBrowsingNeeded = true;
		ConfigurationHelper.getDelegate().loadUserDefinedType();
		clearDynamicCustomCategoriesMap();
	}
	
	//Check to see if a process can be converted to a config-free process
	//To be overridden by sub-class	
	public boolean canBeConfigFree(Process proc) {
		return true;
	}
	
	protected boolean isLoadForBrowsingNeeded() {
		return loadForBrowsingNeeded;
	}

	public void setLoadForBrowsingNeeded(boolean loadForBrowsingNeeded) {
		this.loadForBrowsingNeeded = loadForBrowsingNeeded;
	}
	
	public boolean isAutoSyncedByBrowsing() {
		return autoSyncedByBrowsing;
	}

	public void setAutoSyncedByBrowsing(boolean autoSyncedByBrowsing) {
		this.autoSyncedByBrowsing = autoSyncedByBrowsing;
	}
	
	public ConfigurationData getConfigurationData(MethodConfiguration config) {
		if (config == null) {
			return null;
		}
		IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config);
		ConfigurationData configData = configMgr == null ? null : configMgr.getConfigurationData();
		if (configData == null) {
			LibraryPlugin.getDefault().getLogger().logError("getConfigurationData() == null for: " + config.getName());//$NON-NLS-1$	
		}
		return configData;
	}
	
	public SupportingElementData getSupportingElementData(MethodConfiguration config) {
		if (config == null) {
			return null;
		}
		IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config);
		return configMgr == null ? null : configMgr.getSupportingElementData();
	}
	
	//Make closure if conig stores any making closure info
	//Return true if processed otherwise false
	public boolean makeClosure(MethodConfiguration config) {
		return false;
	}
	
	public void loadUserDefinedType() {
	}
	
	public boolean additionShowConfigSelectMenu(IWorkbenchPage activePage) {
		return false;
	}
	
	public boolean filterOutEmptyCategories() {
		if (isAuthoringMode()) {
			return false;
		}		
		if (isPublishingMode()) {
			//Publishing logic does its own filter out, ok to return false here
			return false;	
		}		
		return true;
	}
	
	
}
