/*
 * Java Genetic Algorithm Library (@__identifier__@).
 * Copyright (c) @__year__@ Franz Wilhelmstötter
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Author:
 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmx.at)
 *
 */
package org.jenetics.internal.util;

import static java.lang.String.format;

import org.jenetics.util.Copyable;


/**
 * @author <a href="mailto:franz.wilhelmstoetter@gmx.at">Franz Wilhelmstötter</a>
 * @since @__new_version__@
 * @version @__new_version__@ &mdash; <em>$Date: 2013-06-30 $</em>
 */
public abstract class ArrayProxy<T> implements Copyable<ArrayProxy<T>>{

	protected final int _start;
	protected final int _end;
	protected final int _length;

	protected ArrayProxy(final int start, final int end) {
		_start = start;
		_end = end;
		_length = _end - _start;
	}

	public abstract T uncheckedOffsetGet(final int absoluteIndex);

	public abstract void uncheckedOffsetSet(final int absoluteIndex, final T value);

	public abstract ArrayProxy<T> sub(final int start, final int end);

	public abstract void swap(
		final int start,
		final int end,
		final ArrayProxy<T> other,
		final int otherStart
	);

	public abstract void cloneIfSealed();

	public abstract ArrayProxyImpl<T> seal();

	/**
	 * Return the <i>array</i> element at the specified position in the
	 * {@code ArrayProxy}.
	 *
	 * @param index index of the element to return
	 * @return the <i>array</i> element at the specified position
	 * @throws IndexOutOfBoundsException if the index it out of range
	 *          (index < 0 || index >= _length).
	 */
	public T get(final int index) {
		checkIndex(index);
		return uncheckedOffsetGet(index + _start);
	}

	public void set(final int index, final T value) {
		checkIndex(index);
		uncheckedOffsetSet(index + _start, value);
	}

	/**
	 * Return the <i>array</i> element at the specified position in the
	 * {@code ArrayProxy}. The array boundaries are not checked.
	 *
	 * @param index index of the element to return
	 * @return the <i>array</i> element at the specified position
	 * @throws IndexOutOfBoundsException if the index it out of range
	 *          (index < 0 || index >= _length).
	 */
	public T uncheckedGet(final int index) {
		return uncheckedOffsetGet(index + _start);
	}

	public void uncheckedSet(final int index, final T value) {
		uncheckedOffsetSet(index + _start, value);
	}

	public ArrayProxy<T> sub(final int start) {
		return sub(start, _length);
	}

	protected final void checkIndex(final int index) {
		if (index < 0 || index >= _length) {
			throw new ArrayIndexOutOfBoundsException(format(
				"Index %s is out of bounds [0, %s)", index, _length
			));
		}
	}

	protected final void checkIndex(final int from, final int to) {
		if (from > to) {
			throw new ArrayIndexOutOfBoundsException(
				"fromIndex(" + from + ") > toIndex(" + to+ ")"
			);
		}
		if (from < 0 || to > _length) {
			throw new ArrayIndexOutOfBoundsException(format(
				"Invalid index range: [%d, %s)", from, to
			));
		}
	}


}




@@ -1204,12 +1204,12 @@
 13-0
-6-30
+7-03
  $%3C/
@@ -1904,12 +1904,8 @@
 roxy
-Impl
 %3CT%3E 

Fix return type of 'ArrayProxy.seal' method.