package de.frajul.endlessroll.entities;

import de.frajul.endlessroll.data.Vector;
import de.frajul.endlessroll.levels.MoveComponent;
import de.frajul.endlessroll.levels.ObstacleData;
import de.frajul.endlessroll.levels.worlds.World;

/**
 * Created by Julian on 20.11.2015.
 */
public class Obstacle extends Entity {

    private boolean deadly;
    private boolean floating;
    private boolean moving;
    private final float GRID_SQUARE_SIZE = 0.1f;
    private Vector gridSize;
    private MoveComponent moveComponent;
    private float movementMultiplier = 1.0f;

    private float moveProgress;
    private float moveDirection;

    private int bombExplosionState = -1;

    public Obstacle(World world, ObstacleData data, float terrainEdge, Player player) {
        super(world.getObstacleTexture(), new Vector(data.getX(), data.getY()), data.getWidth(),
                data.getHeight());
        this.deadly = data.isDeadly();
        this.floating = data.isFloating();
        this.moving = data.isMoving();
        this.moveComponent = data.getMoveComponent();
        if (!floating)
            super.setToTerrain(terrainEdge);
        if (moveComponent != null && moving) {
            moveComponent.init(super.getPosition());
            moveProgress = moveComponent.getStartOffset();
            moveDirection = moveComponent.getDirection();
            //Constant player speed assumed
            float timeTillPlayerReachesTrigger = player.getSpeed() * ((moveComponent
                    .getLeftmostPosition() - super.getWidth() / 2 - moveComponent
                    .getTriggerDistance()) - player.getRightEdge());
            moveDirection *= -1;
            moveWithMoveComponent(timeTillPlayerReachesTrigger * 1000 * 1000, player.getSpeed());
            moveDirection *= -1;
        }
        gridSize = calcGridSize();
    }

    private Vector calcGridSize() {
        int gridWidth = (int) (width / GRID_SQUARE_SIZE);
        int gridHeight = (int) (height / GRID_SQUARE_SIZE);
        gridWidth = Math.max(gridWidth, 2);
        gridHeight = Math.max(gridHeight, 2);
        return new Vector(gridWidth, gridHeight);
    }

    public void slowMovementForOneFrame(float value) {
        movementMultiplier *= value;
    }

    public void moveWithMoveComponent(float frameTime, float playerSpeed) {
        if (moveComponent.isHasPlayerXSpeed()) {
            moveComponent.calcSpeedForPlayerSpeed(playerSpeed);
        }
        float distance = frameTime * moveComponent
                .getSpeed() * moveComponent.TRANSITION_VALUE * movementMultiplier;
        float newProgress = moveDirection * distance / moveComponent.getLength();
        moveProgress += newProgress;
        if (moveProgress < 0) {
            moveProgress *= -1;
            moveDirection *= -1;
        }
        while (moveProgress > 1) {
            moveProgress -= 2;
            if (moveProgress < 0) {
                moveProgress *= -1;
                moveDirection *= -1;
            }
        }

        super.setPosition(moveComponent.getPositionForProgress(moveProgress));
        super.setMovement(moveComponent.getMovementVector(moveDirection));
        movementMultiplier = 1.0f;
    }

    public boolean isMoving() {
        return moving;
    }

    public boolean isDeadly() {
        return deadly;
    }

    public boolean isFloating() {
        return floating;
    }

    public Vector getGridSize() {
        return gridSize;
    }

    public int getBombExplosionState() {
        return bombExplosionState;
    }

    public void setBombExplosionState(int bombExplosionState) {
        this.bombExplosionState = bombExplosionState;
    }
}
