
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Reflection.Emit;

namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class AnimateTextureAttributeChannel:SequenceAction, Animator
  {
    [Export]
    public TextureAttributes textureAttributes;

    [Export]
    public int index = 0;

    [Export]
    public Curve animationCurve;

    [Export]
    public Duration duration;

    [Export]
    public TextureAttributes.Channel channel = TextureAttributes.Channel.Red;

    [Export]
    public TextureAttributes.OperatorType operatorType = TextureAttributes.OperatorType.Set;

    
    [Export]
    public bool interruptCurrent = true;

    public void OnAnimatorStart(){}
    public void OnAnimatorEnd(){}
    public void OnAnimatorCancel(){}

    bool _running = false;

    protected override void _OnTrigger()
    {
      if ( ! interruptCurrent && _running )
      {
        return;
      }

      var ta = textureAttributes;

      if ( ta == null )
      {
        ta = Unique<TextureAttributes>.Get();
      }

      if ( ta == null )
      {
        this.LogInfo( "No attributes found..." );
        return;
      }

      var actionID = DispatchStart(); 

      _running = true;  

      var animationTimeLine = TimeLineManager.Ensure( duration.timeLine );
      var start = animationTimeLine.position;

      AnimationManager.StartAnimation( this, textureAttributes, channel + "" );
      

      TimeLineManager.ScheduleSpanIn( animationTimeLine, 0, duration.GetDurationInSeconds(), 
        ( span, type )=>
        {         
          if ( actionID == -1 )
          {
            return;
          }

          if ( ! IsInstanceValid( textureAttributes ) )
          {
            DispatchCancelled( actionID );
            actionID = -1;
            _running = false;
            return;
          }

          var timeNow = animationTimeLine.position;
          var elapsed = timeNow - start;

          // var index = 0;

          var value = animationCurve.Sample( span.phase );

          
          if ( AnimationManager.IsAnimating( this, textureAttributes, channel + "" ) )
          {
            // this.LogInfo( "Index", index, "Value:", value, "Channel:", channel, "Operator:", operatorType );
            ta.SetChannel( index, value, channel, operatorType );
          }
          

          if ( type == TimeLineSpanUpdateType.End )
          {
            AnimationManager.EndAnimation( this, textureAttributes, channel + "" );            

            DispatchEnd( actionID );
            _running = false;
          }
        },
        this
      );

    }
  }
}