using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIScreen : MonoBehaviour
{
	public enum HorizontalAlign
	{
		Left, Center, Right
	}

	public enum VerticalAlign
	{
		Top, Middle, Bottom
	}

	public enum Transition
	{
		Fade, Left, Right, Up, Down
	}

	public HorizontalAlign horizontalAlign = HorizontalAlign.Center;
	public VerticalAlign verticalAlign = VerticalAlign.Middle;
	public Transition transition = Transition.Up;
	public float transitionTime = 0.3f;
	public float transitionBounce = 0.3f;
	public bool pausesGame = true;
	public GameObject defaultButton;

	public bool shown {
		get {
			return _shown;
		}
		set {
			if (value != _shown) {
				_shown = value;
				gameObject.SetActive(true);
				if (_shown) {
					UIWrangler.Select(defaultButton);
					UIWrangler.ui.screens.Add(this);
				} else {
					UIWrangler.ui.screens.Remove(this);
				}
			}
		}
	}

	bool _shown = false;
	float fade=0, fadeVel=0;
	RectTransform rt;
	CanvasGroup group;
	Vector2 origin;
	Bounds initialBounds;

	void Start() {
		rt = GetComponent<RectTransform>();
		origin = rt.anchoredPosition;

		group = GetComponent<CanvasGroup>();
		if (!group)
			group = gameObject.AddComponent<CanvasGroup>();

		Vector3[] tmp = new Vector3[4];
		rt.GetWorldCorners(tmp);
		initialBounds = new Bounds(tmp[0], Vector3.zero);
		initialBounds.Encapsulate(tmp[1]);
		initialBounds.Encapsulate(tmp[2]);
		initialBounds.Encapsulate(tmp[3]);

		ApplyTransition();

		gameObject.SetActive(true); // in case we were hidden in the editor.
	}

	void Update() {
		float dt = UIWrangler.deltaTime;

		DampedSpring spring = new DampedSpring(dt, transitionTime, transitionBounce);
		spring.Apply(shown ? 1.0f : 0.0f, ref fade, ref fadeVel);

		ApplyTransition();

		if (!shown && fade <= 0)
			gameObject.SetActive(false);
	}

	void ApplyTransition()
	{
		// Find out how big our screen is so we know where to hide.
		float ch = UIWrangler.ui.camera.orthographicSize*2;
		float cw = ch * UIWrangler.ui.camera.aspect;
		Rect camRect = new Rect(-cw*0.5f, -ch*0.5f, cw, ch);

		// Apply centering.
		Vector2 offset = origin;
		switch (horizontalAlign) {
			case HorizontalAlign.Left: offset.x += camRect.xMin - initialBounds.min.x; break;
			case HorizontalAlign.Center: offset.x += camRect.center.x - initialBounds.center.x; break;
			case HorizontalAlign.Right: offset.x += camRect.xMax - initialBounds.max.x; break;
		}
		switch (verticalAlign) {
			case VerticalAlign.Top: offset.y += camRect.yMax - initialBounds.max.y; break;
			case VerticalAlign.Middle: offset.y += camRect.center.y - initialBounds.center.y; break;
			case VerticalAlign.Bottom: offset.y += camRect.yMin - initialBounds.min.y; break;
		}

		// Blend transition.
		float delta;
		switch (transition) {
			case Transition.Left:
				delta = camRect.xMin - initialBounds.max.x;
				rt.anchoredPosition = offset + new Vector2(delta*(1-fade), 0);
				break;
			case Transition.Right:
				delta = camRect.xMax - initialBounds.min.x;
				rt.anchoredPosition = offset + new Vector2(delta*(1-fade), 0);
				break;
			case Transition.Up:
				delta = camRect.yMax - initialBounds.min.y;
				rt.anchoredPosition = offset + new Vector2(0, delta*(1-fade));
				break;
			case Transition.Down:
				delta = camRect.yMin - initialBounds.max.y;
				rt.anchoredPosition = offset + new Vector2(0, delta*(1-fade));
				break;
			case Transition.Fade:
				group.alpha = fade;
				rt.anchoredPosition = offset;
				break;
		}
	}
}
