using Cryville.Common.Math;
using System;
using UnityEngine;

namespace Cryville.Crtr.Event {
	public class GroupHandler : TransformHandler {
		protected override TransformHandler Parent { get { return _ch; } }
		public ChartHandler _ch;

		ColumnVector<float> coeffs;
		SquareMatrix matFrame;
		ContainerState[] tracks;

		public GroupHandler(Chart.Group tg, ChartHandler ch) : base() {
			_ch = ch;
		}
		
		public override string TypeName { get { return "group"; } }

		public override void PreInit() {
			base.PreInit();
			tracks = cs.TypedChildren[typeof(Chart.Track)].ToArray();
			int numTracks = tracks.Length;
			coeffs = new ColumnVector<float>(numTracks);
			matFrame = SquareMatrix.WithPolynomialCoefficients(numTracks);
			frame1 = new ColumnVector<Vector3>(numTracks);
			frame2 = new ColumnVector<Vector3>(numTracks);
		}

		ColumnVector<Vector3> frame1;
		ColumnVector<Vector3> frame2;
		public Vector3 GetCurrentFrame(Func<ContainerState, Vector3> func, float track) {
			for (int i = 0; i < tracks.Length; i++)
				frame1[i] = func(tracks[i]);
			matFrame.Eliminate(frame1, frame2, Vector3Operator.Instance);
			ColumnVector<float>.FillWithPolynomialCoefficients(coeffs, track);
			return frame2.Dot(coeffs, Vector3Operator.Instance);
		}
	}

	class Vector3Operator : IVectorOperator<Vector3> {
		public static Vector3Operator Instance = new Vector3Operator();

		public Vector3 Add(Vector3 lhs, Vector3 rhs) {
			return lhs + rhs;
		}

		public Vector3 ScalarMultiply(float lhs, Vector3 rhs) {
			return lhs * rhs;
		}
	}
}
