/*******************************************************************************
 * 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.internal.provisional.style;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
import org.eclipse.wst.sse.ui.internal.util.EditorUtility;

/**
 * This class is to directly mediate between the Structured Document data
 * structure and the text widget's text and events. It assumes there only the
 * model is interested in text events, and all other views will work from that
 * model. Changes to the text widgets input can cause changes in the model,
 * which in turn cause changes to the widget's display.
 * 
 */
public class Highlighter implements IHighlighter {

	/**
	 * A utility class to do various color manipulations
	 */
	private class YUV_RGBConverter {
		/**
		 * This class "holds" the YUV values corresponding to RGB color
		 */
		private class YUV {

			class NormalizedRGB {
				double blue;
				double green;
				private final double maxRGB = 256.0;
				double red;

				public NormalizedRGB(RGB rgb) {
					// first normalize to between 0 - 1
					red = rgb.red / maxRGB;
					green = rgb.green / maxRGB;
					blue = rgb.blue / maxRGB;

					red = gammaNormalized(red);
					green = gammaNormalized(green);
					blue = gammaNormalized(blue);

				}
			}

			private NormalizedRGB normalizedRGB;

			RGB originalRGB;
			private double u = -1;
			private double v = -1;
			private double y = -1;

			private YUV() {
				super();
			}

			public YUV(double y, double u, double v) {
				this();
				this.y = y;
				this.u = u;
				this.v = v;
			}

			public YUV(RGB rgb) {
				this();
				originalRGB = rgb;
				normalizedRGB = new NormalizedRGB(rgb);
				// force calculations
				getY();
				getV();
				getU();
			}

			/**
			 * normalize to "average" gamma 2.2222 or 1/0.45
			 */
			double gammaNormalized(double colorComponent) {
				if (colorComponent < 0.018) {
					return colorComponent * 0.45;
				}
				else {
					return 1.099 * Math.pow(colorComponent, 0.45) - 0.099;
				}
			}

			/**
			 * @return RGB based on original RGB and current YUV values;
			 */
			public RGB getRGB() {
				RGB result = null;
				double r = getY() + 1.14 * getV();
				double g = getY() - 0.395 * getU() - 0.58 * getV();
				double b = getY() + 2.032 * getU();

				int red = (int) (inverseGammaNormalized(r) * 256);
				int green = (int) (inverseGammaNormalized(g) * 256);
				int blue = (int) (inverseGammaNormalized(b) * 256);
				if (red < 0)
					red = 0;
				else if (red > 255)
					red = 255;
				if (green < 0)
					green = 0;
				else if (green > 255)
					green = 255;
				if (blue < 0)
					blue = 0;
				else if (blue > 255)
					blue = 255;

				result = new RGB(red, green, blue);
				return result;
			}

			public double getU() {
				if (u == -1) {
					u = 0.4949 * (normalizedRGB.blue - getY());
				}
				return u;

			}

			public double getV() {
				if (v == -1) {
					v = 0.877 * (normalizedRGB.red - getY());
				}
				return v;
			}

			public double getY() {
				if (y == -1) {
					y = 0.299 * normalizedRGB.red + 0.587 * normalizedRGB.green + 0.114 * normalizedRGB.blue;
				}
				return y;
			}

			double inverseGammaNormalized(double colorComponent) {
				if (colorComponent < 0.018) {
					return colorComponent * .222;
				}
				else {
					return Math.pow(((.9099 * colorComponent + 0.09)), 2.22);
				}
			}

		}

		public YUV_RGBConverter() {
			super();
		}

		public double calculateYComponent(Color targetColor) {
			return new YUV(targetColor.getRGB()).getY();
		}

		public RGB transformRGB(RGB originalRGB, double scaleFactor, double target) {
			RGB transformedRGB = null;
			// CCIR601 yuv = new CCIR601(originalRGB);
			YUV yuv = new YUV(originalRGB);
			double y = yuv.getY();
			// zero is black, one is white
			if (y < target) {
				// is "dark" make lighter
				y = y + ((target - y) * scaleFactor);
			}
			else {
				// is "light" make darker
				y = y - ((y - target) * scaleFactor);
			}
			// yuv.setY(y);
			YUV newYUV = new YUV(y, yuv.getU(), yuv.getV());
			// CCIR601 newYUV = new CCIR601(y, yuv.getCb601(),
			// yuv.getCr601());
			transformedRGB = newYUV.getRGB();
			return transformedRGB;
		}

		public RGB transformRGBToGrey(RGB originalRGB, double scaleFactor, double target) {
			RGB transformedRGB = null;
			// we left the "full" API method signature, but this
			// version does not take into account originalRGB, though
			// it might someday.
			// for now, we'll simply make the new RGB grey, either a little
			// lighter, or a little darker than background.
			double y = 0;
			double mid = 0.5;
			// zero is black, one is white
			if (target < mid) {
				// is "dark" make lighter
				y = target + scaleFactor;
			}
			else {
				// is "light" make darker
				y = target - scaleFactor;
			}
			int c = (int) Math.round(y * 255);
			// just to gaurd against mis-use, or scale's values greater
			// than mid point (and possibly rounding error)
			if (c > 255)
				c = 255;
			if (c < 0)
				c = 0;
			transformedRGB = new RGB(c, c, c);
			return transformedRGB;
		}
	}

	private final boolean DEBUG = false;
	private final StyleRange[] EMPTY_STYLE_RANGE = new StyleRange[0];
	private static final String LINE_STYLE_PROVIDER_EXTENDED_ID = "linestyleprovider"; //$NON-NLS-1$

	private IPropertyChangeListener fForegroundScaleListener = new IPropertyChangeListener() {
		public void propertyChange(PropertyChangeEvent event) {
			if (EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE.equals(event.getProperty())) {
				IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
				readOnlyForegroundScaleFactor = editorStore.getInt(EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE);
				disposeColorTable();
				refreshDisplay();
			}
		}
	};
	private List fHoldStyleResults;
	private String fPartitioning = IDocumentExtension3.DEFAULT_PARTITIONING;

	private int fSavedLength = -1;
	private int fSavedOffset = -1;
	private StyleRange[] fSavedRanges = null;

	private IStructuredDocument fStructuredDocument;
	private Map fTableOfProviders;

	private Map fExtendedProviders;

	protected final LineStyleProvider NOOP_PROVIDER = new LineStyleProviderForNoOp();

	private double readOnlyBackgroundScaleFactor = 10;
	private Hashtable readOnlyColorTable;
	double readOnlyForegroundScaleFactor = 30;

	private YUV_RGBConverter rgbConverter;
	private ITextViewer textViewer;
	private StyledText textWidget;

	public Highlighter() {
		super();
	}

	protected void addEmptyRange(int start, int length, Collection holdResults) {
		StyleRange result = new StyleRange();
		result.start = start;
		result.length = length;
		holdResults.add(result);
	}

	public void addProvider(String partitionType, LineStyleProvider provider) {
		getTableOfProviders().put(partitionType, provider);
	}

	/**
	 * Adjust the style ranges' start and length so that they refer to the
	 * textviewer widget's range instead of the textviewer's document range.
	 * 
	 * @param ranges
	 * @param adjustment
	 */
	protected void adjust(StyleRange[] ranges, int adjustment) {
		ITextViewer viewer = getTextViewer();
		ITextViewerExtension5 extension = null;
		if (viewer instanceof ITextViewerExtension5) {
			extension = (ITextViewerExtension5) viewer;
		}

		// convert document regions back to widget regions
		for (int i = 0; i < ranges.length; i++) {
			if (extension != null) {
				// get document range, taking into account folding regions in
				// viewer
				IRegion region = extension.modelRange2WidgetRange(new Region(ranges[i].start, ranges[i].length));
				if (region != null) {
					ranges[i].start = region.getOffset();
					ranges[i].length = region.getLength();
				} // else what happens if region is not found?!
			}
			else {
				// just adjust the range using the given adjustment
				ranges[i].start += adjustment;
			}
		}
	}


	/**
	 * @deprecated - Read Only areas have unchanged background colors
	 */
	void adjustBackground(StyleRange styleRange) {
		RGB oldRGB = null;
		Color oldColor = styleRange.background;
		if (oldColor == null) {
			oldColor = getTextWidget().getBackground();
		}
		oldRGB = oldColor.getRGB();
		Color newColor = getCachedColorFor(oldRGB);
		if (newColor == null) {
			double target = getRGBConverter().calculateYComponent(oldColor);
			// if background is "light" make it darker, and vice versa
			if (target < 0.5)
				target = 1.0;
			else
				target = 0.0;
			RGB newRGB = getRGBConverter().transformRGB(oldRGB, readOnlyBackgroundScaleFactor / 100.0, target);

			cacheColor(oldRGB, newRGB);
			newColor = getCachedColorFor(oldRGB);
		}
		styleRange.background = newColor;
	}

	private void adjustForeground(StyleRange styleRange) {
		RGB oldRGB = null;
		// Color oldColor = styleRange.foreground;
		Color oldColor = styleRange.background;
		if (oldColor == null) {
			// oldRGB = getTextWidget().getForeground().getRGB();
			oldColor = getTextWidget().getBackground();
			oldRGB = oldColor.getRGB();
		}
		else {
			oldRGB = oldColor.getRGB();
		}
		Color newColor = getCachedColorFor(oldRGB);
		if (newColor == null) {
			// make text "closer to" background lumanence
			double target = getRGBConverter().calculateYComponent(oldColor);
			RGB newRGB = getRGBConverter().transformRGBToGrey(oldRGB, readOnlyForegroundScaleFactor / 100.0, target);

			// save conversion, so calculations only need to be done once
			cacheColor(oldRGB, newRGB);
			newColor = getCachedColorFor(oldRGB);
		}
		styleRange.foreground = newColor;
	}

	/**
	 * Cache read-only color.
	 * 
	 * @param oldRGB
	 * @param newColor
	 */
	private void cacheColor(RGB oldRGB, RGB newColor) {
		if (readOnlyColorTable == null) {
			readOnlyColorTable = new Hashtable();
		}
		readOnlyColorTable.put(oldRGB, newColor);
	}

	/**
	 * @param result
	 * @return
	 */
	private StyleRange[] convertReadOnlyRegions(StyleRange[] result, int start, int length) {
		IStructuredDocument structuredDocument = getDocument();

		/**
		 * (dmw) For client/provider simplicity (and consistent look and feel)
		 * we'll handle readonly regions in one spot, here in the Highlighter.
		 * Currently it is a fair assumption that each readonly region will be
		 * on an ITextRegion boundary, so we combine consecutive styles when
		 * found to be equivalent. Plus, for now, we'll just adjust
		 * foreground. Eventually will use a "dimming" algrorithm to adjust
		 * color's satuation/brightness.
		 */
		if (structuredDocument.containsReadOnly(start, length)) {
			// something is read-only in the line, so go through each style,
			// and adjust
			for (int i = 0; i < result.length; i++) {
				StyleRange styleRange = result[i];
				if (structuredDocument.containsReadOnly(styleRange.start, styleRange.length)) {
					adjustForeground(styleRange);
				}
			}
		}
		return result;
	}

	/**
	 * Clear out the readOnlyColorTable
	 */
	void disposeColorTable() {
		if (readOnlyColorTable != null) {
			readOnlyColorTable.clear();
		}
		readOnlyColorTable = null;
	}

	/**
	 * This method is just to get existing read-only colors.
	 */
	private Color getCachedColorFor(RGB oldRGB) {
		Color result = null;

		if (readOnlyColorTable != null) {
			RGB readOnlyRGB = (RGB) readOnlyColorTable.get(oldRGB);
			result = EditorUtility.getColor(readOnlyRGB);
		}

		return result;
	}

	protected IStructuredDocument getDocument() {
		return fStructuredDocument;
	}

	/**
	 * Adjust the given widget offset and length so that they are the
	 * textviewer document's offset and length, taking into account what is
	 * actually visible in the document.
	 * 
	 * @param offset
	 * @param length
	 * @return a region containing the offset and length within the
	 *         textviewer's document or null if the offset is not within the
	 *         document
	 */
	private IRegion getDocumentRangeFromWidgetRange(int offset, int length) {
		IRegion styleRegion = null;
		ITextViewer viewer = getTextViewer();
		if (viewer instanceof ITextViewerExtension5) {
			// get document range, taking into account folding regions in
			// viewer
			ITextViewerExtension5 extension = (ITextViewerExtension5) viewer;
			styleRegion = extension.widgetRange2ModelRange(new Region(offset, length));
		}
		else {
			// get document range, taking into account viewer visible region
			// get visible region in viewer
			IRegion vr = null;
			if (viewer != null)
				vr = viewer.getVisibleRegion();
			else
				vr = new Region(0, getDocument().getLength());

			// if offset is not within visible region, then we don't really
			// care
			if (offset <= vr.getLength()) {
				// Adjust the offset to be within visible region
				styleRegion = new Region(offset + vr.getOffset(), length);
			}
		}
		return styleRegion;
	}


	private Map getExtendedProviders() {
		if (fExtendedProviders == null) {
			fExtendedProviders = new HashMap(3);
		}
		return fExtendedProviders;
	}

	/**
	 * Method getProviderFor.
	 * 
	 * @param typedRegion
	 * @return LineStyleProvider
	 */
	private LineStyleProvider getProviderFor(ITypedRegion typedRegion) {
		String type = typedRegion.getType();
		LineStyleProvider result = (LineStyleProvider) fTableOfProviders.get(type);
		if (result == null) {
			// NOT YET FINALIZED - DO NOT CONSIDER AS API
			synchronized (getExtendedProviders()) {
				if (!getExtendedProviders().containsKey(type)) {
					LineStyleProvider provider = (LineStyleProvider) ExtendedConfigurationBuilder.getInstance().getConfiguration(LINE_STYLE_PROVIDER_EXTENDED_ID, type);
					getExtendedProviders().put(type, provider);
					if (provider != null) {
						provider.init(getDocument(), this);
					}
					result = provider;
				}
				else {
					result = (LineStyleProvider) getExtendedProviders().get(type);
				}
			}
		}
		if (result == null) {
			result = NOOP_PROVIDER;
		}
		return result;
	}

	private YUV_RGBConverter getRGBConverter() {
		if (rgbConverter == null) {
			rgbConverter = new YUV_RGBConverter();
		}
		return rgbConverter;
	}

	private Map getTableOfProviders() {
		if (fTableOfProviders == null) {
			fTableOfProviders = new HashMap();
		}
		return fTableOfProviders;
	}

	/**
	 * Returns the textViewer.
	 * 
	 * @return ITextViewer
	 */
	public ITextViewer getTextViewer() {
		return textViewer;
	}

	/**
	 * @return
	 */
	protected StyledText getTextWidget() {
		return textWidget;
	}

	public void install(ITextViewer newTextViewer) {
		this.textViewer = newTextViewer;

		IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
		editorStore.addPropertyChangeListener(fForegroundScaleListener);
		readOnlyForegroundScaleFactor = editorStore.getInt(EditorPreferenceNames.READ_ONLY_FOREGROUND_SCALE);

		if (textWidget != null) {
			textWidget.removeLineStyleListener(this);
		}
		textWidget = newTextViewer.getTextWidget();
		if (textWidget != null) {
			textWidget.addLineStyleListener(this);
		}

		refreshDisplay();
	}

	public StyleRange[] lineGetStyle(int eventLineOffset, int eventLineLength) {
		StyleRange[] eventStyles = EMPTY_STYLE_RANGE;
		try {
			if (getDocument() == null || eventLineLength == 0) {
				// getDocument() == null
				// during initialization, this is sometimes called before our
				// structured
				// is set, in which case we set styles to be the empty style
				// range
				// (event.styles can not be null)

				// eventLineLength == 0
				// we sometimes get odd requests from the very last CRLF in
				// the
				// document
				// it has no length, and there is no node for it!
				eventStyles = EMPTY_STYLE_RANGE;
			}
			else {
				/*
				 * LineStyleProviders work using absolute document offsets. To
				 * support visible regions, adjust the requested range up to
				 * the full document offsets.
				 */
				IRegion styleRegion = getDocumentRangeFromWidgetRange(eventLineOffset, eventLineLength);
				if (styleRegion != null) {
					int start = styleRegion.getOffset();
					int length = styleRegion.getLength();

					ITypedRegion[] partitions = TextUtilities.computePartitioning(getDocument(), fPartitioning, start, length, false);
					eventStyles = prepareStyleRangesArray(partitions, start, length);

					// If there is a subtext offset, the style ranges must be
					// adjusted to the expected
					// offsets
					// just check if eventLineOffset is different than start
					// then adjust, otherwise u can leave it alone
					// unless there is special handling for
					// itextviewerextension5?
					if (start != eventLineOffset) {
						int offset = 0;
						// figure out visible region to use for adjustment
						// only adjust if need to
						if (!(getTextViewer() instanceof ITextViewerExtension5)) {
							IRegion vr = getTextViewer().getVisibleRegion();
							if (vr != null) {
								offset = vr.getOffset();
								if (offset > 0)
									adjust(eventStyles, -offset);
							}
						}
						else {
							if (getTextViewer() instanceof ProjectionViewer) {
								if (((ProjectionViewer) getTextViewer()).isProjectionMode())
									adjust(eventStyles, -offset);
							}
						}

					}

					// for debugging only
					if (DEBUG) {
						if (!valid(eventStyles, eventLineOffset, eventLineLength)) {
							Logger.log(Logger.WARNING, "Highlighter::lineGetStyle found invalid styles at offset " + eventLineOffset); //$NON-NLS-1$
						}
					}
				}

			}

		}
		catch (Exception e) {
			// if ANY exception occurs during highlighting,
			// just return "no highlighting"
			eventStyles = EMPTY_STYLE_RANGE;
			if (Debug.syntaxHighlighting) {
				System.out.println("Exception during highlighting!"); //$NON-NLS-1$
			}
		}

		return eventStyles;
	}

	/**
	 * A passthrough method that extracts relevant data from the
	 * LineStyleEvent and passes it along. This method was separated for
	 * performance testing purposes.
	 * 
	 * @see org.eclipse.swt.custom.LineStyleListener#lineGetStyle(LineStyleEvent)
	 */
	public void lineGetStyle(LineStyleEvent event) {
		int offset = event.lineOffset;
		int length = event.lineText.length();

		/*
		 * For some reason, we are sometimes asked for the same style range
		 * over and over again. This was found to happen during 'revert' of a
		 * file with one line in it that is 40K long! So, while we don't know
		 * root cause, caching the styled ranges in case the exact same
		 * request is made multiple times seems like cheap insurance.
		 */
		if (offset == fSavedOffset && length == fSavedLength && fSavedRanges != null) {
			event.styles = fSavedRanges;
		}
		else {
			// need to assign this array here, or else the field won't get
			// updated
			event.styles = lineGetStyle(offset, length);
			// now saved "cached data" for repeated requests which are exaclty
			// same
			fSavedOffset = offset;
			fSavedLength = length;
			fSavedRanges = event.styles;
		}
	}

	/**
	 * Note: its very important this method never return null, which is why
	 * the final null check is in a finally clause
	 */

	protected StyleRange[] prepareStyleRangesArray(ITypedRegion[] partitions, int start, int length) {

		StyleRange[] result = EMPTY_STYLE_RANGE;

		if (fHoldStyleResults == null) {
			fHoldStyleResults = new ArrayList(partitions.length);
		}
		else {
			fHoldStyleResults.clear();
		}

		// TODO: make some of these instance variables to prevent creation on
		// stack
		LineStyleProvider currentLineStyleProvider = null;
		boolean handled = false;
		for (int i = 0; i < partitions.length; i++) {
			ITypedRegion currentPartition = partitions[i];
			currentLineStyleProvider = getProviderFor(currentPartition);
			currentLineStyleProvider.init(getDocument(), this);
			handled = currentLineStyleProvider.prepareRegions(currentPartition, currentPartition.getOffset(), currentPartition.getLength(), fHoldStyleResults);
			if (Debug.syntaxHighlighting && !handled) {
				System.out.println("Did not handle highlighting in Highlighter inner while"); //$NON-NLS-1$
			}
		}

		int resultSize = fHoldStyleResults.size();
		if (resultSize > 0) {
			result = (StyleRange[]) fHoldStyleResults.toArray(new StyleRange[fHoldStyleResults.size()]);
		}
		else {
			result = EMPTY_STYLE_RANGE;
		}
		result = convertReadOnlyRegions(result, start, length);
		return result;
	}

	public void refreshDisplay() {
		if (textWidget != null && !textWidget.isDisposed())
			textWidget.redraw();
	}

	/**
	 */
	public void refreshDisplay(int start, int length) {
		if (textWidget != null && !textWidget.isDisposed())
			textWidget.redrawRange(start, length, true);
	}

	public void removeProvider(String partitionType) {
		getTableOfProviders().remove(partitionType);
	}

	public void setDocument(IStructuredDocument structuredDocument) {
		fStructuredDocument = structuredDocument;
	}

	public void setDocumentPartitioning(String partitioning) {
		if (partitioning != null) {
			fPartitioning = partitioning;
		}
		else {
			fPartitioning = IDocumentExtension3.DEFAULT_PARTITIONING;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ibm.sed.structured.style.IHighlighter#uninstall()
	 */
	public void uninstall() {
		if (textWidget != null && !textWidget.isDisposed()) {
			textWidget.removeLineStyleListener(this);
		}
		textWidget = null;

		Collection providers = getTableOfProviders().values();
		Iterator iterator = providers.iterator();
		while (iterator.hasNext()) {
			LineStyleProvider lineStyleProvider = (LineStyleProvider) iterator.next();
			lineStyleProvider.release();
			// this remove probably isn't strictly needed, since
			// typically highlighter instance as a whole will go
			// away ... but in case that ever changes, this seems like
			// a better style.
			iterator.remove();
		}

		synchronized (getExtendedProviders()) {
			providers = new ArrayList(getExtendedProviders().values());
			getExtendedProviders().clear();
		}
		iterator = providers.iterator();
		while (iterator.hasNext()) {
			LineStyleProvider lineStyleProvider = (LineStyleProvider) iterator.next();
			if (lineStyleProvider != null) {
				lineStyleProvider.release();
				iterator.remove();
			}
		}

		IPreferenceStore editorStore = SSEUIPlugin.getDefault().getPreferenceStore();
		editorStore.removePropertyChangeListener(fForegroundScaleListener);
		disposeColorTable();

		// clear out cached variables (d282894)
		fSavedOffset = -1;
		fSavedLength = -1;
		fSavedRanges = null;
	}

	/**
	 * Purely a debugging aide.
	 */
	private boolean valid(StyleRange[] eventStyles, int startOffset, int lineLength) {
		boolean result = false;
		if (eventStyles != null) {
			if (eventStyles.length > 0) {
				StyleRange first = eventStyles[0];
				StyleRange last = eventStyles[eventStyles.length - 1];
				if (startOffset > first.start) {
					result = false;
				}
				else {
					int lineEndOffset = startOffset + lineLength;
					int lastOffset = last.start + last.length;
					if (lastOffset > lineEndOffset) {
						result = false;
					}
					else {
						result = true;
					}
				}
			}
			else {
				// a zero length array is ok
				result = true;
			}
		}
		return result;
	}
}
