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

package org.eclipse.ui.console;

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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceColors;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentAdapter;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IPositionUpdater;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
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.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.internal.console.ConsoleDocumentAdapter;
import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition;
import org.eclipse.ui.progress.WorkbenchJob;

/**
 * Default viewer used to display a <code>TextConsole</code>.
 * <p>
 * Clients may subclass this class.
 * </p>
 * 
 * @since 3.1
 */
public class TextConsoleViewer extends SourceViewer implements LineStyleListener, LineBackgroundListener, MouseTrackListener, MouseMoveListener, MouseListener {
    /**
     * Adapts document to the text widget.
     */
    private ConsoleDocumentAdapter documentAdapter;

    private IHyperlink hyperlink;

    private Cursor handCursor;

    private Cursor textCursor;

    private int consoleWidth = -1;

    private TextConsole console;

    private IPropertyChangeListener propertyChangeListener;

    private IDocumentListener documentListener = new IDocumentListener() {
        public void documentAboutToBeChanged(DocumentEvent event) {
        }

        public void documentChanged(DocumentEvent event) {
            updateLinks(event.fOffset);
        }
    };
    // event listener used to send event to hyperlink for IHyperlink2
    private Listener mouseUpListener = new Listener() {
		public void handleEvent(Event event) {
	        if (hyperlink != null) {
	            String selection = getTextWidget().getSelectionText();
	            if (selection.length() <= 0) {
	                if (event.button == 1) {
	                	if (hyperlink instanceof IHyperlink2) {
							((IHyperlink2) hyperlink).linkActivated(event);
						} else {
							hyperlink.linkActivated();
						}
	                }
	            }
	        }
		}
	};

    WorkbenchJob revealJob = new WorkbenchJob("Reveal End of Document") {//$NON-NLS-1$
        public IStatus runInUIThread(IProgressMonitor monitor) {
            StyledText textWidget = getTextWidget();
            if (textWidget != null) {
                int lineCount = textWidget.getLineCount();
                textWidget.setTopIndex(lineCount - 1);
            }
            return Status.OK_STATUS;
        }
    };
    
    private IPositionUpdater positionUpdater = new IPositionUpdater() {
        public void update(DocumentEvent event) {
            try {
                IDocument document = getDocument();
                if (document != null) {
                    Position[] positions = document.getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
                    for (int i = 0; i < positions.length; i++) {
                        Position position = positions[i];
                        if (position.offset == event.fOffset && position.length<=event.fLength) {
                            position.delete();
                        }
                        if (position.isDeleted) {
                            document.removePosition(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY, position);
                        }
                    }
                }
            } catch (BadPositionCategoryException e) {
            }
        }
    };

    /**
     * Constructs a new viewer in the given parent for the specified console.
     * 
     * @param parent
     *            containing widget
     * @param console
     *            text console
     */
    public TextConsoleViewer(Composite parent, TextConsole console) {
        super(parent, null, SWT.V_SCROLL | SWT.H_SCROLL);
        this.console = console;

        IDocument document = console.getDocument();
        setDocument(document);

        StyledText styledText = getTextWidget();
        styledText.setDoubleClickEnabled(true);
        styledText.addLineStyleListener(this);
        styledText.addLineBackgroundListener(this);
        styledText.setEditable(true);
        setFont(console.getFont());
        styledText.addMouseTrackListener(this);
        styledText.addListener(SWT.MouseUp, mouseUpListener);

        ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
        propertyChangeListener = new HyperlinkColorChangeListener();
        colorRegistry.addListener(propertyChangeListener);

        revealJob.setSystem(true);
        document.addDocumentListener(documentListener);
        document.addPositionUpdater(positionUpdater);
    }

    /**
     * Sets the tab width used by this viewer.
     * 
     * @param tabWidth
     *            the tab width used by this viewer
     */
    public void setTabWidth(int tabWidth) {
        StyledText styledText = getTextWidget();
        int oldWidth = styledText.getTabs();
        if (tabWidth != oldWidth) {
            styledText.setTabs(tabWidth);
        }
    }

    /**
     * Sets the font used by this viewer.
     * 
     * @param font
     *            the font used by this viewer
     */
    public void setFont(Font font) {
        StyledText styledText = getTextWidget();
        Font oldFont = styledText.getFont();
        if (oldFont == font) {
            return;
        }
        if (font == null || !(font.equals(oldFont))) {
            styledText.setFont(font);
        }
    }

    /**
     * Positions the cursor at the end of the document.
     */
    protected void revealEndOfDocument() {
        revealJob.schedule(50);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.swt.custom.LineStyleListener#lineGetStyle(org.eclipse.swt.custom.LineStyleEvent)
     */
    public void lineGetStyle(LineStyleEvent event) {
        IDocument document = getDocument();
        if (document != null && document.getLength() > 0) {
            ArrayList ranges = new ArrayList();
            int offset = event.lineOffset;
            int length = event.lineText.length();

            StyleRange[] partitionerStyles = ((IConsoleDocumentPartitioner) document.getDocumentPartitioner()).getStyleRanges(event.lineOffset, event.lineText.length());
            if (partitionerStyles != null) {
                for (int i = 0; i < partitionerStyles.length; i++) {
                    ranges.add(partitionerStyles[i]);
                }
            } else {
                ranges.add(new StyleRange(offset, length, null, null));
            }

            try {
                Position[] positions = getDocument().getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY);
                Position[] overlap = findPosition(offset, length, positions);
                Color color = JFaceColors.getHyperlinkText(Display.getCurrent());
                if (overlap != null) {
                    for (int i = 0; i < overlap.length; i++) {
                        Position position = overlap[i];
                        StyleRange linkRange = new StyleRange(position.offset, position.length, color, null);
                        linkRange.underline = true;
                        override(ranges, linkRange);
                    }
                }
            } catch (BadPositionCategoryException e) {
            }

            if (ranges.size() > 0) {
                event.styles = (StyleRange[]) ranges.toArray(new StyleRange[ranges.size()]);
            }
        }
    }

    private void override(List ranges, StyleRange newRange) {
        if (ranges.isEmpty()) {
            ranges.add(newRange);
            return;
        }

        int start = newRange.start;
        int end = start + newRange.length;
        for (int i = 0; i < ranges.size(); i++) {
            StyleRange existingRange = (StyleRange) ranges.get(i);
            int rEnd = existingRange.start + existingRange.length;
            if (end <= existingRange.start || start >= rEnd) {
                continue;
            }

            if (start < existingRange.start && end > existingRange.start) {
                start = existingRange.start;
            }

            if (start >= existingRange.start && end <= rEnd) {
                existingRange.length = start - existingRange.start;
                ranges.add(++i, newRange);
                if (end != rEnd) {
                    ranges.add(++i, new StyleRange(end, rEnd - end - 1, existingRange.foreground, existingRange.background));
                }
                return;
            } else if (start >= existingRange.start && start < rEnd) {
                existingRange.length = start - existingRange.start;
                ranges.add(++i, newRange);
            } else if (end >= rEnd) {
                ranges.remove(i);
            } else {
                ranges.add(++i, new StyleRange(end + 1, rEnd - end + 1, existingRange.foreground, existingRange.background));
            }
        }
    }

    /**
     * Binary search for the positions overlapping the given range
     * 
     * @param offset
     *            the offset of the range
     * @param length
     *            the length of the range
     * @param positions
     *            the positions to search
     * @return the positions overlapping the given range, or <code>null</code>
     */
    private Position[] findPosition(int offset, int length, Position[] positions) {

        if (positions.length == 0)
            return null;

        int rangeEnd = offset + length;
        int left = 0;
        int right = positions.length - 1;
        int mid = 0;
        Position position = null;

        while (left < right) {

            mid = (left + right) / 2;

            position = positions[mid];
            if (rangeEnd < position.getOffset()) {
                if (left == mid)
                    right = left;
                else
                    right = mid - 1;
            } else if (offset > (position.getOffset() + position.getLength() - 1)) {
                if (right == mid)
                    left = right;
                else
                    left = mid + 1;
            } else {
                left = right = mid;
            }
        }

        List list = new ArrayList();
        int index = left - 1;
        if (index >= 0) {
            position = positions[index];
            while (index >= 0 && (position.getOffset() + position.getLength()) > offset) {
                index--;
                if (index > 0) {
                    position = positions[index];
                }
            }
        }
        index++;
        position = positions[index];
        while (index < positions.length && (position.getOffset() < rangeEnd)) {
            list.add(position);
            index++;
            if (index < positions.length) {
                position = positions[index];
            }
        }

        if (list.isEmpty()) {
            return null;
        }
        return (Position[]) list.toArray(new Position[list.size()]);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.swt.custom.LineBackgroundListener#lineGetBackground(org.eclipse.swt.custom.LineBackgroundEvent)
     */
    public void lineGetBackground(LineBackgroundEvent event) {
        event.lineBackground = null;
    }

    /**
     * Returns the hand cursor.
     * 
     * @return the hand cursor
     */
    protected Cursor getHandCursor() {
        if (handCursor == null) {
            handCursor = new Cursor(ConsolePlugin.getStandardDisplay(), SWT.CURSOR_HAND);
        }
        return handCursor;
    }

    /**
     * Returns the text cursor.
     * 
     * @return the text cursor
     */
    protected Cursor getTextCursor() {
        if (textCursor == null) {
            textCursor = new Cursor(ConsolePlugin.getStandardDisplay(), SWT.CURSOR_IBEAM);
        }
        return textCursor;
    }

    /**
     * Notification a hyperlink has been entered.
     * 
     * @param link
     *            the link that was entered
     */
    protected void linkEntered(IHyperlink link) {
        Control control = getTextWidget();
        if (hyperlink != null) {
            linkExited(hyperlink);
        }
        hyperlink = link;
        hyperlink.linkEntered();
        control.setCursor(getHandCursor());
        control.redraw();
        control.addMouseListener(this);
    }

    /**
     * Notification a link was exited.
     * 
     * @param link
     *            the link that was exited
     */
    protected void linkExited(IHyperlink link) {
        link.linkExited();
        hyperlink = null;
        Control control = getTextWidget();
        control.setCursor(getTextCursor());
        control.redraw();
        control.removeMouseListener(this);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
     */
    public void mouseEnter(MouseEvent e) {
        getTextWidget().addMouseMoveListener(this);
    }

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

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

    /*
     * (non-Javadoc)
     * 
     * @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);
    }

    /**
     * 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) {
            IHyperlink link = getHyperlink(offset);
            if (link != null) {
                if (link.equals(hyperlink)) {
                    return;
                }
                linkEntered(link);
                return;
            }
        }
        if (hyperlink != null) {
            linkExited(hyperlink);
        }
    }

    /**
     * Returns the currently active hyperlink or <code>null</code> if none.
     * 
     * @return the currently active hyperlink or <code>null</code> if none
     */
    public IHyperlink getHyperlink() {
        return hyperlink;
    }

    /**
     * Returns the hyperlink at the specified offset, or <code>null</code> if
     * none.
     * 
     * @param offset
     *            offset at which a hyperlink has been requested
     * @return hyperlink at the specified offset, or <code>null</code> if none
     */
    public IHyperlink getHyperlink(int offset) {
        if (offset >= 0 && console != null) {
            return console.getHyperlink(offset);
        }
        return null;
    }

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

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

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
     */
    public void mouseUp(MouseEvent e) {
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.text.TextViewer#createDocumentAdapter()
     */
    protected IDocumentAdapter createDocumentAdapter() {
        if (documentAdapter == null) {
            documentAdapter = new ConsoleDocumentAdapter(consoleWidth = -1);
        }
        return documentAdapter;
    }

    /**
     * Sets the console to have a fixed character width. Use -1 to indicate that
     * a fixed width should not be used.
     * 
     * @param width
     *            fixed characater width of the console, or -1
     */
    public void setConsoleWidth(int width) {
        if (consoleWidth != width) {
            consoleWidth = width;
            ConsolePlugin.getStandardDisplay().asyncExec(new Runnable() {
                public void run() {
                    if (documentAdapter != null) {
                        documentAdapter.setWidth(consoleWidth);
                    }
                }
            });
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.text.TextViewer#handleDispose()
     */
    protected void handleDispose() {
        super.handleDispose();
        IDocument document = getDocument();
        if (document != null) {
            document.removeDocumentListener(documentListener);
            document.removePositionUpdater(positionUpdater);
        }

        StyledText styledText = getTextWidget();
        styledText.removeLineStyleListener(this);
        styledText.removeLineBackgroundListener(this);
        styledText.removeMouseTrackListener(this);

        handCursor = null;
        textCursor = null;
        hyperlink = null;
        console = null;

        ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
        colorRegistry.removeListener(propertyChangeListener);
    }

    class HyperlinkColorChangeListener implements IPropertyChangeListener {
        public void propertyChange(PropertyChangeEvent event) {
            if (event.getProperty().equals(JFacePreferences.ACTIVE_HYPERLINK_COLOR) || event.getProperty().equals(JFacePreferences.HYPERLINK_COLOR)) {
                getTextWidget().redraw();
            }
        }

    }

    /*
     * work around to memory leak in TextViewer$WidgetCommand
     */
    protected void updateTextListeners(WidgetCommand cmd) {
        super.updateTextListeners(cmd);
        cmd.preservedText = null;
        cmd.event = null;
        cmd.text = null;
    }

    protected void internalRevealRange(int start, int end) {
        StyledText textWidget = getTextWidget();
        int startLine = documentAdapter.getLineAtOffset(start);
        int endLine = documentAdapter.getLineAtOffset(end);

        int top = textWidget.getTopIndex();
        if (top > -1) {
            // scroll vertically
            int lines = getVisibleLinesInViewport();
            int bottom = top + lines;

            // two lines at the top and the bottom should always be left
            // if window is smaller than 5 lines, always center position is
            // chosen
            int bufferZone = 2;
            if (startLine >= top + bufferZone && startLine <= bottom - bufferZone && endLine >= top + bufferZone && endLine <= bottom - bufferZone) {

                // do not scroll at all as it is already visible
            } else {
                int delta = Math.max(0, lines - (endLine - startLine));
                textWidget.setTopIndex(startLine - delta / 3);
                updateViewportListeners(INTERNAL);
            }

            // scroll horizontally
            if (endLine < startLine) {
                endLine += startLine;
                startLine = endLine - startLine;
                endLine -= startLine;
            }

            int startPixel = -1;
            int endPixel = -1;

            if (endLine > startLine) {
                // reveal the beginning of the range in the start line
                IRegion extent = getExtent(start, start);
                startPixel = extent.getOffset() + textWidget.getHorizontalPixel();
                endPixel = startPixel;
            } else {
                IRegion extent = getExtent(start, end);
                startPixel = extent.getOffset() + textWidget.getHorizontalPixel();
                endPixel = startPixel + extent.getLength();
            }

            int visibleStart = textWidget.getHorizontalPixel();
            int visibleEnd = visibleStart + textWidget.getClientArea().width;

            // scroll only if not yet visible
            if (startPixel < visibleStart || visibleEnd < endPixel) {
                // set buffer zone to 10 pixels
                bufferZone = 10;
                int newOffset = visibleStart;
                int visibleWidth = visibleEnd - visibleStart;
                int selectionPixelWidth = endPixel - startPixel;

                if (startPixel < visibleStart)
                    newOffset = startPixel;
                else if (selectionPixelWidth + bufferZone < visibleWidth)
                    newOffset = endPixel + bufferZone - visibleWidth;
                else
                    newOffset = startPixel;

                float index = ((float) newOffset) / ((float) getAverageCharWidth());

                textWidget.setHorizontalIndex(Math.round(index));
            }

        }
    }

}
