/*=============================================================================#
 # Copyright (c) 2009, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.data.impl;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.data.RJIO;


/**
 * This implementation is limited to length of 2<sup>31</sup>-1.
 */
@NonNullByDefault
public class RInteger32Store extends AbstractIntegerStore
		implements RDataResizeExtension<Integer>, ExternalizableRStore, Externalizable {
	
	
	private int length;
	
	protected int [] intValues;
	
	
	public RInteger32Store() {
		this.length= 0;
		this.intValues= EMPTY_INT_ARRAY;
	}
	
	public RInteger32Store(final int length) {
		this.intValues= new int[length];
		this.length= length;
	}
	
	public RInteger32Store(final int [] values) {
		this.length= values.length;
		this.intValues= values;
	}
	
	public RInteger32Store(final int [] values, final int length) {
		this.length= length;
		this.intValues= values;
	}
	
	public RInteger32Store(final int [] values, final int @Nullable[] naIdxs) {
		this.length= values.length;
		this.intValues= values;
		if (naIdxs != null) {
			for (int i= 0; i < naIdxs.length; i++) {
				this.intValues[naIdxs[i]]= NA_integer_INT;
			}
		}
	}
	
	public RInteger32Store(final int [] values, final boolean @Nullable[] isNAs) {
		this.length= values.length;
		this.intValues= values;
		if (isNAs != null) {
			if (isNAs.length != this.length) {
				throw new IllegalArgumentException();
			}
			for (int i= 0; i < isNAs.length; i++) {
				if (isNAs[i]) {
					this.intValues[i]= NA_integer_INT;
				}
			}
		}
	}
	
	
	public RInteger32Store(final RJIO io, final int length) throws IOException {
		this.length= length;
		this.intValues= io.readIntData(new int[length], length);
	}
	
	@Override
	public void writeExternal(final RJIO io) throws IOException {
		io.writeIntData(this.intValues, this.length);
	}
	
	@Override
	public void readExternal(final ObjectInput in) throws IOException {
		this.length= in.readInt();
		this.intValues= new int[this.length];
		for (int i= 0; i < this.length; i++) {
			this.intValues[i]= in.readInt();
		}
	}
	
	@Override
	public void writeExternal(final ObjectOutput out) throws IOException {
		out.writeInt(this.length);
		for (int i= 0; i < this.length; i++) {
			out.writeInt(this.intValues[i]);
		}
	}
	
	
	@Override
	protected final boolean isStructOnly() {
		return false;
	}
	
	
	protected final int length() {
		return this.length;
	}
	
	@Override
	public final long getLength() {
		return this.length;
	}
	
	@Override
	public boolean isNA(final int idx) {
		return (this.intValues[idx] == NA_integer_INT);
	}
	
	@Override
	public boolean isNA(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return (this.intValues[(int)idx] == NA_integer_INT);
	}
	
	@Override
	public void setNA(final int idx) {
		this.intValues[idx]= NA_integer_INT;
	}
	
	@Override
	public void setNA(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		this.intValues[(int)idx]= NA_integer_INT;
	}
	
	@Override
	public boolean isMissing(final int idx) {
		return (this.intValues[idx] == NA_integer_INT);
	}
	
	@Override
	public boolean isMissing(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return (this.intValues[(int)idx] == NA_integer_INT);
	}
	
	@Override
	public int getInt(final int idx) {
		return this.intValues[idx];
	}
	
	@Override
	public int getInt(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return this.intValues[(int)idx];
	}
	
	@Override
	public void setInt(final int idx, final int value) {
//		assert (value != NA_integer_INT);
		this.intValues[idx]= value;
	}
	
	@Override
	public void setInt(final long idx, final int value) {
//		assert (value != NA_integer_INT);
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		this.intValues[(int)idx]= value;
	}
	
	
	private void prepareInsert(final int[] idxs) {
		this.intValues= prepareInsert(this.intValues, this.length, idxs);
		this.length+= idxs.length;
	}
	
	public void insertInt(final int idx, final int value) {
//		assert (value != NA_integer_INT);
		prepareInsert(new int[] { idx });
		this.intValues[idx]= value;
	}
	
	@Override
	public void insertNA(final int idx) {
		prepareInsert(new int[] { idx });
		this.intValues[idx]= NA_integer_INT;
	}
	
	@Override
	public void insertNA(final int[] idxs) {
		if (idxs.length == 0) {
			return;
		}
		prepareInsert(idxs);
		for (int idx= 0; idx < idxs.length; idx++) {
			this.intValues[idxs[idx]+idx]= NA_integer_INT;
		}
	}
	
	@Override
	public void remove(final int idx) {
		this.intValues= remove(this.intValues, this.length, new int[] { idx });
		this.length --;
	}
	
	@Override
	public void remove(final int[] idxs) {
		this.intValues= remove(this.intValues, this.length, idxs);
		this.length-= idxs.length;
	}
	
	
	@Override
	public @Nullable Integer get(final int idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		final int v= this.intValues[idx];
		return (v != NA_integer_INT) ?
				Integer.valueOf(v) : null;
	}
	
	@Override
	public @Nullable Integer get(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		final int v= this.intValues[(int)idx];
		return (v != NA_integer_INT) ?
				Integer.valueOf(v) : null;
	}
	
	@Override
	public @Nullable Integer [] toArray() {
		final var array= new @Nullable Integer [this.length];
		final int[] ints= this.intValues;
		for (int i= 0; i < array.length; i++) {
			final int v= ints[i];
			if (v != NA_integer_INT) {
				array[i]= Integer.valueOf(v);
			}
		}
		return array;
	}
	
	
	@Override
	public final long indexOfNA(long fromIdx) {
		if (fromIdx >= Integer.MAX_VALUE) {
			return -1;
		}
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final int l= this.length;
		final int[] ints= this.intValues;
		for (int i= (int)fromIdx; i < l; i++) {
			if (ints[i] == NA_integer_INT) {
				return i;
			}
		}
		return -1;
	}
	
	@Override
	public final long indexOf(final int integer, long fromIdx) {
		if (fromIdx >= Integer.MAX_VALUE
				|| integer == NA_integer_INT ) {
			return -1;
		}
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final int l= this.length;
		final int[] ints= this.intValues;
		for (int i= (int)fromIdx; i < l; i++) {
			if (ints[i] == integer) {
				return i;
			}
		}
		return -1;
	}
	
	
	public void appendTo(final StringBuilder sb) {
		sb.append('[');
		final int l= this.length;
		if (l > 0) {
			final int[] ints= this.intValues;
			for (int i= 0; i < l; i++) {
				sb.append(ints[i]);
				sb.append(", ");
			}
			sb.delete(sb.length() - 2, sb.length());
		}
		sb.append(']');
	}
	
}
