package de.frajul.endlessroll.entities.collision;

import de.frajul.endlessroll.entities.DestroyEffect;
import de.frajul.endlessroll.entities.Obstacle;
import de.frajul.endlessroll.entities.Player;
import de.frajul.endlessroll.entities.collectables.Energy;
import de.frajul.endlessroll.entities.collectables.Star;
import de.frajul.endlessroll.entities.collision.collisionData.EntityCollisionData;
import de.frajul.endlessroll.entities.collision.collisionData.ObstacleCollisionData;
import de.frajul.endlessroll.entities.collision.collisionData.PlayerCollisionData;
import de.frajul.endlessroll.entities.collision.collisionData.ToolCollisionData;
import de.frajul.endlessroll.entities.tools.Tool;
import de.frajul.endlessroll.main.game.Game;
import de.frajul.endlessroll.main.game.GameScene;
import de.frajul.endlessroll.main.game.Timer;
import de.frajul.endlessroll.main.physics.Physics;

/**
 * Created by Julian on 02.01.2016.
 */
public class CollisionManager {

    private Game game;
    private Player player;
    private Timer timer;

    public CollisionManager(Game game) {
        this.game = game;
    }

    //Check Obstacle always before tool, because at tool, player could be moved etc.
    public void update(Physics physics, GameScene scene, Timer timer) {
        physics.checkToolCollision(scene);

        this.player = scene.getPlayer();
        this.timer = timer;
        PlayerCollisionData data = physics.getPlayerCollisionData(scene);
        if (data.isTerrainCollision())
            checkTerrainCollision(data.getTerrainCollisionData());
        if (data.isCeilingCollision())
            checkCeilingCollision(data.getCeilingCollisionData());
        if (data.isObstacleCollision())
            checkObstacleCollision(data.getObstacleCollisionData(), player.hasSuperPower());
        if (data.isToolCollision())
            checkToolCollision(data.getToolCollisionData());
        if (data.isStarCollision())
            game.onStarCollision((Star) data.getStarCollisionData().getEntity());
        if (data.isEnergyCollision())
            game.onEnergyCollision((Energy) data.getEnergyCollisionData().getEntity());
    }

    private void checkTerrainCollision(EntityCollisionData data) {
        checkEntityCollision(data);
        if (data.getEdge() != Edge.TOP)
            game.onGameOver(true);
    }

    private void checkCeilingCollision(EntityCollisionData data) {
        checkEntityCollision(data);
        if (data.getEdge() == Edge.RIGHT || data.getEdge() == Edge.LEFT)
            game.onGameOver(true);
    }

    private void checkToolCollision(ToolCollisionData data) {
        for (Tool tool : data.getTools())
            tool.onPlayerCollision(player, timer);
    }

    private void checkObstacleCollision(ObstacleCollisionData data, boolean playerHasSuperpower) {
        for (EntityCollisionData entityData : data.getCollisions()) {
            if (playerHasSuperpower) {
                entityData.getEntity().destroy(DestroyEffect.EXPLOSION);
            } else {
                if (entityData.getEdge() != Edge.TOP || ((Obstacle) entityData.getEntity())
                        .isDeadly())
                    game.onGameOver(true);
                else
                    checkEntityCollision(entityData);
            }
        }
    }

    private void checkEntityCollision(EntityCollisionData data) {
        switch (data.getEdge()) {
            case TOP:
                player.getMovement().y = 0;
                player.setToTerrain(data.getEntity().getTopEdge());
                break;
            case BOTTOM:
                player.getMovement().y = 0;
                player.setTopEdge(data.getEntity().getBottomEdge());
                break;
            case LEFT:
                player.getPosition().x = data.getEntity().getLeftEdge() - player.RADIUS;
                break;
            case RIGHT:
                player.getPosition().x = data.getEntity().getRightEdge() + player.RADIUS;
                break;
        }
    }

}
