package electrosphere.entity.state.collidable;

import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.ode4j.ode.DBody;

import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;

/**
 * Client collidable tree
 */
public class ClientCollidableTree implements BehaviorTree {
    
    /**
     * The parent entity of this tree
     */
    Entity parent;

    /**
     * The body for this tree
     */
    DBody body;

    /**
     * The collidable for this tree
     */
    Collidable collidable;

    /**
     * Constructor
     * @param e The entity
     * @param collidable The collidable
     * @param body The body
     */
    public ClientCollidableTree(Entity e, Collidable collidable, DBody body){
        parent = e;
        this.collidable = collidable;
        this.body = body;
    }
    

    /**
     * Simulates the component
     */
    public void simulate(float deltaTime){
        Vector3d position = EntityUtils.getPosition(parent);
        Quaterniond rotation = EntityUtils.getRotation(parent);
        Vector3d newPosition = new Vector3d(position);
        //bound to world bounds
        if(Globals.clientWorldData != null){
            if(newPosition.x < Globals.clientWorldData.getWorldBoundMin().x){
                newPosition.x = Globals.clientWorldData.getWorldBoundMin().x;
            }
            if(newPosition.y < Globals.clientWorldData.getWorldBoundMin().y){
                newPosition.y = Globals.clientWorldData.getWorldBoundMin().y;
            }
            if(newPosition.z < Globals.clientWorldData.getWorldBoundMin().z){
                newPosition.z = Globals.clientWorldData.getWorldBoundMin().z;
            }
        }
        PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), newPosition, rotation, body);
    }
    
    /**
     * 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;
    }

    /**
     * Checks if the entity has a collidable tree
     * @param e The entity
     * @return true if the entity contains a collidable tree, false otherwise
     */
    public static boolean hasClientCollidableTree(Entity e){
        return e.containsKey(EntityDataStrings.CLIENT_COLLIDABLE_TREE);
    }

    /**
     * Gets the collidable tree on the entity
     * @param e The entity
     * @return The tree
     */
    public static ClientCollidableTree getClientCollidableTree(Entity e){
        return (ClientCollidableTree)e.getData(EntityDataStrings.CLIENT_COLLIDABLE_TREE);
    }
    
    
}
