package uebung05.logistics.storage;

import uebung05.logistics.quantities.IntUnit;
import uebung05.logistics.quantities.NeedCollector;

/**
 * The IntStorage class represents an integer storage for a specific IntUnit object.
 * It includes methods for getting the unit, stored amount, and maximum capacity, as
 * well as methods for consuming, filling, and reporting needs.
 *
 * @author Nikolaus Köberlein
 * @version 1.0
 */
public class IntStorage implements IntUnit {

    private final IntUnit unit;
    private int stored;
    private final int max;

    /**
     * Construct an IntStorage object with a stored amount, IntUnit object, and maximum capacity
     *
     * @param stored        The initial stored amount for the IntStorage object
     * @param unit          The IntUnit object for the IntStorage object
     * @param max           The maximum capacity for the IntStorage object
     *
     * @throws java.lang.IllegalArgumentException if unit is negative
     */
    public IntStorage(int stored, IntUnit unit, int max) {
        if (stored < 0 || max < 0) {
            throw new IllegalArgumentException("Units cannot be negative");
        }
        if (stored > max) {
            this.stored = max;
            this.unit = unit;
            this.max = max;
        } else {
            this.stored = stored;
            this.unit = unit;
            this.max = max;
        }
    }

    /**
     * Get the IntUnit object for the IntStorage object
     *
     * @return The IntUnit object for the IntStorage object
     */
    public IntUnit getUnit() {
        return unit;
    }

    /**
     * Get the stored amount for the IntStorage object
     *
     * @return The stored amount for the IntStorage object
     */
    public int getStored() {
        return stored;
    }

    /**
     * Get the maximum capacity for the IntStorage object
     *
     * @return The maximum capacity for the IntStorage object
     */
    public int getMax() {
        return max;
    }

    /**
     * Consume a specific amount from the IntStorage object
     *
     * @param amount The amount to consume from the IntStorage object
     * @return The amount consumed from the IntStorage object
     *
     * @throws java.lang.IllegalArgumentException if consume is negative
     */
    public int consume(int amount) {
        if (amount < 0) {
            throw new IllegalArgumentException("Consume cannot be negative");
        }
        if (stored < amount) {
            int newStored = stored;
            stored = 0;
            return newStored;
        }
        stored -= amount;
        return amount;
    }

    /**
     * Fill the IntStorage object with a specific amount
     *
     * @param amount The amount to fill the IntStorage object with
     *
     * @throws java.lang.IllegalArgumentException if amount is negative
     */
    public void fill(int amount) {
        if (amount < 0) {
            throw new IllegalArgumentException("Filled amount cannot be negative");
        }
        stored += amount;
        if (max < stored) {
            fillUp();
        }
    }

    /**
     * Fill the IntStorage object to its maximum capacity
     */
    public void fillUp() {
        stored = max;
    }

    /**
     * Report the needs of the IntStorage object to a NeedCollector object
     *
     * @param collector The NeedCollector object to which to report the needs
     */
    public void reportNeed (NeedCollector collector) {
        collector.add(max-stored, unit);
    }

    /**
     * Get a string representation of the IntStorage object
     *
     * @return A string representation of the IntStorage object
     */
    @Override
    public String toString() {
        return "storage with " + stored + " of " + max + " " + unit;
    }
}