using System.Collections;
using System.Collections.Generic;
using Godot;

namespace Rokojori
{
	public partial class Smoothing: Resource
	{
    float _currentFloat = 0;
    Vector2 _currentVector2 = Vector2.Zero;
    Vector3 _currentVector3 = Vector3.Zero;
    Vector4 _currentVector4 = Vector4.Zero;
    Quaternion _currentQuaternion = Quaternion.Identity;
    Color _currentColor = Colors.Black;


    public float Smooth( float nextValue, float delta )
    {
      _currentFloat = Mathf.Lerp( _currentFloat, nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentFloat;
    }

    public static float Apply( Smoothing sm, float value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    public Vector2 Smooth( Vector2 nextValue, float delta )
    {
      _currentVector2 = _currentVector2.Lerp( nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentVector2;
    }

    public static Vector2 Apply( Smoothing sm, Vector2 value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    public Vector3 Smooth( Vector3 nextValue, float delta )
    {
      _currentVector3 = _currentVector3.Lerp( nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentVector3;
    }

    public static Vector3 Apply( Smoothing sm, Vector3 value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    public Vector4 Smooth( Vector4 nextValue, float delta )
    {
      _currentVector4 = _currentVector4.Lerp( nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentVector4;
    }

    public static Vector4 Apply( Smoothing sm, Vector4 value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    public Quaternion Smooth( Quaternion nextValue, float delta )
    {
      _currentQuaternion = _currentQuaternion.Slerp( nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentQuaternion;
    }

    public static Quaternion Apply( Smoothing sm, Quaternion value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    public Color Smooth( Color nextValue, float delta )
    {
      _currentColor = _currentColor.Lerp( nextValue, _ComputeInterpolationAmount( delta ) ); 

      return _currentColor;
    }

    public static Color Apply( Smoothing sm, Color value, float delta )
    {
      if ( sm == null ){ return value; }
      return sm.Smooth( value, delta );
    }

    protected virtual float _ComputeInterpolationAmount( float delta )
    {
      return 0;
    }

    public virtual float ComputeDuration( float delta = 1f/480f, float tresholdValue = 0.01f )
    {
      var cached = _currentFloat;      

      var value = 1f; 
      _currentFloat = 1f;

      var duration = 0f;
      var lastValue = value;
      
      var maxDuration = 30;

      while ( value > tresholdValue && duration < maxDuration )
      {
        lastValue = value;
        value = Smooth( 0, delta );

        duration += delta;

      }

      _currentFloat = cached;

      return MathX.RemapClamped( tresholdValue, lastValue, value, duration - delta, duration ); 

    }
  }
}