using System;
using RootMotion.FinalIK;
using UnityEngine;

[Serializable]
public class HandFootIKData : LimbIKData
{
	public HandFootIKData(IKEffector effector, FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKCtrl ik_ctrl, Transform tgt_bone, bool use_old = false) : base(ik_ctrl, chain, tgt_bone, use_old)
	{
		this.Effector = effector;
		this.Effector.target = base.IKTarget;
		this.IKMapping = ik_mapping;
		this.m_ForceIKEnable = true;
		this.ToCorrectBone = this.TargetBone;
	}

	public ShoulderThighIKData ShoulderThighData
	{
		get
		{
			return this.m_ShoulderThighData;
		}
	}

	public ElbowKneeIKData ElbowKneeData
	{
		get
		{
			return this.m_ElbowKneeData;
		}
	}

	public override float PositionWeight
	{
		get
		{
			return this.Effector.positionWeight;
		}
		set
		{
			this.Effector.positionWeight = value;
		}
	}

	public override float RotationWeight
	{
		get
		{
			return this.Effector.rotationWeight;
		}
		set
		{
			this.Effector.rotationWeight = value;
		}
	}

	private void CheckBorder(HandFootIKData.BorderCorrectData correctData)
	{
		if (!correctData.Enable)
		{
			return;
		}
		float d = 0f;
		Vector3 position = this.ToCorrectBone.position;
		if (correctData.CheckBorder(position, ref d))
		{
			if (!base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec)
			{
				base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec = true;
			}
			switch (this.CorrectType)
			{
			case HandFootIKData.BorderCorrectType.Bone:
				base.IKTarget.position += correctData.Axis * d;
				this.m_ElbowKneeData.IKTarget.position += correctData.Axis * d;
				break;
			case HandFootIKData.BorderCorrectType.HalfBody:
				base.IKTarget.position += correctData.Axis * d;
				this.m_ElbowKneeData.IKTarget.position += correctData.Axis * d;
				this.m_ShoulderThighData.IKTarget.position += correctData.Axis * d;
				break;
			case HandFootIKData.BorderCorrectType.Chara:
				this.MyIKCtrl.BodyCtrlData.SetPosOffset(correctData.Axis * d);
				break;
			}
		}
	}

	protected override void SetTargetTransform(IKCtrlData.IKSettingData data, Vector3 pos, Quaternion rot)
	{
		base.SetTargetTransform(data, pos, rot);
		if (!data.IsPointAttach)
		{
			return;
		}
		Transform iktarget = this.m_ShoulderThighData.IKTarget;
		Transform iktarget2 = this.m_ElbowKneeData.IKTarget;
		Vector3 vector = this.m_ElbowKneeData.TargetBone.position - this.TargetBone.position;
		Vector3 vector2 = this.m_ShoulderThighData.TargetBone.position - this.m_ElbowKneeData.TargetBone.position;
		if (this.ElbowKneeData.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec)
		{
			return;
		}
		float f = Vector3.Dot(vector.normalized, vector2.normalized);
		float num = Mathf.Acos(f) * 57.29578f;
		float num2 = Mathf.Clamp01(num / this.m_BendFadeBorder);
		this.ElbowKneeData.PositionWeight = num2 * this.PositionWeight;
		Vector3 position = this.TargetBone.InverseTransformPoint(this.m_ElbowKneeData.TargetBone.position);
		Vector3 position2 = base.IKTarget.TransformPoint(position);
		iktarget2.position = position2;
		if (this.ElbowKneeData.GetIKSettingData(IKCtrlData.IKAttachType.Rotate).IsIKExec)
		{
			this.ElbowKneeData.RotationWeight = this.PositionWeight;
			iktarget2.rotation = Quaternion.FromToRotation(this.TargetBone.position - this.ElbowKneeData.TargetBone.position, base.IKTarget.position - iktarget2.position) * iktarget2.rotation;
		}
	}

	public override void ApplyIKSetting()
	{
		if (!base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec && !base.GetFlagData(IKCtrlData.IKAttachType.NewPoint).IsEnable && (this.FloorCorrect.Enable || this.WallCorrect.Enable))
		{
			base.ForceIK = true;
		}
		base.ApplyIKSetting();
		this.CheckBorder(this.WallCorrect);
		this.CheckBorder(this.FloorCorrect);
	}

	public override void Detach(IKCtrlData.IKAttachType attachType)
	{
		base.Detach(attachType);
		this.WallCorrect.Reset();
		this.FloorCorrect.Reset();
		this.ToCorrectBone = this.TargetBone;
		this.CorrectType = HandFootIKData.BorderCorrectType.Bone;
	}

	public void SetChainData(ElbowKneeIKData elbowknee_data, ShoulderThighIKData shoulderthigh_data)
	{
		this.m_ElbowKneeData = elbowknee_data;
		this.m_ShoulderThighData = shoulderthigh_data;
	}

	[Header("壁・床補正情報")]
	public HandFootIKData.BorderCorrectData WallCorrect = new HandFootIKData.BorderCorrectData(Vector3.forward);

	public HandFootIKData.BorderCorrectData FloorCorrect = new HandFootIKData.BorderCorrectData(Vector3.up);

	public HandFootIKData.BorderCorrectType CorrectType;

	public Transform ToCorrectBone;

	[SerializeField]
	[Space]
	[Range(1f, 90f)]
	private float m_BendFadeBorder = 30f;

	public readonly IKEffector Effector;

	public readonly IKMappingLimb IKMapping;

	private ShoulderThighIKData m_ShoulderThighData;

	private ElbowKneeIKData m_ElbowKneeData;

	public enum BorderCorrectType
	{
		Bone,
		HalfBody,
		Chara,
		All
	}

	[Serializable]
	public class BorderCorrectData
	{
		public BorderCorrectData(Vector3 axis)
		{
			this.Axis = axis;
		}

		public void Reset()
		{
			this.Border = 0f;
			this.Enable = false;
		}

		public float GetValue(Vector3 pos)
		{
			pos = KasaiUtility.Vec3Multiply(pos, this.Axis);
			return pos.magnitude * Vector3.Dot(this.Axis, pos.normalized);
		}

		public bool CheckBorder(Vector3 check_pos, ref float diff)
		{
			float value = this.GetValue(check_pos);
			diff = this.Border - value;
			return value < this.Border;
		}

		public float Border;

		public bool Enable;

		public Vector3 Axis;
	}
}
