using Cinemachine.Utility;
using UnityEngine;
//using static UnityEditor.PlayerSettings;
using UnityEngine.InputSystem;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using System.Collections;
using UnityEngine.Events;
using Unity.VisualScripting;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.UI;
using Cinemachine;
using static UnityEngine.AudioSettings;
using System;

// NOTE: Unified Input System
// Animation triggers are now handled exclusively by InputToAnimation.
// Legacy OnXxx() input handlers in this class are intentionally no-ops to avoid duplicate triggers.
// If you need to fire an animation from code, prefer:
//    GetComponent<InputToAnimation>().TriggerAnimation(AnimationNames.Jab);
// or route via CharacterAttacks for gameplay logic.
[AddComponentMenu("")] // Don't display in add component menu

public class PlayerScript : MonoBehaviour
{

    //Player ID
    private int playerID;

    [Header("Sub Behaviours")]
    public PlayerVisualsBehaviour playerVisualsBehaviour;

    //jump system variables
    static bool jump;
    public GroundCheck groundCheck;
    public FallCheck fallCheck;
    static float jumpForce = 20;

    public GameObject player;
    public GameObject enemy;

    public float distance;
    private AnimatorClipInfo[] m_CurrentClipInfo;
    private float m_CurrentClipLength;
    private string m_ClipName;
    public float nextAnimationTime;
    public float animationInterval;

    static Animator anim;

    public Vector2 input;
    private Camera mainCamera;

    //public EnemyScript enemyscript;
    private HealthNew health;


    public bool block;

    public CharacterAttacks playerAttacks;


    private AnimatorClipInfo[] playerclipinfo;

    // Reference to the currently held item.
    private PickableItem[] pickedItem;

    // Reference to the slot for holding picked item.
    [SerializeField]
    private Transform pickingHands;
    public float pickingdistance;
    private PickableItem item;

    public bool helpless = false;

    static bool held;

    [Header("Input Settings")]
    public PlayerInput playerInput;

    private bool isInputActive = false;

    public bool attack;

    public bool dodge;
    public Transform headTransform;

    public InputBuffer inputBuffer;
    
    // TeamMember reference for control type checking
    private TeamMember _teamMember;

    // Add fields for vicious and special attacks
    private bool canPerformViciousAttack = true;
    private bool canPerformSpecialAttack = true;
    private float viciousAttackCooldown = 5.0f;
    private float specialAttackCooldown = 10.0f;
    private float lastViciousAttackTime = -5.0f;
    private float lastSpecialAttackTime = -10.0f;

    // Use this for initialization
    void Start()
    {
        anim = GetComponent<Animator>();
        mainCamera = Camera.main;
        player = GameObject.FindGameObjectWithTag("Player");
        enemy = GameObject.FindGameObjectWithTag("Enemy");
        animationInterval = 3.0f;
        block = false;
        dodge = false;
        //enemyscript = enemy.GetComponent<EnemyScript>();
        helpless = false;
        held = false;
        health = GetComponent<HealthNew>();
        attack = false;

        playerAttacks = GetComponent<CharacterAttacks>();
        inputBuffer = GetComponent<InputBuffer>();
        
        // Cache TeamMember for control type checking
        _teamMember = GetComponent<TeamMember>();
    }
    private void Update()
    {
        var pmn = GameObject.FindFirstObjectByType<PlayerManagerNew>();
        if (pmn != null && pmn.pause)
            return;

        // Update cooldowns for vicious and special attacks
        canPerformViciousAttack = (Time.time - lastViciousAttackTime >= viciousAttackCooldown);
        canPerformSpecialAttack = (Time.time - lastSpecialAttackTime >= specialAttackCooldown);
        
        // Decay the input value gradually when no input is received, decayrate = 1.0f        
        //input = Vector2.Lerp(input, Vector2.zero, Time.deltaTime * 1.0f);
        
        // Check if we should use mobile controls
        // Include editor platforms so we can test mobile controls in the editor
        bool isMobile = (UnityEngine.Application.platform == RuntimePlatform.Android ||
                         UnityEngine.Application.platform == RuntimePlatform.IPhonePlayer);
        
        // Also enable mobile input path in editor for testing
        bool isEditor = (UnityEngine.Application.platform == RuntimePlatform.LinuxEditor ||
                         UnityEngine.Application.platform == RuntimePlatform.WindowsEditor ||
                         UnityEngine.Application.platform == RuntimePlatform.OSXEditor);
        
        // Use mobile input path in editor OR on actual mobile devices
        if (isMobile || isEditor)
        {
            // Movement now comes from the Input System Move action (fed by MobileOnScreenStick)
            // No direct joystick lookup.
            if (!dodge && !block)
            {
                OnMoveMobile();
            }
            else if (dodge && !block)
            {
                // Use current input vector to determine dodge direction
                var dir = input;
                string joystickDir = GetDirection(dir);
                playerAttacks.DodgeMobile(joystickDir, dir);
            }
            else if (block && !dodge)
            {
                var dir = input;
                string joystickDir = GetDirection(dir);
                playerAttacks.BlockMobile(joystickDir);
            }
        }

    }

    public void OnMove(InputAction.CallbackContext context)
    {
        // CRITICAL: Only process input if this character is HumanControlled
        if (_teamMember != null && _teamMember.CurrentControlType != TeamMember.ControlType.HumanControlled)
        {
            return;
        }
        
        // NOTE: We always update the input vector here. The actual movement gating
        // (attack enabled, not blocking, not dodging) is handled in CharacterMovement.FixedUpdate.
        // We only gate the input reading by device assignment to prevent input cross-contamination.
        
        // Ensure input is from this player's assigned device(s). Allow synthetic devices (on-screen controls)
        // created by Unity's Input System so mobile UI can drive the player.
        var pi = GetComponent<PlayerInput>();
        if (pi != null && pi.devices.Count > 0)
        {
            var device = context.control?.device;
            if (device != null)
            {
                bool isAssignedDevice = false;
                for (int i = 0; i < pi.devices.Count; i++)
                {
                    if (pi.devices[i] == device)
                    {
                        isAssignedDevice = true;
                        break;
                    }
                }

                if (!isAssignedDevice && !device.synthetic)
                    return;
            }
        }

        // Read movement input - ALWAYS update this so CharacterMovement has latest input
        Vector2 rawInput = context.ReadValue<Vector2>();
        input = rawInput;

        // Set the input as active when there is input
        isInputActive = input.magnitude > 0.0f;

        /*//follow moving player
        GameObject camera = GameObject.Find("CinemachineCamera");
        var vcam = camera.GetComponent<CinemachineFreeLook>();
        if (vcam != null)
        {                
            Transform headTransform = transform;
            if (gameObject.name == "Cheetah")
            {
                //Transform firstTarget = targets[0].transform;
                headTransform = gameObject.transform.GetChild(9).GetChild(6).GetChild(1);
            }
            else if (gameObject.name == "Rabbit")
            {
                headTransform = gameObject.transform.GetChild(7).GetChild(6).GetChild(1);
            }


            if (headTransform != null)
            {
                //vcam.LookAt = vcam.Follow = GameObject.Find("DEF-spine.001").transform;
                vcam.LookAt = vcam.Follow = headTransform;
                //vcam.LookAt = vcam.Follow = GameObject.Find("BUILD-WALL").transform;
                vcam.m_Lens.FieldOfView = 43;
            }
        }*/
    }

    public void OnJab(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnHaymaker(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnSpinningBackfist(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnElbowSmash(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnChargePunch(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnAirPunch(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnDropKick(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    
    public void OnLowKick(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }

    public void OnPunch(InputAction.CallbackContext context)
    {
        // Legacy aggregate handler disabled. Animations are handled by InputToAnimation.
        return;
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        if (context.started)
        {
            Jump();
        }
    }
    public void OnKick(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }

    public void OnMoveMobile()
    {
        // Block camera updates only during blocking or dodging (NOT based on 'attack' permission flag)
        if (block == true || dodge == true)
            return;
        // Input is already filled by OnMove from the Input System (MobileOnScreenStick)
        // So we just use the current 'input' vector here.

        // Set the input as active when there is input
        isInputActive = input.magnitude > 0.0f;

        // Camera targeting is handled by CameraManager / SetupSingleCamera.
        // Do NOT override Follow/LookAt here every frame — it fights CinemachineBrain.
    }

    public void OnPunchMobileNew(float verticalValue, float horizontalValue, string punchDirection)
    {
        // Legacy mobile trigger disabled. Animations are handled by InputToAnimation.
        return;
    }

    public void OnKickMobileNew(float verticalValue, float horizontalValue, string kickDirection)
    {
        // Legacy mobile trigger disabled. Animations are handled by InputToAnimation.
        return;
    }

    public void OnLook(InputAction.CallbackContext context)
    {
        if (context.started)
        {
            Look();
        }
    }
    public void OnSprint(InputAction.CallbackContext context)
    {
        //print("is sprinting controls " + context.control);
        // held = !held;
        if (context.performed)
        {
            anim.SetBool("isSprinting", true);
        }
        else if (context.canceled)
        {
            anim.SetBool("isSprinting", false);
        }
    }
    public void OnStrike(InputAction.CallbackContext context)
    {
        // Legacy direct trigger disabled. Animations are handled by InputToAnimation.
        return;
    }
    //This is called from Player Input, when a button has been pushed, that correspons with the 'TogglePause' action
    public void OnTogglePause(InputAction.CallbackContext value)
    {
        if (value.started)
        {
            //GameManager.Instance.TogglePauseState(this);
        }
    }
    public void SetPlayerInputActive(bool activation, PlayerInput selectedPlayerInput)
    {
        // UnityEngine.DevLog.Log("Activating pi at " + Time.time);
        if (playerInput == null)
            playerInput = selectedPlayerInput;

        playerInput.enabled = activation;
    }
    public int GetPlayerID()
    {
        return playerID;
    }
    public PlayerInput GetPlayerInput()
    {
        return playerInput;
    }
    public virtual void UpdatePlayerDirection()
    {
        //print("update player direction");
        Vector3 relativePos = Vector3.zero;
        if (gameObject.CompareTag("Player"))
            relativePos = enemy.transform.position - player.transform.position;
        else if (gameObject.CompareTag("Enemy"))
            relativePos = player.transform.position - enemy.transform.position;
        // the second argument, upwards, defaults to Vector3.up
        if (relativePos.y < 0.1 && jump == false)
        {
            Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up);
            transform.rotation = rotation;
        }

    }
    void Strike()
    {
        m_CurrentClipInfo = enemy.GetComponent<Animator>().GetCurrentAnimatorClipInfo(0);
        m_ClipName = m_CurrentClipInfo[0].clip.name;
        player.transform.LookAt(enemy.transform.position);
        anim.Play("Baseball Strike");
        GameObject wood = GameObject.FindGameObjectWithTag("wood");

        //reposition and rotate the wood to fit properly in the hands
        if (wood.GetComponent<Rigidbody>() == null)
        {
            Vector3 position = new Vector3(-0.01f, 1.06f, -2.38f);
            Vector3 rotationangles = new Vector3(110.06f, 0, 8.9f);
            wood.transform.localPosition = position;
            wood.transform.localEulerAngles = rotationangles;
        }
    }
    void Jump()
    {

        if (player.transform.position.y < 10.5)
        {
            anim.SetBool("jumpkick", false);
            jump = true;
            jumpForce = 40;
            anim.Play("14-Jump-Up");
            player.transform.Translate(new Vector3(0, jumpForce, 0) * Time.deltaTime);
        }
    }
    void Kick(string kickAttack)
    {
        UpdatePlayerDirection();
        inputBuffer.AddInputToBuffer(kickAttack);
        string input = inputBuffer.GetLatestInput();
        if (input != null)
            playerAttacks.KickAttacks(input);
    }
    void KickMobile(float verticalValue, float horizontalValue, string kickDirection)
    {
        UpdatePlayerDirection();

        if (Time.time > nextAnimationTime)
        {
            // Map mobile inputs to our 2 kick animations
            string animation = AnimationNames.LowKick; // Default fallback
            
            switch (kickDirection)
            {
                case "up":
                case "upright":
                case "upleft":
                case "right":
                case "left":
                    animation = AnimationNames.DropKick;
                    break;
                case "down":
                case "downright":
                case "downleft":
                    animation = AnimationNames.LowKick;
                    break;
            }
            
            playerAttacks.KickAttacksDirectly(animation);
        }
    }
    void Look()
    {

    }
    void Punch(string punchAttack)
    {
        UpdatePlayerDirection();
        inputBuffer.AddInputToBuffer(punchAttack);
        string input = inputBuffer.GetLatestInput();
        if (input != null)
            playerAttacks.PunchAttacks(input);
    }
    void PunchMobile(float verticalValue, float horizontalValue, string punchDirection)
    {
        UpdatePlayerDirection();

        if (Time.time > nextAnimationTime)
        {
            // Map mobile inputs to our 6 punch animations
            string animation = AnimationNames.Jab; // Default fallback
            
            switch (punchDirection)
            {
                case "up":
                    animation = AnimationNames.Jab;
                    break;
                case "down":
                    animation = AnimationNames.Haymaker;
                    break;
                case "left":
                case "right":
                    animation = AnimationNames.SpinningBackfist;
                    break;
                case "upleft":
                case "upright":
                    animation = AnimationNames.ElbowSmash;
                    break;
                case "downleft":
                    animation = AnimationNames.ChargedPunch;
                    break;
                case "downright":
                    animation = AnimationNames.AirPunch;
                    break;
            }
            
            playerAttacks.PunchAttacksDirectly(animation);
        }
    }

    public static string GetDirection(Vector2 vector)
    {
        float x = vector.x;
        float y = vector.y;

        if (y > 0.5f && Math.Abs(x) <= 0.5f)
        {
            return "up";
        }
        if (y < -0.5f && Math.Abs(x) <= 0.5f)
        {
            return "down";
        }
        if (x < -0.5f && Math.Abs(y) <= 0.5f)
        {
            return "left";
        }
        if (x > 0.5f && Math.Abs(y) <= 0.5f)
        {
            return "right";
        }
        if (x <= -0.5f && y > 0.5f)
        {
            return "upleft";
        }
        if (x >= 0.5f && y > 0.5f)
        {
            return "upright";
        }
        if (x <= -0.5f && y < -0.5f)
        {
            return "downleft";
        }
        if (x >= 0.5f && y < -0.5f)
        {
            return "downright";
        }

        return "undefined"; // If it doesn't match any of the directions
    }

    public void StartDodge()
    {
        if (!dodge) // Check if dodge is not already active
        {
            dodge = true;
            StartCoroutine(DodgeCoroutine());
        }
    }

    public void StartBlock()
    {
        if (!block)
        {
            block = true;
            //GameObject.FindGameObjectWithTag("Enemy").GetComponent<EnemyScript>().attack = true;
            //attack = false;
            StartCoroutine(BlockCoroutine());
        }
    }

    private IEnumerator DodgeCoroutine()
    {
        // Duration of dodge

        yield return new WaitForSeconds(1.5f);
        // End dodge
        //do not add another statement here the function breaks for some reason
        dodge = false;
    }
    private IEnumerator BlockCoroutine()
    {
        // Duration of dodge
        yield return new WaitForSeconds(1.5f);
        // End dodge
        //do not add another statement here the function breaks for some reason
        //attack = true;
        block = false;
    }

    // VICIOUS ATTACKS
    
    // Example mapped to key combinations or button presses
    public void OnChokeslam(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("Chokeslam");
        }
    }
    
    public void OnSuplex(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("Suplex");
        }
    }
    
    public void OnGiantSwing(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("GiantSwing");
        }
    }
    
    public void OnDiamondCrusher(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("DiamondCrusher");
        }
    }
    
    // SPECIAL FINISHER ATTACKS
    
    public void OnRKO(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformSpecialAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastSpecialAttackTime = Time.time;
            SpecialAttack("RKO");
        }
    }
    
    public void OnSpear(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformSpecialAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastSpecialAttackTime = Time.time;
            SpecialAttack("Spear");
        }
    }
    
    public void OnRockBottom(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformSpecialAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastSpecialAttackTime = Time.time;
            SpecialAttack("RockBottom");
        }
    }
    
    // Helper methods to route to CharacterAttacks
    
    void ViciousAttack(string viciousAttack)
    {
        UpdatePlayerDirection();
        inputBuffer.AddInputToBuffer(viciousAttack);
        string input = inputBuffer.GetLatestInput();
        if (input != null)
            playerAttacks.ViciousAttacks(input);
    }
    
    void SpecialAttack(string specialAttack)
    {
        UpdatePlayerDirection();
        inputBuffer.AddInputToBuffer(specialAttack);
        string input = inputBuffer.GetLatestInput();
        if (input != null)
            playerAttacks.SpecialAttacks(input);
    }
    
    // Mobile support for vicious and special attacks
    
    public void OnViciousAttackMobile(float verticalValue, float horizontalValue, string direction)
    {
        if (attack == false || !canPerformViciousAttack)
            return;
        
        UpdatePlayerDirection();
        lastViciousAttackTime = Time.time;
        
        if (Time.time > nextAnimationTime)
        {
            playerAttacks.ViciousAttacksMobile(verticalValue, horizontalValue, direction);
        }
    }
    
    public void OnSpecialAttackMobile(float verticalValue, float horizontalValue, string direction)
    {
        if (attack == false || !canPerformSpecialAttack)
            return;
        
        UpdatePlayerDirection();
        lastSpecialAttackTime = Time.time;
        
        if (Time.time > nextAnimationTime)
        {
            playerAttacks.SpecialAttacksMobile(verticalValue, horizontalValue, direction);
        }
    }

    // Additional methods for vicious attacks that were referenced in SelectionOptions
    
    public void OnSumoSlap(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("SumoSlap");
        }
    }
    
    public void OnJavelinTackle(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformViciousAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastViciousAttackTime = Time.time;
            ViciousAttack("JavelinTackle");
        }
    }
    
    // Additional methods for special finishers that were referenced in SelectionOptions
    
    public void OnF5(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformSpecialAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastSpecialAttackTime = Time.time;
            SpecialAttack("F5");
        }
    }
    
    public void OnSwantomBomb(InputAction.CallbackContext context)
    {
        if (!context.performed || attack == false || !canPerformSpecialAttack)
            return;
        if (context.control.device == GetComponent<PlayerInput>().devices[0])
        {
            lastSpecialAttackTime = Time.time;
            SpecialAttack("SwantomBomb");
        }
    }

    // STUB METHODS FOR COMMENTED OUT ANIMATIONS
    // The following methods are stubs for animations that are not currently active,
    // but are still referenced in other scripts like SelectionOptions.cs and HealthNew.cs
    
    public void OnRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnLeftHook(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnRightHook(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnLeftElbow(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnRightElbow(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnRightBody(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnPowerPunchLeft(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnSupermanPunch(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnLegKickRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnBodyKickRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnKneeRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnBackSideKick(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnFrontKickRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnLegPowerKickRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnJumpBack(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnJumpLeft(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnJumpRight(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnBlockStepBack(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnBlockBodyLeft(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
    
    public void OnBlockLeg(InputAction.CallbackContext context)
    {
        // Stub method - not active in current configuration
        return;
    }
}

