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

package com.hypixel.hytale.server.npc.instructions;

import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.npc.movement.controllers.MotionController;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.npc.util.IAnnotatedComponent;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.npc.sensorinfo.InfoProvider;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import java.util.Objects;
import javax.annotation.Nonnull;

public class ActionList
{
    public static final ActionList EMPTY_ACTION_LIST;
    @Nonnull
    protected final Action[] actions;
    protected boolean blocking;
    protected boolean atomic;
    protected int actionIndex;
    
    public ActionList(@Nonnull final Action[] actions) {
        Objects.requireNonNull(this.actions = actions, "Action array in sequence must not be null");
        for (final Action action : actions) {
            Objects.requireNonNull(action, "Action in sequence can't be null");
        }
    }
    
    public void setBlocking(final boolean blocking) {
        this.blocking = blocking;
    }
    
    public void setAtomic(final boolean atomic) {
        this.atomic = atomic;
    }
    
    public boolean canExecute(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final InfoProvider sensorInfo, final double dt, @Nonnull final Store<EntityStore> store) {
        if (this.actions.length == 0) {
            return false;
        }
        if (this.blocking) {
            if (this.actionIndex >= this.actions.length) {
                this.actionIndex = 0;
            }
            return this.actions[this.actionIndex].canExecute(ref, role, sensorInfo, dt, store);
        }
        for (final Action action : this.actions) {
            if (action.canExecute(ref, role, sensorInfo, dt, store)) {
                if (!this.atomic) {
                    return true;
                }
            }
            else if (this.atomic) {
                return false;
            }
        }
        return this.atomic;
    }
    
    public boolean execute(@Nonnull final Ref<EntityStore> ref, @Nonnull final Role role, final InfoProvider sensorInfo, final double dt, @Nonnull final Store<EntityStore> store) {
        if (!this.blocking) {
            for (final Action action : this.actions) {
                if (action.canExecute(ref, role, sensorInfo, dt, store)) {
                    if (!action.isActivated()) {
                        action.activate(role, sensorInfo);
                    }
                    action.execute(ref, role, sensorInfo, dt, store);
                }
                else if (action.isActivated()) {
                    action.deactivate(role, sensorInfo);
                }
            }
            return true;
        }
        final Action action2 = this.actions[this.actionIndex];
        if (!action2.canExecute(ref, role, sensorInfo, dt, store)) {
            return false;
        }
        if (!action2.isActivated()) {
            action2.activate(role, sensorInfo);
        }
        if (!action2.execute(ref, role, sensorInfo, dt, store)) {
            return false;
        }
        action2.deactivate(role, sensorInfo);
        ++this.actionIndex;
        return this.actionIndex >= this.actions.length;
    }
    
    public boolean hasCompletedRun() {
        if (this.actionIndex >= this.actions.length) {
            this.actionIndex = 0;
            return true;
        }
        return false;
    }
    
    public void setContext(final IAnnotatedComponent parent) {
        for (int i = 0; i < this.actions.length; ++i) {
            this.actions[i].setContext(parent, i);
        }
    }
    
    public void registerWithSupport(final Role role) {
        for (final Action action : this.actions) {
            action.registerWithSupport(role);
        }
    }
    
    public void motionControllerChanged(@Nullable final Ref<EntityStore> ref, @Nonnull final NPCEntity npcComponent, final MotionController motionController, @Nullable final ComponentAccessor<EntityStore> componentAccessor) {
        for (final Action action : this.actions) {
            action.motionControllerChanged(ref, npcComponent, motionController, componentAccessor);
        }
    }
    
    public void loaded(final Role role) {
        for (final Action action : this.actions) {
            action.loaded(role);
        }
    }
    
    public void spawned(final Role role) {
        for (final Action action : this.actions) {
            action.spawned(role);
        }
    }
    
    public void unloaded(final Role role) {
        for (final Action action : this.actions) {
            action.unloaded(role);
        }
    }
    
    public void removed(final Role role) {
        for (final Action action : this.actions) {
            action.removed(role);
        }
    }
    
    public void teleported(final Role role, final World from, final World to) {
        for (final Action action : this.actions) {
            action.teleported(role, from, to);
        }
    }
    
    public void clearOnce() {
        for (final Action action : this.actions) {
            action.clearOnce();
        }
        this.actionIndex = 0;
    }
    
    public void onEndMotion() {
        if (!this.blocking) {
            this.clearOnce();
        }
    }
    
    public void setOnce() {
        for (final Action action : this.actions) {
            action.setOnce();
        }
    }
    
    public int actionCount() {
        return this.actions.length;
    }
    
    public IAnnotatedComponent getComponent(final int index) {
        return this.actions[index];
    }
    
    static {
        EMPTY_ACTION_LIST = new ActionList(Action.EMPTY_ARRAY);
    }
}
