package uebung05.logistics;

import uebung05.logistics.material.Grease;
import uebung05.logistics.material.Oil;
import uebung05.logistics.quantities.FloatUnit;
import uebung05.logistics.quantities.IntUnit;
import uebung05.logistics.quantities.NeedCollector;
import uebung05.logistics.storage.IntStorage;

/**
 * The Vehicle abstract class represents a vehicle in the logistics system.
 * It includes an abstract reportNeeds method for reporting the needs of the vehicle,
 * an abstract fillUpAll method for filling up the vehicle, an abstract consumeAll method for
 * consuming the vehicle's supplies, and abstract need methods for checking if the vehicle needs
 * a specific IntUnit or FloatUnit object.
 *
 * @author Nikolaus Köberlein
 * @version 1.0
 */
public abstract class Vehicle {

    String name;
    IntStorage oil;
    IntStorage grease;

    private final static int maxOil = 3;
    private final static int maxGrease = 3;

    /**
     * Construct a Vehicle object with a name, oil storage, and grease storage
     *
     * @param name       The name of the vehicle
     * @param oil        The initial amount of oil for the vehicle
     * @param grease     The initial amount of grease for the vehicle
     */
    protected Vehicle(String name, int oil, int grease) {
        this.name = name;
        this.oil = new IntStorage(oil, Oil.getINSTANCE(), maxOil);
        this.grease = new IntStorage(grease, Grease.getINSTANCE(), maxGrease);
    }

    /**
     * Fill up oil and grease.
     */
    public void fillUpBasic () {
        oil.fillUp();
        grease.fillUp();
    }

    /**
     * Consume oil and grease.
     */
    public void consumeBasic () {
        oil.consume(1);
        grease.consume(1);
    }

    /**
     * Report needs of oil and grease.
     */
    public void reportBasicNeeds (NeedCollector collector) {
        oil.reportNeed(collector);
        grease.reportNeed(collector);
    }

    /**
     * Report the needs of the vehicle to a NeedCollector object
     *
     * @param collector The NeedCollector object to which to report the needs
     */
    public abstract void reportNeeds(NeedCollector collector);

    /**
     * Fill up all the supplies for the vehicle
     */
    public abstract void fillUpAll();

    /**
     * Consume the vehicle's supplies based on the intensity rate
     *
     * @param intensityRate The intensity rate for the consumption
     */
    public abstract void consumeAll(int intensityRate);

    /**
     * Check if the vehicle needs a specific IntUnit object
     *
     * @param unit The IntUnit object for which to check the need
     * @return True if the vehicle needs the IntUnit object, false otherwise
     */
    public abstract Boolean need(IntUnit unit);

    /**
     * Check if the vehicle needs a specific FloatUnit object
     *
     * @param unit The FloatUnit object for which to check the need
     * @return True if the vehicle needs the FloatUnit object, false otherwise
     */
    public abstract Boolean need(FloatUnit unit);

    @Override
    public String toString() {
        return name;
    }
}