/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui;

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

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.ConfigurableLineTracker;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentAdapter;
import org.eclipse.jface.text.IDocumentAdapterExtension;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextStore;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.projection.ProjectionDocument;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.TextChangeListener;
import org.eclipse.swt.custom.TextChangedEvent;
import org.eclipse.swt.custom.TextChangingEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.sse.core.document.ILockable;
import org.eclipse.wst.sse.core.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.events.NoChangeEvent;
import org.eclipse.wst.sse.core.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.events.StructuredDocumentEvent;
import org.eclipse.wst.sse.core.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.exceptions.SourceEditingRuntimeException;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.sse.core.util.Debug;
import org.eclipse.wst.sse.core.util.Utilities;
import org.eclipse.wst.sse.ui.util.Assert;


/**
 * Adapts IStructuredDocument events and methods to StyledTextContent events
 * and methods
 */
public class StructuredDocumentToTextAdapter implements IDocumentAdapter, IDocumentAdapterExtension {

	private class DocumentClone extends AbstractDocument {


		/**
		 * Creates a new document clone with the given content.
		 * 
		 * @param content
		 *            the content
		 * @param lineDelimiters
		 *            the line delimiters
		 */
		public DocumentClone(String content, String[] lineDelimiters) {
			super();
			setTextStore(new StringTextStore(content));
			ConfigurableLineTracker tracker = new ConfigurableLineTracker(lineDelimiters);
			setLineTracker(tracker);
			getTracker().set(content);
			completeInitialization();
		}
	}

	// A pre-notification listener for the viewer's Document
	class DocumentListener implements IDocumentListener {
		protected boolean allTextChanged = false;

		protected DocumentEvent currentEvent;

		synchronized public void documentAboutToBeChanged(DocumentEvent event) {
			if (isStoppedForwardingChanges())
				return;

			pendingDocumentChangedEvent = true;
			allTextChanged = event.getOffset() <= 0 && event.getLength() >= StructuredDocumentToTextAdapter.this.getDocument().getLength();
			currentEvent = event;

			StructuredDocumentToTextAdapter.this.relayTextChanging(event.getOffset(), event.getLength(), event.getText());
		}

		synchronized public void documentChanged(DocumentEvent event) {
			if (isStoppedForwardingChanges())
				return;

			if (currentEvent != null && event == currentEvent) {
				if (allTextChanged) {
					StructuredDocumentToTextAdapter.this.relayTextSet();
				} else {
					// temp work around for immediate thread
					// problem.
					// should have more general solution
					// soon. 'syncExec' are rumored to be
					// prone to hang.
					StructuredDocumentToTextAdapter.this.relayTextChanged();
				}
			}

			currentEvent = null;
			pendingDocumentChangedEvent = false;
			handlePendingEvents();
			lastEvent = null;

		}
	}

	private static class StringTextStore implements ITextStore {

		private String fContent;

		/**
		 * Creates a new string text store with the given content.
		 * 
		 * @param content
		 *            the content
		 */
		public StringTextStore(String content) {
			Assert.isNotNull(content);
			fContent = content;
		}

		/*
		 * @see org.eclipse.jface.text.ITextStore#get(int)
		 */
		public char get(int offset) {
			return fContent.charAt(offset);
		}

		/*
		 * @see org.eclipse.jface.text.ITextStore#get(int, int)
		 */
		public String get(int offset, int length) {
			return fContent.substring(offset, offset + length);
		}

		/*
		 * @see org.eclipse.jface.text.ITextStore#getLength()
		 */
		public int getLength() {
			return fContent.length();
		}

		/*
		 * @see org.eclipse.jface.text.ITextStore#replace(int, int,
		 *      java.lang.String)
		 */
		public void replace(int offset, int length, String text) {
		}

		/*
		 * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
		 */
		public void set(String text) {
		}

	}

	/**
	 * Changes to the Document/IStructuredDocument can extend beyond the text
	 * change area and require more redrawing to keep the hilighting correct.
	 * The event must be saved so that the redraw is only sent after a
	 * textChanged event is received.
	 */
	class StructuredDocumentListener implements IStructuredDocumentListener {

		public void newModel(NewDocumentEvent structuredDocumentEvent) {

			if (isStoppedForwardingChanges()) {
				//if
				// (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
				// {
				if (Debug.debugStructuredDocument) {
					System.out.println("skipped relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
				}
				return;
			}
			// should use textSet when all contents have
			// changed
			// otherwise need to use the pair of
			// textChanging and
			// textChanged.
			StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
		}

		public void noChange(final NoChangeEvent structuredDocumentEvent) {

			if (Debug.debugStructuredDocument) {
				System.out.println("skipped relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
			}
			if (structuredDocumentEvent.reason == NoChangeEvent.READ_ONLY_STATE_CHANGE) {
				if (pendingDocumentChangedEvent) {
					if (lastEventQueue == null) {
						lastEventQueue = new ArrayList();
					}
					lastEventQueue.add(structuredDocumentEvent);
				} else {
					StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
				}
			}
		}

		public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {

			if (isStoppedForwardingChanges()) {
				//			if
				// (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
				// {
				if (Debug.debugStructuredDocument) {
					System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
				}
				return;
			}
			if (Debug.debugStructuredDocument) {
				System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
			}
			StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
		}

		public void regionChanged(RegionChangedEvent structuredDocumentEvent) {

			if (isStoppedForwardingChanges()) {
				//			if
				// (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
				// {
				if (Debug.debugStructuredDocument) {
					System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
				}
				return;
			}
			if (Debug.debugStructuredDocument) {
				System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
			}
			StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
		}

		public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {

			if (isStoppedForwardingChanges()) {
				//			if
				// (StructuredDocumentToTextAdapter.this.fStopRelayingChanges)
				// {
				if (Debug.debugStructuredDocument) {
					System.out.println("not relaying StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
				}
				return;
			}
			if (Debug.debugStructuredDocument) {
				System.out.println("saving StructuredDocumentEvent " + structuredDocumentEvent.getClass().getName()); //$NON-NLS-1$
			}
			StructuredDocumentToTextAdapter.this.lastEvent = structuredDocumentEvent;
		}
	}

	private static final String EMPTY_STRING = "";

	private final static boolean redrawBackground = true;

	/** The visible child document. */
	private ProjectionDocument fChildDocument;

	/** The master document */
	private IDocument fDocument;
	/** The document clone for the non-forwarding case. */
	private IDocument fDocumentClone;

	// only use this temp work around if on GTK
	// it causes funny "cursor blinking" if used on windows
	private final boolean forceRedrawOnRegionChanged = Platform.getWS().equals("gtk"); //$NON-NLS-1$
	/** The original content */
	private String fOriginalContent;
	/** The original line delimiters */
	private String[] fOriginalLineDelimiters;

	private int fStopRelayingChangesRequests = 0;

	private StyledText fStyledTextWidget;

	/** The registered text changed listeners */
	TextChangeListener[] fTextChangeListeners;
	protected DocumentListener internalDocumentListener;

	// The listeners for relaying DocumentEvents and
	// requesting repaints
	// after modification
	private IStructuredDocumentListener internalStructuredDocumentListener;

	protected StructuredDocumentEvent lastEvent = null;
	List lastEventQueue;
	boolean pendingDocumentChangedEvent;

	/**
	 * TEST ONLY - TEST ONLY - TEST ONLY NOT API use this constructor only for
	 * tests. Creates a new document adapter which is initiallly not connected
	 * to any document.
	 */
	public StructuredDocumentToTextAdapter() {

		internalStructuredDocumentListener = new StructuredDocumentListener();
		internalDocumentListener = new DocumentListener();
		// for testing only
		//		setDocument(getModelManager().createStructuredDocumentFor(ContentTypeIdentifierForXML.ContentTypeID_XML));
	}

	/**
	 * Creates a new document adapter which is initiallly not connected to any
	 * document.
	 */
	public StructuredDocumentToTextAdapter(StyledText styledTextWidget) {

		// do not use 'this()' in this case
		super();
		internalStructuredDocumentListener = new StructuredDocumentListener();
		internalDocumentListener = new DocumentListener();
		fStyledTextWidget = styledTextWidget;
	}

	private void _setDocument(IDocument newDoc) {
		if ((fDocument != null) && (fDocument instanceof IStructuredDocument)) {
			((IStructuredDocument) fDocument).removeDocumentChangedListener(internalStructuredDocumentListener);
		}
		fDocument = newDoc;
		if (fDocument != null && !(fDocument instanceof ILockable)) {
			System.out.println("warning: non-lockable document used");
		}
		if ((fDocument != null) && (fDocument instanceof IStructuredDocument)) {
			((IStructuredDocument) fDocument).addDocumentChangedListener(internalStructuredDocumentListener);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.custom.StyledTextContent#addTextChangeListener(org.eclipse.swt.custom.TextChangeListener)
	 */
	public synchronized void addTextChangeListener(TextChangeListener listener) {

		// make sure listener is not already in listening
		// (and if it is, print a warning to aid debugging,
		// if needed)

		if (Utilities.contains(fTextChangeListeners, listener)) {
			if (Debug.displayWarnings) {
				System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. listener " + listener + " was added more than once. "); //$NON-NLS-2$//$NON-NLS-1$
			}
		} else {
			if (Debug.debugStructuredDocument) {
				System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. Adding an instance of " + listener.getClass() + " as a listener on text adapter."); //$NON-NLS-2$//$NON-NLS-1$
			}
			int oldSize = 0;
			if (fTextChangeListeners != null) {
				// normally won't be null, but we need to be
				// sure, for first time through
				oldSize = fTextChangeListeners.length;
			}
			int newSize = oldSize + 1;
			TextChangeListener[] newListeners = new TextChangeListener[newSize];
			if (fTextChangeListeners != null) {
				System.arraycopy(fTextChangeListeners, 0, newListeners, 0, oldSize);
			}
			// add listener to last position
			newListeners[newSize - 1] = listener;
			//
			// now switch new for old
			fTextChangeListeners = newListeners;
			//
		}
	}

	/*
	 * @see org.eclipse.swt.custom.StyledTextContent#getCharCount()
	 */
	public int getCharCount() {

		// getDocument can sometimes be null during startup
		// and dispose
		int result = 0;
		IDocument doc = getDocument();
		if (doc != null) {
			result = getSafeDocument().getLength();
		}
		return result;
	}

	private IDocument getClonedDocument() {
		if (fDocumentClone == null) {
			String content = fOriginalContent == null ? "" : fOriginalContent; //$NON-NLS-1$
			String[] delims = fOriginalLineDelimiters == null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters;
			fDocumentClone = new DocumentClone(content, delims);
		}
		return fDocumentClone;
	}

	Display getDisplay() {

		// Note: the workbench should always have a display
		// (unless running headless), whereas Display.getCurrent()
		// only returns the display if the currently executing thread
		// has one.
		if (PlatformUI.isWorkbenchRunning())
			return PlatformUI.getWorkbench().getDisplay();
		else
			return null;
	}

	/**
	 * Returns the visible document.
	 * 
	 * @return IDocument
	 */
	protected IDocument getDocument() {

		if (fChildDocument == null)
			return fDocument;
		return fChildDocument;
	}

	/**
	 * Returns offset visible region of current document
	 * 
	 * @return 0 if no child document exists, offset of child document if
	 *         possible, -1 otherwise
	 */
	private int getDocumentModelAdjustment() {
		if (fChildDocument == null)
			return 0;
		IRegion coverage = fChildDocument.getProjectionMapping().getCoverage();
		if (coverage != null) {
			return coverage.getOffset();
		}

		return -1;
	}

	/**
	 * Return the line at the given character offset without delimiters.
	 * <p>
	 * 
	 * @param offset
	 *            offset of the line to return. Does not include delimiters of
	 *            preceeding lines. Offset 0 is the first character of the
	 *            document.
	 * @return the line text without delimiters
	 */
	public java.lang.String getLine(int lineNumber) {

		String result = null;
		if (lineNumber >= getLineCount()) {
			if (Debug.displayWarnings) {
				System.out.println("Development Debug: IStructuredDocument:getLine() error. lineNumber requested (" + lineNumber + ") was greater than number of lines(" + getLineCount() + "). EmptyString returned"); //$NON-NLS-1$//$NON-NLS-3$//$NON-NLS-2$
			}
			result = EMPTY_STRING;
		} else {
			IDocument doc = getSafeDocument();
			if (doc == null) {
				result = EMPTY_STRING;
			} else {
				try {
					IRegion r = doc.getLineInformation(lineNumber);
					if (r.getLength() > 0) {
						result = doc.get(r.getOffset(), r.getLength());
					} else {
						result = EMPTY_STRING;
					}
				} catch (BadLocationException e) {
					result = EMPTY_STRING;
				}
			}
		}
		return result;
	}

	/**
	 * Return the line index at the given character offset.
	 * <p>
	 * 
	 * @param offset
	 *            offset of the line to return. The first character of the
	 *            document is at offset 0. An offset of getLength() is valid
	 *            and should answer the number of lines.
	 * @return the line index. The first line is at index 0. If the character
	 *         at offset is a delimiter character, answer the line index of
	 *         the line that is delimited. For example, text = "\r\n\r\n",
	 *         delimiter = "\r\n", then: getLineAtOffset(0) == 0
	 *         getLineAtOffset(1) == 0 getLineAtOffset(2) == 1
	 *         getLineAtOffset(3) == 1 getLineAtOffset(4) == 2
	 */
	public int getLineAtOffset(int offset) {

		int result = 0;
		IDocument doc = getSafeDocument();
		if (doc != null) {
			try {
				// TODO: not sure why we need this special check for
				// child document, getDocument should return correct one?
				if (fChildDocument != null) {
					result = fChildDocument.getLineOfOffset(offset);
				} else {
					result = doc.getLineOfOffset(offset);
				}
			} catch (BadLocationException e) {
				// should not occur, but seems to for child
				// document from QEV, related to repainting overview ruler
				result = 0;
			}
		}
		return result;
	}

	public int getLineCount() {
		int result = 0;
		IDocument doc = getSafeDocument();
		if (doc != null) {
			result = doc.getNumberOfLines();
		}
		return result;
	}

	/*
	 * @see org.eclipse.swt.custom.StyledTextContent#getLineDelimiter
	 */
	public String getLineDelimiter() {
		String result = null;
		IDocument doc = getSafeDocument();
		if (getParentDocument() instanceof IStructuredDocument) {
			result = ((IStructuredDocument) getParentDocument()).getLineDelimiter();
		} else {
			result = TextUtilities.getDefaultLineDelimiter(doc);
		}
		return result;
	}

	/**
	 * Return the character offset of the first character of the given line.
	 * <p>
	 * 
	 * @param lineIndex
	 *            index of the line. The first line is at index 0.
	 * @return offset offset of the first character of the line. The first
	 *         character of the document is at offset 0. The return value
	 *         should include line delimiters. For example, text =
	 *         "\r\ntest\r\n", delimiter = "\r\n", then: getOffsetAtLine(0) ==
	 *         0 getOffsetAtLine(1) == 2 getOffsetAtLine(2) == 8 NOTE: When
	 *         there is no text (i.e., no lines), getOffsetAtLine(0) is a
	 *         valid call that should return 0.
	 */
	public int getOffsetAtLine(int lineIndex) {

		int result = 0;
		IDocument doc = getSafeDocument();
		if (doc != null) {
			try {
				result = doc.getLineOffset(lineIndex);
			} catch (BadLocationException e) {
				result = 0;
			}
		}
		return result;
	}

	/**
	 * Returns the parent document
	 * 
	 * @return the parent document
	 */
	private IDocument getParentDocument() {
		return fDocument;
	}

	/**
	 * This is the document to use for request from the StyledText widget. Its
	 * either the live documnet or a clone of it, depending on stop/resume
	 * state.
	 */
	private IDocument getSafeDocument() {
		IDocument result = null;
		if (isStoppedForwardingChanges()) {
			result = getClonedDocument();
		} else {
			// note, this document can be normal structured text document,
			// or the projection/child document as used by QEV
			result = getDocument();
		}
		return result;
	}

	/**
	 * @return org.eclipse.swt.custom.StyledText
	 */
	StyledText getStyledTextWidget() {
		return fStyledTextWidget;
	}

	/**
	 * Returns a string representing the content at the given range.
	 * <p>
	 * 
	 * @param start
	 *            the start offset of the text to return. Offset 0 is the
	 *            first character of the document.
	 * @param length
	 *            the length of the text to return
	 * @return the text at the given range
	 */
	public String getTextRange(int start, int length) {
		String result = null;
		try {
			if (isStoppedForwardingChanges()) {
				result = getClonedDocument().get(start, length);
			} else {
				result = getParentDocument().get(getDocumentModelAdjustment() + start, length);
			}
		} catch (BadLocationException e) {
			result = EMPTY_STRING;
		}
		return result;
	}

	/**
	 * assume only for "no change" events, for now
	 */
	protected void handlePendingEvents() {

		if (lastEventQueue == null)
			return;

		Iterator iterator = lastEventQueue.iterator();
		while (iterator.hasNext()) {
			NoChangeEvent noChangeEvent = (NoChangeEvent) iterator.next();
			redrawNoChange(noChangeEvent);
		}

		lastEventQueue = null;
		lastEvent = null;
	}

	boolean isStoppedForwardingChanges() {
		return fStopRelayingChangesRequests > 0;
	}

	/**
	 * this method is assumed to be called only for read only region changes.
	 */
	protected void redrawNoChange(NoChangeEvent structuredDocumentEvent) {

		if (isStoppedForwardingChanges())
			return;
		if (Debug.debugStructuredDocument) {
			System.out.println("maybe redraw stuff"); //$NON-NLS-1$
		}

		int startOffset = structuredDocumentEvent.getOriginalStart();
		int length = structuredDocumentEvent.getLength();
		redrawRangeWithLength(startOffset, length);

	}

	/**
	 * Request a redraw of the text range occupied by the given
	 * StructuredDocumentRegionsReplacedEvent
	 * 
	 * @param structuredDocumentEvent
	 */
	protected void redrawNodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {

		if (isStoppedForwardingChanges())
			return;
		if (Debug.debugStructuredDocument) {
			System.out.println("maybe redraw stuff"); //$NON-NLS-1$
		}
		// just the new stuff
		IStructuredDocumentRegionList newStructuredDocumentRegions = structuredDocumentEvent.getNewStructuredDocumentRegions();

		int nNewNodes = newStructuredDocumentRegions.getLength();
		if (nNewNodes > 0) {
			IStructuredDocumentRegion firstNode = newStructuredDocumentRegions.item(0);
			IStructuredDocumentRegion lastNode = newStructuredDocumentRegions.item(nNewNodes - 1);
			redrawRange(firstNode.getStartOffset(), lastNode.getEndOffset());
		}
	}

	/**
	 * Redraws the give offsets in terms of the StructuredDocument. If only
	 * part of the model is visible, ensures that only the visible portion of
	 * the given range is redrawn.
	 * 
	 * @param startModelOffset
	 * @param endModelOffset
	 */
	private void redrawRange(final int startModelOffset, final int endModelOffset) {

		if (getDocument() == null)
			return;
		if (Debug.debugStructuredDocument) {
			System.out.println("redraw stuff: " + startModelOffset + "-" + endModelOffset); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (fChildDocument == null) {
			Runnable runnable = new Runnable() {
				public void run() {
					getStyledTextWidget().redrawRange(startModelOffset, endModelOffset - startModelOffset, redrawBackground);
				}
			};
			runOnDisplayThreadIfNeedede(runnable);

		} else {
			int high = getDocument().getLength();
			int adjustment = getDocumentModelAdjustment();
			int startOffset = startModelOffset - adjustment;
			int endOffset = endModelOffset - adjustment;
			// not visible
			if (endOffset < 0 || startOffset > high)
				return;
			// restrict lower bound
			if (startOffset < 0) {
				startOffset = 0;
			}
			// restrict upper bound
			if (endOffset > high) {
				endOffset = high;
			}
			int length = endOffset - startOffset;
			// redrawBackground with false would be faster
			// but assumes background (or font) is not
			// changing
			final int finalStartOffset = startOffset;
			final int finallength = length;

			if (fChildDocument == null) {
				Runnable runnable = new Runnable() {
					public void run() {
						getStyledTextWidget().redrawRange(finalStartOffset, finallength, redrawBackground);
					}
				};
				runOnDisplayThreadIfNeedede(runnable);
			}

		}
	}

	/**
	 * Redraws the give offsets in terms of the Flat Node model. If only part
	 * of the model is visible, ensures that only the visible portion of the
	 * given range is redrawn.
	 * 
	 * @param startModelOffset
	 * @param endModelOffset
	 */
	private void redrawRangeWithLength(final int startModelOffset, final int length) {

		if (getDocument() == null)
			return;
		if (Debug.debugStructuredDocument) {
			System.out.println("redraw stuff: " + startModelOffset + "-" + length); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (fChildDocument == null) {
			Runnable runnable = new Runnable() {
				public void run() {
					getStyledTextWidget().redrawRange(startModelOffset, length, redrawBackground);
				}
			};
			runOnDisplayThreadIfNeedede(runnable);
		} else {
			int high = getDocument().getLength();
			int adjustment = getDocumentModelAdjustment();
			int startOffset = startModelOffset - adjustment;
			int endOffset = startOffset + length - 1;
			// not visible
			if (endOffset < 0 || startOffset > high)
				return;
			// restrict lower bound
			if (startOffset < 0) {
				startOffset = 0;
			}
			// restrict upper bound
			if (endOffset > high) {
				endOffset = high;
			}

			// note: length of the child documnet should be
			// updated,
			// need to investigate why its not at this
			// point, but is
			// probably just because the document event
			// handling is not
			// completely finished.
			int newLength = endOffset - startOffset; // d283007

			// redrawBackground with false would be faster
			// but assumes background (or font) is not
			// changing
			final int finalStartOffset = startOffset;
			final int finalNewLength = newLength;
			Runnable runnable = new Runnable() {
				public void run() {
					getStyledTextWidget().redrawRange(finalStartOffset, finalNewLength, redrawBackground);
				}
			};
			runOnDisplayThreadIfNeedede(runnable);
		}
	}

	/**
	 * Request a redraw of the text range occupied by the given
	 * RegionChangedEvent for certain (not all) ITextRegion contexts
	 * 
	 * @param structuredDocumentEvent
	 */
	protected void redrawRegionChanged(RegionChangedEvent structuredDocumentEvent) {

		if (isStoppedForwardingChanges()) {
			return;
		}
		if (Debug.debugStructuredDocument) {
			System.out.println("maybe redraw stuff"); //$NON-NLS-1$
		}
		// no redraw needed if mere region change
		// unless its one of our embedded regions,
		// in which case we redraw the whole thing
		ITextRegion region = structuredDocumentEvent.getRegion();
		//String type = region.getType();

		// (nsd) TODO: try to make this reliable somehow
		// without being directly content dependent
		//		if ((region instanceof ITextRegionContainer) ||
		// (type == XMLJSPRegionContexts.BLOCK_TEXT) ||
		// (type == XMLJSPRegionContexts.JSP_CONTENT)) {
		//			IStructuredDocumentRegion flatNode =
		// structuredDocumentEvent.getStructuredDocumentRegion();
		//			// redraw background of false is faster,
		//			// but assumes background (or font) is not
		// changing
		//			redrawRange(flatNode.getStartOffset(region),
		// flatNode.getEndOffset(region));
		//		}
		if (forceRedrawOnRegionChanged) {
			// workaround for redrawing problems on Linux-GTK
			int startOffset = structuredDocumentEvent.getOffset();
			int endOffset = structuredDocumentEvent.getOffset() + structuredDocumentEvent.getLength();
			try {
				IRegion startLine = structuredDocumentEvent.fDocument.getLineInformationOfOffset(startOffset);
				IRegion endLine = structuredDocumentEvent.fDocument.getLineInformationOfOffset(endOffset);
				if (startLine != null && endLine != null) {
					redrawRange(startLine.getOffset(), endLine.getOffset() + endLine.getLength());
				}
			} catch (BadLocationException e) {
				// nothing for now
			}
		}
	}

	/**
	 * Request a redraw of the text range occupied by the given
	 * RegionsReplacedEvent
	 * 
	 * @param structuredDocumentEvent
	 */
	protected void redrawRegionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {

		if (isStoppedForwardingChanges())
			return;
		if (Debug.debugStructuredDocument) {
			System.out.println("maybe redraw stuff"); //$NON-NLS-1$
		}
		ITextRegionList newRegions = structuredDocumentEvent.getNewRegions();
		int nRegions = newRegions.size();
		if (nRegions > 0) {
			ITextRegion firstRegion = newRegions.get(0);
			ITextRegion lastRegion = newRegions.get(nRegions - 1);
			IStructuredDocumentRegion flatNode = structuredDocumentEvent.getStructuredDocumentRegion();
			redrawRange(flatNode.getStartOffset(firstRegion), flatNode.getEndOffset(lastRegion));
		}
	}

	protected void redrawTextChanged() {

		if (lastEvent != null) {
			// update display, since some cases can effect
			// highlighting beyond the changed text area.
			if (lastEvent instanceof StructuredDocumentRegionsReplacedEvent)
				redrawNodesReplaced((StructuredDocumentRegionsReplacedEvent) lastEvent);
			if (lastEvent instanceof RegionsReplacedEvent)
				redrawRegionsReplaced((RegionsReplacedEvent) lastEvent);
			if (lastEvent instanceof RegionChangedEvent)
				redrawRegionChanged((RegionChangedEvent) lastEvent);
			// moved following line to 'document changed' so
			// the "last event" can be
			// re-drawn after pending re-draws
			//lastEvent = null;
		}
	}

	/**
	 * Sends a text replace event to all registered listeners.
	 */
	protected void relayTextChanged() {

		if (isStoppedForwardingChanges()) {
			if (Debug.debugStructuredDocument && getDocument() != null) {
				System.out.println("NOT relaying text changed (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return;
		}
		if (Debug.debugStructuredDocument && getDocument() != null) {
			System.out.println("relaying text changed (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		final TextChangedEvent textChangedEvent = new TextChangedEvent(this);

		// we must assign listeners to local variable, since
		// the add and remove listener
		// methods can change the actual instance of the
		// listener array from another thread

		Runnable runnable = new Runnable() {
			public void run() {
				if (fTextChangeListeners != null) {
					Object[] holdListeners = fTextChangeListeners;
					for (int i = 0; i < holdListeners.length; i++) {
						// this is a safe cast, since addListeners
						// requires a IStructuredDocumentListener
						((TextChangeListener) holdListeners[i]).textChanged(textChangedEvent);
					}
				}
			}
		};
		runOnDisplayThreadIfNeedede(runnable);
		redrawTextChanged();
	}

	/**
	 * Sends a text change to all registered listeners
	 */
	protected void relayTextChanging(int requestedStart, int requestedLength, String requestedChange) {

		if (getDocument() == null)
			return;
		if (isStoppedForwardingChanges()) {
			if (Debug.debugStructuredDocument && getDocument() != null) {
				System.out.println("NOT relaying text changing: " + requestedStart + ":" + getDocument().getLength()); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return;
		}
		if (Debug.debugStructuredDocument && getDocument() != null) {
			System.out.println("relaying text changing: " + requestedStart + ":" + getDocument().getLength()); //$NON-NLS-1$ //$NON-NLS-2$
		}
		lastEvent = null;
		try {
			final TextChangingEvent textChangingEvent = new TextChangingEvent(this);

			textChangingEvent.start = requestedStart;
			textChangingEvent.replaceCharCount = requestedLength;
			textChangingEvent.newCharCount = (requestedChange == null ? 0 : requestedChange.length());
			textChangingEvent.replaceLineCount = getDocument().getNumberOfLines(requestedStart, requestedLength) - 1;
			textChangingEvent.newText = requestedChange;
			textChangingEvent.newLineCount = (requestedChange == null ? 0 : getDocument().computeNumberOfLines(requestedChange));

			// we must assign listeners to local variable,
			// since the add and remove listner
			// methods can change the actual instance of the
			// listener array from another thread
			Runnable runnable = new Runnable() {
				public void run() {
					if (fTextChangeListeners != null) {
						TextChangeListener[] holdListeners = fTextChangeListeners;
						for (int i = 0; i < holdListeners.length; i++) {
							// this is a safe cast, since
							// addListeners requires a
							// IStructuredDocumentListener
							holdListeners[i].textChanging(textChangingEvent);
						}
					}
				}
			};
			runOnDisplayThreadIfNeedede(runnable);
		} catch (BadLocationException e) {
			throw new SourceEditingRuntimeException(e);
		}
	}

	/**
	 * Sends a text set event to all registered listeners. Widget should
	 * redraw itself automatically.
	 */
	protected void relayTextSet() {

		if (isStoppedForwardingChanges()) {
			if (Debug.debugStructuredDocument && getDocument() != null) {
				System.out.println("NOT relaying text set (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			return;
		}
		if (Debug.debugStructuredDocument && getDocument() != null) {
			System.out.println("relaying text set (" + getDocument().getLength() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		lastEvent = null;
		final TextChangedEvent textChangedEvent = new TextChangedEvent(this);

		// we must assign listeners to local variable, since
		// the add and remove listner
		// methods can change the actual instance of the
		// listener array from another thread
		Runnable runnable = new Runnable() {
			public void run() {
				if (fTextChangeListeners != null) {
					TextChangeListener[] holdListeners = fTextChangeListeners;
					for (int i = 0; i < holdListeners.length; i++) {
						holdListeners[i].textSet(textChangedEvent);
					}
				}
			}
		};
		runOnDisplayThreadIfNeedede(runnable);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.swt.custom.StyledTextContent#removeTextChangeListener(org.eclipse.swt.custom.TextChangeListener)
	 */
	public synchronized void removeTextChangeListener(final TextChangeListener listener) {

		if ((fTextChangeListeners != null) && (listener != null)) {
			// if its not in the listeners, we'll ignore the
			// request
			if (!Utilities.contains(fTextChangeListeners, listener)) {
				if (Debug.displayWarnings) {
					System.out.println("StructuredDocumentToTextAdapter::removeTextChangedListeners. listener " + listener + " was not present. "); //$NON-NLS-2$//$NON-NLS-1$
				}
			} else {
				if (Debug.debugStructuredDocument) {
					System.out.println("StructuredDocumentToTextAdapter::addTextChangedListeners. Removing an instance of " + listener.getClass() + " as a listener on text adapter."); //$NON-NLS-2$//$NON-NLS-1$
				}
				final int oldSize = fTextChangeListeners.length;
				int newSize = oldSize - 1;
				final TextChangeListener[] newListeners = new TextChangeListener[newSize];

				Runnable runnable = new Runnable() {
					public void run() {
						int index = 0;
						for (int i = 0; i < oldSize; i++) {
							if (fTextChangeListeners[i] != listener) {
								// copy old to new if its not the
								// one we are removing
								newListeners[index++] = fTextChangeListeners[i];
							}
						}
					}
				};
				runOnDisplayThreadIfNeedede(runnable);
				// now that we have a new array, let's
				// switch it for the old one
				fTextChangeListeners = newListeners;
			}
		}
	}

	/**
	 * Replace the text with "newText" starting at position "start" for a
	 * length of "replaceLength".
	 * <p>
	 * Implementors have to notify TextChanged listeners after the content has
	 * been updated. The TextChangedEvent should be set as follows:
	 * <ul>
	 * <li>event.type = SWT.TextReplaced
	 * <li>event.start = start of the replaced text
	 * <li>event.numReplacedLines = number of replaced lines
	 * <li>event.numNewLines = number of new lines
	 * <li>event.replacedLength = length of the replaced text
	 * <li>event.newLength = length of the new text
	 * </ul>
	 * <b>NOTE: </b> numNewLines is the number of inserted lines and
	 * numReplacedLines is the number of deleted lines based on the change
	 * that occurs visually. For example:
	 * <ul>
	 * <li>(replacedText, newText) ==> (numReplacedLines, numNewLines)
	 * <li>("", "\n") ==> (0, 1)
	 * <li>("\n\n", "a") ==> (2, 0)
	 * <li>("a", "\n\n") ==> (0, 2)
	 * <li>("\n", "") ==> (1, 0)
	 * </ul>
	 * </p>
	 * 
	 * @param start
	 *            start offset of text to replace, none of the offsets include
	 *            delimiters of preceeding lines, offset 0 is the first
	 *            character of the document
	 * @param replaceLength
	 *            start offset of text to replace
	 * @param newText
	 *            start offset of text to replace
	 */
	public void replaceTextRange(int start, int replaceLength, String text) {

		if (getParentDocument() instanceof IStructuredDocument) {
			// the structuredDocument initiates the "changing"
			// and "changed" events.
			// they are both fired by the time this method
			// returns.
			((IStructuredDocument) getParentDocument()).replaceText(this, start + getDocumentModelAdjustment(), replaceLength, text);
		} else {
			try {
				getDocument().replace(start, replaceLength, text);
			} catch (BadLocationException x) {
				throw new SourceEditingRuntimeException(x);
			}
		}
	}

	/**
	 * @see org.eclipse.jface.text.IDocumentAdapterExtension#resumeForwardingDocumentChanges()
	 */
	public void resumeForwardingDocumentChanges() {

		// from re-reading the textSet API in StyledText, we
		// must call
		// textSet if all the contents changed. If all the
		// contents did
		// not change, we need to call the pair of APIs,
		// textChanging and
		// textChanged. So, if we ever keep careful track of
		// changes
		// during stop forwarding and resume forwarding, we
		// can
		// investigate change make use of the pair of APIs.
		fStopRelayingChangesRequests--;
		if (fStopRelayingChangesRequests == 0) {
			//fIsForwarding= true;
			fDocumentClone = null;
			fOriginalContent = null;
			fOriginalLineDelimiters = null;
			//fireTextSet();
			relayTextSet();
		}
	}

	/**
	 * This 'Runnable' should be very brief, and should not "call out" to
	 * other code which itself might call syncExec, or deadlock might occur.
	 * 
	 * @param r
	 */
	private void runOnDisplayThreadIfNeedede(Runnable r) {
		// if there is no Display at all (that is, running headless),
		// or if we are already running on the display thread, then
		// simply execute the runnable.
		if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) {
			r.run();
		} else {
			// otherwise force the runnable to run on the display thread.
			//
			// Its unclear if we need this at all, once
			// we "force" document update to always take place on display
			// thread.
			IDocument doc = getDocument();
			if (doc instanceof ILockable) {

				ILock lock = null;
				try {
					lock = ((ILockable) doc).getLockObject();
					lock.acquire();
					getDisplay().syncExec(r);
				} finally {
					if (lock != null) {
						lock.release();
					}
				}
			} else {
				// else, ignore!, since risk of deadlock
				throw new IllegalStateException("non lockable document used for structuredDocumentToTextAdapter");
			}
		}
	}

	/**
	 * @param newModel
	 *            com.ibm.sed.structuredDocument.IStructuredDocument
	 */
	public void setDocument(IDocument document) {

		if (getDocument() != null) {
			getDocument().removePrenotifiedDocumentListener(internalDocumentListener);
		}
		lastEvent = null;
		if (document instanceof ProjectionDocument) {
			fChildDocument = (ProjectionDocument) document;
			_setDocument(fChildDocument.getMasterDocument());
		} else {
			fChildDocument = null;
			_setDocument(document);
		}
		if (getDocument() != null) {
			getDocument().addPrenotifiedDocumentListener(internalDocumentListener);
		}
	}

	/**
	 * @see IDocument#setText
	 */
	public void setText(String string) {

		if (isStoppedForwardingChanges()) {
			fDocumentClone = null;
			fOriginalContent = fDocument.get();
			fOriginalLineDelimiters = fDocument.getLegalLineDelimiters();
		} else if (fChildDocument == null) {
			if (getParentDocument() instanceof IStructuredDocument) {
				((IStructuredDocument) getParentDocument()).setText(this, string);
			} else {
				getParentDocument().set(string);
			}
		} else {
			fChildDocument.set(string);
		}
		relayTextSet();
	}

	/**
	 * This method was added to make testing easier. Normally, the widget is
	 * specified on the constructor.
	 */
	public void setWidget(StyledText widget) {

		fStyledTextWidget = widget;
	}

	/**
	 * @see org.eclipse.jface.text.IDocumentAdapterExtension#stopForwardingDocumentChanges()
	 */
	public void stopForwardingDocumentChanges() {

		fStopRelayingChangesRequests++;
		// only need to take snapshot on first request
		if (fStopRelayingChangesRequests == 1) {
			fDocumentClone = null;
			fOriginalContent = getDocument().get();
			fOriginalLineDelimiters = getDocument().getLegalLineDelimiters();
		}
	}
}
