package electrosphere.entity.types.collision;

import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.shapes.CylinderShape;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
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 CollisionObjUtils {
    
    public static Entity spawnCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation){
        Entity rVal = new Entity();
        
        CollisionObject planeObject = PhysicsUtils.getPlaneObject(scale);
        javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
                PhysicsUtils.jomlToVecmathQuaternionf(rotation),
                PhysicsUtils.jomlToVecmathVector3f(position),
                1.0f);
        planeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
        Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
        Globals.collisionEngine.registerCollisionObject(planeObject, collidable);
        Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
        
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_PLANE, true);
        rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
        rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
        rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, planeObject);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
        rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
        
        Globals.entityManager.registerEntity(rVal);
        return rVal;
    }
    
    
    public static Entity spawnCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation){
        Entity rVal = new Entity();
        
        CollisionObject cubeObject = PhysicsUtils.getCubeObject(scale);
        javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
                PhysicsUtils.jomlToVecmathQuaternionf(rotation),
                PhysicsUtils.jomlToVecmathVector3f(position),
                1.0f);
        cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
        Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
        Globals.collisionEngine.registerCollisionObject(cubeObject, collidable);
        Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
        
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE, true);
        rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
        rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
        rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
        rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
        
        Globals.entityManager.registerEntity(rVal);
        return rVal;
    }
    
    public static Entity spawnCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation){
        Entity rVal = new Entity();
        
        CollisionObject cubeObject = PhysicsUtils.getCylinderObject(scale);
        javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
                PhysicsUtils.jomlToVecmathQuaternionf(rotation),
                PhysicsUtils.jomlToVecmathVector3f(position),
                1.0f);
        cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
        Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
        Globals.collisionEngine.registerCollisionObject(cubeObject, collidable);
        Globals.collisionEngine.registerStructurePhysicsEntity(rVal);
        
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_TYPE_CYLINDER, true);
        rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(position.x,position.y,position.z));
        rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, rotation);
        rVal.putData(EntityDataStrings.DATA_STRING_SCALE, scale);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, cubeObject);
        rVal.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
        rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
        
        Globals.entityManager.registerEntity(rVal);
        return rVal;
    }
    
    
    public static Entity attachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
        Entity rVal = spawnCollisionPlane(scale, position, rotation);
        
        AttachUtils.attachEntityToEntity(parent, rVal);
        
        return rVal;
    }
    
    public static Entity attachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
        Entity rVal = spawnCollisionCube(scale, position, rotation);
        
        AttachUtils.attachEntityToEntity(parent, rVal);
        
        return rVal;
    }
    
    public static Entity attachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
        Entity rVal = spawnCollisionCylinder(scale, position, rotation);
        
        AttachUtils.attachEntityToEntity(parent, rVal);
        
        return rVal;
    }
    
    public static CollisionObject getCollisionBody(Entity e){
        return (CollisionObject)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
    }
    
    public static void positionCharacter(Entity e, Vector3f position){
        EntityUtils.getPosition(e).set(position);
        Quaternionf rotation = EntityUtils.getRotation(e);
        CollisionObject body = getCollisionBody(e);
        PhysicsUtils.setRigidBodyTransform(position, rotation, body);
    }
    
    public static Collidable getCollidable(Entity e){
        return (Collidable)e.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
    }
    
}
