/*
 * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT).
 *
 * Copyright (c) JCThePants (www.jcwhatever.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.jcwhatever.nucleus.providers.npc.ai.goals;

import com.jcwhatever.nucleus.providers.npc.INpc;
import com.jcwhatever.nucleus.providers.npc.ai.actions.INpcAction;
import com.jcwhatever.nucleus.providers.npc.ai.actions.INpcActionSelector;
import com.jcwhatever.nucleus.utils.PreCon;

import javax.annotation.Nullable;

/**
 * A goal designed to be added from a script. Supports script
 * shorthand functions.
 */
public class NpcScriptGoal implements INpcGoal {

    private Runnable _onReset;
    private IOnRunHandler _onRunHandler;
    private ICanRunHandler _canRunHandler;
    private boolean _isTransient;

    @Override
    public void reset() {
        if (_onReset != null)
            _onReset.run();
    }

    @Override
    public void run(INpcActionSelector director) {
        if (_onRunHandler != null)
            _onRunHandler.run(director);
        else
            director.finish(null);
    }

    @Override
    public boolean canRun() {
        if (_canRunHandler != null && _canRunHandler.canRun()) {
            return true;
        }
        return false;
    }

    /**
     * Determine if the goal is removed when it is finished.
     *
     * <p>Default value is false.</p>
     */
    public boolean isTransient() {
        return _isTransient;
    }

    /**
     * Set the transient flag on the goal.
     *
     * @param isTransient  True to remove the goal when it finishes, otherwise false.
     *
     * @return  Self for chaining.
     */
    public NpcScriptGoal setTransient(boolean isTransient) {
        _isTransient = isTransient;
        return this;
    }

    /**
     * Attach the reset handler.
     *
     * @param runnable  The reset handler.
     *
     * @return  Self for chaining.
     */
    public NpcScriptGoal onReset(Runnable runnable) {
        PreCon.notNull(runnable, "runnable");
        _onReset = runnable;

        return this;
    }

    /**
     * Attach the run handler.
     *
     * @param handler  The run handler.
     *
     * @return  Self for chaining.
     */
    public NpcScriptGoal onRun(IOnRunHandler handler) {
        PreCon.notNull(handler, "handler");

        _onRunHandler = handler;

        return this;
    }

    /**
     * Attach the canRun handler.
     *
     * @param handler  The canRun handler.
     *
     * @return  Self for chaining.
     */
    public NpcScriptGoal onCanRun(ICanRunHandler handler) {
        PreCon.notNull(handler, "handler");

        _canRunHandler = handler;

        return this;
    }

    /**
     * canRun handler for use by a script. Supports
     * shorthand functions.
     */
    public interface ICanRunHandler {
        boolean canRun();
    }

    /**
     * run handler for use by a script. Supports
     * shorthand functions.
     */
    public interface IOnRunHandler {

        /**
         * Invoked when the goals {@code run} method is invoked.
         *
         * @param selector  The {@code INpcActionSelector}.
         */
        void run(INpcActionSelector selector);
    }

    private class Selector implements INpcActionSelector {

        INpcActionSelector selector;

        Selector(INpcActionSelector selector) {
            this.selector = selector;
        }


        @Override
        public INpc getNpc() {
            return selector.getNpc();
        }

        @Override
        public boolean isFinished() {
            return selector.isFinished();
        }

        @Override
        public void finish() {
            selector.finish();
            checkTransient();
        }

        @Override
        public void finish(@Nullable INpcAction action) {
            selector.finish(action);
            checkTransient();
        }

        @Override
        public void cancel() {
            selector.cancel();
            checkTransient();
        }

        @Override
        public void cancel(@Nullable INpcAction action) {
            selector.cancel();
            checkTransient();
        }

        @Override
        public INpcActionSelector run(INpcAction action) {
            return selector.run(action);
        }

        @Override
        public INpcActionSelector next(INpcAction action) {
            return selector.next(action);
        }

        private void checkTransient() {
            if (_isTransient)
                selector.getNpc().getGoals().remove(NpcScriptGoal.this);
        }
    }
}

@@ -1279,125 +1279,8 @@
 s;%0A%0A
-import com.jcwhatever.nucleus.providers.npc.INpc;%0Aimport com.jcwhatever.nucleus.providers.npc.ai.actions.INpcAction;%0A
 impo
@@ -1399,43 +1399,8 @@
 n;%0A%0A
-import javax.annotation.Nullable;%0A%0A
 /**%0A
@@ -4097,1374 +4097,7 @@
    %7D
-%0A%0A    private class Selector implements INpcActionSelector %7B%0A%0A        INpcActionSelector selector;%0A%0A        Selector(INpcActionSelector selector) %7B%0A            this.selector = selector;%0A        %7D%0A%0A%0A        @Override%0A        public INpc getNpc() %7B%0A            return selector.getNpc();%0A        %7D%0A%0A        @Override%0A        public boolean isFinished() %7B%0A            return selector.isFinished();%0A        %7D%0A%0A        @Override%0A        public void finish() %7B%0A            selector.finish();%0A            checkTransient();%0A        %7D%0A%0A        @Override%0A        public void finish(@Nullable INpcAction action) %7B%0A            selector.finish(action);%0A            checkTransient();%0A        %7D%0A%0A        @Override%0A        public void cancel() %7B%0A            selector.cancel();%0A            checkTransient();%0A        %7D%0A%0A        @Override%0A        public void cancel(@Nullable INpcAction action) %7B%0A            selector.cancel();%0A            checkTransient();%0A        %7D%0A%0A        @Override%0A        public INpcActionSelector run(INpcAction action) %7B%0A            return selector.run(action);%0A        %7D%0A%0A        @Override%0A        public INpcActionSelector next(INpcAction action) %7B%0A            return selector.next(action);%0A        %7D%0A%0A        private void checkTransient() %7B%0A            if (_isTransient)%0A                selector.getNpc().getGoals().remove(NpcScriptGoal.this);%0A        %7D%0A    %7D
 %0A%7D%0A

remove unused code