using System;
using UnityEngine;
using wf;

public class GizmoObject : MonoBehaviour
{
	public GizmoRender gizmoRot { get; private set; }

	public WorldTransformAxis gizmoAxis { get; private set; }

	public Vector3 position
	{
		get
		{
			return base.transform.position;
		}
		set
		{
			Vector3 vector = base.transform.position - value;
			base.transform.position = value;
			if (vector.sqrMagnitude > 0f && this.onChangePosition != null)
			{
				this.onChangePosition(value);
			}
			this.m_CachedSnapPosition = value;
		}
	}

	public Vector3 eulerAngles
	{
		get
		{
			return this.rotation.eulerAngles;
		}
		set
		{
			this.rotation = Quaternion.Euler(value);
		}
	}

	public Vector3 scale
	{
		get
		{
			return this.gizmoRot.transform.localScale;
		}
		set
		{
			Vector3 vector = this.gizmoRot.transform.localScale - value;
			this.gizmoRot.transform.localScale = value;
			if (vector.sqrMagnitude > 0f && this.onChangeScale != null)
			{
				this.onChangeScale(value);
			}
			this.m_CachedSnapScale = value;
		}
	}

	public Vector3 nonCallbackScale
	{
		set
		{
			this.gizmoRot.transform.localScale = value;
			this.UpdateSnapping();
		}
	}

	public Quaternion rotation
	{
		get
		{
			return this.gizmoRot.transform.rotation;
		}
		set
		{
			float f = Quaternion.Angle(this.gizmoRot.transform.rotation, value);
			this.gizmoRot.transform.rotation = value;
			if (Mathf.Abs(f) > 0f && this.onChangeRotation != null)
			{
				this.onChangeRotation(value);
			}
			this.m_CachedSnapRotation = value;
		}
	}

	public bool activeAxis
	{
		get
		{
			return this.gizmoAxis.gameObject.activeInHierarchy;
		}
		set
		{
			this.gizmoAxis.gameObject.SetActive(value);
		}
	}

	public bool activeRot
	{
		get
		{
			return this.gizmoRot.gameObject.activeInHierarchy;
		}
		set
		{
			this.gizmoRot.gameObject.SetActive(value);
		}
	}

	public GizmoObject.ControlType controlType
	{
		get
		{
			return this.m_ControlType;
		}
		set
		{
			this.m_ControlType = value;
		}
	}

	public float snapValuePosition
	{
		get
		{
			return this.m_SnapValuePosition;
		}
		set
		{
			this.m_SnapValuePosition = value;
		}
	}

	public float snapValueAngles
	{
		get
		{
			return this.m_SnapValueAngles;
		}
		set
		{
			this.m_SnapValueAngles = value;
		}
	}

	public float snapValueScale
	{
		get
		{
			return this.m_SnapValueScale;
		}
		set
		{
			this.m_SnapValueScale = value;
		}
	}

	public Vector3 cachedSnapScale
	{
		get
		{
			return this.m_CachedSnapScale;
		}
	}

	private void Awake()
	{
		GameObject gameObject = new GameObject("Gizmo Rot");
		GizmoRender gizmoRot = gameObject.AddComponent<GizmoRender>();
		this.gizmoRot = gizmoRot;
		Transform transform = gameObject.transform;
		transform.SetParent(base.gameObject.transform);
		transform.localPosition = Vector3.zero;
		transform.localRotation = Quaternion.identity;
		transform.localScale = Vector3.one;
		GameObject gameObject2 = Utility.CreatePrefab(null, "System/Prefab/XYZAxis", true);
		WorldTransformAxis component = gameObject2.GetComponent<WorldTransformAxis>();
		this.gizmoAxis = component;
		Transform transform2 = gameObject2.transform;
		transform2.SetParent(base.gameObject.transform);
		transform2.localPosition = Vector3.zero;
		transform2.localRotation = Quaternion.AngleAxis(90f, Vector3.left);
		transform2.localScale = Vector3.one;
		this.gizmoAxis.TargetObject = base.gameObject;
		this.m_CachedSnapPosition = this.position;
		this.m_CachedSnapRotation = this.rotation;
		this.m_CachedSnapScale = this.scale;
	}

	private void OnDestroy()
	{
		if (this.gizmoRot != null && this.gizmoRot.lineMaterial != null)
		{
			UnityEngine.Object.Destroy(this.gizmoRot.lineMaterial);
		}
		this.onChangePosition = null;
		this.onChangeRotation = null;
		this.onChangeScale = null;
	}

	private void LateUpdate()
	{
		if (NInput.GetMouseButtonDown(0))
		{
			this.OnClickEnter();
		}
		else if (NInput.GetMouseButton(0))
		{
			this.OnClickExecute();
		}
		else if (NInput.GetMouseButtonUp(0))
		{
			this.OnClickExit();
		}
		if (!GizmoRender.UIVisible && GizmoRender.UIVisible != base.gameObject.activeInHierarchy)
		{
			base.gameObject.SetActive(false);
		}
	}

	private void OnClickEnter()
	{
	}

	private void OnClickExecute()
	{
		this.UpdateSnapping();
		this.UpdateTargetTransform();
	}

	private void OnClickExit()
	{
		this.UpdateSnapping();
		this.UpdateTargetTransform();
		if (this.controlType == GizmoObject.ControlType.Snap)
		{
			this.position = this.m_CachedSnapPosition;
			this.rotation = this.m_CachedSnapRotation;
			this.scale = this.m_CachedSnapScale;
		}
	}

	private void UpdateTargetTransform()
	{
		if (this.target == null)
		{
			return;
		}
		Transform transform = this.target.transform;
		if (this.controlType == GizmoObject.ControlType.Default)
		{
			transform.position = this.position;
			transform.rotation = this.rotation;
			transform.localScale = this.scale;
		}
		else if (this.controlType == GizmoObject.ControlType.Snap)
		{
			transform.position = this.m_CachedSnapPosition;
			transform.rotation = this.m_CachedSnapRotation;
			transform.localScale = this.m_CachedSnapScale;
		}
	}

	private void UpdateSnapping()
	{
		float sqrMagnitude = (this.m_CachedSnapPosition - this.position).sqrMagnitude;
		float num = Quaternion.Angle(this.m_CachedSnapRotation, this.rotation);
		float sqrMagnitude2 = (this.m_CachedSnapScale - this.scale).sqrMagnitude;
		if (this.controlType == GizmoObject.ControlType.Default)
		{
			this.m_CachedSnapPosition = this.position;
			this.m_CachedSnapRotation = this.rotation;
			this.m_CachedSnapScale = this.scale;
			if (sqrMagnitude > 0f && this.onChangePosition != null)
			{
				this.m_CachedSnapPosition = this.position;
				this.onChangePosition(this.position);
			}
			if (num > 0f && this.onChangeRotation != null)
			{
				this.m_CachedSnapRotation = this.rotation;
				this.onChangeRotation(this.rotation);
			}
			if (sqrMagnitude2 > 0f && this.onChangeScale != null)
			{
				this.m_CachedSnapScale = this.scale;
				this.onChangeScale(this.scale);
			}
		}
		else if (this.controlType == GizmoObject.ControlType.Snap)
		{
			if (sqrMagnitude >= this.snapValuePosition * this.snapValuePosition)
			{
				Vector3 position = this.position;
				position.x = Mathf.Round(position.x / this.snapValuePosition) * this.snapValuePosition;
				position.y = Mathf.Round(position.y / this.snapValuePosition) * this.snapValuePosition;
				position.z = Mathf.Round(position.z / this.snapValuePosition) * this.snapValuePosition;
				if (!float.IsNaN(position.x) && !float.IsNaN(position.y) && !float.IsNaN(position.z))
				{
					this.position = position;
					this.m_CachedSnapPosition = position;
				}
			}
			if (num >= this.snapValueAngles)
			{
				Quaternion rotation = this.rotation;
				Quaternion cachedSnapRotation = this.m_CachedSnapRotation;
				float snapValueAngles = this.snapValueAngles;
				float num2 = Quaternion.Angle(cachedSnapRotation, rotation);
				if (Mathf.Abs(num2) > snapValueAngles)
				{
					Quaternion quaternion = Quaternion.RotateTowards(cachedSnapRotation, rotation, Mathf.Floor(num2 / snapValueAngles) * snapValueAngles);
					this.rotation = quaternion;
					this.m_CachedSnapRotation = quaternion;
				}
			}
			if (sqrMagnitude2 >= this.snapValueScale * this.snapValueScale)
			{
				Vector3 vector = Mathf.Round(this.scale.x / this.snapValueScale) * this.snapValueScale * Vector3.one;
				if (!float.IsNaN(vector.x) && !float.IsNaN(vector.y) && !float.IsNaN(vector.z))
				{
					this.scale = vector;
					this.m_CachedSnapScale = vector;
				}
			}
		}
	}

	public GameObject target;

	[SerializeField]
	private GizmoObject.ControlType m_ControlType;

	[SerializeField]
	private float m_SnapValuePosition = 1f;

	[SerializeField]
	private float m_SnapValueAngles = 30f;

	[SerializeField]
	private float m_SnapValueScale = 1f;

	private Vector3 m_CachedSnapPosition;

	private Quaternion m_CachedSnapRotation;

	private Vector3 m_CachedSnapScale;

	public Action<Vector3> onChangePosition;

	public Action<Quaternion> onChangeRotation;

	public Action<Vector3> onChangeScale;

	public enum ControlType
	{
		Default,
		Snap
	}
}
