/*******************************************************************************
 * 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.jface.text;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Control;

import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;


/**
 * Manages the painters of a text viewer. Clients usually instantiate and configure
 * objects of this type.
 * 
 * @since 2.1
 */
public final class PaintManager implements KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {		
					
	/**
	 * Position updater used by the position manager. This position updater differes from the default position
	 * updater in that it extends a position when an insertion happens at the position's offset and right behind
	 * the position.
	 */
	static class PaintPositionUpdater extends DefaultPositionUpdater {
		
		/**
		 * Creates the position updater for the given category.
		 * 
		 * @param category the position category
		 */
		protected PaintPositionUpdater(String category) {
			super(category);
		}
		
		/**
		 * If an insertion happens at a position's offset, the
		 * position is extended rather than shifted. Also, if something is added 
		 * right behind the end of the position, the position is extended rather
		 * than kept stable.
		 */
		protected void adaptToInsert() {
			
			int myStart= fPosition.offset;
			int myEnd=   fPosition.offset + fPosition.length;
			myEnd= Math.max(myStart, myEnd);
			
			int yoursStart= fOffset;
			int yoursEnd=   fOffset + fReplaceLength;// - 1;
			yoursEnd= Math.max(yoursStart, yoursEnd);
			
			if (myEnd < yoursStart)
				return;
			
			if (myStart <= yoursStart)
				fPosition.length += fReplaceLength;
			else
				fPosition.offset += fReplaceLength;
		}
	};

	/**
	 * The paint position manager used by this paint manager. The paint position
	 * manager is installed on a single document and control the creation/disposed
	 * and updating of a position category that will be used for managing positions.
	 */
	static class PositionManager implements IPaintPositionManager {
		
		/** The document this positon manager works on */
		private IDocument fDocument;
		/** The position updater used for the managing position category */
		private IPositionUpdater fPositionUpdater;
		/** The managing position category */
		private String fCategory;
		
		/**
		 * Creates a new position manager. Initializes the managing
		 * position category using its class name and its hash value.
		 */
		public PositionManager() {
			fCategory= getClass().getName() + hashCode();
			fPositionUpdater= new PaintPositionUpdater(fCategory);
		}
		
		/**
		 * Installs this position manager in the given document. The position manager stays
		 * active until <code>uninstall</code> or <code>dispose</code> 
		 * is called. 
		 * 
		 * @param document the document to be installed on
		 */
		public void install(IDocument document) {
			fDocument= document;
			fDocument.addPositionCategory(fCategory);
			fDocument.addPositionUpdater(fPositionUpdater);
		}
		
		/**
		 * Diposes this position manager. The position manager is automatically
		 * uninstalled from the document it has previously been installed
		 * on.
		 */
		public void dispose() {
			uninstall(fDocument);
		}
		
		/**
		 * Uninstalls this position manager form the given document. If the position
		 * manager has no been installed on this document, this method is without effect.
		 * 
		 * @param document the document form which to uninstall
		 */
		public void uninstall(IDocument document) {
			if (document == fDocument && document != null) {
				try {
					fDocument.removePositionUpdater(fPositionUpdater);
					fDocument.removePositionCategory(fCategory);			
				} catch (BadPositionCategoryException x) {
					// should not happen
				}
				fDocument= null;
			}
		}
		
		/*
		 * @see IPositionManager#addManagedPosition(Position)
		 */
		public void managePosition(Position position) {
			try {
				fDocument.addPosition(fCategory, position);
			} catch (BadPositionCategoryException x) {
				// should not happen
			} catch (BadLocationException x) {
				// should not happen
			}
		}
		
		/*
		 * @see IPositionManager#removeManagedPosition(Position)
		 */
		public void unmanagePosition(Position position) {
			try {
				fDocument.removePosition(fCategory, position);
			} catch (BadPositionCategoryException x) {
				// should not happen
			}
		}
	};
	
	
	/** The painters managed by this paint manager. */
	private List fPainters= new ArrayList(2);
	/** The position manager used by this paint manager */
	private PositionManager fManager;
	/** The associated text viewer */
	private ITextViewer fTextViewer;
	
	/**
	 * Creates a new paint manager for the given text viewer.
	 * 
	 * @param textViewer the text viewer associated to this newly created paint manager
	 */
	public PaintManager(ITextViewer textViewer) {
		fTextViewer= textViewer;
	}
	
	
	/**
	 * Adds the given painter to the list of painters managed by this paint manager.
	 * If the painter is already registered with this paint manager, this method is 
	 * without effect.
	 * 
	 * @param painter the painter to be added
	 */
	public void addPainter(IPainter painter) {
		if (!fPainters.contains(painter)) {
			fPainters.add(painter);
			if (fPainters.size() == 1)
				install();
			painter.setPositionManager(fManager);
			painter.paint(IPainter.INTERNAL);
		}
	}
	
	/**
	 * Removes the given painter from the list of painters managed by this
	 * paint manager. If the painter has not previously been added to this
	 * paint manager, this method is without effect.
	 * 
	 * @param painter the painter to be removed
	 */
	public void removePainter(IPainter painter) {
		if (fPainters.remove(painter))
			painter.setPositionManager(null);
		if (fPainters.size() == 0)
			dispose();
	}
	
	/**
	 * Installs/activates this paint manager. Is called as soon as the
	 * first painter is to be managed by this paint manager.
	 */
	private void install() {
		
		fManager= new PositionManager();
		if (fTextViewer.getDocument() != null)
			fManager.install(fTextViewer.getDocument());
		
		fTextViewer.addTextInputListener(this);
		
		ISelectionProvider provider= fTextViewer.getSelectionProvider();
		provider.addSelectionChangedListener(this);
		
		fTextViewer.addTextListener(this);
		
		StyledText text= fTextViewer.getTextWidget();
		text.addKeyListener(this);
		text.addMouseListener(this);
	}
	
	/**
	 * Disposes this paint manager. The paint manager uninstalls itself
	 * and clears all registered painters. This method is also called when the
	 * last painter is removed from the list of managed painters.
	 */
	public void dispose() {
		
		if (fManager != null) {
			fManager.dispose();
			fManager= null;
		}
		
		for (Iterator e = fPainters.iterator(); e.hasNext();)
			((IPainter) e.next()).dispose();	
		fPainters.clear();
		
		fTextViewer.removeTextInputListener(this);
		
		ISelectionProvider provider= fTextViewer.getSelectionProvider();
		if (provider != null)
			provider.removeSelectionChangedListener(this);
		
		fTextViewer.removeTextListener(this);
		
		StyledText text= fTextViewer.getTextWidget();
		if (text != null && !text.isDisposed()) {
			text.removeKeyListener(this);
			text.removeMouseListener(this);
		}
	}
	
	/**
	 * Triggers all registered painters for the given reason.
	 * 
	 * @param reason the reason
	 * @see IPainter
	 */
	private void paint(int reason) {
		for (Iterator e = fPainters.iterator(); e.hasNext();)
			((IPainter) e.next()).paint(reason);
	}
	
	/*
	 * @see KeyListener#keyPressed(KeyEvent)
	 */
	public void keyPressed(KeyEvent e) {
		paint(IPainter.KEY_STROKE);
	}

	/*
	 * @see KeyListener#keyReleased(KeyEvent)
	 */
	public void keyReleased(KeyEvent e) {
	}

	/*
	 * @see MouseListener#mouseDoubleClick(MouseEvent)
	 */
	public void mouseDoubleClick(MouseEvent e) {
	}
	
	/*
	 * @see MouseListener#mouseDown(MouseEvent)
	 */
	public void mouseDown(MouseEvent e) {
		paint(IPainter.MOUSE_BUTTON);
	}
	
	/*
	 * @see MouseListener#mouseUp(MouseEvent)
	 */
	public void mouseUp(MouseEvent e) {
	}
	
	/*
	 * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		paint(IPainter.SELECTION);
	}
	
	/*
	 * @see ITextListener#textChanged(TextEvent)
	 */
	public void textChanged(TextEvent event) {
		
		if (!event.getViewerRedrawState())
			return;
			
		Control control= fTextViewer.getTextWidget();
		if (control != null) {
			control.getDisplay().asyncExec(new Runnable() {
				public void run() {
					if (fTextViewer != null) 
						paint(IPainter.TEXT_CHANGE);
				}
			});
		}
	}
	
	/*
	 * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
	 */
	public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
		if (oldInput != null) {
			for (Iterator e = fPainters.iterator(); e.hasNext();)
				((IPainter) e.next()).deactivate(false);				
			fManager.uninstall(oldInput);
		}
	}
	
	/*
	 * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
	 */
	public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
		if (newInput != null) {
			fManager.install(newInput);
			paint(IPainter.TEXT_CHANGE);
		}
	}
}

