package electrosphere.collision.collidable;

import electrosphere.entity.Entity;
import electrosphere.entity.state.collidable.Impulse;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;


/**
 * Stores the type of the collidable object as well as the impulses currently applied to it
 */
public class Collidable {
    
    //The entity this collidable is attached to
    Entity parent;
    //The type of collidable
    String type;

    //If true, once impulses are applied to the collidable, have the parent entity resynchronize its position with the collidable
    boolean parentTracksCollidable = true;
    
    //The impulses to be applied to this collidable
    List<Impulse> impulses = new LinkedList<Impulse>();

    /**
     * The params for the surface of this collidable when a collision occurs
     */
    SurfaceParams surfaceParams;
    
    //these should have corresponding category bits along with them
    public static final String TYPE_STATIC = "static";
    public static final long TYPE_STATIC_BIT = 0x1;

    public static final String TYPE_CREATURE = "creature";
    public static final long TYPE_CREATURE_BIT = 0x4;

    public static final String TYPE_OBJECT = "object";
    public static final long TYPE_OBJECT_BIT = 0x40;

    public static final String TYPE_WORLD_BOUND = "worldBound";
    public static final long TYPE_WORLD_BOUND_BIT = 0x100;

    /**
     * A ray casting mask to exclude terrain
     */
    public static final List<String> MASK_NO_TERRAIN = Arrays.asList(new String[]{
        TYPE_STATIC,
        TYPE_CREATURE,
        TYPE_OBJECT,
        TYPE_WORLD_BOUND,
    });

    
    /**
     * Constructor
     * @param parent The parent entity
     * @param type The type of collidable
     * @param parentTracksCollidable true if the parent should have the same position as the collidable, false otherwise
     */
    public Collidable(Entity parent, String type, boolean parentTracksCollidable){
        this.parent = parent;
        this.type = type;
        this.parentTracksCollidable = parentTracksCollidable;
        this.surfaceParams = new SurfaceParams();
    }

    /**
     * Sets the surface params for the collidable
     * @param surfaceParams The surface params
     */
    public void setSurfaceParams(SurfaceParams surfaceParams){
        this.surfaceParams = surfaceParams;
    }

    /**
     * Gets the surface params for the collidable
     * @return The surface params
     */
    public SurfaceParams getSurfaceParams(){
        return this.surfaceParams;
    }

    public List<Impulse> getImpulses() {
        return impulses;
    }

    public void addImpulse(Impulse impulse) {
        impulses.add(impulse);
    }

    public Entity getParent() {
        return parent;
    }

    public String getType() {
        return type;
    }

    /**
     * Gets whether the parent tracks the collidable's position
     * @return True if the parent tracks the collidable's position, false otherwise
     */
    public boolean getParentTracksCollidable(){
        return parentTracksCollidable;
    }

    public void overrideType(String type){
        this.type = type;
    }
    
    public void clear(){
        impulses.clear();
    }
    
    
    
}
