/*=============================================================================#
 # 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 org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

import org.eclipse.statet.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;


@NonNullByDefault
public abstract class AbstractCharacterStore extends AbstractRStore<String>
		implements RCharacterStore {
	
	
	protected static final boolean toLogi(final String character) {
		switch (character.length()) {
		case 1:
			switch (character.charAt(0)) {
			case 'F':
				return false;
			case 'T':
				return true;
			default:
				break;
			}
			break;
		case 4:
			if ("true".regionMatches(0, character, 0, 4)) {
				return true;
			}
			break;
		case 5:
			if ("false".regionMatches(0, character, 0, 5)) {
				return false;
			}
			break;
		default:
			break;
		}
		throw new NumberFormatException(character);
	}
	
	
	@Override
	public final byte getStoreType() {
		return RStore.CHARACTER;
	}
	
	@Override
	public final String getBaseVectorRClassName() {
		return RObject.CLASSNAME_CHARACTER;
	}
	
	
	@Override
	public void setLogi(final int idx, final boolean logi) {
		setChar(idx, AbstractLogicalStore.toChar(logi));
	}
	
	@Override
	public void setLogi(final long idx, final boolean logi) {
		setChar(idx, AbstractLogicalStore.toChar(logi));
	}
	
	@Override
	public boolean getLogi(final int idx) {
		return toLogi(getChar(idx));
	}
	
	@Override
	public boolean getLogi(final long idx) {
		return toLogi(getChar(idx));
	}
	
	@Override
	public final void setInt(final int idx, final int integer) {
		setChar(idx, Integer.toString(integer));
	}
	
	@Override
	public final void setInt(final long idx, final int integer) {
		setChar(idx, Integer.toString(integer));
	}
	
	@Override
	public void setCplx(final int idx, final double real, final double imaginary) {
		setChar(idx, AbstractComplexStore.toChar(real, imaginary));
	}
	
	@Override
	public void setCplx(final long idx, final double real, final double imaginary) {
		setChar(idx, AbstractComplexStore.toChar(real, imaginary));
	}
	
	@Override
	public final void setRaw(final int idx, final byte raw) {
		setChar(idx, AbstractRawStore.toChar(raw));
	}
	
	@Override
	public final void setRaw(final long idx, final byte raw) {
		setChar(idx, AbstractRawStore.toChar(raw));
	}
	
	@Override
	public long indexOf(final int integer, final long fromIdx) {
		return indexOf(Integer.toString(integer), fromIdx);
	}
	
	
	@Override
	public abstract @Nullable String [] toArray();
	
	
	@Override
	public boolean allEqual(final RStore<?> other) {
		final long length= getLength();
		if (CHARACTER != other.getStoreType() || length != other.getLength()) {
			return false;
		}
		if (length < 0) {
			return true;
		}
		else if (length <= Integer.MAX_VALUE) {
			final int ilength= (int)length;
			for (int idx= 0; idx < ilength; idx++) {
				if (!(isNA(idx) ? other.isNA(idx) :
						getChar(idx).equals(other.getChar(idx)) )) {
					return false;
				}
			}
		}
		else {
			for (long idx= 0; idx < length; idx++) {
				if (!(isNA(idx) ? other.isNA(idx) :
						getChar(idx).equals(other.getChar(idx)) )) {
					return false;
				}
			}
		}
		return true;
	}
	
}
