/*******************************************************************************
 * 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);
		}
	}
}

