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

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class AnimateTransform:SequenceAction, Animator
  { 

    [Export]
    public TransformAnimations animations;

    [Export]
    public Node3D target;

    [Export]
    public bool interruptCurrent = true;

    List<Vector3> _frameValues;
    List<Vector3> _randomizations;

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

    bool _running = false;

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

      _frameValues = new List<Vector3>();
      _randomizations = new List<Vector3>();

      foreach ( var curve in animations.curves )
      {
        _frameValues.Add( TransformTargets.Get( target, curve.transformTarget ) );
        _randomizations.Add( curve.Randomize() );
      }

      var timeline = animations.timeline;
      var duration = animations.GetMaxDuration( _randomizations );

      var start = timeline.position;
      var end   = start + animations.GetMaxDuration( _randomizations );
       
      var actionID = DispatchStart(); 

      _running = true;

      foreach ( var c in animations.curves )
      {
        AnimationManager.StartAnimation( c, target, c.animationMember );
      }
      
      TimeLineManager.ScheduleSpanIn( timeline, 0, duration, 
        ( span, type )=>
        {         
          if ( actionID == -1 )
          {
            return;
          }

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

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

          var index = 0;

          foreach ( var c in animations.curves )
          {
            if ( AnimationManager.IsAnimating( c, target, c.animationMember ) )
            {
              c.Apply( elapsed, target, _randomizations[ index ], _frameValues[ index ] );
            }

            index ++;
          }

          if ( type == TimeLineSpanUpdateType.End )
          {
            foreach ( var c in animations.curves )
            {
              AnimationManager.EndAnimation( c, target, c.animationMember );
            }

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

      
    } 

    

    
  }
}