// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.registry;

import java.util.Collections;
import com.hypixel.hytale.function.consumer.BooleanConsumer;
import java.util.List;
import javax.annotation.Nonnull;
import java.util.function.BooleanSupplier;

public abstract class Registry<T extends Registration>
{
    @Nonnull
    private final BooleanSupplier precondition;
    private final String preconditionMessage;
    private final RegistrationWrapFunction<T> wrappingFunction;
    @Nonnull
    private final List<BooleanConsumer> registrations;
    @Nonnull
    private final List<BooleanConsumer> unmodifiableRegistrations;
    private boolean enabled;
    
    protected Registry(@Nonnull final List<BooleanConsumer> registrations, @Nonnull final BooleanSupplier precondition, final String preconditionMessage, @Nonnull final RegistrationWrapFunction<T> wrappingFunction) {
        this.enabled = true;
        this.registrations = registrations;
        this.unmodifiableRegistrations = Collections.unmodifiableList((List<? extends BooleanConsumer>)registrations);
        this.precondition = precondition;
        this.preconditionMessage = preconditionMessage;
        this.wrappingFunction = wrappingFunction;
    }
    
    protected void checkPrecondition() {
        if (!this.precondition.getAsBoolean()) {
            throw new IllegalStateException(this.preconditionMessage);
        }
    }
    
    public boolean isEnabled() {
        return this.enabled;
    }
    
    public void enable() {
        this.enabled = true;
    }
    
    public void shutdown() {
        this.enabled = false;
    }
    
    public T register(@Nonnull final T registration) {
        if (!this.enabled) {
            registration.unregister();
            throw new IllegalStateException("Registry is not enabled!");
        }
        final BooleanConsumer reg = v -> registration.unregister();
        this.registrations.add(reg);
        return this.wrappingFunction.wrap(registration, () -> this.enabled || registration.isRegistered(), () -> {
            this.registrations.remove(reg);
            registration.unregister();
        });
    }
    
    @Nonnull
    public List<BooleanConsumer> getRegistrations() {
        return this.unmodifiableRegistrations;
    }
    
    @Nonnull
    @Override
    public String toString() {
        return "Registry{registrations.size()=" + this.registrations.size();
    }
    
    public interface RegistrationWrapFunction<T extends Registration>
    {
        T wrap(final T p0, final BooleanSupplier p1, final Runnable p2);
    }
}
