//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.HashMap;
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.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceListener;
import org.eclipse.epf.library.configuration.closure.IConfigurationError;
import org.eclipse.epf.library.edit.navigator.ConfigurationsItemProvider;
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.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.ui.ide.IDE;

/**
 *  Helper class to handle Configuration error markers
 * @author Jeff Hardy
 * @author Jinhua Xi
 *
 */
public class ConfigurationMarkerHelper {	
	public static final ConfigurationMarkerHelper INSTANCE = new ConfigurationMarkerHelper();
	public static final String ATTR_ERROR_ID = "errorID"; //$NON-NLS-1$
	public static final String ATTR_CONFIG_GUID = "configGuid"; //$NON-NLS-1$
	public static final String ATTR_ERROR_ELEMENT_GUID = "elementGuid"; //$NON-NLS-1$
	public static final String ATTR_CAUSE_ELEMENT_GUID = "causeGuid"; //$NON-NLS-1$

	// marker ID
	public static final String MARKER_ID = "org.eclipse.epf.authoring.ui.configuration"; //$NON-NLS-1$

	
//	private Map<ElementDependencyError, IMarker> errorMarkerMap = new HashMap<ElementDependencyError, IMarker>();
	
	// private constructor
	private ConfigurationMarkerHelper() {
	}
	
	private static class ContainerMap extends HashMap<Object, Integer> {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ContainerMap() {
			super();
			initMap();
			LibraryService.getInstance().addListener(new LibraryServiceListener() {
				public void libraryOpened(MethodLibrary library) {
					initMap();
				}
				
				public void libraryClosed(MethodLibrary library) {
					clear();
				}
				
				public void libraryReopened(MethodLibrary library) {
					initMap();
				}				
			});
		}
		
		private void initMap() {
			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(ATTR_CONFIG_GUID);
							MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid);
							if(e != null) {
								// remove its containers from containersOfMarkedObjects
								//
								markContainers(e);
							}
						}
					} catch (CoreException e) {
					}
				}
			}
		}
		
		private void increment(Object object) {
			Integer count;
			if (containsKey(object)) {
				count = get(object);
			} else {
				count = new Integer(0);
			}
			count++;
			put(object, count);
		}

		private void decrement(Object object) {
			if (containsKey(object)) {
				Integer count = get(object);
				if (count == 1) {
					// remove object
					remove(object);
				} else {
					count--;
					put(object, count);
				}
			}
		}
		
		private void markContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				increment(container);
			}
		}

		private void unmarkContainers(MethodElement e) {
			for(EObject container = e.eContainer(); container != null; container = container.eContainer()) {
				decrement(container);
			}
		}
	}
	
	private static ContainerMap containersOfMarkedObjects = new ContainerMap();	
	
	
	protected String getMarkerID() {
		return MARKER_ID;
	}
	                                                                                                                             
	/* (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());
		}
	    String scheme = uri.scheme();
	    if ("platform".equals(scheme) && uri.segmentCount() > 1 && "resource".equals(uri.segment(0))) //$NON-NLS-1$ //$NON-NLS-2$
	    {
	      StringBuffer platformResourcePath = new StringBuffer();
	      for (int j = 1, size = uri.segmentCount(); j < size; ++j)
	      {
	        platformResourcePath.append('/');
	        platformResourcePath.append(URI.decode(uri.segment(j)));
	      }
	      return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformResourcePath.toString()));
	    }
	    return null;
	}
		
	/**
	 * Used by decorators to determine to put an error tick on the Object
	 * @param object
	 * @return
	 */
	public static boolean isInvalid(Object object) {
		if (object instanceof ConfigurationsItemProvider) {
			Collection children = ((ConfigurationsItemProvider)object).getChildren(object);
			for (Iterator iter = children.iterator(); iter.hasNext();) {
				Object obj = TngUtil.unwrap(iter.next());
				if(containersOfMarkedObjects.containsKey(obj)) {
					return true;
				}				
				if (obj instanceof MethodConfiguration) {
					if (INSTANCE.hasMarkers((MethodConfiguration)obj)) {
						return true;
					}
				}
			}
			return false;
		} else if (object instanceof MethodConfiguration) {
			if (INSTANCE.hasMarkers((MethodConfiguration)object)) {
				return true;
			}
		}
		return containersOfMarkedObjects.containsKey(object);
	}
		    
    public void deleteMarker(MethodConfiguration config, IConfigurationError error) {
    	try {
	    	IMarker marker = getMarker(config, error);
	    	if (marker != null) {
	    		marker.delete();
	    		containersOfMarkedObjects.unmarkContainers(config);
	    	}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
    }
	
    public IMarker createMarker(MethodConfiguration config, IConfigurationError error) {
//    	if (error.getErrorMethodElement() == null) return null;
//    	if (error.getCauseMethodElement() == null) return null;
    	
    	IMarker existingMarker = getMarker(config, error);
    	if (existingMarker != null) {
    		adjustMarker(existingMarker, config, error);
    		return existingMarker;
    	}
    	try {
	    	IResource resource = getIResource(config);
	    	if (resource != null && resource.exists()) {
	    		IMarker marker = resource.createMarker(getMarkerID());
	    		marker.setAttribute(IDE.EDITOR_ID_ATTR, "org.eclipse.epf.authoring.ui.editors.ConfigurationEditor"); //$NON-NLS-1$
	    		adjustMarker(marker, config, error);
	    		containersOfMarkedObjects.markContainers(config);
	    		return marker;
	    	}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
    }
    
    public void adjustMarker(IMarker marker, MethodConfiguration config, IConfigurationError error) {
    	if (config == null || error == null) return;
       	try {
       		if (marker == null) {
       			// try to find marker
       			marker = getMarker(config, error);
       		}
       		if (marker == null) return;
			marker.setAttribute(IMarker.SEVERITY, error.getSeverity());
	    	String message = getMessage(error);
			marker.setAttribute(IMarker.MESSAGE, message);
			marker.setAttribute(IMarker.LINE_NUMBER, 0);
			marker.setAttribute(ATTR_CONFIG_GUID, config.getGuid());
			marker.setAttribute(ATTR_ERROR_ID, error.getId());
	    	if (error.getErrorMethodElement() != null) {
				marker.setAttribute(IMarker.LOCATION, TngUtil.getLabelWithPath(error.getErrorMethodElement()));
				marker.setAttribute(ATTR_ERROR_ELEMENT_GUID, error.getErrorMethodElement().getGuid());
	    	}
	    	if (error.getCauseMethodElement() != null) {
	    		marker.setAttribute(ATTR_CAUSE_ELEMENT_GUID, error.getCauseMethodElement().getGuid());
	    	}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
   }
    	
    public boolean hasMarker(MethodConfiguration config, IConfigurationError error) {
		if (getMarker(config, error) != null) {
			return true;
		}
   		return false;
    }
    
    /**                                                                                                
     * Returns whether the a maker with id equals to the return of {@link #getMarkerID()}              
     * is available in the IResource computed from the specified object.                               
     * @param object                                                                                   
     * @return boolean                                                                                 
     */
    public boolean hasMarkers(MethodConfiguration config) {
    	IResource resource = getIResource(config);
        if (resource != null && resource.exists()) {
        	try {
				IMarker[] markers = resource.findMarkers(getMarkerID(), true, IResource.DEPTH_ZERO);
				return markers.length > 0;
	  		} catch (CoreException e) {
				AuthoringUIPlugin.getDefault().getLogger().logError(e);
			}
        }
        return false;
    }
    
    public IMarker getMarker(MethodConfiguration config, IConfigurationError error) {
    	if (config == null || error == null) {
    		return null;
    	}
    	try {
	    	IResource resource = getIResource(config);                                                     
	        if (resource != null) {                                                     
				IMarker[] markers = resource.findMarkers(getMarkerID(), false, IResource.DEPTH_ZERO);
				for (int i = 0; i < markers.length; i++) {
					IMarker marker = markers[i];
					String markerErrorId = (String) marker.getAttribute(ATTR_ERROR_ID);
					if (error.getId().equals(markerErrorId)) {
						return marker;
					}
				}
	        }
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
    }
    
    private String getMessage(IConfigurationError error) {
    	return error.getErrorMessage();
    }
    
    private IResource getIResource(MethodConfiguration config) {
    	Resource resource = config.eResource();
        URI uri = resource.getURI();
        uri = resource.getResourceSet().getURIConverter().normalize(uri);
        return getFile(uri);

    }
	
	public MethodConfiguration getConfig(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String configGuid = (String) marker.getAttribute(ATTR_CONFIG_GUID);
			MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(configGuid);
			if (e instanceof MethodConfiguration) {
				return (MethodConfiguration)e;
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}
	
	public MethodElement getErrorMethodElement(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String errorGuid = (String) marker.getAttribute(ATTR_ERROR_ELEMENT_GUID);
			if (errorGuid != null) {
				MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(errorGuid);
				if (e instanceof MethodElement) {
					return (MethodElement)e;
				}
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}

	public MethodElement getCauseMethodElement(IMarker marker) {
		if (marker == null) {
			return null;
		}
		try {
			String causeGuid = (String) marker.getAttribute(ATTR_CAUSE_ELEMENT_GUID);
			if (causeGuid != null) {
				MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(causeGuid);
				if (e instanceof MethodElement) {
					return (MethodElement)e;
				}
			}
		} catch (CoreException e) {
			AuthoringUIPlugin.getDefault().getLogger().logError(e);
		}
		return null;
	}

}
