package speiger.src.coreengine.utils.collections.pools;

import java.util.Collection;
import java.util.Iterator;
import java.util.function.Consumer;

import speiger.src.coreengine.utils.functions.Functions;

public class FixedPool<T> implements IPool<T> {
	T[] stack;
	int stored;
	Consumer<T> acceptor;
	
	public FixedPool(T[] stack) {
		this(stack, 0);
	}
	
	public FixedPool(T[] stack, int stored) {
		this(stack, stored, Functions.getVoidConsumer());
	}
	
	public FixedPool(T[] stack, Consumer<T> acceptor) {
		this(stack, 0, acceptor);
	}
	
	public FixedPool(T[] stack, int stored, Consumer<T> acceptor) {
		this.stack = stack;
		this.stored = stored;
		this.acceptor = acceptor;
	}
	
	@Override
	public T get() {
		if(stored <= 0) throw new IllegalStateException("Pool is empty");
		T result = stack[stored];
		stack[stored--] = null;
		return result;
	}
	
	@Override
	public T[] get(T[] input) {
		if(stored < input.length) throw new IllegalStateException("Pool is to Small");
		for(int i = 0,m = input.length;i < m;i++) {
			input[i] = stack[stored];
			stack[stored--] = null;
		}
		return input;
	}
	
	@Override
	public void accept(T t) {
		if(stored >= stack.length) throw new IllegalStateException("Pool is Full");
		acceptor.accept(t);
		stack[stored++] = t;
	}
	
	@Override
	public void accept(T[] values) {
		for(int i = 0,m = Math.min(values.length, stack.length - stored);i < m;i++) {
			stack[stored++] = values[i];
			acceptor.accept(values[i]);
		}
	}
	
	@Override
	public void accept(Collection<T> values) {
		Iterator<T> iter = values.iterator();
		for(int i = 0,m = Math.min(values.size(), stack.length - stored);i < m && iter.hasNext();i++) {
			T value = iter.next();
			stack[stored++] = value;
			acceptor.accept(value);
		}
	}
}
