package electrosphere.entity.state.collidable;

import electrosphere.collision.collidable.Collidable;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.movement.fall.ServerFallTree;

import org.ode4j.ode.DBody;

/**
 * Server collidable tree
 */
public class ServerCollidableTree implements BehaviorTree {
    
    Entity parent;
    DBody body;
    Collidable collidable;
    boolean applyImpulses = true;
    

    public ServerCollidableTree(Entity e, Collidable collidable, DBody body){
        parent = e;
        this.collidable = collidable;
        this.body = body;
    }
    
    public ServerCollidableTree(Entity e, Collidable collidable, DBody body, boolean applyImpulses){
        parent = e;
        this.collidable = collidable;
        this.body = body;
        this.applyImpulses = applyImpulses;
    }
    
    static int incrementer = 0;
    
    public void simulate(float deltaTime){
        //have we hit a terrain impulse?
        //handle impulses
        for(Impulse impulse : collidable.getImpulses()){
            if(impulse.type.matches(Collidable.TYPE_CREATURE)){
                if(ServerGravityTree.getServerGravityTree(parent)!=null){
                    ServerGravityTree.getServerGravityTree(parent).start();
                }
            }
            if(impulse.type.matches(Collidable.TYPE_WORLD_BOUND)){
                this.resetGravityFall();
            }
        }
    }
    
    
    /**
     * Sets the structures backing this collidable tree
     * @param body The ode body
     * @param collidable The collidable
     */
    public void setCollisionObject(DBody body, Collidable collidable){
        this.body = body;
        this.collidable = collidable;
    }
    
    public static boolean hasServerCollidableTree(Entity e){
        return e.containsKey(EntityDataStrings.SERVER_COLLIDABLE_TREE);
    }

    public static ServerCollidableTree getServerCollidableTree(Entity e){
        return (ServerCollidableTree)e.getData(EntityDataStrings.SERVER_COLLIDABLE_TREE);
    }

    /**
     * Adds a terrain collision to the collidable list
     */
    protected void resetGravityFall(){
        if(ServerGravityTree.getServerGravityTree(parent)!=null){
            ServerGravityTree.getServerGravityTree(parent).stop();
        }
        if(ServerFallTree.getFallTree(parent)!=null){
            ServerFallTree.getFallTree(parent).land();
        }
    }
    
    
}
