package org.eclipse.jface.text.source;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */


import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Layout;

import org.eclipse.jface.text.AbstractHoverInformationControlManager;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.IContentFormatter;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;


/**
 * SWT based implementation of <code>ISourceViewer</code>. The same rules apply 
 * as for <code>TextViewer</code>. A source viewer uses an <code>IVerticalRuler</code>
 * as its annotation presentation area. The vertical ruler is a small strip shown left
 * of the viewer's text widget.<p>
 * Clients are supposed to instantiate a source viewer and subsequently to communicate
 * with it exclusively using the <code>ISourceViewer</code> interface. Clients should not
 * subclass this class as it is rather likely that subclasses will be broken by future releases. 
 */
public class SourceViewer extends TextViewer implements ISourceViewer {


	/**
	 * Layout of a source viewer. Vertical ruler and text widget are shown side by side.
	 */
	class RulerLayout extends Layout {
		
		protected int fGap;
		
		protected RulerLayout(int gap) {
			fGap= gap;
		}
		
		protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
			Control[] children= composite.getChildren();
			Point s= children[children.length - 1].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
			if (fVerticalRuler != null && fIsVerticalRulerVisible)
				s.x += fVerticalRuler.getWidth() + fGap;
			return s;
		}
		
		protected void layout(Composite composite, boolean flushCache) {
			Rectangle clArea= composite.getClientArea();
			if (fVerticalRuler != null && fIsVerticalRulerVisible) {
				
				Rectangle trim= getTextWidget().computeTrim(0, 0, 0, 0);
				int scrollbarHeight= trim.height;
				
				int rulerWidth= fVerticalRuler.getWidth();
				fVerticalRuler.getControl().setBounds(0, 0, rulerWidth, clArea.height - scrollbarHeight);
				getTextWidget().setBounds(rulerWidth + fGap, 0, clArea.width - rulerWidth - fGap, clArea.height);
			
			} else
				getTextWidget().setBounds(0, 0, clArea.width, clArea.height);
		}
	};
	
	
	/** The viewer's content assistant */
	protected IContentAssistant fContentAssistant;
	/** The viewer's content formatter */
	protected IContentFormatter fContentFormatter;
	/** The viewer's model reconciler */
	protected IReconciler fReconciler;
	/** The viewer's presentation reconciler */
	protected IPresentationReconciler fPresentationReconciler;
	/** The viewer's annotation hover */
	protected IAnnotationHover fAnnotationHover;
	/** The viewer's information presenter */
	protected IInformationPresenter fInformationPresenter;
	
	/** Visual vertical ruler */
	private IVerticalRuler fVerticalRuler;
	/** Visibility of vertical ruler */
	private boolean fIsVerticalRulerVisible;
	/** The SWT widget used when supporting a vertical ruler */
	private Composite fComposite;
	/** The vertical ruler's annotation model */
	private VisualAnnotationModel fVisualAnnotationModel;
	/** The viewer's range indicator to be shown in the vertical ruler */
	private Annotation fRangeIndicator;
	/** The viewer's vertical ruler hovering controller */
	private AbstractHoverInformationControlManager fVerticalRulerHoveringController;
	
	
	
	/** The size of the gap between the vertical ruler and the text widget */
	protected final static int GAP_SIZE= 2;
	
	/**
	 * Constructs a new source viewer. The vertical ruler is initially visible.
	 * The viewer has not yet been initialized with a source viewer configuration.
	 *
	 * @param parent the parent of the viewer's control
	 * @param ruler the vertical ruler used by this source viewer
	 * @patam styles the SWT style bits
	 */
	public SourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
		super();
		
		fVerticalRuler= ruler;
		fIsVerticalRulerVisible= (ruler != null);
		createControl(parent, styles);
	}
	
	/*
	 * @see TextViewer#createControl
	 */
	protected void createControl(Composite parent, int styles) {
		
		if (fVerticalRuler != null) {
			styles= (styles & ~SWT.BORDER);
			fComposite= new Canvas(parent, SWT.NONE);
			fComposite.setLayout(new RulerLayout(GAP_SIZE));
			parent= fComposite;
		}
		
		super.createControl(parent, styles);
					
		if (fComposite != null)
			fVerticalRuler.createControl(fComposite, this);
	}
	
	/*
	 * @see TextViewer#getControl
	 */
	public Control getControl() {
		if (fComposite != null)
			return fComposite;
		return super.getControl();
	}
	
	/*
	 * @see ISourceViewer#setAnnotationHover
	 */
	public void setAnnotationHover(IAnnotationHover annotationHover) {
		fAnnotationHover= annotationHover;
	}
	
	/*
	 * @see ISourceViewer#configure
	 */
	public void configure(SourceViewerConfiguration configuration) {
		
		if (getTextWidget() == null)
			return;
		
		// install content type independent plugins
		fPresentationReconciler= configuration.getPresentationReconciler(this);
		if (fPresentationReconciler != null)
			fPresentationReconciler.install(this);
								
		fReconciler= configuration.getReconciler(this);
		if (fReconciler != null)
			fReconciler.install(this);
			
		fContentAssistant= configuration.getContentAssistant(this);
		if (fContentAssistant != null)
			fContentAssistant.install(this);
			
		fContentFormatter= configuration.getContentFormatter(this);
		
		fInformationPresenter= configuration.getInformationPresenter(this);
		if (fInformationPresenter != null)
			fInformationPresenter.install(this);
		
		setUndoManager(configuration.getUndoManager(this));
		
		getTextWidget().setTabs(configuration.getTabWidth(this));
		
		setAnnotationHover(configuration.getAnnotationHover(this));
		
		setHoverControlCreator(configuration.getInformationControlCreator(this));
		
		// install content type specific plugins
		String[] types= configuration.getConfiguredContentTypes(this);
		for (int i= 0; i < types.length; i++) {
			
			String t= types[i];
				
			setAutoIndentStrategy(configuration.getAutoIndentStrategy(this, t), t);
			setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t);
			setTextHover(configuration.getTextHover(this, t), t);
			
			String[] prefixes= configuration.getIndentPrefixes(this, t);
			if (prefixes != null && prefixes.length > 0)
				setIndentPrefixes(prefixes, t);
			
			prefixes= configuration.getDefaultPrefixes(this, t);
			if (prefixes != null && prefixes.length > 0)
				setDefaultPrefixes(prefixes, t);
		}
		
		activatePlugins();
	}
	
	/*
	 * @see TextViewer#activatePlugins
	 */
	public void activatePlugins() {
		
		if (fVerticalRuler != null && fAnnotationHover != null && fVerticalRulerHoveringController == null) {
			fVerticalRulerHoveringController= new AnnotationBarHoverManager(this, fVerticalRuler, fAnnotationHover, fHoverControlCreator);
			fVerticalRulerHoveringController.install(fVerticalRuler.getControl());
		}
		
		super.activatePlugins();
	}
	
	/*
	 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel)
	 */
	public void setDocument(IDocument document) {
		setDocument(document, null, -1, -1);		
	}
	
	/*
	 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
	 */
	public void setDocument(IDocument document, int visibleRegionOffset, int visibleRegionLength) {
		setDocument(document, null, visibleRegionOffset, visibleRegionLength);
	}
	
	/*
	 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel)
	 */
	public void setDocument(IDocument document, IAnnotationModel annotationModel) {
		setDocument(document, annotationModel, -1, -1);		
	}
	
	/*
	 * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
	 */
	public void setDocument(IDocument document, IAnnotationModel annotationModel, int visibleRegionOffset, int visibleRegionLength) {
		
		if (fVerticalRuler == null) {
			
			if (visibleRegionOffset == -1 && visibleRegionLength == -1)
				super.setDocument(document);
			else
				super.setDocument(document, visibleRegionOffset, visibleRegionLength);
		
		} else {
			
			if (fVisualAnnotationModel != null && getDocument() != null)
				fVisualAnnotationModel.disconnect(getDocument());
			
			if (visibleRegionOffset == -1 && visibleRegionLength == -1)
				super.setDocument(document);
			else
				super.setDocument(document, visibleRegionOffset, visibleRegionLength);
			
			if (annotationModel != null && document != null) {
				fVisualAnnotationModel= new VisualAnnotationModel(annotationModel);
				fVisualAnnotationModel.connect(document);
			} else {
				fVisualAnnotationModel= null;
			}
			
			fVerticalRuler.setModel(fVisualAnnotationModel);
		}
	}
	
	/*
	 * @see ISourceViewer#getAnnotationModel
	 */
	public IAnnotationModel getAnnotationModel() {
		if (fVisualAnnotationModel != null)
			return fVisualAnnotationModel.getModelAnnotationModel();
		return null;
	}
	
	/*
	 * @see TextViewer#handleDispose
	 */
	protected void handleDispose() {
		
		if (fPresentationReconciler != null) {
			fPresentationReconciler.uninstall();
			fPresentationReconciler= null;
		}
		
		if (fReconciler != null) {
			fReconciler.uninstall();
			fReconciler= null;
		}
		
		if (fContentAssistant != null) {
			fContentAssistant.uninstall();
			fContentAssistant= null;
		}
		
		fContentFormatter= null;
		
		if (fInformationPresenter != null) {
			fInformationPresenter.uninstall();
			fInformationPresenter= null;
		}
		
		if (fVisualAnnotationModel != null && getDocument() != null) {
			fVisualAnnotationModel.disconnect(getDocument());
			fVisualAnnotationModel= null;
		}
		
		fVerticalRuler= null;
				
		if (fVerticalRulerHoveringController != null) {
			fVerticalRulerHoveringController.dispose();
			fVerticalRulerHoveringController= null;
		}
		
		super.handleDispose();
	}
	
	/*
	 * @see ITextOperationTarget#canDoOperation
	 */
	public boolean canDoOperation(int operation) {
		
		if (getTextWidget() == null)
			return false;
		
		if (operation == CONTENTASSIST_PROPOSALS)
			return fContentAssistant != null && isEditable();
			
		if (operation == CONTENTASSIST_CONTEXT_INFORMATION)
			return fContentAssistant != null;
			
		if (operation == INFORMATION)
			return fInformationPresenter != null;
			
		if (operation == FORMAT) {
			Point p= getSelectedRange();
			int length= (p == null ? -1 : p.y);
			return (fContentFormatter != null && isEditable() && (length == 0 || isBlockSelected()));
		}
		
		return super.canDoOperation(operation);
	}
	
	/*
	 * @see ITextOperationTarget#doOperation
	 */
	public void doOperation(int operation) {
		
		if (getTextWidget() == null)
			return;
		
		switch (operation) {
			case CONTENTASSIST_PROPOSALS:
				fContentAssistant.showPossibleCompletions();
				return;
			case CONTENTASSIST_CONTEXT_INFORMATION:
				fContentAssistant.showContextInformation();
				return;
			case INFORMATION:
				fInformationPresenter.showInformation();
				return;
			case FORMAT: {
				Point s= getSelectedRange();
				IDocument document= getDocument();
				
				Position p= new Position(s.x, s.y);
				IRegion r= (s.y == 0) ? getVisibleRegion() : new Region(s.x, s.y);

				try {
					document.addPosition(p);
					fContentFormatter.format(document, r);

					setSelectedRange(p.getOffset(), p.getLength());
						
				} catch (BadLocationException e) {
					// should not happen
				} finally {
					document.removePosition(p);					
				}

				return;
			}
			default:
				super.doOperation(operation);
		}
	}		
		
	/*
	 * @see ISourceViewer#setRangeIndicator
	 */
	public void setRangeIndicator(Annotation rangeIndicator) {
		fRangeIndicator= rangeIndicator;
	}
		
	/*
	 * @see ISourceViewer#setRangeIndication 	 
	 */
	public void setRangeIndication(int start, int length, boolean moveCursor) {
		
		if (moveCursor) {
			setSelectedRange(start, 0);
			revealRange(start, length);
		}
		
		if (fRangeIndicator != null && fVisualAnnotationModel != null)
			fVisualAnnotationModel.modifyAnnotation(fRangeIndicator, new Position(start, length));
	}
	
	/*
	 * @see ISourceViewer#getRangeIndication
	 */
	public IRegion getRangeIndication() {
		if (fRangeIndicator != null && fVisualAnnotationModel != null) {
			Position position= fVisualAnnotationModel.getPosition(fRangeIndicator);
			if (position != null)
				return new Region(position.getOffset(), position.getLength());
		}
		
		return null;
	}
	
	/*
	 * @see ISourceViewer#removeRangeIndication
	 */
	public void removeRangeIndication() {
		if (fRangeIndicator != null && fVisualAnnotationModel != null)
			fVisualAnnotationModel.modifyAnnotation(fRangeIndicator, null);
	}
	
	/*
	 * @see ISourceViewer#showAnnotations
	 */
	public void showAnnotations(boolean show) {
		boolean old= fIsVerticalRulerVisible;
		fIsVerticalRulerVisible= (show && fVerticalRuler != null);
		if (old != fIsVerticalRulerVisible)
			fComposite.layout();
	}		
}