//Copyright (c) 2014, Jesús Martín Berlanga. All rights reserved. 
//Distributed under the BSD licence. Read "com/jme3/ai/license.txt".
package steeringDemos.demos;

import com.jme3.ai.agents.Agent;
import com.jme3.ai.agents.behaviors.npc.SimpleMainBehavior;
import com.jme3.ai.agents.behaviors.npc.steering.HideBehavior;
import com.jme3.ai.agents.behaviors.npc.steering.PathFollowBehavior;
import com.jme3.ai.agents.util.GameEntity;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import java.util.ArrayList;
import java.util.List;
import steeringDemos.BasicDemo;
import steeringDemos.control.CustomSteerControl;

/**
 * Hide demo
 *
 * @author Jesús Martín Berlanga
 * @version 1.0.0
 */
public class HideDemo extends BasicDemo {

    private PathFollowBehavior targetPathFollow;

    public static void main(String[] args) {
        HideDemo app = new HideDemo();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        this.steerControl = new CustomSteerControl(8.5f, 5);
        this.steerControl.setCameraSettings(getCamera());
        this.steerControl.setFlyCameraSettings(getFlyByCamera());

        //defining rootNode for brainsAppState processing
        brainsAppState.setApp(this);
        brainsAppState.setGameControl(this.steerControl);

        Vector3f[] spawnArea = null;

        Agent target = this.createBoid("Target", this.targetColor, 0.11f);
        brainsAppState.addAgent(target); //Add the target to the brainsAppState
        brainsAppState.getGameControl().spawn(target, new Vector3f(0, 0, -1));
        this.setStats(
                target,
                this.targetMoveSpeed,
                this.targetRotationSpeed,
                this.targetMass,
                this.targetMaxForce);

        Agent hider = this.createBoid("Seeker", this.neighboursColor, 0.11f);
        brainsAppState.addAgent(hider);
        this.setStats(
                hider,
                this.neighboursMoveSpeed,
                this.neighboursMoveSpeed,
                this.neighboursMass,
                this.neighboursMaxForce);
        brainsAppState.getGameControl().spawn(hider, spawnArea);

        Agent obstacle = this.createSphere("Obstacle", ColorRGBA.Yellow, 0.35f);
        brainsAppState.addAgent(obstacle);
        this.setStats(
                obstacle,
                this.neighboursMoveSpeed,
                this.neighboursRotationSpeed,
                this.neighboursMass,
                this.neighboursMaxForce);
        brainsAppState.getGameControl().spawn(obstacle, new Vector3f(2.5f, 2.5f, 2.5f));

        Agent farAwayObstacle = this.createSphere("Obstacle", ColorRGBA.Yellow, 0.35f);
        brainsAppState.addAgent(farAwayObstacle);
        this.setStats(
                farAwayObstacle,
                this.neighboursMoveSpeed,
                this.neighboursRotationSpeed,
                this.neighboursMass,
                this.neighboursMaxForce);
        brainsAppState.getGameControl().spawn(farAwayObstacle, new Vector3f(7.5f, 7.5f, 5f));

        List obstacles = new ArrayList();
        obstacles.add(obstacle);
        obstacles.add(farAwayObstacle);

        ArrayList orderedPointsList = new ArrayList();
        orderedPointsList.add(new Vector3f(0, 0, 0));
        orderedPointsList.add(new Vector3f(0, 0, 5));
        orderedPointsList.add(new Vector3f(5, 0, 5));
        orderedPointsList.add(new Vector3f(5, 5, 5));
        orderedPointsList.add(new Vector3f(5, 5, 0));
        orderedPointsList.add(new Vector3f(0, 5, 0));
        orderedPointsList.add(new Vector3f(0, 0, 0));

        SimpleMainBehavior targetMainBehavior = new SimpleMainBehavior(target);
        this.targetPathFollow = new PathFollowBehavior(target, orderedPointsList, 1, 1);
        targetMainBehavior.addBehavior(this.targetPathFollow);
        target.setMainBehavior(targetMainBehavior);

        obstacle.setMainBehavior(new SimpleMainBehavior(obstacle));
        farAwayObstacle.setMainBehavior(new SimpleMainBehavior(obstacle));

        SimpleMainBehavior hiderMainBehavior = new SimpleMainBehavior(hider);
        HideBehavior hide = new HideBehavior(hider, target, obstacles, 1f);
        hiderMainBehavior.addBehavior(hide);
        hider.setMainBehavior(hiderMainBehavior);

        brainsAppState.start();
    }

    @Override
    public void simpleUpdate(float tpf) {
        brainsAppState.update(tpf);

        if (!this.targetPathFollow.isActive()) {
            this.targetPathFollow.reset();
        }
    }
}