package de.frajul.particlelab.entities.particles;

import de.frajul.particlelab.data.Vector;
import de.frajul.particlelab.entities.Entity;
import de.frajul.particlelab.entities.particles.attributes.attributeValues.Range;
import de.frajul.particlelab.entities.particles.attributes.attributeValues.Timeline;
import de.frajul.particlelab.entities.particles.attributes.attributeValues.TintTimeline;
import de.frajul.particlelab.main.GameLog;
import de.frajul.particlelab.rendering.Timer;

import java.util.Random;

/**
 * Created by Julian on 02.08.2016.
 */
public class Particle extends Entity {

    private Random random;
    private boolean active;
    private float maxLife;
    private float passedLifetime;

    private Timeline scaleTimeline;
    private Range scale;
    private Timeline velocityTimeline;
    private Range velocity;
    private Timeline angleTimeline;
    private Range angle;
    private Timeline rotationTimeline;
    private Range rotation;
    private Timeline transparencyTimeline;
    private TintTimeline tintTimeline;

    public Particle(Random random) {
        super(null, new Vector(), 1, 1);
        this.random = random;
    }

    public void activate(Vector position, float liveValue, ParticleData particleData) {
        active = true;
        passedLifetime = 0;
        super.setPosition(position);
        maxLife = particleData.getLife().createValue(random, liveValue);
        scaleTimeline = particleData.getScaleTR().getTimeline();
        scale = particleData.getScaleTR().getRange().createNormalizedInstance(random);
        velocityTimeline = particleData.getVelocityTR().getTimeline();
        velocity = particleData.getVelocityTR().getRange().createNormalizedInstance(random);
        angleTimeline = particleData.getAngleTR().getTimeline();
        angle = particleData.getAngleTR().getRange().createNormalizedInstance(random);
        rotationTimeline = particleData.getRotationTR().getTimeline();
        rotation = particleData.getRotationTR().getRange().createNormalizedInstance(random);
        transparencyTimeline = particleData.getTransparencyT();
        tintTimeline = particleData.getTint();
    }

    public void update(Timer timer, float windStrength, float gravityStrength) {
        if (active) {
            passedLifetime += timer.getFrameTime();
            if (passedLifetime >= maxLife)
                active = false;
            float lifetimePercent = passedLifetime / maxLife;
            setScale(scale.createValue(random, scaleTimeline.getValueAtTime(lifetimePercent)));
            setMovement(velocity.createValue(random, velocityTimeline.getValueAtTime(lifetimePercent)),
                    angle.createValue(random, angleTimeline.getValueAtTime(lifetimePercent)), windStrength, gravityStrength);
            super.setRotation(-rotation.createValue(random, rotationTimeline.getValueAtTime(lifetimePercent)));
            super.setAlpha(transparencyTimeline.getValueAtTime(lifetimePercent));
            super.setColor(tintTimeline.getValueAtTime(lifetimePercent));
        }
    }

    private void setScale(float scale) {
        super.setWidth(scale * ParticleSystem.TRANSFER_VALUE);
        super.setHeight(scale * ParticleSystem.TRANSFER_VALUE);
    }

    private void setMovement(float velocity, float angle, float windStrength, float gravityStrength) {
        float radians = (float) Math.toRadians(angle);
        Vector normalMovement = new Vector();
        normalMovement.setX((float) Math.cos(radians));
        normalMovement.setY((float) Math.sin(radians));
        normalMovement.mul(velocity * ParticleSystem.TRANSFER_VALUE);
        normalMovement.translate(windStrength * ParticleSystem.TRANSFER_VALUE, gravityStrength * ParticleSystem.TRANSFER_VALUE);
        super.setMovement(normalMovement);
    }

    public boolean isActive() {
        return active;
    }
}
