package de.siphalor.was.game;

import de.siphalor.was.content.product.Product;
import de.siphalor.was.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Arrays;
import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class StorageSlot {
	final int depth;
	final Product[] products;

	public StorageSlot(int depth) {
		this.depth = depth;
		this.products = new Product[depth];
	}

	@NotNull
	public Product[] getProducts() {
		return products;
	}

	@NotNull
	public Collection<Pair<Integer, Product>> getProductsIndexed() {
		Queue<Pair<Integer, Product>> queue = new ConcurrentLinkedQueue<>();
		int index = 0;
		for (int i = 0; i < depth; i++) {
			if (products[i] == null) {
				break;
			}

			queue.add(Pair.of(index, products[i]));
			index += products[i].getDepth();
		}
		return queue;
	}

	public void clear() {
		Arrays.fill(products, null);
	}

	@Nullable
	public Product front() {
		for (int i = products.length - 1; i >= 0; i--) {
			Product product = products[i];
			if (product != null) {
				return product;
			}
		}
		return null;
	}

	public int pop() {
		if (products[0] == null)
			return -1;
		int d = 0;
		for (int i = 1; i < products.length; i++) {
			if (products[i] == null) {
				products[i - 1] = null;
				return d;
			}
			d += products[i - 1].getDepth();
		}
		products[products.length - 1] = null;
		return d;
	}

	public boolean fits(@NotNull Product product) {
		int blocked = 0;
		for (Product p : products) {
			if (p == null) break;
			blocked += p.getDepth();
		}

		return product.getDepth() <= depth - blocked;
	}

	public int add(@NotNull Product product) {
		int blocked = 0;
		int i;
		for (i = 0; i < products.length; i++) {
			Product p = products[i];
			if (p == null) {
				break;
			}
			blocked += p.getDepth();
			if (blocked >= depth) {
				return -1;
			}
		}
		if (i < products.length && product.getDepth() <= depth - blocked) {
			products[i] = product;
			return blocked;
		}
		return -1;
	}
}
