/*=============================================================================#
 # 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.IOException;

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

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


@NonNullByDefault
public class RRawFix64Store extends AbstractRawStore
		implements ExternalizableRStore {
	
	
	public static final int SEGMENT_LENGTH= DEFAULT_LONG_DATA_SEGMENT_LENGTH;
	
	
	private final long length;
	
	protected final byte [] @NonNull[] byteValues;
	
	
	public RRawFix64Store(final long length) {
		this.length= length;
		this.byteValues= new2dByteArray(length, SEGMENT_LENGTH);
	}
	
	public RRawFix64Store(final byte [] @NonNull[] values) {
		this.length= check2dArrayLength(values, SEGMENT_LENGTH);
		this.byteValues= values;
	}
	
	
	public RRawFix64Store(final RJIO io, final long length) throws IOException {
		this.length= length;
		this.byteValues= new2dByteArray(length, SEGMENT_LENGTH);
		for (int i= 0; i < this.byteValues.length; i++) {
			io.readByteData(this.byteValues[i], this.byteValues[i].length);
		}
	}
	
	@Override
	public void writeExternal(final RJIO io) throws IOException {
		for (int i= 0; i < this.byteValues.length; i++) {
			io.writeByteData(this.byteValues[i], this.byteValues[i].length);
		}
	}
	
	
	@Override
	protected final boolean isStructOnly() {
		return false;
	}
	
	
	@Override
	public final long getLength() {
		return this.length;
	}
	
	@Override
	public byte getRaw(final int idx) {
		return this.byteValues[idx / SEGMENT_LENGTH][idx % SEGMENT_LENGTH];
	}
	
	@Override
	public byte getRaw(final long idx) {
		return this.byteValues[(int)(idx / SEGMENT_LENGTH)][(int)(idx % SEGMENT_LENGTH)];
	}
	
	@Override
	public void setRaw(final int idx, final byte value) {
		this.byteValues[idx / SEGMENT_LENGTH][idx % SEGMENT_LENGTH] =
				value;
	}
	
	@Override
	public void setRaw(final long idx, final byte value) {
		this.byteValues[(int)(idx / SEGMENT_LENGTH)][(int)(idx % SEGMENT_LENGTH)] =
				value;
	}
	
	
	@Override
	public Byte get(final int idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return Byte.valueOf(this.byteValues[idx / SEGMENT_LENGTH][idx % SEGMENT_LENGTH]);
	}
	
	@Override
	public Byte get(final long idx) {
		if (idx < 0 || idx >= this.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return Byte.valueOf(this.byteValues[(int)(idx / SEGMENT_LENGTH)][(int)(idx % SEGMENT_LENGTH)]);
	}
	
	@Override
	public @NonNull Byte [] toArray() {
		final int l= checkToArrayLength();
		final var array= new @NonNull Byte [l];
		int k= 0;
		for (int i= 0; i < this.byteValues.length; i++, k++) {
			final byte[] raws= this.byteValues[i];
			for (int j= 0; j < raws.length; j++) {
				array[k]= Byte.valueOf(raws[j]);
			}
		}
		return array;
	}
	
	
	@Override
	public long indexOf(final int integer, final long fromIdx) {
		if ((integer & 0xffffff00) != 0) {
			return -1;
		}
		final byte raw= (byte) (integer & 0xff);
		int i= (int)(fromIdx / SEGMENT_LENGTH);
		int j= (int)(fromIdx % SEGMENT_LENGTH);
		while (i < this.byteValues.length) {
			final byte[] raws= this.byteValues[i];
			while (j < raws.length) {
				if (raws[i] == raw) {
					return (i * (long)SEGMENT_LENGTH) + j;
				}
			}
			i++;
			j= 0;
		}
		return -1;
	}
	
	
	@Override
	public boolean allEqual(final RStore<?> other) {
		throw new UnsupportedOperationException("Not yet implemented");
	}
	
}
