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

package com.hypixel.hytale.component.system;

import java.util.List;
import com.hypixel.hytale.component.ResourceType;
import com.hypixel.hytale.component.Resource;
import javax.annotation.Nullable;
import java.util.Objects;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Component;
import java.util.function.Supplier;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.component.ResourceRegistration;
import javax.annotation.Nonnull;
import com.hypixel.hytale.component.ComponentRegistration;
import it.unimi.dsi.fastutil.objects.ObjectList;

public abstract class System<ECS_TYPE> implements ISystem<ECS_TYPE>
{
    @Nonnull
    private final ObjectList<ComponentRegistration<ECS_TYPE, ?>> componentRegistrations;
    @Nonnull
    private final ObjectList<ResourceRegistration<ECS_TYPE, ?>> resourceRegistrations;
    
    public System() {
        this.componentRegistrations = new ObjectArrayList<ComponentRegistration<ECS_TYPE, ?>>();
        this.resourceRegistrations = new ObjectArrayList<ResourceRegistration<ECS_TYPE, ?>>();
    }
    
    @Nonnull
    protected <T extends Component<ECS_TYPE>> ComponentType<ECS_TYPE, T> registerComponent(@Nonnull final Class<? super T> tClass, @Nonnull final Supplier<T> supplier) {
        return this.registerComponent(tClass, null, null, supplier);
    }
    
    @Nonnull
    protected <T extends Component<ECS_TYPE>> ComponentType<ECS_TYPE, T> registerComponent(@Nonnull final Class<? super T> tClass, @Nonnull final String id, @Nonnull final BuilderCodec<T> codec) {
        Objects.requireNonNull(codec);
        return this.registerComponent(tClass, id, codec, codec::getDefaultValue);
    }
    
    @Nonnull
    protected <T extends Component<ECS_TYPE>> ComponentType<ECS_TYPE, T> registerComponent(@Nonnull final Class<? super T> tClass, @Nullable final String id, @Nullable final BuilderCodec<T> codec, @Nonnull final Supplier<T> supplier) {
        final ComponentType<ECS_TYPE, T> componentType = new ComponentType<ECS_TYPE, T>();
        this.componentRegistrations.add(new ComponentRegistration<ECS_TYPE, Object>((Class<? super Object>)tClass, id, (BuilderCodec<Object>)codec, (Supplier<Object>)supplier, (ComponentType<ECS_TYPE, Object>)componentType));
        return componentType;
    }
    
    @Nonnull
    public <T extends Resource<ECS_TYPE>> ResourceType<ECS_TYPE, T> registerResource(@Nonnull final Class<? super T> tClass, @Nonnull final Supplier<T> supplier) {
        return this.registerResource(tClass, null, null, supplier);
    }
    
    @Nonnull
    public <T extends Resource<ECS_TYPE>> ResourceType<ECS_TYPE, T> registerResource(@Nonnull final Class<? super T> tClass, @Nonnull final String id, @Nonnull final BuilderCodec<T> codec) {
        Objects.requireNonNull(codec);
        return this.registerResource(tClass, id, codec, codec::getDefaultValue);
    }
    
    @Nonnull
    private <T extends Resource<ECS_TYPE>> ResourceType<ECS_TYPE, T> registerResource(@Nonnull final Class<? super T> tClass, @Nullable final String id, @Nullable final BuilderCodec<T> codec, @Nonnull final Supplier<T> supplier) {
        final ResourceType<ECS_TYPE, T> componentType = new ResourceType<ECS_TYPE, T>();
        this.resourceRegistrations.add(new ResourceRegistration<ECS_TYPE, Object>((Class<? super Object>)tClass, id, (BuilderCodec<Object>)codec, (Supplier<Object>)supplier, (ResourceType<ECS_TYPE, Object>)componentType));
        return componentType;
    }
    
    @Nonnull
    public List<ComponentRegistration<ECS_TYPE, ?>> getComponentRegistrations() {
        return this.componentRegistrations;
    }
    
    @Nonnull
    public List<ResourceRegistration<ECS_TYPE, ?>> getResourceRegistrations() {
        return this.resourceRegistrations;
    }
}
