package electrosphere.collision.hitbox;

import electrosphere.collision.CollisionEngine;
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
import electrosphere.engine.Globals;
import electrosphere.entity.state.hitbox.HitboxCollectionState;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Manages all hitboxes on either the server or client
 */
public class HitboxManager {
    
    //the list of all hitboxes
    CopyOnWriteArrayList<HitboxCollectionState> hitboxes = new CopyOnWriteArrayList<HitboxCollectionState>();

    //the collision engine for this hitbox manager
    CollisionEngine collisionEngine;

    //an id incrementer for hitboxes
    long idIncrementer = 0;
    
    /**
     * Constructor
     * @param resolutionCallback The callback that fires when a collision occurs
     */
    public HitboxManager(CollisionResolutionCallback resolutionCallback){
        collisionEngine = new CollisionEngine();
        collisionEngine.setCollisionResolutionCallback(resolutionCallback);
    }
    
    /**
     * Registers a hitbox to the manager
     * @param hitbox the hitbox to register
     */
    public void registerHitbox(HitboxCollectionState hitbox){
        hitboxes.add(hitbox);
        idIncrementer++;
    }
    
    /**
     * Gets all hitboxes in the manager
     * @return all hitboxes in the manager
     */
    public CopyOnWriteArrayList<HitboxCollectionState> getAllHitboxes(){
        return hitboxes;
    }

    /**
     * Deregisters a hitbox from the manager
     * @param hitbox the hitbox to deregister
     */
    public void deregisterHitbox(HitboxCollectionState hitbox){
        hitboxes.remove(hitbox);
    }

    /**
     * Gets the collision engine associated with the hitbox manager
     * @return The collision engine
     */
    public CollisionEngine getCollisionEngine(){
        return this.collisionEngine;
    }

    /**
     * Runs all per frame functions of the hitbox manager
     */
    public void simulate(){
        //update all positions
        Globals.profiler.beginCpuSample("Update hitbox positions");
        for(HitboxCollectionState state : hitboxes){
            state.clearCollisions();
            state.updateHitboxPositions(this.collisionEngine);
        }
        Globals.profiler.endCpuSample();
        //collide hitboxes
        Globals.profiler.beginCpuSample("Collide hitboxes");
        this.collisionEngine.collide();
        this.collisionEngine.clearCollidableImpulseLists();
        Globals.profiler.endCpuSample();
    }



}
