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

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


@NonNullByDefault
public class RDataUtils {
	
	/**
	 * Returns the common abbreviation for the type of the given data store.
	 * These are the abbreviations used by the R function <code>str(x)</code>.
	 * If there is no abbreviation for the given type, it return the class name
	 * of an R vector with data of this type.
	 * 
	 * @param store the data store
	 * @return an abbreviation
	 */
	public static final String getStoreAbbr(final RStore<?> store) {
		switch (store.getStoreType()) {
		case RStore.LOGICAL:
			return "logi";
		case RStore.INTEGER:
			return "int";
		case RStore.NUMERIC:
			return "num";
		case RStore.CHARACTER:
			return "chr";
		case RStore.COMPLEX:
			return "cplx";
		case RStore.RAW:
			return "raw";
		case RStore.FACTOR:
			return ((RFactorStore) store).isOrdered() ? RObject.CLASSNAME_ORDERED : RObject.CLASSNAME_FACTOR;
		default:
			return "";
		}
	}
	
	/**
	 * Returns the class name of an R vector with data of the type of the given data store.
	 * 
	 * @param store the data store
	 * @return an class name
	 */
	public static final String getStoreClass(final RStore<?> store) {
		switch (store.getStoreType()) {
		case RStore.LOGICAL:
			return RObject.CLASSNAME_LOGICAL;
		case RStore.INTEGER:
			return RObject.CLASSNAME_INTEGER;
		case RStore.NUMERIC:
			return RObject.CLASSNAME_NUMERIC;
		case RStore.CHARACTER:
			return RObject.CLASSNAME_CHARACTER;
		case RStore.COMPLEX:
			return RObject.CLASSNAME_COMPLEX;
		case RStore.RAW:
			return RObject.CLASSNAME_RAW;
		case RStore.FACTOR:
			return ((RFactorStore) store).isOrdered() ? RObject.CLASSNAME_ORDERED : RObject.CLASSNAME_FACTOR;
		default:
			return "";
		}
	}
	
	public static final String getStoreMode(final int storeType) {
		switch (storeType) {
		case RStore.LOGICAL:
			return "logical";
		case RStore.INTEGER:
		case RStore.FACTOR:
			return "integer";
		case RStore.NUMERIC:
			return "numeric";
		case RStore.CHARACTER:
			return "character";
		case RStore.COMPLEX:
			return "complex";
		case RStore.RAW:
			return "raw";
		default:
			return "";
		}
	}
	
	public static final String getObjectTypeName(final byte type) {
		switch (type) {
		case RObject.TYPE_NULL:
			return "RNull";
		case RObject.TYPE_VECTOR:
			return "RVector";
		case RObject.TYPE_ARRAY:
			return "RArray";
		case RObject.TYPE_LIST:
			return "RList";
		case RObject.TYPE_DATAFRAME:
			return "RDataFrame";
		case RObject.TYPE_S4OBJECT:
			return "RS4Object";
		case RObject.TYPE_ENVIRONMENT:
			return "REnvironment";
		case RObject.TYPE_LANGUAGE:
			return "RLanguage";
		case RObject.TYPE_FUNCTION:
			return "RFunction";
		case RObject.TYPE_REFERENCE:
			return "RReference";
		case RObject.TYPE_OTHER:
			return "<other>";
		case RObject.TYPE_MISSING:
			return "RMissing";
		case RObject.TYPE_PROMISE:
			return "RPromise";
		default:
			return "<unkown>";
		}
	}
	
	public static final long computeLengthFromDim(final int[] dims) {
		if (dims.length == 0) {
			return 0;
		}
		long length= 1;
		for (int i= 0; i < dims.length; i++) {
			length *= dims[i];
		}
		return length;
	}
	
	public static final long getDataIdx(final int[] dims, final int... idxs) {
		assert (dims.length > 0);
		assert (dims.length == idxs.length);
		
		long dataIdx= idxs[0];
		long step= dims[0];
		// alt: idx=0; step=1; i=0;
		for (int i= 1; i < dims.length; i++) {
			dataIdx+= step*idxs[i];
			step *= dims[i];
		}
		return dataIdx;
	}
	
	public static final long getDataIdx(final RStore<?> dims, final int... idxs) {
		assert (dims.getLength() > 0);
		assert (dims.getLength() == idxs.length);
		
		long dataIdx= idxs[0];
		long step= dims.getInt(0);
		// alt: idx=0; step=1; i=0;
		for (int i= 1; i < dims.getLength(); i++) {
			dataIdx+= step * idxs[i];
			step *= dims.getInt(i);
		}
		return dataIdx;
	}
	
	/**
	 * Computes the index of a data value in a store of a matrix / 2 dimensional arrays
	 * specified by its column and row indexes.
	 * 
	 * @param rowCount count of rows of the matrix
	 * @param rowIdx row index (zero-based) of the matrix
	 * @param columnIdx column index (zero-based) of the matrix
	 * @return the index in the data store
	 * 
	 * @see #getDataIdx(int[], int...)
	 */
	public static final long getDataIdx(final long rowCount, final long rowIdx, final long columnIdx) {
		return rowIdx + rowCount * columnIdx;
	}
	
	public static final int[] getDataIdxs(final int[] dims, final int dim, final int idx) {
		assert (dims.length > 0);
		assert (0 <= dim && dim < dims.length);
		assert (0 <= idx && idx < dims[dim]);
		
		final int size;
		final int dimsCount= dims.length;
		if (dimsCount == 1) {
			size= 1;
		}
		else if (dimsCount == 2) {
			size= dims[(dim == 0) ? 1 : 0];
		}
		else {
			int counter= 1;
			for (int dimIdx= 0; dimIdx < dimsCount; dimIdx++) {
				if (dimIdx != dim) {
					counter *= dims[dimIdx];
				}
			}
			size= counter;
		}
		
		final int[] dataIdxs= new int[size];
		int step= 1;
		int stepCount= 1;
		for (int dimIdx= 0; dimIdx < dimsCount; dimIdx++) {
			final int dimSize= dims[dimIdx];
			if (dimIdx == dim) {
				final int add= step*idx;
				for (int i= 0; i < size; i++) {
					dataIdxs[i]+= add;
				}
			}
			else {
				for (int i= 0, idxInDim= 0; i < size; idxInDim++) {
					if (idxInDim == dimSize) {
						idxInDim= 0;
					}
					final int add= step*idxInDim;
					for (int j= 0; j < stepCount && i < size; i++,j++) {
						dataIdxs[i]+= add;
					}
				}
				stepCount *= dimSize;
			}
			step *= dimSize;
		}
		return dataIdxs;
	}
	
	
	public static final boolean isSingleString(final @Nullable RObject obj) {
		final RStore<?> data;
		return (obj != null && (data= obj.getData()) != null
				&& data.getStoreType() == RStore.CHARACTER
				&& data.getLength() == 1 );
	}
	
	
	public static final RVector<?> checkRVector(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		return (RVector<?>) obj;
	}
	
	@SuppressWarnings("unchecked")
	public static final RVector<RLogicalStore> checkRLogiVector(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getData().getStoreType() != RStore.LOGICAL) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getStoreAbbr(obj.getData()));
		}
		return (RVector<RLogicalStore>) obj;
	}
	
	@SuppressWarnings("unchecked")
	public static final RVector<RIntegerStore> checkRIntVector(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getData().getStoreType() != RStore.INTEGER) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getStoreAbbr(obj.getData()));
		}
		return (RVector<RIntegerStore>) obj;
	}
	
	@SuppressWarnings("unchecked")
	public static final RVector<RNumericStore> checkRNumVector(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getData().getStoreType() != RStore.NUMERIC) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getStoreAbbr(obj.getData()));
		}
		return (RVector<RNumericStore>) obj;
	}
	
	@SuppressWarnings("unchecked")
	public static final RVector<RCharacterStore> checkRCharVector(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_VECTOR) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getData().getStoreType() != RStore.CHARACTER) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getStoreAbbr(obj.getData()));
		}
		return (RVector<RCharacterStore>) obj;
	}
	
	public static final RArray<?> checkRArray(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_ARRAY) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		return (RArray<?>) obj;
	}
	
	public static final RArray<?> checkRArray(final @Nullable RObject obj, final int dim) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_ARRAY) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		final RArray<?> array= (RArray<?>) obj;
		if (dim > 0) {
			if (dim != array.getDim().getLength()) {
				throw new UnexpectedRDataException("Unexpected R array dimension: " + array.getDim().getLength());
			}
		}
		return array;
	}
	
	public static final RArray<?> checkRArray(final @Nullable RObject obj, final long dim) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_ARRAY) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		final RArray<?> array= (RArray<?>) obj;
		if (dim > 0) {
			if (dim != array.getDim().getLength()) {
				throw new UnexpectedRDataException("Unexpected R array dimension: " + array.getDim().getLength());
			}
		}
		return array;
	}
	
	@SuppressWarnings("unchecked")
	public static final RArray<RCharacterStore> checkRCharArray(final @Nullable RObject obj, final int dim) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_ARRAY) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getData().getStoreType() != RStore.CHARACTER) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(obj.getData()));
		}
		final RArray<RCharacterStore> array= (RArray<RCharacterStore>) obj;
		if (dim > 0) {
			if (dim != array.getDim().getLength()) {
				throw new UnexpectedRDataException("Unexpected R array dimension: " + array.getDim().getLength());
			}
		}
		return array;
	}
	
	public static final RList checkRList(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_LIST) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		return (RList) obj;
	}
	
	public static final RDataFrame checkRDataFrame(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_DATAFRAME) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		return (RDataFrame) obj;
	}
	
	public static final RDataFrame checkRDataFrame(final @Nullable RObject obj, final long length) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_DATAFRAME) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		if (obj.getLength() != length) {
			throw new UnexpectedRDataException("Unexpected R dataframe column count: " + obj.getLength());
		}
		return (RDataFrame) obj;
	}
	
	public static final RReference checkRReference(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_REFERENCE) {
			throw new UnexpectedRDataException(
					"Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) );
		}
		return (RReference) obj;
	}
	
	public static final RReference checkRReference(final @Nullable RObject obj, final byte referencedObjectType)
			throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_REFERENCE) {
			throw new UnexpectedRDataException(
					"Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) );
		}
		final RReference reference= (RReference) obj;
		if (reference.getReferencedRObjectType() != referencedObjectType) {
			throw new UnexpectedRDataException(
					"Unexpected referenced R object type: " + getObjectTypeName(obj.getRObjectType()) +
					", but " + getObjectTypeName(referencedObjectType) + " expected." );
		}
		return (RReference) obj;
	}
	
	public static final RLanguage checkRLanguage(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != RObject.TYPE_LANGUAGE) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()));
		}
		return (RLanguage) obj;
	}
	
	public static final @Nullable Boolean checkSingleLogi(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.LOGICAL) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			return null;
		}
		return Boolean.valueOf(data.getLogi(0));
	}
	
	public static final boolean checkSingleLogiValue(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.LOGICAL) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return data.getLogi(0);
	}
	
	public static final @Nullable Integer checkSingleInt(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.INTEGER) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			return null;
		}
		return Integer.valueOf(data.getInt(0));
	}
	
	public static final int checkSingleIntValue(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.INTEGER) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return data.getInt(0);
	}
	
	public static final @Nullable Double checkSingleNum(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.NUMERIC) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			return null;
		}
		return Double.valueOf(data.getNum(0));
	}
	
	public static final double checkSingleNumValue(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.NUMERIC) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return data.getNum(0);
	}
	
	public static final @Nullable String checkSingleChar(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.CHARACTER) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		return data.getChar(0);
	}
	
	public static final String checkSingleCharValue(final @Nullable RObject obj) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		final RStore<?> data= obj.getData();
		if (data == null) {
			throw new UnexpectedRDataException("Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) + " (without R data)");
		}
		if (data.getStoreType() != RStore.CHARACTER) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data));
		}
		if (data.getLength() != 1) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == 1 expected.");
		}
		if (data.isNA(0)) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return data.getChar(0);
	}
	
	public static final RObject checkType(final @Nullable RObject obj, final byte objectType) throws UnexpectedRDataException {
		if (obj == null) {
			throw new UnexpectedRDataException("Missing R object.");
		}
		if (obj.getRObjectType() != objectType) {
			throw new UnexpectedRDataException(
					"Unexpected R object type: " + getObjectTypeName(obj.getRObjectType()) +
					", but " + getObjectTypeName(objectType) + " expected." );
		}
		return obj;
	}
	
	public static final RStore<?> checkData(final RStore<?> data, final byte storeType) throws UnexpectedRDataException {
		if (data.getStoreType() != storeType) {
			throw new UnexpectedRDataException("Unexpected R data type: " + getStoreAbbr(data) + ", but " + storeType + " expected.");
		}
		return data;
	}
	
	
	public static final int checkIntLength(final RObject obj) throws UnexpectedRDataException {
		return checkIntLength(obj.getLength());
	}
	
	public static final int checkIntLength(final RStore<?> data) throws UnexpectedRDataException {
		return checkIntLength(data.getLength());
	}
	
	public static final int checkIntLength(final long length) throws UnexpectedRDataException {
		if (length < 0 || length > Integer.MAX_VALUE) {
			throw new UnexpectedRDataException("Unexpected R data length: " + length + ", but <= 2^31-1 expected.");
		}
		return (int)length;
	}
	
	public static final int checkIntIdx(final long idx) throws UnexpectedRDataException {
		if (idx < 0 || idx >= Integer.MAX_VALUE) {
			throw new UnexpectedRDataException("Unexpected R data index: " + idx + ", but < 2^31-1 expected.");
		}
		return (int)idx;
	}
	
	public static final <T extends RObject> T checkLengthEqual(final T obj, final long length) throws UnexpectedRDataException {
		if (obj.getLength() != length) {
			throw new UnexpectedRDataException("Unexpected R object length: " + obj.getLength() + ", but == " + length + " expected.");
		}
		return obj;
	}
	
	public static final <TData extends RStore<?>> TData checkLengthEqual(final TData data,
			final long length)
			throws UnexpectedRDataException {
		if (data.getLength() != length) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but == " + length + " expected.");
		}
		return data;
	}
	
	public static final <TData extends RStore<?>> TData checkLengthGreaterOrEqual(final TData data,
			final long length)
			throws UnexpectedRDataException {
		if (data.getLength() < length) {
			throw new UnexpectedRDataException("Unexpected R data length: " + data.getLength() + ", but >= " + length + " expected.");
		}
		return data;
	}
	
	public static final <P> P checkValue(final RStore<P> data, final int idx) throws UnexpectedRDataException {
		final P value= data.get(idx);
		if (value == null) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return value;
	}
	
	public static final <P> P checkValue(final RStore<P> data, final long idx) throws UnexpectedRDataException {
		final P value= data.get(idx);
		if (value == null) {
			throw new UnexpectedRDataException("Unexpected R data value: NA");
		}
		return value;
	}
	
	public static final <P> P getValue(final RStore<P> data, final int idx, final P na) {
		final P value= data.get(idx);
		return (value != null) ? value : na;
	}
	
	public static final <P> P getValue(final RStore<P> data, final long idx, final P na) {
		final P value= data.get(idx);
		return (value != null) ? value : na;
	}
	
	
	/*-- 2d --*/
	
	public static final int getRowCount(final RArray<?> array) throws UnexpectedRDataException {
		return array.getDim().getInt(0);
	}
	
	public static final void checkRowCountEqual(final RArray<?> array, final int count) throws UnexpectedRDataException {
		if (array.getDim().getInt(0) != count) {
			throw new UnexpectedRDataException("Unexpected R matrix row count: " + array.getDim().getInt(0) + ", but == " + count + " expected.");
		}
	}
	
	public static final void checkRowCountEqual(final RDataFrame dataframe, final long count) throws UnexpectedRDataException {
		if (dataframe.getRowCount() != count) {
			throw new UnexpectedRDataException("Unexpected R dataframe row count: " + dataframe.getRowCount() + ", but == " + count + " expected.");
		}
	}
	
	public static final int getColumnCount(final RArray<?> array) throws UnexpectedRDataException {
		return array.getDim().getInt(1);
	}
	
	public static final void checkColumnCountEqual(final RArray<?> array, final int count) throws UnexpectedRDataException {
		if (array.getDim().getInt(1) != count) {
			throw new UnexpectedRDataException("Unexpected R matrix column count: " + array.getDim().getInt(1) + ", but == " + count + " expected.");
		}
	}
	
	public static final long checkColumnName(final RArray<?> array, final String name) throws UnexpectedRDataException {
		final long idx= array.getNames(1).indexOf(name);
		if (idx < 0) {
			throw new UnexpectedRDataException("Missing R matrix column: " + name);
		}
		return idx;
	}
	
	public static final void checkColumnCountEqual(final RDataFrame dataframe, final long count) throws UnexpectedRDataException {
		if (dataframe.getColumnCount() != count) {
			throw new UnexpectedRDataException("Unexpected R dataframe column count: " + dataframe.getColumnCount() + ", but == " + count + " expected.");
		}
	}
	
	
	/*-- int --*/
	
	public static final long binarySearch(final RVector<?> vector, final int value) {
		final RStore<?> data= vector.getData();
		return binarySearch(data, 0, data.getLength(), value);
	}
	
	public static final long binarySearch(final RStore<?> data, final int value) {
		return binarySearch(data, 0, data.getLength(), value);
	}
	
	public static final int binarySearch(final RStore<?> data, final int fromIdx, final int toIdx, final int value) {
		if (fromIdx < 0 || fromIdx > data.getLength()
				|| toIdx < 0 || toIdx > data.getLength()) {
			throw new IndexOutOfBoundsException(Long.toString(fromIdx));
		}
		if (fromIdx > toIdx) {
			throw new IllegalArgumentException();
		}
		
		return doBinarySearch(data, fromIdx, toIdx - 1, value);
	}
	
	private static int doBinarySearch(final RStore<?> data, int low, int high, final int value) {
		while (low <= high) {
			final int mid= (low + high) >>> 1;
			final int midValue= data.getInt(mid);
			if (midValue < value) {
				low= mid + 1;
			}
			else if (midValue > value) {
				high= mid - 1;
			}
			else {
				return mid; // key found
			}
		}
		return -(low + 1);  // key not found.
	}
	
	public static final long binarySearch(final RStore<?> data, final long fromIdx, final long toIdx, final int value) {
		if (fromIdx < 0 || fromIdx > data.getLength()
				|| toIdx < 0 || toIdx > data.getLength()) {
			throw new IndexOutOfBoundsException(Long.toString(fromIdx));
		}
		if (fromIdx > toIdx) {
			throw new IllegalArgumentException();
		}
		if (toIdx <= Integer.MAX_VALUE) {
			return doBinarySearch(data, (int)fromIdx, (int)toIdx - 1, value);
		}
		
		return doBinarySearch(data, fromIdx, toIdx - 1, value);
	}
	
	private static long doBinarySearch(final RStore<?> data, long low, long high, final int value) {
		while (low <= high) {
			final long mid= (low + high) >>> 1;
			final int midValue= data.getInt(mid);
			if (midValue < value) {
				low= mid + 1;
			}
			else if (midValue > value) {
				high= mid - 1;
			}
			else {
				return mid; // key found
			}
		}
		return -(low + 1);  // key not found.
	}
	
	public static final int binarySearch(final RStore<?> data,
			final long[] fromIdxs, final int length, final int[] values) {
		if (fromIdxs.length > values.length) {
			throw new IllegalArgumentException();
		}
		if (length < 0 || length > data.getLength()) {
			throw new IllegalArgumentException();
		}
		for (int i= 0; i < fromIdxs.length; i++) {
			if (fromIdxs[i] < 0 || fromIdxs[i] + length > data.getLength()) {
				throw new IndexOutOfBoundsException(Long.toString(fromIdxs[i]));
			}
		}
		
		int low= 0;
		int high= length - 1;
		ITER_IDX: while (low <= high) {
			final int mid= (low + high) >>> 1;
			for (int i= 0; i < fromIdxs.length; i++) {
				final int midValue= data.getInt(fromIdxs[i] + mid);
				if (midValue < values[i]) {
					low= mid + 1;
					continue ITER_IDX;
				}
				if (midValue > values[i]) {
					high= mid - 1;
					continue ITER_IDX;
				}
			}
			return mid; // key found
		}
		return -(low + 1);  // key not found.
	}
	
	public static final int compare(final int[] values1, final int[] values2) {
		for (int i= 0; i < values1.length; i++) {
			if (values1[i] < values2[i]) {
				return -1;
			}
			if (values1[i] > values2[i]) {
				return +1;
			}
		}
		return 0; // equal
	}
	
	
	/*-- long ~ num -- */
	
	public static final long binarySearch(final RStore<?> data, final long value) {
		return binarySearch(data, 0, data.getLength(), value);
	}
	
	public static final int binarySearch(final RStore<?> data, final int fromIdx, final int toIdx, final long value) {
		if (fromIdx < 0 || fromIdx > data.getLength()
				|| toIdx < 0 || toIdx > data.getLength()) {
			throw new IndexOutOfBoundsException(Long.toString(fromIdx));
		}
		if (fromIdx > toIdx) {
			throw new IllegalArgumentException();
		}
		
		return doBinarySearch(data, fromIdx, toIdx - 1, value);
	}
	
	private static int doBinarySearch(final RStore<?> data, int low, int high, final long value) {
		while (low <= high) {
			final int mid= (low + high) >>> 1;
			final double midValue= data.getNum(mid);
			if (midValue < value) {
				low= mid + 1;
			}
			else if (midValue > value) {
				high= mid - 1;
			}
			else {
				return mid; // key found
			}
		}
		return -(low + 1);  // key not found.
	}
	
	public static final long binarySearch(final RStore<?> data, final long fromIdx, final long toIdx, final long value) {
		if (fromIdx < 0 || fromIdx > data.getLength()
				|| toIdx < 0 || toIdx > data.getLength()) {
			throw new IndexOutOfBoundsException(Long.toString(fromIdx));
		}
		if (fromIdx > toIdx) {
			throw new IllegalArgumentException();
		}
		if (toIdx <= Integer.MAX_VALUE) {
			return doBinarySearch(data, (int)fromIdx, (int)toIdx - 1, value);
		}
		
		return doBinarySearch(data, fromIdx, toIdx - 1, value);
	}
	
	private static long doBinarySearch(final RStore<?> data, long low, long high, final long value) {
		while (low <= high) {
			final long mid= (low + high) >>> 1;
		final double midValue= data.getNum(mid);
		if (midValue < value) {
			low= mid + 1;
		}
		else if (midValue > value) {
			high= mid - 1;
		}
		else {
			return mid; // key found
		}
		}
		return -(low + 1);  // key not found.
	}
	
	public static final int binarySearch(final RStore<?> data,
			final long[] fromIdxs, final int length, final long[] values) {
		if (fromIdxs.length > values.length) {
			throw new IllegalArgumentException();
		}
		if (length < 0 || length > data.getLength()) {
			throw new IllegalArgumentException();
		}
		for (int i= 0; i < fromIdxs.length; i++) {
			if (fromIdxs[i] < 0 || fromIdxs[i] + length > data.getLength()) {
				throw new IndexOutOfBoundsException(Long.toString(fromIdxs[i]));
			}
		}
		
		int low= 0;
		int high= length - 1;
		ITER_IDX: while (low <= high) {
			final int mid= (low + high) >>> 1;
			for (int i= 0; i < fromIdxs.length; i++) {
				final double midValue= data.getNum(fromIdxs[i] + mid);
				if (midValue < values[i]) {
					low= mid + 1;
					continue ITER_IDX;
				}
				if (midValue > values[i]) {
					high= mid - 1;
					continue ITER_IDX;
				}
			}
			return mid; // key found
		}
		return -(low + 1);  // key not found.
	}
	
	public static final int compare(final long[] values1, final long[] values2) {
		for (int i= 0; i < values1.length; i++) {
			if (values1[i] < values2[i]) {
				return -1;
			}
			if (values1[i] > values2[i]) {
				return +1;
			}
		}
		return 0; // equal
	}
	
	
	public static final byte[] encodeLongToRaw(final long id) {
		final byte[] raw= new byte[8];
		encodeLongToRaw(id, raw, 0);
		return raw;
	}
	
	public static final void encodeLongToRaw(final long id, final byte[] raw, int idx) {
		raw[idx++]= (byte) (id >>> 56);
		raw[idx++]= (byte) (id >>> 48);
		raw[idx++]= (byte) (id >>> 40);
		raw[idx++]= (byte) (id >>> 32);
		raw[idx++]= (byte) (id >>> 24);
		raw[idx++]= (byte) (id >>> 16);
		raw[idx++]= (byte) (id >>> 8);
		raw[idx]= (byte) (id);
	}
	
	public static final long decodeLongFromRaw(final byte[] raw) {
		return decodeLongFromRaw(raw, 0);
	}
	
	public static final long decodeLongFromRaw(final byte[] raw, int idx) {
		return(	((long)(raw[idx++] & 0xff) << 56) |
				((long)(raw[idx++] & 0xff) << 48) |
				((long)(raw[idx++] & 0xff) << 40) |
				((long)(raw[idx++] & 0xff) << 32) |
				((long)(raw[idx++] & 0xff) << 24) |
				((raw[idx++] & 0xff) << 16) |
				((raw[idx++] & 0xff) << 8) |
				((raw[idx] & 0xff)) );
	}
	
}
