// Creates the main splash scene (if you can even call it a scene)
//
// times: [Array<SplashTime>] All of the timing objects of your splash
//
// If you assign an onEnd property to the object and it's a function, it'll fire
// once the splash is completed.

export class Splash {
	constructor(times) {
		this._times = times;
	}

	run() {
		this._previousTime = window.performance.now();

		for (let time of this._times) {
			time.start();
		}

		this._update();
	}

	_update() {
		let now = window.performance.now(),
			delta = Math.min(now - this._previousTime, 100);
		this._previousTime = now;

		for (let time of this._times) {
			time.update(delta);
		}

		requestAnimationFrame(this._update.bind(this));
	}
}

// Creates a splash instace from an array of objects.
//
// Example:
// ```
// from([
//     {
//         delay: 1, in: 0.5, out: 0.5,
//         effects: [new GrowAndShrink(element)]
//     },
//     {
//         delay: 2, in: 1, stay: 0.2, out: 1
//         effects: [new FadeInAndOut(element)]
//     }
// ]);
// ```
// (Yes, I am aware that this would be pointless to do, but whatever)
export function splashFromArray(array) {
	let splashTimers = [];
	for (let time of array) {
		splashTimers.push(new SplashTimer(
			time.delay || 0,
			time.effects,
			{
				open: time.in || 0,
				stay: time.stay || 0,
				out: time.out || 0
			}
		));
	}
	return new Splash(splashTimers);
}

// Creates a splash timer object. Used for timing all the effects.
//
// delay: How much should this timer be delayed after the splash was started (seconds)
// effects: [Array<SplashEffect>] What effects to use
// parts: {
//     open: [Float] How long opening does this timer have (seconds)
//     stay: [Float] How long does it stay (the middle part) (seconds)
//     out: [Float] How long does it take it to end (seconds)
// }
//
// If one of the parts isn't present, a value of 0 seconds will be assumed.

export class SplashTimer {
	constructor(delay, effects, parts) {
		this.delay = delay;
		this.effects = effects;
		this.parts = {
			open: parts.open || 0,
			stay: parts.stay || 0,
			out: parts.out || 0
		}
	}

	update(delta) {
		this.seconds += delta / 1000;

		if (this.started) {
			if (this.seconds <= this._times[0]) {
				let value = this.seconds / this.parts.open;
				this._runEffect("in", value);
			} else if (this.seconds <= this._times[1]) {
				if (this._count == 0) {
					this._runEffect("in", 1);
					this._count = 1;
				}

				let value = (this.seconds - this._times[0]) / this.parts.stay;
				this._runEffect("stay", value);
			} else if (this.seconds <= this._times[2]) {
				if (this._count == 1) {
					this._runEffect("stay", 1);
					this._count = 2;
				}

				let value = (this.seconds - this._times[1]) / this.parts.out;
				this._runEffect("out", value);
			} else if (this._count < 3) {
				switch (this._count) {
					case 0: this._runEffect("in", 1); break;
					case 1: this._runEffect("stay", 1); break;
					case 2: this._runEffect("out", 1); break;
				}
				this._count = 3;
			}
		} else {
			this._runEffect("in", 0);

			if (this.seconds >= this.delay) {
				this.seconds = 0;
				this.started = true;
			}
		}
	}

	_runEffect(stage, value) {
		for (let effect of this.effects) {
			if (typeof effect[stage] == "function") effect[stage](value);
		}
	}

	start() {
		this.seconds = 0;
		this._times = [
			this.parts.open,
			this.parts.open + this.parts.stay,
			this.parts.open + this.parts.stay + this.parts.out
		];
		this._count = 0;
	}
}

import * as effects from "./effects";
import * as interpolation from "./interpolation.js";

export { effects };
export { interpolation };

@@ -1,16 +1,91 @@
+const ANIMATING_IN = 1,%0A%09PAUSING = 2,%0A%09ANIMATING_OUT = 3,%0A%09AFTER_END = 4;%0A%0A
 // Creates the m
@@ -2454,18 +2454,29 @@
 is._
-count == 0
+state == ANIMATING_IN
 ) %7B%0A
@@ -2521,17 +2521,23 @@
 is._
-count = 1
+state = PAUSING
 ;%0A%09%09
@@ -2710,18 +2710,24 @@
 is._
-count == 1
+state == PAUSING
 ) %7B%0A
@@ -2774,17 +2774,29 @@
 is._
-count = 2
+state = ANIMATING_OUT
 ;%0A%09%09
@@ -2925,17 +2925,25 @@
 is._
-count %3C 3
+state %3C AFTER_END
 ) %7B%0A
@@ -2960,21 +2960,21 @@
  (this._
-count
+state
 ) %7B%0A%09%09%09%09
@@ -2979,17 +2979,28 @@
 %09%09%09case 
-0
+ANIMATING_IN
 : this._
@@ -3036,17 +3036,23 @@
 %09%09%09case 
-1
+PAUSING
 : this._
@@ -3090,17 +3090,29 @@
 %09%09%09case 
-2
+ANIMATING_OUT
 : this._
@@ -3159,17 +3159,25 @@
 is._
-count = 3
+state = AFTER_END
 ;%0A%09%09
@@ -3633,17 +3633,28 @@
 is._
-count = 0
+state = ANIMATING_IN
 ;%0A%09%7D

Clear up state changes