/*******************************************************************************
 * Copyright (c) 2001, 2010 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
 *     David Carver (Intalio) - bug 300434 - Make inner classes static where possible
 *******************************************************************************/
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 {

	static 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 static class RegionIterator implements Iterator {
		private ITextRegion[] fIteratorRegions;
		private int index = -1;
		private int maxindex = -1;

		public RegionIterator(ITextRegion[] regions) {
			fIteratorRegions = regions;
			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() {
			if (index < 0) {
				// next() has never been called
				throw new IllegalStateException("can not remove regions without prior invocation of next()"); //$NON-NLS-1$
			}
			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 newRegionList) {
		// 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 newRegionListSize = newRegionList.size();

		ensureCapacity(fRegionsCount + newRegionListSize);

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

		if (newRegionList instanceof TextRegionListImpl && ((TextRegionListImpl) newRegionList).fRegions != null) {
			System.arraycopy(((TextRegionListImpl) newRegionList).fRegions, 0, fRegions, insertPos, newRegionListSize);
		}
		else {
			for (int i = 0; i < newRegionListSize; i++) {
				fRegions[insertPos++] = newRegionList.get(i);
			}
		}
		fRegionsCount += newRegionListSize;
		return newRegionListSize != 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) {
		// fRegionCount may not equal fRegions.length
		if (index < 0 || index >= fRegionsCount) {
			throw new ArrayIndexOutOfBoundsException(index);
		}
		return fRegions[index];
	}

	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(toArray());
		}
	}

	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;
	}
	
	public void trimToSize() {
		if (fRegions.length > fRegionsCount) {
			ITextRegion[] newRegions = new ITextRegion[fRegionsCount];
			System.arraycopy(fRegions, 0, newRegions, 0, fRegionsCount);
			fRegions = newRegions;
		}
	}

}
