using UnityEngine;

[AddComponentMenu("Dynamic Bone/Dynamic Bone Collider")]
public class DynamicBoneCollider : MonoBehaviour
{
	public enum Direction
	{
		X,
		Y,
		Z
	}

	public enum Bound
	{
		Outside,
		Inside
	}

	public Vector3 m_Center = Vector3.zero;

	public float m_Radius = 0.5f;

	public float m_Height;

	public Direction m_Direction;

	public Bound m_Bound;

	private void OnValidate()
	{
		m_Radius = Mathf.Max(m_Radius, 0f);
		m_Height = Mathf.Max(m_Height, 0f);
	}

	public void Collide(ref Vector3 particlePosition, float particleRadius)
	{
		float num = m_Radius * Mathf.Abs(base.transform.lossyScale.x);
		float num2 = m_Height * 0.5f - m_Radius;
		if (num2 <= 0f)
		{
			if (m_Bound == Bound.Outside)
			{
				OutsideSphere(ref particlePosition, particleRadius, base.transform.TransformPoint(m_Center), num);
			}
			else
			{
				InsideSphere(ref particlePosition, particleRadius, base.transform.TransformPoint(m_Center), num);
			}
			return;
		}
		Vector3 center = m_Center;
		Vector3 center2 = m_Center;
		switch (m_Direction)
		{
		case Direction.X:
			center.x -= num2;
			center2.x += num2;
			break;
		case Direction.Y:
			center.y -= num2;
			center2.y += num2;
			break;
		case Direction.Z:
			center.z -= num2;
			center2.z += num2;
			break;
		}
		if (m_Bound == Bound.Outside)
		{
			OutsideCapsule(ref particlePosition, particleRadius, base.transform.TransformPoint(center), base.transform.TransformPoint(center2), num);
		}
		else
		{
			InsideCapsule(ref particlePosition, particleRadius, base.transform.TransformPoint(center), base.transform.TransformPoint(center2), num);
		}
	}

	private static void OutsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
	{
		float num = sphereRadius + particleRadius;
		float num2 = num * num;
		Vector3 vector = particlePosition - sphereCenter;
		float sqrMagnitude = vector.sqrMagnitude;
		if (sqrMagnitude > 0f && sqrMagnitude < num2)
		{
			float num3 = Mathf.Sqrt(sqrMagnitude);
			particlePosition = sphereCenter + vector * (num / num3);
		}
	}

	private static void InsideSphere(ref Vector3 particlePosition, float particleRadius, Vector3 sphereCenter, float sphereRadius)
	{
		float num = sphereRadius - particleRadius;
		float num2 = num * num;
		Vector3 vector = particlePosition - sphereCenter;
		float sqrMagnitude = vector.sqrMagnitude;
		if (sqrMagnitude > num2)
		{
			float num3 = Mathf.Sqrt(sqrMagnitude);
			particlePosition = sphereCenter + vector * (num / num3);
		}
	}

	private static void OutsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
	{
		float num = capsuleRadius + particleRadius;
		float num2 = num * num;
		Vector3 vector = capsuleP1 - capsuleP0;
		Vector3 vector2 = particlePosition - capsuleP0;
		float num3 = Vector3.Dot(vector2, vector);
		if (num3 <= 0f)
		{
			float sqrMagnitude = vector2.sqrMagnitude;
			if (sqrMagnitude > 0f && sqrMagnitude < num2)
			{
				float num4 = Mathf.Sqrt(sqrMagnitude);
				particlePosition = capsuleP0 + vector2 * (num / num4);
			}
			return;
		}
		float sqrMagnitude2 = vector.sqrMagnitude;
		if (num3 >= sqrMagnitude2)
		{
			vector2 = particlePosition - capsuleP1;
			float sqrMagnitude3 = vector2.sqrMagnitude;
			if (sqrMagnitude3 > 0f && sqrMagnitude3 < num2)
			{
				float num5 = Mathf.Sqrt(sqrMagnitude3);
				particlePosition = capsuleP1 + vector2 * (num / num5);
			}
		}
		else if (sqrMagnitude2 > 0f)
		{
			num3 /= sqrMagnitude2;
			vector2 -= vector * num3;
			float sqrMagnitude4 = vector2.sqrMagnitude;
			if (sqrMagnitude4 > 0f && sqrMagnitude4 < num2)
			{
				float num6 = Mathf.Sqrt(sqrMagnitude4);
				particlePosition += vector2 * ((num - num6) / num6);
			}
		}
	}

	private static void InsideCapsule(ref Vector3 particlePosition, float particleRadius, Vector3 capsuleP0, Vector3 capsuleP1, float capsuleRadius)
	{
		float num = capsuleRadius - particleRadius;
		float num2 = num * num;
		Vector3 vector = capsuleP1 - capsuleP0;
		Vector3 vector2 = particlePosition - capsuleP0;
		float num3 = Vector3.Dot(vector2, vector);
		if (num3 <= 0f)
		{
			float sqrMagnitude = vector2.sqrMagnitude;
			if (sqrMagnitude > num2)
			{
				float num4 = Mathf.Sqrt(sqrMagnitude);
				particlePosition = capsuleP0 + vector2 * (num / num4);
			}
			return;
		}
		float sqrMagnitude2 = vector.sqrMagnitude;
		if (num3 >= sqrMagnitude2)
		{
			vector2 = particlePosition - capsuleP1;
			float sqrMagnitude3 = vector2.sqrMagnitude;
			if (sqrMagnitude3 > num2)
			{
				float num5 = Mathf.Sqrt(sqrMagnitude3);
				particlePosition = capsuleP1 + vector2 * (num / num5);
			}
		}
		else if (sqrMagnitude2 > 0f)
		{
			num3 /= sqrMagnitude2;
			vector2 -= vector * num3;
			float sqrMagnitude4 = vector2.sqrMagnitude;
			if (sqrMagnitude4 > num2)
			{
				float num6 = Mathf.Sqrt(sqrMagnitude4);
				particlePosition += vector2 * ((num - num6) / num6);
			}
		}
	}

	private void OnDrawGizmosSelected()
	{
		if (!base.enabled)
		{
			return;
		}
		if (m_Bound == Bound.Outside)
		{
			Gizmos.color = Color.yellow;
		}
		else
		{
			Gizmos.color = Color.magenta;
		}
		float radius = m_Radius * Mathf.Abs(base.transform.lossyScale.x);
		float num = m_Height * 0.5f - m_Radius;
		if (num <= 0f)
		{
			Gizmos.DrawWireSphere(base.transform.TransformPoint(m_Center), radius);
			return;
		}
		Vector3 center = m_Center;
		Vector3 center2 = m_Center;
		switch (m_Direction)
		{
		case Direction.X:
			center.x -= num;
			center2.x += num;
			break;
		case Direction.Y:
			center.y -= num;
			center2.y += num;
			break;
		case Direction.Z:
			center.z -= num;
			center2.z += num;
			break;
		}
		Gizmos.DrawWireSphere(base.transform.TransformPoint(center), radius);
		Gizmos.DrawWireSphere(base.transform.TransformPoint(center2), radius);
	}
}
