/*******************************************************************************
 * Copyright (c) 2000, 2008 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 org.eclipse.swt.*;

/**
 * Instances of this class represent bullets in the <code>StyledText</code>.
 * <p>
 * The hashCode() method in this class uses the values of the public
 * fields to compute the hash value. When storing instances of the
 * class in hashed collections, do not modify these fields after the
 * object has been inserted.
 * </p>
 * <p>
 * Application code does <em>not</em> need to explicitly release the
 * resources managed by each instance when those instances are no longer
 * required, and thus no <code>dispose()</code> method is provided.
 * </p>
 *
 * @see StyledText#setLineBullet(int, int, Bullet)
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 *
 * @since 3.2
 */
public class Bullet {
	/**
	* The bullet type.  Possible values are:
	* <ul>
	* <li><code>ST.BULLET_DOT</code></li>
	* <li><code>ST.BULLET_NUMBER</code></li>
	* <li><code>ST.BULLET_LETTER_LOWER</code></li>
	* <li><code>ST.BULLET_LETTER_UPPER</code></li>
	* <li><code>ST.BULLET_TEXT</code></li>
	* <li><code>ST.BULLET_CUSTOM</code></li>
	* </ul>
	*/
	public int type;

	/**
	* The bullet style.
	*/
	public StyleRange style;

	/**
	* The bullet text.
	*/
	public String text;

	int[] linesIndices;
	int count;

/**
 * Create a new bullet with the specified style, and type <code>ST.BULLET_DOT</code>.
 * The style must have a glyph metrics set.
 *
 * @param style the style
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT when the style or the glyph metrics are null</li>
 * </ul>
 */
public Bullet(StyleRange style) {
	this(ST.BULLET_DOT, style);
}
/**
 * Create a new bullet the specified style and type.
 * The style must have a glyph metrics set.
 *
 * @param type the bullet type
 * @param style the style
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT when the style or the glyph metrics are null</li>
 * </ul>
 */
public Bullet(int type, StyleRange style) {
	if (style == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	if (style.metrics == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	this.type = type;
	this.style = style;
}
void addIndices (int startLine, int lineCount) {
	if (linesIndices == null) {
		linesIndices = new int[lineCount];
		count = lineCount;
		for (int i = 0; i < lineCount; i++) linesIndices[i] = startLine + i;
	} else {
		int modifyStart = 0;
		while (modifyStart < count) {
			if (startLine <= linesIndices[modifyStart]) break;
			modifyStart++;
		}
		int modifyEnd = modifyStart;
		while (modifyEnd < count) {
			if (startLine + lineCount <= linesIndices[modifyEnd]) break;
			modifyEnd++;
		}
		int newSize = modifyStart + lineCount + count - modifyEnd;
		if (newSize > linesIndices.length) {
			int[] newLinesIndices = new int[newSize];
			System.arraycopy(linesIndices, 0, newLinesIndices, 0, count);
			linesIndices = newLinesIndices;
		}
		System.arraycopy(linesIndices, modifyEnd, linesIndices, modifyStart + lineCount, count - modifyEnd);
		for (int i = 0; i < lineCount; i++) linesIndices[modifyStart + i] = startLine + i;
		count = newSize;
	}
}
int indexOf (int lineIndex) {
	for (int i = 0; i < count; i++) {
		if (linesIndices[i] == lineIndex) return i;
	}
	return -1;
}
@Override
public int hashCode() {
	return style.hashCode() ^ type;
}
int[] removeIndices (int startLine, int replaceLineCount, int newLineCount, boolean update) {
	if (count == 0) return null;
	if (startLine > linesIndices[count - 1]) return null;
	int endLine = startLine + replaceLineCount;
	int delta = newLineCount - replaceLineCount;
	for (int i = 0; i < count; i++) {
		int index = linesIndices[i];
		if (startLine <= index) {
			int j = i;
			while (j < count) {
				if (linesIndices[j] >= endLine) break;
				j++;
			}
			if (update) {
				for (int k = j; k < count; k++) linesIndices[k] += delta;
			}
			int[] redrawLines = new int[count - j];
			System.arraycopy(linesIndices, j, redrawLines, 0, count - j);
			System.arraycopy(linesIndices, j, linesIndices, i, count - j);
			count -= (j - i);
			return redrawLines;
		}
	}
	for (int i = 0; i < count; i++) linesIndices[i] += delta;
	return null;
}
int size() {
	return count;
}
}
