using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(CanvasGroup))]
public class uGUIDraggingObject : UIBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IEventSystemHandler
{
	private RectTransform rectTrans
	{
		get
		{
			return this.m_RectTrans;
		}
	}

	private CanvasGroup canvasGroup
	{
		get
		{
			return this.m_CanvasGroup;
		}
	}

	public UnityEvent onSelectEvent
	{
		get
		{
			return this.m_OnSelectEvent;
		}
		set
		{
			this.m_OnSelectEvent = value;
		}
	}

	public UnityEvent onDeselectEvent
	{
		get
		{
			return this.m_OnDeselectEvent;
		}
		set
		{
			this.m_OnDeselectEvent = value;
		}
	}

	public UnityEvent onClickEvent
	{
		get
		{
			return this.m_OnClickEvent;
		}
		set
		{
			this.m_OnClickEvent = value;
		}
	}

	public bool isScaling
	{
		get
		{
			return this.m_IsScaling;
		}
		set
		{
			this.m_IsScaling = value;
		}
	}

	public float minSizeX
	{
		get
		{
			return this.m_MinSizeX;
		}
		set
		{
			this.m_MinSizeX = Mathf.Clamp(value, 20f, float.PositiveInfinity);
		}
	}

	public float minSizeY
	{
		get
		{
			return this.m_MinSizeY;
		}
		set
		{
			this.m_MinSizeY = Mathf.Clamp(value, 20f, float.PositiveInfinity);
		}
	}

	protected override void Start()
	{
		base.Start();
		this.m_StartPosition = this.rectTrans.anchoredPosition;
		this.m_StartSizeDelta = this.rectTrans.sizeDelta;
		if (this.rectTrans.parent)
		{
			int siblingIndex = base.transform.GetSiblingIndex();
			uGUIDraggingObject[] componentsInChildren = this.rectTrans.parent.GetComponentsInChildren<uGUIDraggingObject>();
			int num = componentsInChildren.Length - 1;
			if (componentsInChildren[num] == this)
			{
				this.canvasGroup.alpha = 1f;
				this.canvasGroup.interactable = true;
			}
			else
			{
				this.canvasGroup.alpha = 0.5f;
				this.canvasGroup.interactable = false;
				this.CreateBlocker();
			}
		}
		this.m_IsStarted = true;
	}

	public void ResetTransform()
	{
		if (!this.m_IsStarted)
		{
			return;
		}
		this.rectTrans.anchoredPosition = this.m_StartPosition;
		this.rectTrans.sizeDelta = this.m_StartSizeDelta;
	}

	public void OnPointerDown(PointerEventData eventData)
	{
		if (eventData.button != PointerEventData.InputButton.Left)
		{
			return;
		}
		this.ChangeWindowColor();
		EventSystem.current.SetSelectedGameObject(base.gameObject);
		this.OnBeginDrag(eventData);
	}

	public void OnDrag(PointerEventData eventData)
	{
		if (!this.m_IsMove)
		{
			return;
		}
		if (eventData.button != PointerEventData.InputButton.Left)
		{
			return;
		}
		Vector3 b = eventData.position - eventData.pressPosition;
		b.Scale(this.m_ReciprocalCanvasScale);
		Rect rect = this.rectTrans.rect;
		Vector3 vector = this.m_ClickPosition;
		if (this.m_IsDragRight)
		{
			rect.width = this.m_ClickRect.width + b.x;
			vector -= new Vector3(b.x * 0.5f, b.y, 0f);
		}
		if (this.m_IsDragLeft)
		{
			rect.width = this.m_ClickRect.width - b.x;
			vector -= new Vector3(b.x * 0.5f, b.y, 0f);
		}
		if (this.m_IsDragBottom)
		{
			rect.height = this.m_ClickRect.height + b.y;
			vector -= new Vector3(b.x, b.y * 0.5f, 0f);
		}
		if (this.m_IsDragTop)
		{
			rect.height = this.m_ClickRect.height - b.y;
			vector -= new Vector3(b.x, b.y * 0.5f, 0f);
		}
		if (rect.size.x < this.minSizeX)
		{
			rect.width = this.minSizeX;
			float num = Mathf.Sign(b.x);
			vector.x -= (b.x - num * (this.m_ClickRect.width - this.minSizeX)) * 0.5f;
		}
		if (rect.size.y < this.minSizeY)
		{
			rect.height = this.minSizeY;
			float num2 = Mathf.Sign(b.y);
			vector.y -= (b.y - num2 * (this.m_ClickRect.height - this.minSizeY)) * 0.5f;
		}
		if ((this.m_IsDragRight || this.m_IsDragLeft) && (this.m_IsDragTop || this.m_IsDragBottom))
		{
			vector += b;
		}
		vector += b;
		this.rectTrans.localPosition = vector;
		this.rectTrans.sizeDelta = rect.size;
	}

	public void OnPointerUp(PointerEventData eventData)
	{
		if (eventData.button != PointerEventData.InputButton.Left)
		{
			return;
		}
		this.m_IsDragRight = false;
		this.m_IsDragLeft = false;
		this.m_IsDragTop = false;
		this.m_IsDragBottom = false;
		this.m_IsMove = false;
	}

	public void OnPointerClick(PointerEventData eventData)
	{
		if (this.onClickEvent != null)
		{
			this.onClickEvent.Invoke();
		}
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		if (this.m_IsMove)
		{
			return;
		}
		Canvas rootCanvas = base.GetComponentInParent<Canvas>().rootCanvas;
		RectTransform component = rootCanvas.GetComponent<RectTransform>();
		this.UpdateReciprocalCanvasScale();
		Vector2 position = eventData.position;
		Rect rect = this.rectTrans.rect;
		Vector2 vector = position - new Vector2(this.rectTrans.localPosition.x, this.rectTrans.localPosition.y);
		vector = position - RectTransformUtility.WorldToScreenPoint(rootCanvas.worldCamera, this.rectTrans.position);
		vector.Scale(this.m_ReciprocalCanvasScale);
		this.m_ClickPosition = this.rectTrans.localPosition;
		this.m_ClickRect = rect;
		if (this.isScaling)
		{
			float dragScalingRange = this.m_DragScalingRange;
			this.m_IsDragRight = (Mathf.Abs(vector.x - rect.xMax) < dragScalingRange);
			this.m_IsDragLeft = (Mathf.Abs(vector.x - rect.xMin) < dragScalingRange);
			this.m_IsDragBottom = (Mathf.Abs(vector.y - rect.yMax) < dragScalingRange);
			this.m_IsDragTop = (Mathf.Abs(vector.y - rect.yMin) < dragScalingRange);
		}
		this.m_IsMove = true;
	}

	public void OnEndDrag(PointerEventData eventData)
	{
		this.OnPointerUp(eventData);
	}

	private void UpdateReciprocalCanvasScale()
	{
		Canvas rootCanvas = base.GetComponentInParent<Canvas>().rootCanvas;
		UIRoot componentInParent = base.GetComponentInParent<UIRoot>();
		Vector2 v = new Vector2((float)componentInParent.manualWidth, (float)componentInParent.manualHeight);
		Vector2 vector = new Vector2((float)rootCanvas.worldCamera.pixelWidth, (float)rootCanvas.worldCamera.pixelHeight);
		float num = v.y / v.x;
		float num2 = vector.y / vector.x;
		float num3 = num2 / num;
		this.m_ReciprocalCanvasScale = v;
		this.m_ReciprocalCanvasScale.x = this.m_ReciprocalCanvasScale.x / vector.x;
		this.m_ReciprocalCanvasScale.y = this.m_ReciprocalCanvasScale.y / vector.y;
		if (num3 > 1f)
		{
			this.m_ReciprocalCanvasScale.y = this.m_ReciprocalCanvasScale.y * num3;
		}
		else
		{
			this.m_ReciprocalCanvasScale.x = this.m_ReciprocalCanvasScale.x / num3;
		}
	}

	private void ChangeWindowColor()
	{
		this.rectTrans.SetAsLastSibling();
		if (this.canvasGroup)
		{
			this.canvasGroup.alpha = 1f;
			this.canvasGroup.interactable = true;
		}
		if (this.onSelectEvent != null)
		{
			this.onSelectEvent.Invoke();
		}
		if (this.rectTrans.parent)
		{
			uGUIDraggingObject[] componentsInChildren = this.rectTrans.parent.GetComponentsInChildren<uGUIDraggingObject>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (!(componentsInChildren[i] == this))
				{
					CanvasGroup canvasGroup = componentsInChildren[i].canvasGroup;
					if (canvasGroup)
					{
						canvasGroup.alpha = 0.5f;
						canvasGroup.interactable = false;
						componentsInChildren[i].CreateBlocker();
					}
					if (componentsInChildren[i].m_OnDeselectEvent != null)
					{
						componentsInChildren[i].m_OnDeselectEvent.Invoke();
					}
				}
			}
		}
	}

	private void CreateBlocker()
	{
		if (this.m_Blocker)
		{
			return;
		}
		GameObject blocker = new GameObject("[uGUIDraggingObject] Raycast Blocker");
		this.m_Blocker = blocker;
		RectTransform rectTransform = blocker.AddComponent<RectTransform>();
		rectTransform.SetParent(this.rectTrans, false);
		rectTransform.anchorMin = Vector3.zero;
		rectTransform.anchorMax = Vector3.one;
		rectTransform.sizeDelta = Vector2.zero;
		Canvas canvas = blocker.AddComponent<Canvas>();
		canvas.overrideSorting = true;
		canvas.sortingOrder = base.GetComponentInParent<Canvas>().sortingOrder + 10;
		CanvasGroup canvasGroup = blocker.AddComponent<CanvasGroup>();
		canvasGroup.ignoreParentGroups = true;
		canvasGroup.interactable = true;
		canvasGroup.blocksRaycasts = true;
		GraphicRaycaster graphicRaycaster = blocker.AddComponent<GraphicRaycaster>();
		graphicRaycaster.blockingObjects = GraphicRaycaster.BlockingObjects.All;
		Image image = blocker.AddComponent<Image>();
		image.color = Color.clear;
		uGUIDraggingObject.RaycastBlocker raycastBlocker = blocker.AddComponent<uGUIDraggingObject.RaycastBlocker>();
		raycastBlocker.onPointerDown = delegate(PointerEventData data)
		{
			UnityEngine.Object.Destroy(blocker);
			this.m_Blocker = null;
			this.OnPointerDown(data);
		};
	}

	private void OnReset()
	{
		Canvas canvas = base.GetComponent<Canvas>();
		if (!canvas)
		{
			canvas = base.gameObject.AddComponent<Canvas>();
			canvas.overrideSorting = false;
			uGUIUtility.SetLayer(base.gameObject, LayerMask.NameToLayer("NGUI"), true);
		}
		GraphicRaycaster graphicRaycaster = base.GetComponent<GraphicRaycaster>();
		if (!graphicRaycaster)
		{
			graphicRaycaster = base.gameObject.AddComponent<GraphicRaycaster>();
			graphicRaycaster.blockingObjects = GraphicRaycaster.BlockingObjects.All;
		}
		CanvasGroup exists = base.GetComponent<CanvasGroup>();
		if (!exists)
		{
			exists = base.gameObject.AddComponent<CanvasGroup>();
		}
		if (!this.m_RectTrans)
		{
			this.m_RectTrans = base.GetComponent<RectTransform>();
		}
		if (!this.m_CanvasGroup)
		{
			this.m_CanvasGroup = base.GetComponent<CanvasGroup>();
		}
	}

	[SerializeField]
	[HideInInspector]
	private RectTransform m_RectTrans;

	[SerializeField]
	[HideInInspector]
	private CanvasGroup m_CanvasGroup;

	[SerializeField]
	[Tooltip("選択されたときのイベント")]
	private UnityEvent m_OnSelectEvent;

	[SerializeField]
	[Tooltip("別のウィンドウが選択されたときのイベント")]
	private UnityEvent m_OnDeselectEvent;

	[SerializeField]
	[Tooltip("クリックされるたびに呼ばれるイベント")]
	private UnityEvent m_OnClickEvent;

	[SerializeField]
	[Tooltip("端のドラッグによるスケーリングを行うかどうか")]
	private bool m_IsScaling;

	[SerializeField]
	private float m_MinSizeX = 100f;

	[SerializeField]
	private float m_MinSizeY = 100f;

	private bool m_IsDragRight;

	private bool m_IsDragLeft;

	private bool m_IsDragTop;

	private bool m_IsDragBottom;

	private float m_DragScalingRange = 15f;

	private bool m_IsMove;

	private Vector3 m_ClickPosition = Vector3.zero;

	private Rect m_ClickRect;

	private Vector3 m_StartPosition;

	private Vector2 m_StartSizeDelta;

	private Vector3 m_ReciprocalCanvasScale;

	private GameObject m_Blocker;

	private bool m_IsStarted;

	private class RaycastBlocker : MonoBehaviour, IPointerDownHandler, IEventSystemHandler
	{
		public void OnPointerDown(PointerEventData eventData)
		{
			if (this.onPointerDown != null)
			{
				this.onPointerDown(eventData);
			}
		}

		public Action<PointerEventData> onPointerDown;
	}
}
