//------------------------------------------------------------------------------
// 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.ArrayList;
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.Practice;
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;
		}
		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;
		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();
	}
	
	public List<Practice> calcUtdList(MethodElement element, ElementRealizer realizer) {
		List<Practice> utdList = new ArrayList<Practice>();
		MethodElementPropUtil propUtil = MethodElementPropUtil.getMethodElementPropUtil();
		if (propUtil.hasUdtList(element)) {
			List<Practice> list = propUtil.getUdtList(element, false);
			if (list != null) {
				for (Practice p : list) {
					Object realized = ConfigurationHelper.getCalculatedElement(p, realizer);
					if (realized instanceof Practice) {
						utdList.add(p);
					}
				}
			}
		}		
		return utdList;
	}
	
	
}
