/**
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */
using Live2D.Cubism.Core;
using System;
using UnityEngine;
namespace Live2D.Cubism.Framework.Physics
{
    /// 
    /// Input data of physics.
    /// 
    [Serializable]
    public struct CubismPhysicsInput
    {
        /// 
        /// Delegation of function of getting normalized parameter value.
        /// 
        /// Result of translation.
        /// Result of rotation.
        /// Parameter.
        /// Normalized components.
        /// Weight.
        public delegate void NormalizedParameterValueGetter(
            ref Vector2 targetTranslation,
            ref float targetAngle,
            CubismParameter parameter,
            CubismPhysicsNormalization normalization,
            float weight
        );
        /// 
        /// Gets Normalized parameter value from input translation X-axis.
        /// 
        /// Result of translation.
        /// Result of rotation.
        /// Parameter.
        /// Normalized components.
        /// Weight.
        private void GetInputTranslationXFromNormalizedParameterValue(
             ref Vector2 targetTranslation,
             ref float targetAngle,
             CubismParameter parameter,
             CubismPhysicsNormalization normalization,
             float weight
        )
        {
            targetTranslation.x += CubismPhysicsMath.Normalize(
                                    parameter,
                                    normalization.Position.Minimum,
                                    normalization.Position.Maximum,
                                    normalization.Position.Default,
                                    IsInverted
                                    ) * weight;
        }
        /// 
        /// Gets Normalized parameter value from input translation Y-axis.
        /// 
        /// Result of translation.
        /// Result of rotation.
        /// Parameter.
        /// Normalized components.
        /// Weight.
        private void GetInputTranslationYFromNormalizedParameterValue(
            ref Vector2 targetTranslation,
            ref float targetAngle,
            CubismParameter parameter,
            CubismPhysicsNormalization normalization,
            float weight
        )
        {
            targetTranslation.y += CubismPhysicsMath.Normalize(
                        parameter,
                        normalization.Position.Minimum,
                        normalization.Position.Maximum,
                        normalization.Position.Default,
                        IsInverted
                        ) * weight;
        }
        /// 
        /// Gets Normalized parameter value from input rotation.
        /// 
        /// Result of translation.
        /// Result of rotation.
        /// Parameter.
        /// Normalized components.
        /// Weight.
        private void GetInputAngleFromNormalizedParameterValue(
            ref Vector2 targetTranslation,
            ref float targetAngle,
            CubismParameter parameter,
            CubismPhysicsNormalization normalization,
            float weight
        )
        {
            targetAngle += CubismPhysicsMath.Normalize(
                              parameter,
                              normalization.Angle.Minimum,
                              normalization.Angle.Maximum,
                              normalization.Angle.Default,
                              IsInverted
                              ) * weight;
        }
        public void InitializeGetter()
        {
            switch (SourceComponent)
            {
                case CubismPhysicsSourceComponent.X:
                    {
                        GetNormalizedParameterValue =
                            GetInputTranslationXFromNormalizedParameterValue;
                    }
                    break;
                case CubismPhysicsSourceComponent.Y:
                    {
                        GetNormalizedParameterValue =
                            GetInputTranslationYFromNormalizedParameterValue;
                    }
                    break;
                case CubismPhysicsSourceComponent.Angle:
                    {
                        GetNormalizedParameterValue =
                            GetInputAngleFromNormalizedParameterValue;
                    }
                    break;
            }
        }
        /// 
        /// Parameter ID of source.
        /// 
        [SerializeField]
        public string SourceId;
        /// 
        /// Scale of translation.
        /// 
        [SerializeField]
        public Vector2 ScaleOfTranslation;
        /// 
        /// Scale of angle.
        /// 
        [SerializeField]
        public float AngleScale;
        /// 
        /// Weight.
        /// 
        [SerializeField]
        public float Weight;
        /// 
        /// Component of source.
        /// 
        [SerializeField]
        public CubismPhysicsSourceComponent SourceComponent;
        /// 
        /// True if value is inverted; otherwise.
        /// 
        [SerializeField]
        public bool IsInverted;
        /// 
        /// Source data from parameter.
        /// 
        [NonSerialized]
        public CubismParameter Source;
        /// 
        /// Function of getting normalized parameter value.
        /// 
        [NonSerialized]
        public NormalizedParameterValueGetter GetNormalizedParameterValue;
    }
}