/*******************************************************************************
 * Copyright (c) 2001, 2005 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.core.internal.text;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;


public class TextRegionListImpl implements ITextRegionList {

	private class NullIterator implements Iterator {
		public NullIterator() {
		}

		public boolean hasNext() {
			return false;
		}

		public Object next() {
			throw new NoSuchElementException();
		}

		public void remove() {
			throw new UnsupportedOperationException("can not remove regions via iterator"); //$NON-NLS-1$

		}

	}

	private class RegionIterator implements Iterator {
		private ITextRegion[] fIteratorRegions;
		private int index = -1;
		private int maxindex = -1;

		public RegionIterator() {
			fIteratorRegions = toArray();
			maxindex = fIteratorRegions.length - 1;
		}

		public boolean hasNext() {
			return index < maxindex;
		}

		public Object next() {
			if (!(index < maxindex))
				throw new NoSuchElementException();
			return fIteratorRegions[++index];
		}

		public void remove() {
			throw new UnsupportedOperationException("can not remove regions via iterator"); //$NON-NLS-1$

		}

	}

	private final static int growthConstant = 2;

	private ITextRegion[] fRegions;
	private int fRegionsCount = 0;

	public TextRegionListImpl() {
		super();
	}

	public TextRegionListImpl(ITextRegionList regionList) {
		this();
		fRegions = (ITextRegion[]) regionList.toArray().clone();
		fRegionsCount = fRegions.length;
	}

	public boolean add(ITextRegion region) {

		if (region == null)
			return false;
		ensureCapacity(fRegionsCount + 1);
		fRegions[fRegionsCount++] = region;
		return true;
	}

	public boolean addAll(int insertPos, ITextRegionList newRegions) {
		// beginning of list is 0 to insertPos-1
		// remainder of list is insertPos to fRegionsCount
		// resulting total will be be fRegionsCount + newRegions.size()
		if (insertPos < 0 || insertPos > fRegionsCount) {
			throw new ArrayIndexOutOfBoundsException(insertPos);
		}

		int newRegionsSize = newRegions.size();

		ensureCapacity(fRegionsCount + newRegionsSize);

		int numMoved = fRegionsCount - insertPos;
		if (numMoved > 0)
			System.arraycopy(fRegions, insertPos, fRegions, insertPos + newRegionsSize, numMoved);

		for (int i = 0; i < newRegionsSize; i++)
			fRegions[insertPos++] = newRegions.get(i);

		fRegionsCount += newRegionsSize;
		return newRegionsSize != 0;

	}

	public void clear() {
		// note: size of array is not reduced!
		fRegionsCount = 0;
	}

	private void ensureCapacity(int needed) {
		if (fRegions == null) {
			// first time
			fRegions = new ITextRegion[needed];
			return;
		}
		int oldLength = fRegions.length;
		if (oldLength < needed) {
			ITextRegion[] oldAdapters = fRegions;
			ITextRegion[] newAdapters = new ITextRegion[needed + growthConstant];
			System.arraycopy(oldAdapters, 0, newAdapters, 0, fRegionsCount);
			fRegions = newAdapters;
		}
	}

	public ITextRegion get(int index) {
		if (index < 0 || index > fRegionsCount) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		ITextRegion result = fRegions[index];
		return result;
	}

	public int indexOf(ITextRegion region) {

		int result = -1;
		if (region != null) {
			if (fRegions != null) {
				for (int i = 0; i < fRegions.length; i++) {
					if (region.equals(fRegions[i])) {
						result = i;
						break;
					}
				}
			}
		}
		return result;
	}

	public boolean isEmpty() {
		return fRegionsCount == 0;
	}

	public Iterator iterator() {
		if (size() == 0) {
			return new NullIterator();
		} else {
			return new RegionIterator();
		}
	}

	public ITextRegion remove(int index) {
		// much more efficient ways to implement this, but
		// I doubt if called often
		ITextRegion oneToRemove = get(index);
		remove(oneToRemove);
		return oneToRemove;
	}

	public void remove(ITextRegion a) {
		if (fRegions == null || a == null)
			return;
		int newIndex = 0;
		ITextRegion[] newRegions = new ITextRegion[fRegionsCount];
		int oldRegionCount = fRegionsCount;
		boolean found = false;
		for (int oldIndex = 0; oldIndex < oldRegionCount; oldIndex++) {
			ITextRegion candidate = fRegions[oldIndex];
			if (a == candidate) {
				fRegionsCount--;
				found = true;
			} else
				newRegions[newIndex++] = fRegions[oldIndex];
		}
		if (found)
			fRegions = newRegions;
	}

	public void removeAll(ITextRegionList regionList) {
		// much more efficient ways to implement this, but
		// I doubt if called often
		if (regionList != null) {
			for (int i = 0; i < regionList.size(); i++) {
				this.remove(regionList.get(i));
			}
		}

	}

	public int size() {
		return fRegionsCount;
	}

	public ITextRegion[] toArray() {
		// return "clone" of internal array
		ITextRegion[] newArray = new ITextRegion[fRegionsCount];
		System.arraycopy(fRegions, 0, newArray, 0, fRegionsCount);
		return newArray;
	}

}
