import java.util.HashMap;

    /* Keep a reference to a singleton instance of each FuelType
     * class. To add a new FuelType subclass:
     *        (i)   Define the subclass, e.g GreenGas.
     *        (ii)  Add an instance to the fuels array
     *              GreenGas.getInstance().
     *  (iii) Calculate the percentage likelihood of it being
     *        requested and redistribute the percentages between
     *        all of the fuel types as recorded in the
     *        typePercentages array.
     */

class FuelFactory {
        // Provide access to the singleton instance of this class.
    public static FuelFactory getInstance(){
        return factory;
    }
        
        // Return a random instance of the FuelType class.
    public FuelType randomFuelType() throws RuntimeException {
        // Generate a random fuel type.
        final int num = (int) (Math.random() * 100.0);
        for(int i = 0; i < typePercentages.length; i++){
            if(num < typePercentages[i]){
                return fuels[i];
            }
        }
        throw new RuntimeException("Failure in FuelFactory.randomFuelType()");
    }

        // type should be "Diesel", etc.
    public FuelType getFuel(String type) throws RuntimeException {
        Object fuel = fuelRegistry.get(type.toLowerCase());
        if((fuel != null) && (fuel instanceof FuelType)){
            return (FuelType) fuel;
        }
        else{
            throw new RuntimeException("Unknown fuel type: "+type+" passed to: "+
                                        "FuelFactory.getFuel()");
        }
    }

        // Prevent arbitrary creation.
    protected FuelFactory(){
    }

        // The unique set of FuelType objects.
    private final FuelType[] fuels = {
        Diesel.getInstance(),
        Leaded.getInstance(),
        Unleaded.getInstance(),
    };

    // Provide a registry of fuel types. Each fuel type may be
    // looked up by the name returned by its toString method.
    private final HashMap fuelRegistry = new HashMap();
    {
        // Initialise the registry of fuel types. This allows
        // lookup by fuel name.
        for(int i = 0; i < fuels.length; i++){
            fuelRegistry.put(fuels[i].toString().toLowerCase(),fuels[i]);
        }
    }

    // Cumulative percentage for each fuel type.
    //     Assert: typePercentages[typePercentages.length-1] == 100
    //     Assert: typePercentages.length == fuels.length
    private static final int[] typePercentages = { 20, 50, 100 };

    // The singleton instance of this class - returned by instance().
    private static FuelFactory factory = new FuelFactory();
}
