/*=============================================================================#
 # Copyright (c) 2009, 2018 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.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RObjectFactory;
import org.eclipse.statet.rj.data.RS4Object;
import org.eclipse.statet.rj.data.RStore;


public class RS4ObjectImpl extends AbstractRObject
		implements RS4Object, ExternalizableRObject {
	
	
	private String className;
	
	private int dataSlotIdx;
	private RCharacter32Store slotNames;
	private RObject[] slotValues;
	
	
	public RS4ObjectImpl(final String className, final String[] slotNames, final RObject[] slotValues) {
		if (className == null || slotNames == null || slotValues == null) {
			throw new NullPointerException();
		}
		this.className= className;
		this.slotNames= new RCharacter32Store(slotNames);
		
		this.dataSlotIdx= this.slotNames.indexOf(".Data", 0);
		this.slotValues= slotValues;
	}
	
	public RS4ObjectImpl(final RJIO io, final RObjectFactory factory) throws IOException {
		readExternal(io, factory);
	}
	
	public void readExternal(final RJIO io, final RObjectFactory factory) throws IOException {
		//-- options
		final int options= io.readInt();
		//-- special attributes
		this.className= io.readString();
		//-- data
		final int l= (int) io.readVULong((byte) (options & RObjectFactory.O_LENGTHGRADE_MASK));
		
		this.dataSlotIdx= io.readInt();
		this.slotNames= new RCharacter32Store(io, l);
		this.slotValues= new RObject[l];
		for (int i= 0; i < l; i++) {
			this.slotValues[i]= factory.readObject(io);
		}
	}
	
	@Override
	public void writeExternal(final RJIO io, final RObjectFactory factory) throws IOException {
		final int l= this.slotValues.length;
		//-- options
		final int options= io.getVULongGrade(l);
		io.writeInt(options);
		//-- special attributes
		io.writeString(this.className);
		//-- data
		io.writeVULong((byte) (options & RObjectFactory.O_LENGTHGRADE_MASK), l);
		
		io.writeInt(this.dataSlotIdx);
		this.slotNames.writeExternal(io);
		for (int i= 0; i < l; i++) {
			factory.writeObject(this.slotValues[i], io);
		}
	}
	
	@Override
	public byte getRObjectType() {
		return TYPE_S4OBJECT;
	}
	
	@Override
	public String getRClassName() {
		return this.className;
	}
	
	
	@Override
	public long getLength() {
		return this.slotValues.length;
	}
	
	@Override
	public boolean hasDataSlot() {
		return (this.dataSlotIdx >= 0);
	}
	
	@Override
	public RObject getDataSlot() {
		return (this.dataSlotIdx >= 0) ? this.slotValues[this.dataSlotIdx] : null;
	}
	
	public byte getDataType() {
		return (this.dataSlotIdx >= 0 && this.slotValues[this.dataSlotIdx] != null) ?
				this.slotValues[this.dataSlotIdx].getData().getStoreType() : 0;
	}
	
	@Override
	public RStore<?> getData() {
		return (this.dataSlotIdx >= 0 && this.slotValues[this.dataSlotIdx] != null) ?
				this.slotValues[this.dataSlotIdx].getData() : null;
	}
	
	@Override
	public RCharacterStore getNames() {
		return this.slotNames;
	}
	
	@Override
	public String getName(final int idx) {
		return this.slotNames.getChar(idx);
	}
	
	@Override
	public String getName(final long idx) {
		return this.slotNames.getChar(idx);
	}
	
	@Override
	public RObject get(final int idx) {
		return this.slotValues[idx];
	}
	
	@Override
	public RObject get(final long idx) {
		if (idx < 0 || idx >= Integer.MAX_VALUE) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return this.slotValues[(int) idx];
	}
	
	@Override
	public RObject get(final String name) {
		final int idx= this.slotNames.indexOf(name, 0);
		if (idx >= 0) {
			return this.slotValues[idx];
		}
		throw new IllegalArgumentException();
	}
	
	
	public void insert(final int idx, final String name, final RObject component) {
		throw new UnsupportedOperationException();
	}
	
	public void add(final String name, final RObject component) {
		throw new UnsupportedOperationException();
	}
	
	public void remove(final int idx) {
		throw new UnsupportedOperationException();
	}
	
	public boolean set(final int idx, final RObject value) {
		this.slotValues[idx]= value;
		return true;
	}
	
	public boolean set(final String name, final RObject component) {
		if (this.dataSlotIdx >= 0 && name.equals(".Data")) {
			this.slotValues[this.dataSlotIdx]= component;
			return true;
		}
		else {
			final int i= this.slotNames.indexOf(name, 0);
			if (i >= 0) {
				this.slotValues[i]= component;
				return true;
			}
		}
		return false;
	}
	
}
