/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.custom;

import java.util.*;
import java.util.List;

import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.widgets.*;

class DefaultContent implements StyledTextContent {
	private final static String LineDelimiter = System.lineSeparator();

	List<StyledTextListener> textListeners = new ArrayList<>(); // stores text listeners for event sending
	char[] textStore = new char[0];	// stores the actual text
	int gapStart = -1;	// the character position start of the gap
	int gapEnd = -1;	// the character position after the end of the gap
	int gapLine = -1;	// the line on which the gap exists, the gap will always be associated with one line
	int highWatermark = 300;
	int lowWatermark = 50;

	int[][] lines = new int[50][2];	// array of character positions and lengths representing the lines of text
	int lineCount = 0;	// the number of lines of text
	int expandExp = 1; 	// the expansion exponent, used to increase the lines array exponentially
	int replaceExpandExp = 1; 	// the expansion exponent, used to increase the lines array exponentially

/**
 * Creates a new DefaultContent and initializes it.  A <code>StyledTextContent</code> will always have
 * at least one empty line.
 */
DefaultContent() {
	super();
	setText("");
}
/**
 * Adds a line to the end of the line indexes array.  Increases the size of the array if necessary.
 * <code>lineCount</code> is updated to reflect the new entry.
 * <p>
 *
 * @param start the start of the line
 * @param length the length of the line
 */
void addLineIndex(int start, int length) {
	int size = lines.length;
	if (lineCount == size) {
		// expand the lines by powers of 2
		int[][] newLines = new int[size+Compatibility.pow2(expandExp)][2];
		System.arraycopy(lines, 0, newLines, 0, size);
		lines = newLines;
		expandExp++;
	}
	int[] range = new int[] {start, length};
	lines[lineCount] = range;
	lineCount++;
}
/**
 * Adds a line index to the end of <code>linesArray</code>.  Increases the
 * size of the array if necessary and returns a new array.
 * <p>
 *
 * @param start the start of the line
 * @param length the length of the line
 * @param linesArray the array to which to add the line index
 * @param count the position at which to add the line
 * @return a new array of line indexes
 */
int[][] addLineIndex(int start, int length, int[][] linesArray, int count) {
	int size = linesArray.length;
	int[][] newLines = linesArray;
	if (count == size) {
		newLines = new int[size+Compatibility.pow2(replaceExpandExp)][2];
		replaceExpandExp++;
		System.arraycopy(linesArray, 0, newLines, 0, size);
	}
	int[] range = new int[] {start, length};
	newLines[count] = range;
	return newLines;
}
/**
 * Adds a <code>TextChangeListener</code> listening for
 * <code>TextChangingEvent</code> and <code>TextChangedEvent</code>. A
 * <code>TextChangingEvent</code> is sent before changes to the text occur.
 * A <code>TextChangedEvent</code> is sent after changes to the text
 * occurred.
 * <p>
 *
 * @param listener the listener
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT when listener is null</li>
 * </ul>
 */
@Override
public void addTextChangeListener(TextChangeListener listener) {
	if (listener == null) error(SWT.ERROR_NULL_ARGUMENT);
	StyledTextListener typedListener = new StyledTextListener(listener);
	textListeners.add(typedListener);
}
/**
 * Adjusts the gap to accommodate a text change that is occurring.
 * <p>
 *
 * @param position the position at which a change is occurring
 * @param sizeHint the size of the change
 * @param line the line where the gap will go
 */
void adjustGap(int position, int sizeHint, int line) {
	if (position == gapStart) {
		// text is being inserted at the gap position
		int size = (gapEnd - gapStart) - sizeHint;
		if (lowWatermark <= size && size <= highWatermark)
			return;
	} else if ((position + sizeHint == gapStart) && (sizeHint < 0)) {
		// text is being deleted at the gap position
		int size = (gapEnd - gapStart) - sizeHint;
		if (lowWatermark <= size && size <= highWatermark)
			return;
	}
	moveAndResizeGap(position, sizeHint, line);
}
/**
 * Calculates the indexes of each line in the text store.  Assumes no gap exists.
 * Optimized to do less checking.
 */
void indexLines(){
	int start = 0;
	lineCount = 0;
	int textLength = textStore.length;
	int i;
	for (i = start; i < textLength; i++) {
		char ch = textStore[i];
		if (ch == SWT.CR) {
			// see if the next character is a LF
			if (i + 1 < textLength) {
				ch = textStore[i+1];
				if (ch == SWT.LF) {
					i++;
				}
			}
			addLineIndex(start, i - start + 1);
			start = i + 1;
		} else if (ch == SWT.LF) {
			addLineIndex(start, i - start + 1);
			start = i + 1;
		}
	}
	addLineIndex(start, i - start);
}
/**
 * Returns whether or not the given character is a line delimiter.  Both CR and LF
 * are valid line delimiters.
 * <p>
 *
 * @param ch the character to test
 * @return true if ch is a delimiter, false otherwise
 */
boolean isDelimiter(char ch) {
	if (ch == SWT.CR) return true;
	if (ch == SWT.LF) return true;
	return false;
}

private boolean isInsideCRLF(int pos) {
	if (pos == 0) return false;
	if (pos == getCharCount()) return false;

	char charBefore = getTextRange(pos - 1, 1).charAt(0);
	if (charBefore != '\r') return false;

	char charAfter = getTextRange(pos, 1).charAt(0);
	if (charAfter != '\n') return false;

	/*
	 * Bug 568033: in case of this.setText("\rxxx\n")
	 * \r and \n are already parsed as separate line endings, so it
	 * shouldn't be wrong to delete 'xxx' and type something there.
	 */
	if (getLineAtOffset(pos - 1) != getLineAtOffset(pos))
		return false;

	return true;
}

/**
 * Validates the replace operation.  DefaultContent will not allow
 * the \r\n line delimiter to be split or partially deleted.
 * <p>
 *
 * @param start start offset of text to replace
 * @param replaceLength start offset of text to replace
 */
private void validateReplace(int start, int replaceLength) {
	if (replaceLength == 0) {
		// inserting text, see if the \r\n line delimiter is being split
		if (isInsideCRLF(start)) {
			String message = " [0: start=" + start + " len=" + replaceLength + "]";
			SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, message);
		}
	} else {
		// deleting text, see if part of a \r\n line delimiter is being deleted
		if (isInsideCRLF(start)) {
			String message = " [1: start=" + start + " len=" + replaceLength + "]";
			SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, message);
		}

		if (isInsideCRLF(start + replaceLength)) {
			String message = " [2: start=" + start + " len=" + replaceLength + "]";
			SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, message);
		}
	}
}
/**
 * Calculates the indexes of each line of text in the given range.
 * <p>
 *
 * @param offset the logical start offset of the text lineate
 * @param length the length of the text to lineate, includes gap
 * @param numLines the number of lines to initially allocate for the line index array,
 *	passed in for efficiency (the exact number of lines may be known)
 * @return a line indexes array where each line is identified by a start offset and
 * 	a length
 */
int[][] indexLines(int offset, int length, int numLines){
	int[][] indexedLines = new int[numLines][2];
	int start = 0;
	int lineCount = 0;
	int i;
	replaceExpandExp = 1;
	for (i = start; i < length; i++) {
		int location = i + offset;
		if ((location >= gapStart) && (location < gapEnd)) {
			// ignore the gap
		} else {
			char ch = textStore[location];
			if (ch == SWT.CR) {
				// see if the next character is a LF
				if (location+1 < textStore.length) {
					ch = textStore[location+1];
					if (ch == SWT.LF) {
						i++;
					}
				}
				indexedLines = addLineIndex(start, i - start + 1, indexedLines, lineCount);
				lineCount++;
				start = i + 1;
			} else if (ch == SWT.LF) {
				indexedLines = addLineIndex(start, i - start + 1, indexedLines, lineCount);
				lineCount++;
				start = i + 1;
			}
		}
	}
	int[][] newLines = new int[lineCount+1][2];
	System.arraycopy(indexedLines, 0, newLines, 0, lineCount);
	int[] range = new int[] {start, i - start};
	newLines[lineCount] = range;
	return newLines;
}
/**
 * Inserts text.
 * <p>
 *
 * @param position the position at which to insert the text
 * @param text the text to insert
 */
void insert(int position, String text) {
	if (text.length() == 0) return;

	int startLine = getLineAtOffset(position);
	int change = text.length();
	boolean endInsert = position == getCharCount();
	adjustGap(position, change, startLine);

	// during an insert the gap will be adjusted to start at
	// position and it will be associated with startline, the
	// inserted text will be placed in the gap
	int startLineOffset = getOffsetAtLine(startLine);
	// at this point, startLineLength will include the start line
	// and all of the newly inserted text
	int	startLineLength = getPhysicalLine(startLine).length();

	if (change > 0) {
		// shrink gap
		gapStart += (change);
		for (int i = 0; i < text.length(); i++) {
			textStore[position + i]= text.charAt(i);
		}
	}

	// figure out the number of new lines that have been inserted
	int [][] newLines = indexLines(startLineOffset, startLineLength, 10);
	// only insert an empty line if it is the last line in the text
	int numNewLines = newLines.length - 1;
	if (newLines[numNewLines][1] == 0) {
		// last inserted line is a new line
		if (endInsert) {
			// insert happening at end of the text, leave numNewLines as
			// is since the last new line will not be concatenated with another
			// line
			numNewLines += 1;
		} else {
			numNewLines -= 1;
		}
	}

	// make room for the new lines
	expandLinesBy(numNewLines);
	// shift down the lines after the replace line
	for (int i = lineCount - 1; i > startLine; i--) {
		lines[i + numNewLines]=lines[i];
	}
	// insert the new lines
	for (int i = 0; i < numNewLines; i++) {
		newLines[i][0] += startLineOffset;
		lines[startLine + i]=newLines[i];
	}
	// update the last inserted line
	if (numNewLines < newLines.length) {
		newLines[numNewLines][0] += startLineOffset;
		lines[startLine + numNewLines] = newLines[numNewLines];
	}

	lineCount += numNewLines;
	gapLine = getLineAtPhysicalOffset(gapStart);
}
/**
 * Moves the gap and adjusts its size in anticipation of a text change.
 * The gap is resized to actual size + the specified size and moved to the given
 * position.
 * <p>
 *
 * @param position the position at which a change is occurring
 * @param size the size of the change
 * @param newGapLine the line where the gap should be put
 */
void moveAndResizeGap(int position, int size, int newGapLine) {
	char[] content = null;
	int oldSize = gapEnd - gapStart;
	int newSize;
	if (size > 0) {
		newSize = highWatermark + size;
	} else {
		newSize = lowWatermark - size;
	}
	// remove the old gap from the lines information
	if (gapExists()) {
		// adjust the line length
		lines[gapLine][1] = lines[gapLine][1] - oldSize;
		// adjust the offsets of the lines after the gapLine
		for (int i = gapLine + 1; i < lineCount; i++) {
			lines[i][0] = lines[i][0] - oldSize;
		}
	}

	if (newSize < 0) {
		if (oldSize > 0) {
			// removing the gap
			content = new char[textStore.length - oldSize];
			System.arraycopy(textStore, 0, content, 0, gapStart);
			System.arraycopy(textStore, gapEnd, content, gapStart, content.length - gapStart);
			textStore = content;
		}
		gapStart = gapEnd = position;
		return;
	}
	content = new char[textStore.length + (newSize - oldSize)];
	int newGapStart = position;
	int newGapEnd = newGapStart + newSize;
	if (oldSize == 0) {
		System.arraycopy(textStore, 0, content, 0, newGapStart);
		System.arraycopy(textStore, newGapStart, content, newGapEnd, content.length - newGapEnd);
	} else if (newGapStart < gapStart) {
		int delta = gapStart - newGapStart;
		System.arraycopy(textStore, 0, content, 0, newGapStart);
		System.arraycopy(textStore, newGapStart, content, newGapEnd, delta);
		System.arraycopy(textStore, gapEnd, content, newGapEnd + delta, textStore.length - gapEnd);
	} else {
		int delta = newGapStart - gapStart;
		System.arraycopy(textStore, 0, content, 0, gapStart);
		System.arraycopy(textStore, gapEnd, content, gapStart, delta);
		System.arraycopy(textStore, gapEnd + delta, content, newGapEnd, content.length - newGapEnd);
	}
	textStore = content;
	gapStart = newGapStart;
	gapEnd = newGapEnd;

	// add the new gap to the lines information
	if (gapExists()) {
		gapLine = newGapLine;
		// adjust the line length
		int gapLength = gapEnd - gapStart;
		lines[gapLine][1] = lines[gapLine][1] + (gapLength);
		// adjust the offsets of the lines after the gapLine
		for (int i = gapLine + 1; i < lineCount; i++) {
			lines[i][0] = lines[i][0] + gapLength;
		}
	}
}
/**
 * Returns the number of lines that are in the specified text.
 * <p>
 *
 * @param startOffset the start of the text to lineate
 * @param length the length of the text to lineate
 * @return number of lines
 */
int lineCount(int startOffset, int length){
	if (length == 0) {
		return 0;
	}
	int lineCount = 0;
	int count = 0;
	int i = startOffset;
	if (i >= gapStart) {
		i += gapEnd - gapStart;
	}
	while (count < length) {
		if ((i >= gapStart) && (i < gapEnd)) {
			// ignore the gap
		} else {
			char ch = textStore[i];
			if (ch == SWT.CR) {
				// see if the next character is a LF
				if (i + 1 < textStore.length) {
					ch = textStore[i+1];
					if (ch == SWT.LF) {
						i++;
						count++;
					}
				}
				lineCount++;
			} else if (ch == SWT.LF) {
				lineCount++;
			}
			count++;
		}
		i++;
	}
	return lineCount;
}
/**
 * Returns the number of lines that are in the specified text.
 * <p>
 *
 * @param text the text to lineate
 * @return number of lines in the text
 */
int lineCount(String text){
	int lineCount = 0;
	int length = text.length();
	for (int i = 0; i < length; i++) {
		char ch = text.charAt(i);
		if (ch == SWT.CR) {
			if (i + 1 < length && text.charAt(i + 1) == SWT.LF) {
				i++;
			}
			lineCount++;
		} else if (ch == SWT.LF) {
			lineCount++;
		}
	}
	return lineCount;
}
/**
 * @return the logical length of the text store
 */
@Override
public int getCharCount() {
	int length = gapEnd - gapStart;
	return (textStore.length - length);
}
/**
 * Returns the line at <code>index</code> without delimiters.
 * <p>
 *
 * @param index	the index of the line to return
 * @return the logical line text (i.e., without the gap)
 * @exception IllegalArgumentException <ul>
 *   <li>ERROR_INVALID_ARGUMENT when index is out of range</li>
 * </ul>
 */
@Override
public String getLine(int index) {
	if ((index >= lineCount) || (index < 0)) error(SWT.ERROR_INVALID_ARGUMENT);
	int start = lines[index][0];
	int length = lines[index][1];
	int end = start + length - 1;
	if (!gapExists() || (end < gapStart) || (start >= gapEnd)) {
		// line is before or after the gap
		while ((length - 1 >= 0) && isDelimiter(textStore[start+length-1])) {
			length--;
		}
		return new String(textStore, start, length);
	} else {
		// gap is in the specified range, strip out the gap
		StringBuilder buf = new StringBuilder();
		int gapLength = gapEnd - gapStart;
		buf.append(textStore, start, gapStart - start);
		buf.append(textStore, gapEnd, length - gapLength - (gapStart - start));
		length = buf.length();
		while ((length - 1 >=0) && isDelimiter(buf.charAt(length - 1))) {
			length--;
		}
		return buf.toString().substring(0, length);
	}
}
/**
 * Returns the line delimiter that should be used by the StyledText
 * widget when inserting new lines.  This delimiter may be different than the
 * delimiter that is used by the <code>StyledTextContent</code> interface.
 * <p>
 *
 * @return the platform line delimiter as specified in the line.separator
 * 	system property.
 */
@Override
public String getLineDelimiter() {
	return LineDelimiter;
}
/**
 * Returns the line at the given index with delimiters.
 * <p>
 * @param index	the index of the line to return
 * @return the logical line text (i.e., without the gap) with delimiters
 */
String getFullLine(int index) {
	int start = lines[index][0];
	int length = lines[index][1];
	int end = start + length - 1;
	if (!gapExists() || (end < gapStart) || (start >= gapEnd)) {
		// line is before or after the gap
		return new String(textStore, start, length);
	} else {
		// gap is in the specified range, strip out the gap
		StringBuilder buffer = new StringBuilder();
		int gapLength = gapEnd - gapStart;
		buffer.append(textStore, start, gapStart - start);
		buffer.append(textStore, gapEnd, length - gapLength - (gapStart - start));
		return buffer.toString();
	}
}
/**
 * Returns the physical line at the given index (i.e., with delimiters and the gap).
 * <p>
 *
 * @param index the line index
 * @return the physical line
 */
String getPhysicalLine(int index) {
	int start = lines[index][0];
	int length = lines[index][1];
	return getPhysicalText(start, length);
}
/**
 * @return the number of lines in the text store
 */
@Override
public int getLineCount(){
	return lineCount;
}
/**
 * Returns the line at the given offset.
 * <p>
 *
 * @param charPosition logical character offset (i.e., does not include gap)
 * @return the line index
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT when charPosition is out of range</li>
 * </ul>
 */
@Override
public int getLineAtOffset(int charPosition){
	if ((charPosition > getCharCount()) || (charPosition < 0)) error(SWT.ERROR_INVALID_ARGUMENT);
	int position;
	if (charPosition < gapStart) {
		// position is before the gap
		position = charPosition;
	} else {
		// position includes the gap
		position = charPosition + (gapEnd - gapStart);
	}

	// if last line and the line is not empty you can ask for
	// a position that doesn't exist (the one to the right of the
	// last character) - for inserting
	if (lineCount > 0) {
		int lastLine = lineCount - 1;
		if (position == lines[lastLine][0] + lines[lastLine][1])
			return lastLine;
	}

	int high = lineCount;
	int low = -1;
	int index = lineCount;
	while (high - low > 1) {
		index = (high + low) / 2;
		int lineStart = lines[index][0];
		int lineEnd = lineStart + lines[index][1] - 1;
		if (position <= lineStart) {
			high = index;
		} else if (position <= lineEnd) {
			high = index;
			break;
		} else {
			low = index;
		}
	}
	return high;
}
/**
 * Returns the line index at the given physical offset.
 * <p>
 *
 * @param position physical character offset (i.e., includes gap)
 * @return the line index
 */
int getLineAtPhysicalOffset(int position){
	int high = lineCount;
	int low = -1;
	int index = lineCount;
	while (high - low > 1) {
		index = (high + low) / 2;
		int lineStart = lines[index][0];
		int lineEnd = lineStart + lines[index][1] - 1;
		if (position <= lineStart) {
			high = index;
		} else if (position <= lineEnd) {
			high = index;
			break;
		} else {
			low = index;
		}
	}
	return high;
}
/**
 * Returns the logical offset of the given line.
 * <p>
 *
 * @param lineIndex index of line
 * @return the logical starting offset of the line.  When there are not any lines,
 * 	getOffsetAtLine(0) is a valid call that should answer 0.
 * @exception IllegalArgumentException <ul>
 *   <li>ERROR_INVALID_ARGUMENT when lineIndex is out of range</li>
 * </ul>
 */
@Override
public int getOffsetAtLine(int lineIndex) {
	if (lineIndex == 0) return 0;
	if ((lineIndex >= lineCount) || (lineIndex < 0)) error(SWT.ERROR_INVALID_ARGUMENT);
	int start = lines[lineIndex][0];
	if (start > gapEnd) {
		return start - (gapEnd - gapStart);
	} else {
		return start;
	}
}
/**
 * Increases the line indexes array to accommodate more lines.
 * <p>
 *
 * @param numLines the number to increase the array by
 */
void expandLinesBy(int numLines) {
	int size = lines.length;
	if (size - lineCount >= numLines) {
		return;
	}
	int[][] newLines = new int[size+Math.max(10, numLines)][2];
	System.arraycopy(lines, 0, newLines, 0, size);
	lines = newLines;
}
/**
 * Reports an SWT error.
 * <p>
 *
 * @param code the error code
 */
void error (int code) {
	SWT.error(code);
}
/**
 * Returns whether or not a gap exists in the text store.
 * <p>
 *
 * @return true if gap exists, false otherwise
 */
boolean gapExists() {
	return gapStart != gapEnd;
}
/**
 * Returns a string representing the continuous content of
 * the text store.
 * <p>
 *
 * @param start	the physical start offset of the text to return
 * @param length the physical length of the text to return
 * @return the text
 */
String getPhysicalText(int start, int length) {
	return new String(textStore, start, length);
}
/**
 * Returns a string representing the logical content of
 * the text store (i.e., gap stripped out).
 * <p>
 *
 * @param start the logical start offset of the text to return
 * @param length the logical length of the text to return
 * @return the text
 */
@Override
public String getTextRange(int start, int length) {
	if (textStore == null)
		return "";
	if (length == 0)
		return "";
	int end= start + length;
	if (!gapExists() || (end < gapStart))
		return new String(textStore, start, length);
	if (gapStart < start) {
		int gapLength= gapEnd - gapStart;
		return new String(textStore, start + gapLength , length);
	}
	StringBuilder buf = new StringBuilder();
	buf.append(textStore, start, gapStart - start);
	buf.append(textStore, gapEnd, end - gapStart);
	return buf.toString();
}
/**
 * Removes the specified <code>TextChangeListener</code>.
 * <p>
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT when listener is null</li>
 * </ul>
 */
@Override
public void removeTextChangeListener(TextChangeListener listener){
	if (listener == null) error(SWT.ERROR_NULL_ARGUMENT);
	for (int i = 0; i < textListeners.size(); i++) {
		TypedListener typedListener = textListeners.get(i);
		if (typedListener.getEventListener () == listener) {
			textListeners.remove(i);
			break;
		}
	}
}
/**
 * Replaces the text with <code>newText</code> starting at position <code>start</code>
 * for a length of <code>replaceLength</code>.  Notifies the appropriate listeners.
 * <p>
 *
 * When sending the TextChangingEvent, <code>newLineCount</code> is the number of
 * lines that are going to be inserted and <code>replaceLineCount</code> is
 * the number of lines that are going to be deleted, based on the change
 * that occurs visually.  For example:
 * </p>
 * <ul>
 * <li>(replaceText,newText) ==&gt; (replaceLineCount,newLineCount)
 * <li>("","\n") ==&gt; (0,1)
 * <li>("\n\n","a") ==&gt; (2,0)
 * </ul>
 *
 * @param start	start offset of text to replace
 * @param replaceLength start offset of text to replace
 * @param newText start offset of text to replace
 *
 * @exception SWTException <ul>
 *   <li>ERROR_INVALID_ARGUMENT when the text change results in a multi byte
 *      line delimiter being split or partially deleted.  Splitting a line
 *      delimiter by inserting text between the CR and LF characters of the
 *      \r\n delimiter or deleting part of this line delimiter is not supported</li>
 * </ul>
 */
@Override
public void replaceTextRange(int start, int replaceLength, String newText){
	// check for invalid replace operations
	validateReplace(start, replaceLength);

	// inform listeners
	StyledTextEvent event = new StyledTextEvent(this);
	event.type = ST.TextChanging;
	event.start = start;
	event.replaceLineCount = lineCount(start, replaceLength);
	event.text = newText;
	event.newLineCount = lineCount(newText);
	event.replaceCharCount = replaceLength;
	event.newCharCount = newText.length();
	sendTextEvent(event);

	// first delete the text to be replaced
	delete(start, replaceLength, event.replaceLineCount + 1);
	// then insert the new text
	insert(start, newText);
	// inform listeners
	event = new StyledTextEvent(this);
	event.type = ST.TextChanged;
	sendTextEvent(event);
}
/**
 * Sends the text listeners the TextChanged event.
 */
void sendTextEvent(StyledTextEvent event) {
	for (StyledTextListener textListener : textListeners) {
		textListener.handleEvent(event);
	}
}
/**
 * Sets the content to text and removes the gap since there are no sensible predictions
 * about where the next change will occur.
 * <p>
 *
 * @param text the text
 */
@Override
public void setText (String text){
	textStore = text.toCharArray();
	gapStart = -1;
	gapEnd = -1;
	expandExp = 1;
	indexLines();
	StyledTextEvent event = new StyledTextEvent(this);
	event.type = ST.TextSet;
	event.text = "";
	sendTextEvent(event);
}
/**
 * Deletes text.
 * <p>
 * @param position the position at which the text to delete starts
 * @param length the length of the text to delete
 * @param numLines the number of lines that are being deleted
 */
void delete(int position, int length, int numLines) {
	if (length == 0) return;

	int startLine = getLineAtOffset(position);
	int startLineOffset = getOffsetAtLine(startLine);
	int endLine = getLineAtOffset(position + length);

	String endText = "";
	boolean splittingDelimiter = false;
	if (position + length < getCharCount()) {
		endText = getTextRange(position + length - 1, 2);
		if ((endText.charAt(0) == SWT.CR) && (endText.charAt(1) == SWT.LF)) {
			splittingDelimiter = true;
		}
	}

	adjustGap(position + length, -length, startLine);
	int [][] oldLines = indexLines(position, length + (gapEnd - gapStart), numLines);

	// enlarge the gap - the gap can be enlarged either to the
	// right or left
	if (position + length == gapStart) {
		gapStart -= length;
	} else {
		gapEnd += length;
	}

	// figure out the length of the new concatenated line, do so by
	// finding the first line delimiter after position
	int j = position;
	boolean eol = false;
	while (j < textStore.length && !eol) {
		if (j < gapStart || j >= gapEnd) {
			char ch = textStore[j];
			if (isDelimiter(ch)) {
				if (j + 1 < textStore.length) {
					if (ch == SWT.CR && (textStore[j+1] == SWT.LF)) {
						j++;
					}
				}
				eol = true;
			}
		}
		j++;
	}
	// update the line where the deletion started
	lines[startLine][1] = (position - startLineOffset) + (j - position);
	// figure out the number of lines that have been deleted
	int numOldLines = oldLines.length - 1;
	if (splittingDelimiter) numOldLines -= 1;
	// shift up the lines after the last deleted line, no need to update
	// the offset or length of the lines
	for (int i = endLine + 1; i < lineCount; i++) {
		lines[i - numOldLines] = lines[i];
	}
	lineCount -= numOldLines;
	gapLine = getLineAtPhysicalOffset(gapStart);
}
}
