package speiger.src.coreengine.rendering.tesselation.format;

import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import speiger.src.collections.ints.lists.IntArrayList;
import speiger.src.collections.ints.lists.IntList;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.rendering.tesselation.format.VertexElement.Usage;
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;

public class VertexFormat implements Iterable<VertexElement> {
	List<VertexElement> elements = new ObjectArrayList<>();
	Set<Usage> types = EnumSet.noneOf(Usage.class);
	IntList offsets = new IntArrayList();
	int totalOffset;
	
	private VertexFormat() {}
	
	private VertexFormat(VertexFormat vertexList) {
		elements.addAll(vertexList.elements);
		offsets.addAll(vertexList.offsets);
		totalOffset = vertexList.totalOffset;
	}
	
	public static Builder builder() {
		return new Builder();
	}
	
	public static Builder builder(VertexFormat format) {
		return new Builder(format);
	}
	
	private void add(VertexElement element) {
		elements.add(element);
		offsets.add(totalOffset);
		totalOffset += element.size();
		types.add(element.usage());
	}
	
	public int totalOffset() { return totalOffset; }
	public int size() { return elements.size(); }
	public VertexElement get(int index) { return elements.get(index); }
	public int offset(int index) { return offsets.getInt(index); }
	@Override
	public Iterator<VertexElement> iterator() { return new ReadOnlyIterator<>(elements.iterator()); }
	public boolean hasType(Usage type) { return types.contains(type); }
	
	public static class Builder {
		VertexFormat format;
		
		public Builder() {
			format = new VertexFormat();
		}
		
		public Builder(VertexFormat prev) {
			format = new VertexFormat(prev);
		}
		
		public Builder add(VertexElement element) {
			format.add(element);
			return this;
		}
		
		public VertexFormat build() {
			return format;
		}
	}
}