/*******************************************************************************
 * 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.debug.internal.ui.views.console;


import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
import org.eclipse.debug.ui.console.IConsoleColorProvider;
import org.eclipse.debug.ui.console.IConsoleHyperlink;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

public class ConsoleViewer extends TextViewer implements IPropertyChangeListener, MouseTrackListener, MouseMoveListener, MouseListener, PaintListener, LineStyleListener, Listener {
	
	/**
	 * Hand cursor
	 */
	private Cursor fHandCursor;
	
	/**
	 * Text cursor
	 */
	private Cursor fTextCursor;
	
	/**
	 * The active hyperlink, or <code>null</code>
	 */
	private IConsoleHyperlink fHyperLink = null;
		
	protected InternalDocumentListener fInternalDocumentListener= new InternalDocumentListener();
	
	/**
	 * Whether the console scrolls as output is appended.
	 */
	private boolean fAutoScroll = true;
	
	/**
	 * Internal document listener.
	 */
	class InternalDocumentListener implements IDocumentListener {
		/**
		 * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
		 */
		public void documentAboutToBeChanged(DocumentEvent e) {
		}
		
		/**
		 * @see IDocumentListener#documentChanged(DocumentEvent)
		 */
		public void documentChanged(DocumentEvent e) {
			ConsoleDocument doc= (ConsoleDocument)getDocument();
			if (doc == null) {
				getTextWidget().setEditable(false);
				return;
			}
			getTextWidget().setEditable(!doc.isReadOnly());
			revealEndOfDocument();
		}
	}
	
	/**
	 * Creates a new console viewer and adds verification checking
	 * to only allow text modification if the text is being modified
	 * in the editable portion of the underlying document.
	 *
	 * @see org.eclipse.swt.events.VerifyListener
	 */	
	public ConsoleViewer(Composite parent) {
		super(parent, getSWTStyles());
		
		getTextWidget().setDoubleClickEnabled(true);
		
		DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		JFaceResources.getFontRegistry().addListener(this);

		getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.CONSOLE_FONT));
		getTextWidget().addMouseTrackListener(this);
		getTextWidget().addPaintListener(this);
		getTextWidget().addLineStyleListener(this);
		getTextWidget().addListener(SWT.KeyUp, this);
	}
	
	/**
	 * Returns the SWT style flags used when instantiating this viewer
	 */
	private static int getSWTStyles() {
		int styles= SWT.H_SCROLL | SWT.V_SCROLL;
		return styles;
	}

	/**
	 * Reveals (makes visible) the end of the current document
	 */
	protected void revealEndOfDocument() {
		if (isAutoScroll()) {
			IDocument doc = getDocument();
			int lines = doc.getNumberOfLines();
			try {
				// lines are 0-based
				int lineStartOffset = doc.getLineOffset(lines - 1);
				StyledText widget= getTextWidget();
				if (lineStartOffset > 0) {
					widget.setCaretOffset(lineStartOffset);
					widget.showSelection();
				}
				int lineEndOffset = lineStartOffset + doc.getLineLength(lines - 1);
				if (lineEndOffset > 0) {
					widget.setCaretOffset(lineEndOffset);
				}
			} catch (BadLocationException e) {
			}
		}
	}

	/**
	 * @see ITextViewer#setDocument(IDocument)
	 */
	public void setDocument(IDocument doc) {
		IDocument oldDoc= getDocument();
		IDocument document= doc;
		if (oldDoc == null && document == null) {
			return;
		}
		if (oldDoc != null) {
			oldDoc.removeDocumentListener(fInternalDocumentListener);
			if (oldDoc.equals(document)) {
				document.addDocumentListener(fInternalDocumentListener);
				return;
			}
		}

		super.setDocument(document);
		if (document != null) {
			revealEndOfDocument();
			document.addDocumentListener(fInternalDocumentListener);
		}
	}
	
	/**
	 * @see IFindReplaceTarget#canPerformFind()
	 */
	protected boolean canPerformFind() {
		return (getTextWidget() != null && getVisibleDocument() != null && getVisibleDocument().getLength() > 0);
	}	
	
	/**
	 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent event) {
		String propertyName= event.getProperty();
		if (propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_IN_RGB) ||
			propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_OUT_RGB) ||
			propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_ERR_RGB)) {
				getTextWidget().redraw();
		} else if (propertyName.equals(IInternalDebugUIConstants.CONSOLE_FONT)) {
			getTextWidget().setFont(JFaceResources.getFont(IInternalDebugUIConstants.CONSOLE_FONT));
		}
	}
	
	/**
	 * Dispose this viewer and resources
	 */
	public void dispose() {
		Control control = getTextWidget();
		if (control != null) {
			control.removeMouseTrackListener(this);
			control.removePaintListener(this);
		}
		if (fHandCursor != null) {
			fHandCursor.dispose();
		}
		if (fTextCursor != null) {
			fTextCursor.dispose();
		}
		DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
		JFaceResources.getFontRegistry().removeListener(this);
	}
	
	/**
	 * Only allow text to be typed at the end of the document.
	 * 
	 * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent)
	 */
	protected void handleVerifyEvent(VerifyEvent e) {
		ConsoleDocument doc= (ConsoleDocument)getDocument();
		if (doc != null) {
			if (doc.isReadOnly()) {
				e.doit = false;
				return;
			}
			IDocumentPartitioner partitioner = doc.getDocumentPartitioner();
			if (partitioner != null) {
				int length = doc.getLength();
				ITypedRegion[] partitions = partitioner.computePartitioning(length, 0);
				if (partitions.length == 0) {
				} else {
					ITypedRegion partition = partitions[partitions.length - 1];
					if (partition.getType().equals(InputPartition.INPUT_PARTITION_TYPE)) {
						// > 1 char in the input buffer
						e.doit = (e.start >= partition.getOffset()) && (e.end <= (partition.getLength() + partition.getOffset()));
					} else {
						// first character in the input buffer
						e.doit = length == e.start;
					}
				}
			}
		}
	}
	
	/**
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseEnter(MouseEvent e) {
		getTextWidget().addMouseMoveListener(this);
	}

	/**
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseExit(MouseEvent e) {
		getTextWidget().removeMouseMoveListener(this);
		if (fHyperLink != null) {
			linkExited(fHyperLink);
		}
	}

	/**
	 * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseHover(MouseEvent e) {
	}

	/**
	 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseMove(MouseEvent e) {
		int offset = -1;
		try {
			Point p = new Point(e.x, e.y);
			offset = getTextWidget().getOffsetAtLocation(p);
		} catch (IllegalArgumentException ex) {
			// out of the document range
		}
		updateLinks(offset);	
	}

	public IConsoleHyperlink getHyperlink(int offset) {
		if (offset >= 0 && getDocument() != null) {
			Position[] positions = null;
			try {
				positions = getDocument().getPositions(HyperlinkPosition.HYPER_LINK_CATEGORY);
			} catch (BadPositionCategoryException ex) {
				// no links have been added
				return null;
			}
			for (int i = 0; i < positions.length; i++) {
				Position position = positions[i];
				if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) {
					return ((HyperlinkPosition)position).getHyperLink();
				}
			}
		}
		return null;
	}

	protected void linkEntered(IConsoleHyperlink link) {
		Control control = getTextWidget();
		control.setRedraw(false);
		if (fHyperLink != null) {
			linkExited(fHyperLink);
		}
		fHyperLink = link;
		fHyperLink.linkEntered();
		control.setCursor(getHandCursor());
		control.setRedraw(true);
		control.redraw();
		control.addMouseListener(this);
	}
	
	protected void linkExited(IConsoleHyperlink link) {
		link.linkExited();
		fHyperLink = null;
		Control control = getTextWidget();
		control.setCursor(getTextCursor());
		control.redraw();
		control.removeMouseListener(this);
	}
	/**
	 * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
	 */
	public void paintControl(PaintEvent e) {
		if (fHyperLink != null) {
			IDocument doc = getDocument();
			if (doc == null) {
				return;
			}
			ConsoleDocumentPartitioner partitioner = (ConsoleDocumentPartitioner)doc.getDocumentPartitioner();
			if (partitioner == null) {
				return;
			}
			IRegion linkRegion = partitioner.getRegion(fHyperLink);
			if (linkRegion != null) {
				int start = linkRegion.getOffset();
				int end = start + linkRegion.getLength();
				IConsoleColorProvider contentProvider = partitioner.getContentProvider();
				try {
					ITypedRegion partition = doc.getPartition(start);
					Color fontColor = e.gc.getForeground();
					if (partition instanceof StreamPartition) {
						StreamPartition streamPartition = (StreamPartition)partition;
						fontColor = contentProvider.getColor(streamPartition.getStreamIdentifier());
					}
					int startLine = doc.getLineOfOffset(start);
					int endLine = doc.getLineOfOffset(end);
					for (int i = startLine; i <= endLine; i++) {
						IRegion lineRegion = doc.getLineInformation(i);
						int lineStart = lineRegion.getOffset();
						int lineEnd = lineStart + lineRegion.getLength();
						Color color = e.gc.getForeground();
						e.gc.setForeground(fontColor);
						if (lineStart < end) {
							lineStart = Math.max(start, lineStart);
							lineEnd = Math.min(end, lineEnd);
							Point p1 = getTextWidget().getLocationAtOffset(lineStart);
							Point p2 = getTextWidget().getLocationAtOffset(lineEnd);
							FontMetrics metrics = e.gc.getFontMetrics();
							int height = metrics.getHeight();
							e.gc.drawLine(p1.x, p1.y + height, p2.x, p2.y + height);
						}
						e.gc.setForeground(color);
					}
				} catch (BadLocationException ex) {
				}
			}
		}
	}
	
	protected Cursor getHandCursor() {
		if (fHandCursor == null) {
			fHandCursor = new Cursor(DebugUIPlugin.getStandardDisplay(), SWT.CURSOR_HAND);
		}
		return fHandCursor;
	}
	
	protected Cursor getTextCursor() {
		if (fTextCursor == null) {
			fTextCursor = new Cursor(DebugUIPlugin.getStandardDisplay(), SWT.CURSOR_IBEAM);
		}
		return fTextCursor;
	}	

	/**
	 * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDoubleClick(MouseEvent e) {
	}

	/**
	 * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseDown(MouseEvent e) {
	}

	/**
	 * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
	 */
	public void mouseUp(MouseEvent e) {
		if (fHyperLink != null) {
			String selection = getTextWidget().getSelectionText();
			if (selection.length() <= 0) {
				if (e.button == 1) {
					fHyperLink.linkActivated();
				}
			}
		}
	}

	/**
	 * @see org.eclipse.swt.custom.LineStyleListener#lineGetStyle(org.eclipse.swt.custom.LineStyleEvent)
	 */
	public void lineGetStyle(LineStyleEvent event) {
		IDocument document = getDocument();
		if (document != null) {
			ConsoleDocumentPartitioner partitioner = (ConsoleDocumentPartitioner)document.getDocumentPartitioner();
			if (partitioner != null) {
				IConsoleColorProvider contentProvider = partitioner.getContentProvider();
				ITypedRegion[] regions = partitioner.computePartitioning(event.lineOffset, event.lineOffset + event.lineText.length());
				StyleRange[] styles = new StyleRange[regions.length];
				for (int i = 0; i < regions.length; i++) {
					StreamPartition partition = (StreamPartition)regions[i];
					Color color = contentProvider.getColor(partition.getStreamIdentifier());
					styles[i] = new StyleRange(partition.getOffset(), partition.getLength(), color, null);
				}	
				event.styles = styles;
			}
		}
	}
	
	/**
	 * Sets whether this viewer should auto-scroll as output is appended to the
	 * document.
	 * 
	 * @param scroll
	 */
	public void setAutoScroll(boolean scroll) {
		fAutoScroll = scroll;
	}
	
	/**
	 * Returns whether this viewer should auto-scroll as output is appended to
	 * the document.
	 */
	public boolean isAutoScroll() {
		return fAutoScroll;
	}	

	/**
	 * On KeyUp events, see if we need to enter/exit a link.
	 * 
	 * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
	 */
	public void handleEvent(Event event) {
		int offset = getTextWidget().getCaretOffset();
		updateLinks(offset);
	}
	
	/**
	 * The cursor has just be moved to the given offset, the mouse has
	 * hovered over the given offset. Update link rendering.
	 * 
	 * @param offset
	 */
	protected void updateLinks(int offset) {
		if (offset >= 0) {
			IConsoleHyperlink link = getHyperlink(offset);
			if (link != null) {
				if (link.equals(fHyperLink)) {
					return;
				} else {
					linkEntered(link);
					return;
				}
			}
		}
		if (fHyperLink != null) {
			linkExited(fHyperLink);
		}		
	}

}

