package net.mgsx.game.examples.openworld.systems;

import com.badlogic.ashley.core.EntitySystem;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.math.CatmullRomSpline;
import com.badlogic.gdx.math.Vector3;

import net.mgsx.game.core.GamePipeline;
import net.mgsx.game.core.annotations.Editable;
import net.mgsx.game.core.annotations.EditableSystem;
import net.mgsx.game.core.annotations.Inject;
import net.mgsx.game.core.annotations.Storable;
import net.mgsx.game.examples.openworld.model.OpenWorldPathBuilder;

@Storable("ow.camera.path")
@EditableSystem
public class OpenWorldCameraPathSystem extends EntitySystem
{
	@Inject OpenWorldGeneratorSystem generator;
	@Inject OpenWorldCameraSystem cameraSystem;
	
	@Editable public float speed = 0.1f;
	@Editable public float distance = 5f;
	@Editable public float offsetMin = 10f;
	@Editable public float offsetRange = 5f;
	
	CatmullRomSpline<Vector3> spline = new CatmullRomSpline<Vector3>();
	Vector3 [] controlPoints;
	float time = 0;

	private float splineLength;
	
	private OpenWorldPathBuilder pathBuilder = new OpenWorldPathBuilder();
	
	public OpenWorldCameraPathSystem() {
		super(GamePipeline.BEFORE_INPUT); // actually before other camera
	}
	
	@Override
	public void update(float deltaTime) 
	{
		Camera camera = cameraSystem.getCamera();
		if(camera == null) return;
		
		if(controlPoints != null) time += deltaTime * speed / splineLength;
		
		if(time > 1 || controlPoints == null)
		{
			pathBuilder.set(generator, 30, distance, 1);
			pathBuilder.resetLimit().groundMin(offsetMin).groundMax(offsetMin + offsetRange);
			
			if(controlPoints == null){
				controlPoints = new Vector3[4];
				
				pathBuilder.createPath(controlPoints, camera.position);
				
			}else{
				
				pathBuilder.updateDynamicPath(controlPoints);
				
				time -= 1;
			}
			spline.set(controlPoints, false);
			splineLength = spline.approxLength(100); // TODO precision
		}
		
		
		spline.valueAt(camera.position, time);
		
		camera.update(); // TODO maybe not necessary ...
	}
}

@@ -174,24 +174,64 @@
 lRomSpline;%0A
+import com.badlogic.gdx.math.MathUtils;%0A
 import com.b
@@ -1428,21 +1428,31 @@
 aTime * 
+Math.abs(
 speed
+)
  / splin
@@ -1459,16 +1459,34 @@
 eLength;
+ // avoid negative
 %0A%09%09%0A%09%09if
@@ -1994,16 +1994,94 @@
 %0A%09%09%7D%0A%09%09%0A
+%09%09// quick fix in case of too much time%0A%09%09time = MathUtils.clamp(time, 0, 1);%0A
 %09%09%0A%09%09spl

fix path over/under flow