
using Godot;
using Rokojori;
 
namespace Rokojori
{ 
  public enum UIColorAnimationBlend
  {
    Multiply,
    Add,
    Replace
  }

  [Tool]
  [GlobalClass] 
  public partial class UIColor : Resource
  { 
    [Export]
    public Color color = Colors.White;

    [Export]
    public bool isAnimated = false;

    [Export]
    public Gradient animationGradient;

    [Export]
    public ColorBlendModeType blendMode = ColorBlendModeType.Multiply;

    [Export]
    public float animationDuration = 1;

    [Export]
    public float animationOffset = 0;

    [Export]
    public TimeLine timeLine;

    public static Color Compute( Control control, UIStyleColorProperty property, Color defaultColor )
    {
      var container = control as UIStylePropertyContainer;
      var transition = UIStyle.GetTransition( container, property );

      var uiColor = UIStyle.GetUIColorProperty( control as UIStylePropertyContainer, property );
      var computedColor = Compute( control, uiColor, defaultColor );    

      var allSettings = UIStyle.GetTransitionSettingsAll( container );

      var usesTransition = transition != null || allSettings != null && allSettings.transitionAllProperties;

      if ( ! usesTransition )
      {
        return computedColor; 
      }     

      var activeNumberTransitions = container.GetActiveUIColorTransitions();

      var propertyTransition = activeNumberTransitions.Find( t => t != null && t.propertyType == property );

      if ( propertyTransition == null )
      {
        propertyTransition = new ActiveStyleTransition<UIColor, UIStyleColorProperty>();
        propertyTransition.propertyType = property;
        propertyTransition.value = uiColor;         
        propertyTransition.transitioning = false;

        activeNumberTransitions.Add( propertyTransition );

        return computedColor;
      } 
      else
      {

        if ( propertyTransition.value != uiColor && ! propertyTransition.transitioning && UIStyle.GetTransitionSettings( container, property ) != null)
        {
          var transitionSettings = UIStyle.GetTransitionSettings( container, property );
          propertyTransition.timeLine = transitionSettings.timeLine;       
          propertyTransition.start = transitionSettings.timeLine.position;
          propertyTransition.end = propertyTransition.start + transitionSettings.duration;
          propertyTransition.transitioning = true;          
          propertyTransition.curve = transitionSettings.curve;
        }
      }

      if ( propertyTransition.value == uiColor )
      {
        propertyTransition.transitioning = false;
        return computedColor;
      }

      var computedTransitionValue = Compute( control, propertyTransition.value, defaultColor );    

      var transitionPhase = propertyTransition.timeLine.ComputeRange( propertyTransition.start, propertyTransition.end );
     
      if ( transitionPhase >= 1 )
      {
        activeNumberTransitions.Remove( propertyTransition );
      }

      var amount = MathX.Clamp01( transitionPhase );
      var curveAmount = amount;

      if ( propertyTransition.curve != null )
      {
        curveAmount = propertyTransition.curve.Sample( curveAmount );
      }

      return ColorX.Lerp( computedTransitionValue, computedColor, curveAmount );
    }

    public static Color Compute( Control control, UIColor color, Color defaultColor )
    {
      if ( color == null )
      {
        return defaultColor;
      }

      if ( ! color.isAnimated || color.animationGradient == null )
      {
        return color.color;
      }

      // var phase = TimeLineManager.GetPhase( color.timeLine, color.animationDuration, color.animationOffset );
      var phase = color.timeLine.ComputePhase( color.animationDuration, color.animationOffset );

      var gradientColor = color.animationGradient.Sample( phase );

      return ColorBlendMode.Blend( color.blendMode, color.color, gradientColor );

    }

  }
}