package de.frajul.endlessroll.entities.tools;

import de.frajul.endlessroll.data.Vector;
import de.frajul.endlessroll.entities.DestroyEffect;
import de.frajul.endlessroll.entities.Player;
import de.frajul.endlessroll.entities.collision.geometry.Geometry;
import de.frajul.endlessroll.entities.particles.ParticleSource;
import de.frajul.endlessroll.entities.particles.ParticleSystem;
import de.frajul.endlessroll.main.game.Timer;
import de.frajul.endlessroll.sounds.SoundManager;
import de.frajul.endlessroll.sounds.SoundStream;

/**
 * Created by Julian on 11.02.2016.
 */
public class Stasis extends Tool {

    private SoundManager soundManager;
    private ParticleSource particleSource;
    private boolean firstCollision = true;
    private final static float Y_SLOW_FACTOR = .4f; //Final .2f
    private final static float X_SLOW_FACTOR = .9f; //Final .8f
    private float forceValue;

    private SoundStream soundStream;

    public Stasis(Vector position, ParticleSystem particleSystem, SoundManager soundManager) {
        super(ToolType.STASIS, position,
                .7f * ToolType.STASIS.getCurrentUpgradeValue(ToolUpgradeType.SIZE) / 100,
                .7f * ToolType.STASIS.getCurrentUpgradeValue(ToolUpgradeType.SIZE) / 100, false,
                false);
        this.soundManager = soundManager;
        animation.setLooping(true);
        animation.setRequiredDelta(300);
        animation.setIndexSequence(new int[]{1, 1, 2, 3, 2, 4, 4, 3, 2, 2, 3, 3});
        super.setFloating(true);
        particleSource = new ParticleSource(new Vector(position), particleSystem.stasis);
        particleSource.setSpawnSize(new Vector(super.width, super.height));
        particleSource.start();
        forceValue = ToolType.STASIS.getCurrentUpgradeValue(ToolUpgradeType.FORCE);
        soundStream = soundManager.playSound(soundManager.stasisSound);
    }

    public void updateSoundVolume(Player player) {
        float distanceToPlayer = super.getPosition().getX() - player.getPosition().getX();
        boolean playerInXRange = (player.getRightEdge() >= super.getLeftEdge() && player
                .getRightEdge() <= super.getRightEdge()) || (player.getLeftEdge() >= super
                .getLeftEdge() && player.getLeftEdge() <= super.getRightEdge());
        float factor = 1.0f;
        if (!playerInXRange) {
            factor = 1.0f / (distanceToPlayer * distanceToPlayer);
            if (distanceToPlayer < -2) {
                soundManager.stopSound(soundStream);
                return;
            }
        }
        soundStream.setCurrentVolumeModifier(factor);
        soundManager.onStreamVolumeChanged(soundStream);
    }

    @Override
    public void destroy(DestroyEffect destroyEffect) {
        super.destroy(destroyEffect);
        particleSource.kill();
        soundManager.stopSound(soundStream);
    }

    @Override
    public void onPlayerCollision(Player player, Timer timer) {
        player.addStasis(this);
    }

    @Override
    protected Geometry createWorldCollisionBounds() {
        return this;
    }

    @Override
    protected Geometry createPlayerCollisionBounds() {
        return this;
    }

    public void influencePlayerMovementValues(Player player) {
        float finalXSlow = getCurrentXSlowFactor();
        player.manipulateAllForces(Y_SLOW_FACTOR / forceValue);
        player.getMovement().setX(player.getMovement().getX() * finalXSlow);
        if (firstCollision) {
            player.getMovement().y *= Y_SLOW_FACTOR / forceValue;
            firstCollision = false;
        }
    }

    public float getCurrentXSlowFactor() {
        return X_SLOW_FACTOR - forceValue / 20f;
    }
}
