package net.mostlyoriginal.game.system.ship;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.annotations.Wire;
import com.artemis.systems.EntityProcessingSystem;
import com.artemis.utils.EntityBuilder;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.MathUtils;
import net.mostlyoriginal.api.component.basic.Pos;
import net.mostlyoriginal.api.component.graphics.Anim;
import net.mostlyoriginal.game.G;
import net.mostlyoriginal.game.component.ship.Star;

/**
 * @author Daan van Yperen
 */
@Wire
public class AccelerationEffectSystem extends EntityProcessingSystem {

    protected TravelSimulationSystem travelSimulationSystem;

    /**
     * speed factor of ship.
     */
    private float timer;
    public float speedFactor;

    protected ComponentMapper<Star> mStar;
    protected ComponentMapper<Anim> mAnim;
    protected ComponentMapper<Pos> mPos;
    private int animStage;

    public AccelerationEffectSystem() {
        super(Aspect.getAspectForAll(Star.class, Pos.class, Anim.class));
    }

    @Override
    protected void initialize() {
        super.initialize();

        for (int i = 0; i < 20; i++) {
            spawnStar(MathUtils.random(0, G.SCREEN_WIDTH), randomStarY(), MathUtils.random(100) < 10 ? 0 : MathUtils.random(100) < 15 ? 1 : 2);
        }

    }


    private int randomStarY() {
        return MathUtils.random(0, G.SCREEN_HEIGHT);
    }

    private void spawnStar(int x, int y, int kind) {
        new EntityBuilder(world).with(new Pos(x, y), new Star(kind), new Anim(-50)).build();
    }


    private void trustEffect() {

        // work towards full thrust.
        if (travelSimulationSystem.isTraveling()) {
            timer += world.delta * 0.25f;
            timer = MathUtils.clamp(timer, 0f, 1f);
            speedFactor = Interpolation.exp5.apply(timer * 0.95f);
        } else {
            timer -= world.delta * 0.25f;
            timer = MathUtils.clamp(timer, 0f, 1f);
            speedFactor = Interpolation.exp5.apply(timer * 0.95f);
        }

    }

    @Override
    protected void begin() {
        super.begin();
        trustEffect();

        if (speedFactor > 0.5) {
            animStage = 3;
        } else if (speedFactor > 0.25) {
            animStage = 2;
        } else if (speedFactor > 0.05) {
            animStage = 1;
        } else animStage = 0;
    }

    @Override
    protected void process(Entity e) {

        // match animation to speed.
        Star star = mStar.get(e);
        Anim anim = mAnim.get(e);

        int id = 2 + animStage;
        if (animStage == 0) {
            // just blinking
            id = (int) (star.blinkTimer % 3f);
            star.blinkTimer += world.delta;
        }

        anim.id = star.animId[id];

        Pos pos = mPos.get(e);

        // move star to the left, and randomize location to give the appearance of more stars.
        pos.x -= ((5f + (speedFactor * 1000f)) * world.delta * star.speedFactor);
        if (pos.x < -100) {
            pos.x = G.SCREEN_WIDTH;
            pos.y = randomStarY();
        }
    }
}

@@ -643,24 +643,78 @@
 ngSystem %7B%0A%0A
+    public static final int BIGGEST_STAR_WIDTH = 100;%0A
     protecte
@@ -1245,17 +1245,17 @@
  0; i %3C 
-2
+6
 0; i++) 
@@ -1312,16 +1312,37 @@
 EN_WIDTH
+ + BIGGEST_STAR_WIDTH
 ), rando
@@ -1379,14 +1379,14 @@
 ) %3C 
-1
+2
 0 ? 
-0
+1
  : M
@@ -1412,14 +1412,14 @@
 ) %3C 
-15 ? 1
+20 ? 0
  : 2
@@ -1581,24 +1581,280 @@
 int kind) %7B%0A
+        Anim anim = new Anim(-50);%0A        anim.color.r = MathUtils.random(0.6f,1f);%0A        anim.color.g = MathUtils.random(0.6f,1f);%0A        anim.color.b = MathUtils.random(0.6f,1f);%0A        anim.color.a = MathUtils.random(kind == 0 ? 0.1f : 0.5f,0.9f);%0A
         new 
@@ -1910,29 +1910,20 @@
 (kind), 
-new Anim(-50)
+anim
 ).build(
@@ -3271,17 +3271,17 @@
 .x -= ((
-5
+8
 f + (spe
@@ -3355,19 +3355,34 @@
 os.x %3C -
-100
+BIGGEST_STAR_WIDTH
 ) %7B%0A    

Add some variation to the stars.