/*=============================================================================#
 # Copyright (c) 2009, 2021 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.internal.r.rdata;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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

import org.eclipse.statet.ltk.model.core.element.LtkModelElementFilter;
import org.eclipse.statet.r.core.data.CombinedRElement;
import org.eclipse.statet.r.core.data.CombinedRList;
import org.eclipse.statet.r.core.model.RElementName;
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;
import org.eclipse.statet.rj.data.impl.ExternalizableRObject;
import org.eclipse.statet.rj.data.impl.RCharacter32Store;


@NonNullByDefault
public final class RS4ObjectVar extends BasicCombinedRElement
		implements RS4Object, CombinedRList, ExternalizableRObject {
	
	
	private final String className;
	
	private final RCharacter32Store slotNames;
	private final BasicCombinedRElement[] slotValues;
	private final int dataSlotIdx;
	
	
	public RS4ObjectVar(final RJIO io, final CombinedFactory factory,
			final @Nullable BasicCombinedRElement parent, final @Nullable RElementName name)
			throws IOException {
		super(parent, name);
		
		//-- 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 BasicCombinedRElement[l];
		for (int i= 0; i < l; i++) {
			this.slotValues[i]= factory.readObject(io, this,
					RElementName.create(RElementName.SUB_NAMEDSLOT, this.slotNames.getChar(i)));
		}
	}
	
	@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 @Nullable RObject getDataSlot() {
		return (this.dataSlotIdx >= 0) ? this.slotValues[this.dataSlotIdx] : null;
	}
	
	@Override
	public @Nullable 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 CombinedRElement get(final int idx) {
		return this.slotValues[idx];
	}
	
	@Override
	public CombinedRElement get(final long idx) {
		if (idx < 0 || idx >= this.slotValues.length) {
			throw new IndexOutOfBoundsException(Long.toString(idx));
		}
		return this.slotValues[(int) idx];
	}
	
	@Override
	public CombinedRElement get(final String name) {
		final int idx= this.slotNames.indexOf(name, 0);
		if (idx >= 0) {
			return this.slotValues[idx];
		}
		throw new IllegalArgumentException();
	}
	
	
	@Override
	public int getElementType() {
		return R_GENERAL_VARIABLE;
	}
	
	@Override
	public boolean hasModelChildren(final @Nullable LtkModelElementFilter filter) {
		if (filter == null) {
			return (this.slotValues.length > 0);
		}
		else {
			for (final BasicCombinedRElement component : this.slotValues) {
				if (filter.include(component)) {
					return true;
				}
			}
			return false;
		}
	}
	
	@Override
	public List<? extends CombinedRElement> getModelChildren(final @Nullable LtkModelElementFilter filter) {
		if (filter == null) {
			return ImCollections.newList(this.slotValues);
		}
		else {
			final List<BasicCombinedRElement> list= new ArrayList<>();
			for (final BasicCombinedRElement component : this.slotValues) {
				if (filter.include(component)) {
					list.add(component);
				}
			}
			return list;
		}
	}
	
}
