using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRTK;

public class VRTK_ControllerEvents_Listener_Deforming : MonoBehaviour {

    

    [SerializeField]
    private DeformationManager _deformationManager;

    public enum EventQuickSelect
    {
        Custom,
        None,
        All,
        ButtonOnly,
        AxisOnly,
        SenseAxisOnly
    }

    [Header("Quick Select")]

    public EventQuickSelect quickSelect = EventQuickSelect.All;

    [Header("Button Events Debug")]

    public bool triggerButtonEvents = true;
    public bool gripButtonEvents = true;
    public bool touchpadButtonEvents = true;
    public bool buttonOneButtonEvents = true;
    public bool buttonTwoButtonEvents = true;
    public bool startMenuButtonEvents = true;

    [Header("Axis Events Debug")]

    public bool triggerAxisEvents = true;
    public bool gripAxisEvents = true;
    public bool touchpadAxisEvents = true;
    public bool touchpadTwoAxisEvents = true;

    [Header("Sense Axis Events Debug")]

    public bool triggerSenseAxisEvents = true;
    public bool touchpadSenseAxisEvents = true;
    public bool middleFingerSenseAxisEvents = true;
    public bool ringFingerSenseAxisEvents = true;
    public bool pinkyFingerSenseAxisEvents = true;

    private VRTK_ControllerEvents controllerEvents;

    private void Start()
    {
        controllerEvents = GetComponent<VRTK_ControllerEvents>();
        if (controllerEvents == null)
        {
            VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_GAMEOBJECT, "VRTK_ControllerEvents_ListenerExample", "VRTK_ControllerEvents", "the same"));
            return;
        }
        controllerEvents.TouchpadPressed += DisableDeformationControls;
        controllerEvents.GripPressed += DisableDeformationControls;

        controllerEvents.TouchpadReleased += EnableDeformationControls;
        controllerEvents.GripReleased += EnableDeformationControls;

    }

    [ContextMenu("Swap controllers")]
    public void SwapControllerEvents()
    {
        controllerEvents.SetControllerEvent();
    }

    private void OnEnable()
    {
        controllerEvents = GetComponent<VRTK_ControllerEvents>();
        if (controllerEvents == null)
        {
            VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.REQUIRED_COMPONENT_MISSING_FROM_GAMEOBJECT, "VRTK_ControllerEvents_ListenerExample", "VRTK_ControllerEvents", "the same"));
            return;
        }

        //Setup controller event listeners
        controllerEvents.TriggerPressed += DoTriggerPressed;
        controllerEvents.TriggerPressed += DoStartDeformation;
        controllerEvents.TriggerReleased += DoTriggerReleased;
        controllerEvents.TriggerReleased += DoStopDeformation;

        
    }

    private void OnDisable()
    {
        if (controllerEvents != null)
        {
            controllerEvents.TriggerPressed -= DoTriggerPressed;
            controllerEvents.TriggerPressed -= DoStartDeformation;
            controllerEvents.TriggerReleased -= DoTriggerReleased;
            controllerEvents.TriggerReleased -= DoStopDeformation;


        }
    }

    private void LateUpdate()
    {
        switch (quickSelect)
        {
            case EventQuickSelect.None:
                triggerButtonEvents = false;
                gripButtonEvents = false;
                touchpadButtonEvents = false;
                buttonOneButtonEvents = false;
                buttonTwoButtonEvents = false;
                startMenuButtonEvents = false;

                triggerAxisEvents = false;
                gripAxisEvents = false;
                touchpadAxisEvents = false;
                touchpadTwoAxisEvents = false;

                triggerSenseAxisEvents = false;
                touchpadSenseAxisEvents = false;
                middleFingerSenseAxisEvents = false;
                ringFingerSenseAxisEvents = false;
                pinkyFingerSenseAxisEvents = false;
                break;
            case EventQuickSelect.All:
                triggerButtonEvents = true;
                gripButtonEvents = true;
                touchpadButtonEvents = true;
                buttonOneButtonEvents = true;
                buttonTwoButtonEvents = true;
                startMenuButtonEvents = true;

                triggerAxisEvents = true;
                gripAxisEvents = true;
                touchpadAxisEvents = true;
                touchpadTwoAxisEvents = true;

                triggerSenseAxisEvents = true;
                touchpadSenseAxisEvents = true;
                middleFingerSenseAxisEvents = true;
                ringFingerSenseAxisEvents = true;
                pinkyFingerSenseAxisEvents = true;
                break;
            case EventQuickSelect.ButtonOnly:
                triggerButtonEvents = true;
                gripButtonEvents = true;
                touchpadButtonEvents = true;
                buttonOneButtonEvents = true;
                buttonTwoButtonEvents = true;
                startMenuButtonEvents = true;

                triggerAxisEvents = false;
                gripAxisEvents = false;
                touchpadAxisEvents = false;
                touchpadTwoAxisEvents = false;

                triggerSenseAxisEvents = false;
                touchpadSenseAxisEvents = false;
                middleFingerSenseAxisEvents = false;
                ringFingerSenseAxisEvents = false;
                pinkyFingerSenseAxisEvents = false;
                break;
            case EventQuickSelect.AxisOnly:
                triggerButtonEvents = false;
                gripButtonEvents = false;
                touchpadButtonEvents = false;
                buttonOneButtonEvents = false;
                buttonTwoButtonEvents = false;
                startMenuButtonEvents = false;

                triggerAxisEvents = true;
                gripAxisEvents = true;
                touchpadAxisEvents = true;
                touchpadTwoAxisEvents = true;

                triggerSenseAxisEvents = false;
                touchpadSenseAxisEvents = false;
                middleFingerSenseAxisEvents = false;
                ringFingerSenseAxisEvents = false;
                pinkyFingerSenseAxisEvents = false;
                break;
            case EventQuickSelect.SenseAxisOnly:
                triggerButtonEvents = false;
                gripButtonEvents = false;
                touchpadButtonEvents = false;
                buttonOneButtonEvents = false;
                buttonTwoButtonEvents = false;
                startMenuButtonEvents = false;

                triggerAxisEvents = false;
                gripAxisEvents = false;
                touchpadAxisEvents = false;
                touchpadTwoAxisEvents = false;

                triggerSenseAxisEvents = true;
                touchpadSenseAxisEvents = true;
                middleFingerSenseAxisEvents = true;
                ringFingerSenseAxisEvents = true;
                pinkyFingerSenseAxisEvents = true;
                break;
        }
    }

    private void DebugLogger(uint index, string button, string action, ControllerInteractionEventArgs e)
    {
        string debugString = "Controller on index '" + index + "' " + button + " has been " + action
                             + " with a pressure of " + e.buttonPressure + " / Primary Touchpad axis at: " + e.touchpadAxis + " (" + e.touchpadAngle + " degrees)" + " / Secondary Touchpad axis at: " + e.touchpadTwoAxis + " (" + e.touchpadTwoAngle + " degrees)";
        VRTK_Logger.Info(debugString);
    }

    private void DoTriggerPressed(object sender, ControllerInteractionEventArgs e)
    {
        if (triggerButtonEvents)
        {
            DebugLogger(VRTK_ControllerReference.GetRealIndex(e.controllerReference), "TRIGGER", "pressed", e);
        }
    }

    private void DoTriggerReleased(object sender, ControllerInteractionEventArgs e)
    {
        if (triggerButtonEvents)
        {
            DebugLogger(VRTK_ControllerReference.GetRealIndex(e.controllerReference), "TRIGGER", "released", e);
        }
    }

    private void DoStartDeformation(object sender, ControllerInteractionEventArgs e)
    {
        _deformationManager.StartDeforming();
    }

    private void DoStopDeformation(object sender, ControllerInteractionEventArgs e)
    {
        _deformationManager.StopDeforming();
    }


    private void Update()
    {
        if (Mathf.Abs(controllerEvents.GetTouchpadAxis().x) > Mathf.Abs(controllerEvents.GetTouchpadAxis().y))
        {
            ChangeIntensity();
        }
        else
        {
            ChangeAOE();
        }

    }

    
    private void ChangeIntensity()
    {
        float amount = controllerEvents.GetTouchpadAxis().x * 0.5f * Time.deltaTime;
        if (amount != 0)
        {
            _deformationManager.CurrentIntensity = (_deformationManager.CurrentIntensity + amount);
        }
    }

    private void ChangeAOE()
    {
        float amount = controllerEvents.GetTouchpadAxis().y * 0.2f * Time.deltaTime;
        if (amount != 0)
        {
            _deformationManager.AreaOfEffect = (_deformationManager.AreaOfEffect + amount);
        }
    }
    
    private void EnableDeformationControls(object sender, ControllerInteractionEventArgs e)
    {
        enabled = true;
    }

    private void DisableDeformationControls(object sender, ControllerInteractionEventArgs e)
    {
        _deformationManager.StopDeforming();
        enabled = false;
    }

}
