//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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.authoring.ui.util;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.emf.edit.ui.action.ValidateAction.EclipseResourcesUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.edit.LibraryEditResources;
import org.eclipse.epf.library.edit.element.TransientContentPackageItemProvider;
import org.eclipse.epf.library.edit.navigator.ContentItemProvider;
import org.eclipse.epf.library.edit.navigator.MethodPackagesItemProvider;
import org.eclipse.epf.library.edit.navigator.ProcessesItemProvider;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.project.MethodLibraryProject;
import org.eclipse.epf.persistence.FileManager;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;

/**
 * @author Phong Nguyen Le
 * @since  1.1
 */
public class LibraryValidationMarkerHelper extends EclipseResourcesUtil {	
	public static final LibraryValidationMarkerHelper INSTANCE = new LibraryValidationMarkerHelper();
	public static final String GUID = "guid";
	
	private static class ContainerSet extends HashSet {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ContainerSet() {
			super();
			init();
			LibraryService.getInstance().addListener(new LibraryServiceListener() {
				public void libraryOpened(MethodLibrary library) {
					init();
				}
				
				public void libraryClosed(MethodLibrary library) {
					clear();
				}
				
				public void libraryReopened(MethodLibrary library) {
					init();
				}				
			});
		}
		
		private void init() {
			clear();
			
			// fill this set with containers of marked objects
			//
			MethodLibrary lib = LibraryService.getInstance().getCurrentMethodLibrary();
			if(lib != null) {
				IProject prj = MethodLibraryProject.findProject(lib);
				if(prj != null) {
					try {
						IMarker[] markers = prj.findMarkers(INSTANCE.getMarkerID(), false, IResource.DEPTH_INFINITE);
						for (int i = 0; i < markers.length; i++) {
							IMarker marker = markers[i];
							String guid = (String) marker.getAttribute(GUID);
							MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
							if(e != null) {
								// remove its containers from containersOfMarkedObjects
								//
								markContainers(e);
							}
						}
					} catch (CoreException e) {
					}
				}
			}
		}
		
		private void markContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				add(container);
			}
		}

		private void unmarkContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				remove(container);
			}
		}
	}
	
	private static ContainerSet containersOfMarkedObjects = new ContainerSet();	
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.ui.MarkerHelper#getFile(org.eclipse.emf.common.util.URI)
	 */
	protected IFile getFile(URI uri) {
		if(uri.isFile()) {
			return (IFile) FileManager.getResourceForLocation(uri.toFileString());
		}
		return super.getFile(uri);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.edit.ui.util.EditUIMarkerHelper#adjustMarker(org.eclipse.core.resources.IMarker, org.eclipse.emf.common.util.Diagnostic)
	 */
	protected boolean adjustMarker(IMarker marker, Diagnostic diagnostic) throws CoreException {
		boolean ret = super.adjustMarker(marker, diagnostic);
		if(!diagnostic.getData().isEmpty()) {
			Object o = diagnostic.getData().get(0);
			if(o instanceof MethodElement) {
				marker.setAttribute(GUID, ((MethodElement)o).getGuid());
				marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(o));
			}
		}
		return ret;
	}
	
	public static boolean isInvalid(Object object) {
		if(object instanceof ProcessesItemProvider) {
			// this is an UI object: Processes
			//
			ProcessesItemProvider ip = (ProcessesItemProvider) object;
			Object o;
			return ((o = ip.getCapabilityPatternPackage()) != null && containersOfMarkedObjects.contains(o))
				|| ((o = ip.getDeliveryProcessPackage()) != null && containersOfMarkedObjects.contains(o));
		}
		else if(object instanceof MethodPackagesItemProvider
				|| object instanceof ContentItemProvider) {
			// this is an UI object
			//
			object = ((ItemProviderAdapter)object).getTarget();
		}
		else if(object instanceof TransientContentPackageItemProvider) {
			// this is an UI object: either Tasks, Roles, Work Products, or Guidance
			//
			Collection children = ((TransientContentPackageItemProvider)object).getChildren(object);
			for (Iterator iter = children.iterator(); iter.hasNext();) {
				if(INSTANCE.hasMarkers(iter.next())) {
					return true;
				}				
			}
			return false;
		}
		return containersOfMarkedObjects.contains(object) || INSTANCE.hasMarkers(object);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.emf.common.ui.MarkerHelper#hasMarkers(java.lang.Object)
	 */
	public boolean hasMarkers(Object object) {
		if(object instanceof MethodElement) {
			IResource resource = getFile(object);
			if (resource != null && resource.exists())
			{
				try
				{
					String guid = ((MethodElement)object).getGuid();
					IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
					for (int i = 0; i < markers.length; i++) {
						IMarker marker = markers[i];
						if(guid.equals(marker.getAttribute(GUID))) {
							return true;
						}
					}
				}
				catch (CoreException e)
				{
				}
			}
			return false;
		}

		return super.hasMarkers(object);
	}
	
	public void deleteMarkers(Object object) {
		if(object instanceof MethodElement) {
			IResource resource = getFile(object);
			if (resource != null && resource.exists())
			{
				try
				{
					String guid = ((MethodElement)object).getGuid();
					IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
					for (int i = 0; i < markers.length; i++) {
						IMarker marker = markers[i];
						if(guid.equals(marker.getAttribute(GUID))) {
							marker.delete();
						}
					}
				}
				catch (CoreException e)
				{
				}
			}
			return;
		}
		
		super.deleteMarkers(object);
	}

	protected void deleteMarkers(IResource resource, boolean includeSubtypes, int depth) {
		if (resource != null && resource.exists()) {
			try {				
				IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
				for (int i = 0; i < markers.length; i++) {
					IMarker marker = markers[i];
					String guid = (String) marker.getAttribute(GUID);
					MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
					if(e != null) {
						// remove its containers from containersOfMarkedObjects
						//
						containersOfMarkedObjects.unmarkContainers(e);
					}
				}

			} catch (CoreException e) {
				
			}			
		}
			
		super.deleteMarkers(resource, includeSubtypes, depth);
	}
	
	protected void createMarkers(IResource resource, Diagnostic diagnostic, Diagnostic parentDiagnostic) throws CoreException {
		super.createMarkers(resource, diagnostic, parentDiagnostic);
		
		if (resource != null && resource.exists()) {
			try {				
				IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
				for (int i = 0; i < markers.length; i++) {
					IMarker marker = markers[i];
					String guid = (String) marker.getAttribute(GUID);
					MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
					if(e != null) {
						// remove its containers from containersOfMarkedObjects
						//
						containersOfMarkedObjects.markContainers(e);
					}
				}

			} catch (CoreException e) {
				
			}			
		}
	}
	
	//Override to seperate error message in error dialog and problems view (bug 174351)
	//Note: better fix is to extend BasicDiagnostic to encapsulate both types of msgs -> to do later
	protected String composeMessage(Diagnostic diagnostic, Diagnostic parentDiagnostic) {
		int ix = diagnostic.getMessage().indexOf(LibraryEditResources.duplicateElementNameError_msg2);
		if (ix > 0) {
			return diagnostic.getMessage().substring(0, ix);
		}
		return super.composeMessage(diagnostic, parentDiagnostic);
	}

}