/// <reference path="../AI.ts" />
module AIRules {
    export var Wander = AI.rules.createAndAddRule({
        name : "Wander",
        firstPriority : AIRules.PRIORITY_ACTING_ON_IDLE,
        conditions : (runner : RulebookRunner<Person>) => {
            let person = runner.noun;
            return person.AI.wanderer && (Math.random() * 100) > person.AI.wanderChance;
        },
        code : (runner : RulebookRunner<Person>) => {
            let person = runner.noun;
            let room = <RoomRandom> person.getRoom();

            if (person.AI.wandersOn != undefined) {
                // stick to region while wandering
                if (person.AI.wandersOn.containsRoom(room)) {
                    // Alredy in region, so just wander off inside it
                    let connections = room.connections.slice();
                    let realConnections = [];
                    for (let i = 0; i < connections.length; i++) {
                        if (connections[i] != undefined && person.AI.wandersOn.containsRoom(connections[i])) {
                            realConnections.push(i);
                        }
                    }
                    let direction = ((new Shuffler(realConnections)).getOne());
                    return new ActionGo(person, direction);
                } else {
                    // return to region
                    let regionRooms = person.AI.wandersOn.getRooms().filter((a : Room) => {
                        if (a instanceof RoomRandom && a.placed) {
                            return true;
                        }
                    });
                    // Ideally we'd actually make a path to it and check the distance, since mazes can make it be longer than it really is
                    // But this is quick and dirty enough. And since regions are closely packed, even if this is not really the closest room, the NPC will end up
                    // entering the region earlier by accident.
                    regionRooms.sort((a : RoomRandom, b : RoomRandom) => {
                        let dist = a.getDistanceTo(b);
                        if (dist != undefined) {
                            return -dist; // This means that the latest element will be the closest.
                        } else {
                            return 0; // This means that the first elements will be unreachable
                        }
                    });

                    let targetRoom = regionRooms.pop();
                    return new ActionGo(person, targetRoom);
                }
            } else {
                // just wander in random direction
                let direction = room.getConnectedDirection();
                return new ActionGo(person, direction);
            }
        }
    });
}