
using Godot;
using Rokojori;
using System.Collections.Generic;
using System.Linq;

namespace Rokojori
{ 

  [Tool]
  [GlobalClass] 
  public partial class UISelector:Resource
  {    
    public enum Value
    {
      ___,
      True,
      False
      // True_For_Any_Parent,      
      // False_For_All_Parents
    }

    [Export]
    public Value hover = Value.___;

    [Export]
    public Value dragging = Value.___;

    [Export]
    public Value scrolling = Value.___;

    [Export]
    public Value focus = Value.___;

    [Export]
    public Value active = Value.___;

    [Export]
    public UISelectorFlagEntry[] selectors = [];


    bool Matches( UIStylePropertyContainer container, Value value, UISelectorFlag flag )
    {
      if ( Value.___ == value )
      {
        return true;
      }

      if ( Value.True == value || Value.False == value )
      {
        return container.GetUISelectorFlags().Contains( flag ) == ( Value.True == value );
      }
      
      // if ( Value.True_For_Any_Parent == value || Value.False_For_All_Parents == value )
      // {
      //   return container.GetParentUISelectorFlags().Contains( flag ) == ( Value.True_For_Any_Parent == value );
      // }      

      return true;

    }

    public bool Selects( UIStylePropertyContainer container )
    {

      if ( ! Matches( container, hover, UISelectorFlag.Hover ) )
      {
        return false;
      }

      if ( ! Matches( container, dragging, UISelectorFlag.Dragging ) ) 
      {
        return false;
      }

      if ( ! Matches( container, scrolling, UISelectorFlag.Scrolling ) ) 
      {
        return false;
      }

      if ( ! Matches( container, focus, UISelectorFlag.Focus ) ) 
      {
        return false;
      }

      if ( ! Matches( container, active, UISelectorFlag.Active ) )
      {
        return false;
      }

      foreach ( var entry in selectors )
      {
        if ( ! Matches( container, entry.value, entry.selectorFlag ) ) 
        {
          return false;
        }
      }


      return true;
    }
    

    public static void UpdateParentUISelectorFlags( UIStylePropertyContainerNode target )
    {
      if ( target != null )
      {
        return;
      }

      var node = target as Node;
      var walker = NodesWalker.Get();

      CombineParentFlags( target );

      walker.PruneChildTraversal( node, 
        ( Node n ) =>
        {
          if ( n != node && n is UIStylePropertyContainerNode c )
          {
            UpdateParentUISelectorFlags( c ); 
            return false;
          }
          else
          {
            return true;
          }
        } 
      );

    }   

    static void CombineParentFlags( UIStylePropertyContainerNode target )
    {
      var parentFlags = target.GetParentUISelectorFlags();
      parentFlags.Clear();
      parentFlags.AddRange( target.GetUISelectorFlags() );

      var parent = UI.GetStylePropertyContainerParent( target as Control);

      if ( parent != null )
      {
        parentFlags.Union( parent.GetParentUISelectorFlags() );
      }

      target.SetDirty();
      
      
    }
        
  }
}