
using Godot;
using System.Collections.Generic;

namespace Rokojori
{
  [Tool]
  [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/MouseSensor.svg")]
  public partial class MouseButtonSensor : Sensor, iOnInputSensor
  {
    [Export]
    public MouseButton button;

    [ExportGroup( "Modifiers")]
    [Export] 
    public Trillean ctrlHold = Trillean.Any;

    [Export]
    public Trillean altHold = Trillean.Any;

    [Export]
    public Trillean shiftHold = Trillean.Any;

    public bool modifiersEnabled => ! TrilleanLogic.AllAny( ctrlHold, altHold, shiftHold );

    public enum ModifiersMode
    {
      Hold_Modifiers_Only_On_Down,
      Hold_Modifiers_All_The_Time
    }

    [Export]
    public ModifiersMode modifiersMode;
    
    float _lastInput = 0;

    public override string ToString()
    {
      return RJLog.GetInfo( this, button, "Ctrl/Alt/Shift:" + ctrlHold + "/" + altHold + "/" + shiftHold );
    }

  
    bool IsWheel()
    {
      return button == MouseButton.WheelUp || button == MouseButton.WheelDown;      
    }

    protected override void UpdateValue()
    {
      
      SetFloatValue( _lastInput );

      if ( IsWheel() )
      {
        _lastInput = 0;
      }
      
            
    }

    public void _Input( InputEvent ev )
    {
      
      var mouseEvent = ev as InputEventMouseButton;

      if ( mouseEvent == null )
      {
        return;
      }       

      if ( mouseEvent.ButtonIndex != button )
      {
        return;
      }

      var checkModifiers = modifiersEnabled && 
                           ( 
                            ModifiersMode.Hold_Modifiers_All_The_Time == modifiersMode ||
                           _lastInput == 0 && ModifiersMode.Hold_Modifiers_Only_On_Down == modifiersMode 
                           );

      if ( checkModifiers )
      {

        if ( ! TrilleanLogic.Matches( ctrlHold, mouseEvent.CtrlPressed ) )
        {
          _lastInput = 0; 
          return;
        }

        if ( ! TrilleanLogic.Matches( altHold, mouseEvent.AltPressed ) )
        {
          _lastInput = 0;
          return;
        }

        if ( ! TrilleanLogic.Matches( shiftHold, mouseEvent.ShiftPressed ) )
        {
          _lastInput = 0;
          return;
        }
      }

      var isActive = mouseEvent.IsPressed();

      if ( IsWheel() && ! isActive )
      {
        return;
      }

      _lastInput = isActive ? 1 : 0; 

      UpdateSensorUsage();
  
    }

    public override List<InputIcon> GetInputIcons()
    {
      var icon = new MouseInputIcon();
      icon.button = button;

      return new List<InputIcon>(){ icon };
    }

        
  }
}