/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.decorators;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.LabelProviderChangedEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * The DecorationScheduler is the class that handles the
 * decoration of elements using a background thread.
 */
public class DecorationScheduler {

	// When decorations are computed they are added to this cache via decorated() method
	Map resultCache = new HashMap();

	// Objects that need an icon and text computed for display to the user
	List awaitingDecoration = new ArrayList();

	// Objects that are awaiting a label update.
	Set pendingUpdate = new HashSet();

	Object resultLock = new Object();

	Map awaitingDecorationValues = new HashMap();

	DecoratorManager decoratorManager;

	boolean shutdown = false;

	Job decorationJob;
	UIJob updateJob;

	/**
	 * Return a new instance of the receiver configured for
	 * the supplied DecoratorManager.
	 * @param manager
	 */
	DecorationScheduler(DecoratorManager manager) {
		decoratorManager = manager;
		createDecorationJob();
	}

	/**
	* Decorate the text for the receiver. If it has already
	* been done then return the result, otherwise queue
	* it for decoration.
	* 
	* @return String
	* @param text
	* @param element
	* @param adaptedElement. The adapted value of element. May be null.
	*/

	public String decorateWithText(
		String text,
		Object element,
		Object adaptedElement) {

		//We do not support decoration of null
		if (element == null)
			return text;
		
		
		DecorationResult decoration =
			(DecorationResult) resultCache.get(element);

		if (decoration == null) {
			queueForDecoration(element, adaptedElement, false,text);
			return text;
		} else
			return decoration.decorateWithText(text);

	}
	/**
	 * Queue the element and its adapted value if it has not been
	 * already.
	 * @param element
	 * @param adaptedElement. The adapted value of element. May be null.
	 * @param forceUpdate. If true then a labelProviderChanged is fired
	 * 	whether decoration occured or not.
	 * @param String undecoratedText - the String that we are starting 
	 * 	decoration with.
	 */

	synchronized void queueForDecoration(
		Object element,
		Object adaptedElement,
		boolean forceUpdate,
		String undecoratedText) {

		if (awaitingDecorationValues.containsKey(element)) {
			if(forceUpdate){//Make sure we don't loose a force
				DecorationReference reference = 
					(DecorationReference) awaitingDecorationValues.get(element);
				reference.setForceUpdate(forceUpdate);
			}			
		}		
		else{
			DecorationReference reference =
				new DecorationReference(element, adaptedElement);
			reference.setForceUpdate(forceUpdate);
			reference.setUndecoratedText(undecoratedText);
			awaitingDecorationValues.put(element, reference);
			awaitingDecoration.add(element);
			if (shutdown)
				return;
			decorationJob.schedule();
		}
		
		
			

	}

	/**
	 * Decorate the supplied image, element and its adapted value.
	 * 
	 * @return Image
	 * @param image
	 * @param element
	 * @param adaptedElement. The adapted value of element. May be null.
	 * 
	 */
	public Image decorateWithOverlays(
		Image image,
		Object element,
		Object adaptedElement) {

		//We do not support decoration of null
		if (element == null)
			return image;

		DecorationResult decoration =
			(DecorationResult) resultCache.get(element);

		if (decoration == null) {
			queueForDecoration(element, adaptedElement, false,null);
			return image;
		} else
			return decoration.decorateWithOverlays(
				image,
				decoratorManager.getLightweightManager().getOverlayCache());
	}

	/**
	 * Execute a label update using the pending decorations.
	 * @param resources
	 * @param decorationResults
	 */
	synchronized void decorated() {

		//Don't bother if we are shutdown now
		if (shutdown)
			return;

		//Lazy initialize the job
		if (updateJob == null) {
			updateJob = getUpdateJob();
			updateJob.setPriority(Job.DECORATE);
		}
	
		//Give it a big of a lag for other updates to occur
		updateJob.schedule(100);
	}

	/**
	 * Shutdown the decoration.
	 */
	void shutdown() {
		shutdown = true;
	}

	/**
	 * Get the next resource to be decorated.
	 * @return IResource
	 */
	synchronized DecorationReference nextElement() {

		if (shutdown || awaitingDecoration.isEmpty()) {
			return null;
		}
		Object element = awaitingDecoration.remove(0);

		return (DecorationReference) awaitingDecorationValues.remove(element);
	}

	/**
	 * Create the Thread used for running decoration.
	 */
	private void createDecorationJob() {
			decorationJob = new Job(WorkbenchMessages.getString("DecorationScheduler.CalculationJobName")) {//$NON-NLS-1$
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
	 */
			public IStatus run(IProgressMonitor monitor) {
				monitor.beginTask(WorkbenchMessages.getString("DecorationScheduler.CalculatingTask"), 100); //$NON-NLS-1$
				//will block if there are no resources to be decorated
				DecorationReference reference;
				monitor.worked(5);
				int workCount = 5;
				while ((reference = nextElement()) != null) {

					//Count up to 90 to give the appearance of updating
					if(workCount < 90){
						monitor.worked(1);
						workCount++;
					}
					
					DecorationBuilder cacheResult = new DecorationBuilder();

					monitor.subTask(reference.getSubTask()); //$NON-NLS-1$
					//Don't decorate if there is already a pending result
					Object element = reference.getElement();
					Object adapted = reference.getAdaptedElement();
					
					boolean elementIsCached = true;
					DecorationResult adaptedResult = null;

					//Synchronize on the result lock as we want to
					//be sure that we do not try and decorate during
					//label update servicing.
					synchronized (resultLock) {
						elementIsCached = resultCache.containsKey(element);
						if (elementIsCached) {
							pendingUpdate.add(element);
						}
						if (adapted != null) {
							adaptedResult =
								(DecorationResult) resultCache.get(adapted);
						}
					}
					if (!elementIsCached) {
						//Just build for the resource first
						if (adapted != null) {
							if (adaptedResult == null) {
								decoratorManager
									.getLightweightManager()
									.getDecorations(
									adapted,
									cacheResult,
									true);
								if (cacheResult.hasValue()) {
									adaptedResult = cacheResult.createResult();
								}
							} else {
								// If we already calculated the decoration 
								// for the adapted element, reuse the result.
								cacheResult.applyResult(adaptedResult);
								// Set adaptedResult to null to indicate that
								// we do not need to cache the result again.
								adaptedResult = null;
							}
						}

						//Now add in the results for the main object

						decoratorManager
							.getLightweightManager()
							.getDecorations(
							element,
							cacheResult,
							false);	

						//If we should update regardless then put a result anyways
						if (cacheResult.hasValue()
							|| reference.shouldForceUpdate()) {
							
							//Synchronize on the result lock as we want to
							//be sure that we do not try and decorate during
							//label update servicing.
							//Note: resultCache and pendingUpdate modifications
							//must be done atomically.  
							synchronized (resultLock) {
								if (adaptedResult != null) {
									resultCache.put(adapted, adaptedResult);
								}
								// Add the decoration even if it's empty in order to indicate that the decoration is ready
								resultCache.put(
									element,
									cacheResult.createResult());

								//Add an update for only the original element to 
								//prevent multiple updates and clear the cache.
								pendingUpdate.add(element);
							}
						}
					}

					// Only notify listeners when we have exhausted the
					// queue of decoration requests.
					if (awaitingDecoration.isEmpty()) {
						decorated();
					}
				}
				monitor.worked(100 - workCount);
				monitor.done();
				return Status.OK_STATUS;
			}
			
			/* (non-Javadoc)
			 * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object)
			 */
			public boolean belongsTo(Object family) {
				return DecoratorManager.FAMILY_DECORATE == family;
			}
		};

		decorationJob.setSystem(true);
		decorationJob.setPriority(Job.DECORATE);
		decorationJob.schedule();
	}

	/**
	 * An external update request has been made. Clear the results as
	 * they are likely obsolete now.
	 */
	void clearResults() {
		synchronized (resultLock) {
			resultCache.clear();
		}

	}

	/**
	 * Get the update WorkbenchJob.
	 * @return WorkbenchJob
	 */
	private WorkbenchJob getUpdateJob() {
		WorkbenchJob job = new WorkbenchJob(WorkbenchMessages.getString("DecorationScheduler.UpdateJobName")) {//$NON-NLS-1$
			public IStatus runInUIThread(IProgressMonitor monitor) {
				//Check again in case someone has already cleared it out.
				synchronized (resultLock) {
					if (pendingUpdate.isEmpty())
						return Status.OK_STATUS;
				
					//Get the elements awaiting update and then
					//clear the list
					Object[] elements =
						pendingUpdate.toArray(new Object[pendingUpdate.size()]);
					monitor.beginTask(WorkbenchMessages.getString("DecorationScheduler.UpdatingTask"), elements.length + 20); //$NON-NLS-1$
					pendingUpdate.clear();
					monitor.worked(15);
					decoratorManager.fireListeners(
						new LabelProviderChangedEvent(
							decoratorManager,
							elements));
					monitor.worked(elements.length);
					//Other decoration requests may have occured due to
					//updates. Only clear the results if there are none pending.
					if (awaitingDecoration.isEmpty())
						resultCache.clear();
					monitor.worked(5);
					monitor.done();
				}
				return Status.OK_STATUS;
			}
			
			/* (non-Javadoc)
			 * @see org.eclipse.ui.progress.WorkbenchJob#performDone(org.eclipse.core.runtime.jobs.IJobChangeEvent)
			 */
			public void performDone(IJobChangeEvent event) {
				if(!pendingUpdate.isEmpty())
					decorated();
			}
		};

		job.setSystem(true);
		return job;
	}
	
	/**
	 * Return whether or not there is a decoration fro this element ready.
	 * @param element
	 * @return boolean true if the element is ready.
	 */
	public boolean isDecorationReady(Object element) {
		return resultCache.get(element) != null;
	 	}
	

}
