package electrosphere.entity.state.collidable;

import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.GravityTree;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.main.Globals;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;

/**
 *
 * @author amaterasu
 */
public class CollidableTree {
    
    Entity parent;
    CollisionObject body;
    Collidable collidable;
    
    
    
    public CollidableTree(Entity e, Collidable collidable, CollisionObject body){
        parent = e;
        this.collidable = collidable;
        this.body = body;
    }
    
    
    public void simulate(){
        Vector3d position = EntityUtils.getPosition(parent);
        Quaternionf rotation = EntityUtils.getRotation(parent);
        Vector3d offsetVector = new Vector3d();
        Vector3d newPosition = new Vector3d(position);
        javax.vecmath.Matrix4f bodyTransformMatrix;
        //have we hit a terrain impulse?
        boolean hitTerrain = false;
        //handle impulses
        for(Impulse impulse : collidable.getImpulses()){
//            collidable.getImpulses().remove(impulse);
            Vector3d impulseForce = new Vector3d(impulse.getDirection()).mul(impulse.getForce());
            if(impulse.type.matches(Collidable.TYPE_TERRAIN)){
                hitTerrain = true;
//                System.out.println("Impulse force: " + impulseForce);
//                System.out.println("Position: " + position);
            }
            if(impulse.type.matches(Collidable.TYPE_ITEM)){
                if(parent.getDataKeys().contains(EntityDataStrings.GRAVITY_TREE)){
                    ((GravityTree)parent.getData(EntityDataStrings.GRAVITY_TREE)).start();
                }
            }
            if(impulse.type.matches(Collidable.TYPE_CREATURE)){
//                System.out.println(System.currentTimeMillis() + " creature hit!");
                if(parent.getDataKeys().contains(EntityDataStrings.GRAVITY_TREE)){
                    ((GravityTree)parent.getData(EntityDataStrings.GRAVITY_TREE)).start();
                }
            }
            
//            if(impulse.type.matches("movement")){
//                System.out.println("Impulse force: " + impulseForce);
//            }
            offsetVector.add(impulseForce);
        }
        
        //the reasoning here is that if we have something above something else and it's pushing it into the terrain,
        //we should instead just not push into terrain and push along terrain
        if(hitTerrain && offsetVector.y < 0){
            offsetVector.y = 0;
        }
        
        //make sure we're in a valid (World bounds) position
        newPosition.add(offsetVector);
        if(!Globals.collisionEngine.checkCanOccupyPosition(Globals.commonWorldData, parent, newPosition)){
            newPosition = Globals.collisionEngine.suggestMovementPosition(Globals.commonWorldData, parent, newPosition);
        }
        position.set(newPosition);
        
        //update collision engine of this thing's position
        bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x,(float)position.y,(float)position.z)),1.0f);
        body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
        
//        bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)newPosition.x,(float)newPosition.y,(float)newPosition.z)),1.0f);
//        body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
        
    }
    
    
    public void setCollisionObject(CollisionObject body, Collidable collidable){
        this.body = body;
        this.collidable = collidable;
    }
    
    
    
    
}
