/*=============================================================================#
 # 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.rj.data.RJIO;
import org.eclipse.statet.rj.data.RStore;


/**
 * This implementation is limited to length of 2<sup>31</sup>-1.
 */
public class RRaw32Store extends AbstractRawStore
		implements RDataResizeExtension<Byte>, ExternalizableRStore, Externalizable {
	
	
	private int length;
	
	protected byte[] byteValues;
	
	
	public RRaw32Store() {
		this.byteValues= EMPTY_BYTE_ARRAY;
		this.length= 0;
	}
	
	public RRaw32Store(final int length) {
		this.byteValues= new byte[length];
		this.length= length;
	}
	
	public RRaw32Store(final byte[] values) {
		this.byteValues= values;
		this.length= this.byteValues.length;
	}
	
	
	public RRaw32Store(final RJIO io, final int length) throws IOException {
		this.length= length;
		this.byteValues= io.readByteData(new byte[length], length);
	}
	
	@Override
	public void writeExternal(final RJIO io) throws IOException {
		io.writeByteData(this.byteValues, this.length);
	}
	
	@Override
	public void readExternal(final ObjectInput in) throws IOException {
		this.length= in.readInt();
		this.byteValues= new byte[this.length];
		in.readFully(this.byteValues, 0, this.length);
	}
	
	@Override
	public void writeExternal(final ObjectOutput out) throws IOException {
		out.writeInt(this.length);
		out.write(this.byteValues, 0, this.length);
	}
	
	
	@Override
	protected final boolean isStructOnly() {
		return false;
	}
	
	
	protected final int length() {
		return this.length;
	}
	
	@Override
	public final long getLength() {
		return this.length;
	}
	
	@Override
	public byte getRaw(final int idx) {
		return this.byteValues[idx];
	}
	
	@Override
	public byte getRaw(final long idx) {
		if (idx < 0 || idx >= length()) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return this.byteValues[(int) idx];
	}
	
	@Override
	public void setRaw(final int idx, final byte value) {
		this.byteValues[idx]= value;
	}
	
	@Override
	public void setRaw(final long idx, final byte value) {
		if (idx < 0 || idx >= length()) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		this.byteValues[(int) idx]= value;
	}
	
	
	private void prepareInsert(final int[] idxs) {
		this.byteValues= prepareInsert(this.byteValues, this.length, idxs);
		this.length+= idxs.length;
	}
	
	public void insert(final int idx, final byte value) {
		prepareInsert(new int[] { idx });
		this.byteValues[idx]= value;
	}
	
	@Override
	public void insertNA(final int idx) {
		prepareInsert(new int[] { idx });
		this.byteValues[idx]= NA_byte_BYTE;
	}
	
	@Override
	public void insertNA(final int[] idxs) {
		if (idxs.length == 0) {
			return;
		}
		prepareInsert(idxs);
		for (int idx= 0; idx < idxs.length; idx++) {
			this.byteValues[idx]= NA_byte_BYTE;
		}
	}
	
	@Override
	public void remove(final int idx) {
		this.byteValues= remove(this.byteValues, this.length, new int[] { idx });
		this.length--;
	}
	
	@Override
	public void remove(final int[] idxs) {
		this.byteValues= remove(this.byteValues, this.length, idxs);
		this.length-= idxs.length;
	}
	
	
	@Override
	public Byte get(final int idx) {
		if (idx < 0 || idx >= length()) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return Byte.valueOf(this.byteValues[idx]);
	}
	
	@Override
	public Byte get(final long idx) {
		if (idx < 0 || idx >= length()) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return Byte.valueOf(this.byteValues[(int) idx]);
	}
	
	@Override
	public Byte[] toArray() {
		final Byte[] array= new Byte[length()];
		final byte[] raws= this.byteValues;
		for (int i= 0; i < array.length; i++) {
			array[i]= Byte.valueOf(raws[i]);
		}
		return array;
	}
	
	
	@Override
	public long indexOf(final int integer, long fromIdx) {
		if (fromIdx >= Integer.MAX_VALUE
				|| (integer & 0xffffff00) != 0 ) {
			return -1;
		}
		if (fromIdx < 0) {
			fromIdx= 0;
		}
		final byte raw= (byte) (integer & 0xff);
		final int l= length();
		final byte[] raws= this.byteValues;
		for (int i= (int) fromIdx; i < l; i++) {
			if (raws[i] == raw) {
				return i;
			}
		}
		return -1;
	}
	
	
	@Override
	public boolean allEqual(final RStore<?> other) {
		throw new UnsupportedOperationException("Not yet implemented");
	}
	
}
