using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using Godot;

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class AnimationCurve3D:Resource
  { 
    [Export]
    public float duration = 1;

    [Export]
    public float durationRandomRange = 0;
    
    [Export]
    public float delay = 0;

    [Export]
    public float delayRandomRange = 0;


    [Export]
    public Curve xCurve = MathX.Curve( 0, 0, -1, 1 );

    [Export]
    public Curve yCurve = MathX.Curve( 0, 0, -1, 1 );

    [Export]
    public Curve zCurve = MathX.Curve( 0, 0, -1, 1 );
    

    [Export]
    public float scaleAll = 1;

    [Export]
    public float scaleAllRandomRange = 0;

    public float GetRandomizedDuration( Vector3 random )
    {
      return duration + random.X;
    }

    public float GetRandomizedDelay( Vector3 random )
    {
      return delay + random.Y;
    }

    public float GetRandomizedEndTime( Vector3 random )
    {
      return GetRandomizedDuration( random ) + GetRandomizedDelay( random );
    }

    public float GetRandomizedScale( Vector3 random )
    {
      return scaleAll + random.Z;
    }

    public Vector3 Randomize( RandomEngine random = null )
    {
      random = random == null ? GodotRandom.Get() : random;

      return new Vector3( 
        random.Polar() * durationRandomRange,  
        random.Polar() * delayRandomRange,  
        random.Polar() * scaleAllRandomRange
      );

    }
    
    public Vector3 Sample( float time, float durationOffset = 0, float delayOffset = 0, float scaleOffset = 0 )
    {
      time -= Mathf.Max( 0f, delay + delayOffset );
      var phase = MathX.Clamp01( time / ( Mathf.Max( 0.001f, duration + durationOffset ) ) );

      
      var x = xCurve.Sample( phase ) * ( scaleAll + scaleOffset );
      var y = yCurve.Sample( phase ) * ( scaleAll + scaleOffset );
      var z = zCurve.Sample( phase ) * ( scaleAll + scaleOffset );

      return new Vector3( x, y, z );
    }

    public Vector3 Sample( float time, Vector3 randomization )
    {
      return Sample( time, randomization.X, randomization.Y, randomization.Z );
    }
  }
  
}