/*******************************************************************************
 * Copyright (c) 2000, 2015 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 java.util.concurrent.atomic.AtomicBoolean;

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.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.MouseWheelListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
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.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.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;

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.JFaceTextUtil;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.SourceViewer;

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 IScrollLockStateProvider scrollLockStateProvider;

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

        @Override
		public void documentChanged(DocumentEvent event) {
            updateLinks(event.fOffset);
        }
    };
    // event listener used to send event to hyperlink for IHyperlink2
    private Listener mouseUpListener = new Listener() {
		@Override
		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();
						}
	                }
	            }
	        }
		}
	};

	// to store to user scroll lock action
	private AtomicBoolean userHoldsScrollLock = new AtomicBoolean(false);

    WorkbenchJob revealJob = new WorkbenchJob("Reveal End of Document") {//$NON-NLS-1$
        @Override
		public IStatus runInUIThread(IProgressMonitor monitor) {
			scrollToEndOfDocument();
            return Status.OK_STATUS;
        }
    };

	// reveal the end of the document
	private void scrollToEndOfDocument() {
		StyledText textWidget = getTextWidget();
		if (textWidget != null && !textWidget.isDisposed()) {
			int lineCount = textWidget.getLineCount();
			textWidget.setTopIndex(lineCount > 0 ? lineCount - 1 : 0);
		}

	}

	// set the scroll Lock setting for Console Viewer and Console View
	private void setScrollLock(boolean lock) {
		userHoldsScrollLock.set(lock);
		if (scrollLockStateProvider != null && scrollLockStateProvider.getAutoScrollLock() != lock) {
			scrollLockStateProvider.setAutoScrollLock(lock);
		}
	}

	// set the scroll Lock setting for Console Viewer and Console View
	private boolean checkEndOfDocument() {
		StyledText textWidget = getTextWidget();
		if (textWidget != null && !textWidget.isDisposed()) {
			int partialIndex = JFaceTextUtil.getPartialBottomIndex(textWidget);
			int bottomLine = JFaceTextUtil.getLineIndex(textWidget, partialIndex);
			int lineCount = textWidget.getLineCount();
			int delta = textWidget.getVerticalBar().getIncrement() * 2;
			return lineCount - bottomLine < delta;
		}
		return false;
	}

    private IPositionUpdater positionUpdater = new IPositionUpdater() {
        @Override
		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 the containing composite
	 * @param console the text console
	 * @param scrollLockStateProvider the scroll lock state provider
	 * @since 3.6
	 */
	public TextConsoleViewer(Composite parent, TextConsole console, IScrollLockStateProvider scrollLockStateProvider) {
		this(parent, console);
		this.scrollLockStateProvider = scrollLockStateProvider;


	}

	/**
	 * 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);
        styledText.setBackground(console.getBackground());
        setFont(console.getFont());
        styledText.addMouseTrackListener(this);
        styledText.addListener(SWT.MouseUp, mouseUpListener);
		// event listener used to send event to vertical scroll bar
		styledText.getVerticalBar().addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				// scroll lock if vertical scroll bar dragged, OR selection on
				// vertical bar used
				if (e.detail == SWT.TOP || e.detail == SWT.HOME) {
					// selecting TOP or HOME should lock
					setScrollLock(true);
				} else if (e.detail == SWT.ARROW_UP || e.detail == SWT.PAGE_UP) {
					// selecting TOP or HOME should lock if not end of document
					if (checkEndOfDocument()) {
						setScrollLock(false);
					} else {
						setScrollLock(true);
					}
				} else if (e.detail == SWT.END || e.detail == SWT.BOTTOM) {
					// selecting BOTTOM or END from vertical scroll makes it
					// reveal the end
					setScrollLock(false);
				} else if (e.detail == SWT.DRAG) {
					if (checkEndOfDocument()) {
						setScrollLock(false);
					} else {
						setScrollLock(true);
					}
				} else if ((e.detail == SWT.PAGE_DOWN || e.detail == SWT.ARROW_DOWN) && checkEndOfDocument()) {
					// unlock if Down at the end of document
					setScrollLock(false);
				}
			}
		});
		styledText.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				// lock the scroll if PAGE_UP ,HOME or TOP selected
				if (e.keyCode == SWT.HOME || e.keyCode == SWT.TOP) {
					setScrollLock(true);
				} else if (e.keyCode == SWT.PAGE_UP || e.keyCode == SWT.ARROW_UP) {
					if (checkEndOfDocument()) {
						setScrollLock(false);
					} else {
						setScrollLock(true);
					}
				} else if (e.keyCode == SWT.END || e.keyCode == SWT.BOTTOM) {
					setScrollLock(false);// selecting END makes it reveal the
											// end
				} else if ((e.keyCode == SWT.PAGE_DOWN || e.keyCode == SWT.ARROW_DOWN) && checkEndOfDocument()) {
					// unlock if Down at the end of document
					setScrollLock(false);
				}
			}
		});
		styledText.addMouseWheelListener(new MouseWheelListener() {
			@Override
			public void mouseScrolled(MouseEvent e) {
				if (e.count < 0) { // Mouse dragged down
					if (checkEndOfDocument()) {
						setScrollLock(false);
					}
				} else if (!userHoldsScrollLock.get()) {
					if (checkEndOfDocument()) {
						setScrollLock(false);
					} else {
						setScrollLock(true);
					}
				}
			}
		});

		styledText.addVerifyListener(new VerifyListener() {
			@Override
			public void verifyText(VerifyEvent e) {
				// unlock the auto lock if user starts typing only if it was not manual lock
				if (scrollLockStateProvider != null && !scrollLockStateProvider.getScrollLock()) {
					setScrollLock(false);
				}
			}
		});

        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)
     */
    @Override
	public void lineGetStyle(LineStyleEvent event) {
        IDocument document = getDocument();
        if (document != null && document.getLength() > 0) {
			ArrayList<StyleRange> ranges = new ArrayList<StyleRange>();
            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 = ranges.toArray(new StyleRange[ranges.size()]);
            }
        }
    }

	private void override(List<StyleRange> 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 = 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<Position> list = new ArrayList<Position>();
        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 list.toArray(new Position[list.size()]);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.swt.custom.LineBackgroundListener#lineGetBackground(org.eclipse.swt.custom.LineBackgroundEvent)
     */
    @Override
	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)
     */
    @Override
	public void mouseEnter(MouseEvent e) {
        getTextWidget().addMouseMoveListener(this);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
     */
    @Override
	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)
     */
    @Override
	public void mouseHover(MouseEvent e) {
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
     */
    @Override
	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)
     */
    @Override
	public void mouseDoubleClick(MouseEvent e) {
    }

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

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

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.jface.text.TextViewer#createDocumentAdapter()
     */
	@Override
	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 character width of the console, or -1
     */
    public void setConsoleWidth(int width) {
        if (consoleWidth != width) {
            consoleWidth = width;
            ConsolePlugin.getStandardDisplay().asyncExec(new Runnable() {
                @Override
				public void run() {
                    if (documentAdapter != null) {
                        documentAdapter.setWidth(consoleWidth);
                    }
                }
            });
        }
    }

    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.jface.text.TextViewer#handleDispose()
     */
    @Override
	protected void 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);

        if(handCursor != null) {
        	handCursor.dispose();
        }
        handCursor = null;
        if(textCursor != null) {
        	textCursor.dispose();
        }
        textCursor = null;
        hyperlink = null;
        console = null;

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

        super.handleDispose();
    }

    class HyperlinkColorChangeListener implements IPropertyChangeListener {
        @Override
		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
     */
    @Override
	protected void updateTextListeners(WidgetCommand cmd) {
        super.updateTextListeners(cmd);
        cmd.preservedText = null;
        cmd.event = null;
        cmd.text = null;
    }

    @Override
	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
			@SuppressWarnings("deprecation")
			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));
            }

        }
    }


}
