/// <reference path="Rulebook.ts" />
/// <reference path="Rule.ts" />
/// <reference path="../EveryTurn.ts" />
/// <reference path="../../Functions.ts" />

interface AIOptions {
    wanderer? : boolean,
    wandersOn? : Region,
    picksShinies? : boolean
}

class AI {
    public wanderer = true;
    public wandersOn : Region;
    public wanderChance = 50;
    public picksShinies = true;

    public constructor (options : AIOptions) {
        for (let key in options) {
            this[key] = options[key];
        }
    }

    /**
     * Executing an AI returns an Action. DOESN'T execute the action, just finds it!
     * @returns {Promise<Action>}
     */
    public async execute (actor : Thing) : Promise<Action> {
        let promise : Promise<Action>;
        // TODO: if actor.isInCombat();
        if (promise != undefined) {
            promise = AI.combatRules.execute({
                noun : actor
            }, ...this.extraCombatRules);
        } else {
            promise = AI.rules.execute({
                noun : actor
            }, ...this.extraRules);
        }

        let result : Action = await promise;

        return result;
    }

    public addRulesBook (...books : Array<Rulebook<Thing>>) {
        this.extraRules.push(...books)
        arrayUnique(this.extraRules);
    }

    public addCombatRulesBook (...books : Array<Rulebook<Thing>>) {
        this.extraCombatRules.push(...books)
        arrayUnique(this.extraCombatRules);
    }

    public static rules = new Rulebook<Thing>("Default AI Rules");
    public extraRules : Array<Rulebook<Thing>> = [];
    public static combatRules = new Rulebook<Thing>("Default AI Combat Rules");
    public extraCombatRules : Array<Rulebook<Thing>> = [];
}

module AIRules {
    /**
     * This is or behavioral rules regarding something that is happening RIGHT NOW.
     * i.e. Rule for what a monster does when the player has just insulted them, or for when the player triggers an alarm, etc.
     * @type {number}
     */
    export var PRIORITY_ACTING_ON_SITUATION = 5;

    /**
     * This is for behavioral rules about what the NPC SEES.
     * i.e. Is there a shiny on the ground for me to take? Do I see the player and if so how do I feel about it?
     * @type {number}
     */
    export var PRIORITY_ACTING_ON_PLACE = 3;

    /**
     * This is for rules for when the NPC has nothing better to do.
     * i.e. Standard guarding routes, etc.
     * @type {number}
     */
    export var PRIORITY_ACTING_ON_IDLE = 1;
}