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

public class VirtualJoystickController : MonoBehaviour {
	public enum Type {Left, Right};

	// SET
	public Color color = Color.white;
	public Type type = Type.Left;
	public 	bool lockPosition = false;
	public float radius = 40;
	public Vector2 position = Vector2.zero;
	public bool hide = true;

	// GET
	private float rotation;
	private bool doubleTap = false;
	private bool trippleTap = false;
	// + Get Power
	// + Get Down

	private Texture texture1;
	private Texture texture2;
	private Texture texture3;

	private TimerHelper timer;

	static public VirtualJoystickController leftInstance;
	static public VirtualJoystickController rightInstance;

	private void SetDown(bool state) {
		if (mouseDown == false && state == true) {
			float size = (radius / 200) * Screen.width;
			float positionx = (position.x / 100) * Screen.width - size;
			float positiony = (position.y / 100) * Screen.height - size;
			float distance = Vector2.Distance(mousePosition, new Vector2(positionx, positiony) + new Vector2(size, size));
			if (distance > size * 0.8f) {
				return;
			}
		}
		mouseDown = state;
	}

	// Misc
	float power = 0;
	float hitColor = 0f;
	int tapping = 0;
	bool mouseHit = false;
	bool mouseDown = false;
	bool usingTouch = false;
	Vector2 mousePosition = Vector2.zero;
	Touch currentTouch;

	public float GetRotation() {
		return(rotation);
	}

	public bool GetDoubleTap() {
		bool result = doubleTap;
		doubleTap = false;
		return(result);
	}

	public bool GetTrippleTap() {
		bool result = trippleTap;
		trippleTap = false;
		return(result);
	}

	public float GetPower() {
		return((power / GetLength()) / 0.7f);
	}

	public bool GetDown() {
		return(mouseDown);
	}
	
	void Awake () {
		switch(type) {
			case Type.Left:
				leftInstance = this;
			break;

			case Type.Right:
				rightInstance = this;
			break;
		}

		texture1 = Resources.Load<Texture>("GUI/Joystick/oval");
		texture2 = Resources.Load<Texture>("GUI/Joystick/joystick");
		texture3 = Resources.Load<Texture>("GUI/Joystick/touch");

		timer = TimerHelper.Create();
	}

	public bool PositionInPad(Vector2 pos) {
		float size = (radius / 200) * Screen.width;
		float positionx = (position.x / 100) * Screen.width - size;
		float positiony = (position.y / 100) * Screen.height - size;

		//Vector2 screenMidle = new Vector2(Screen.width / 2, Screen.height / 2);

		float distance = Vector2.Distance(pos, new Vector2(positionx, positiony) + new Vector2(size, size));

		if (distance > size) {
		//	Debug.Log(distance);
			return(false);
		}
		/*
		if (Vector2.Distance(screenMidle, position) < Screen.height / 3) {
			return(false);
		}

		switch(type) {
			case Type.Left:
				if (position.x > Screen.width / 2) {
					return(false);
				}
			break;

			case Type.Right:
				if (position.x < Screen.width / 2) {
					return(false);
				}
			break;
		} */

		return(true);
	}

	public bool GetTouch() {
		currentTouch = new Touch();
		
		bool found = false;
		for(int i = 0; i < Input.touchCount; i++) {
			Touch touch = Input.GetTouch(i);

			if (PositionInPad(touch.position)) {
				found = true;

				currentTouch = touch;
			}
		}
		return(found);
	}

	public bool UpdateMouse() {
		if (PositionInPad(Input.mousePosition) == false) {
			if (mouseDown) {
				SetDown(false);
			}
			
			return(true);
		}

		if (Input.GetMouseButton(0) == true) {
			if (PositionInPad(Input.mousePosition) ) {
				mousePosition = Input.mousePosition;
			}

			return(false);
		}

		if (mouseDown == true) {
			SetDown(false);
			return(true);
		}
		
		if (mouseDown == false) {
			return(true);
		}
		return(false);
	}

	bool UpdateTouch(bool touchFound) {
		if ((PositionInPad(currentTouch.position) == false) && currentTouch.position.x > 0 && currentTouch.position.y > 0) {
			if (mouseDown) {
				SetDown(false);
			}
			
			
			return(true);
		}

		if (touchFound == true) {
			
			if (PositionInPad(currentTouch.position)) {
				mousePosition = currentTouch.position;
			}

			return(false);
		}

		if (mouseDown == true) {
			SetDown(false);
			return(true);
		}
		
		if (mouseDown == false) {
			return(true);
		}

		return(false);
	}

	public void TouchUpdate() {
		mouseHit = false;
		if (mouseDown == false) {
			mouseHit = true;
		}
		SetDown(true);
	}

	public float GetLength() {
		float length = Mathf.Sqrt((Screen.width * Screen.width) + (Screen.height * Screen.height)) / 2;
		float size = (radius / 100f) * length;
		return(size);
	}

	void Update () {
		bool touchFound = GetTouch();

		if (touchFound) {
			usingTouch = true;
		}

		if (usingTouch) {
			if (UpdateTouch(touchFound)) {
				return;
			}	
		} else {
			if (UpdateMouse()) {
				return;
			}	
		}

			TouchUpdate();

		if (PositionInPad(mousePosition)) {	
			if (mouseHit) {
				if (lockPosition == false) {
					position.x = (mousePosition.x / Screen.width) * 100;
					position.y = (mousePosition.y / Screen.height) * 100;
				}
				
				hitColor = 1;
			}
		}
	}

	void OnGUI() {

		Vector2 circlePos = new Vector2((position.x / 100) * Screen.width, (position.y / 100) * Screen.height);

		power *= 0.95f;
		hitColor *= 0.95f;
		
		if (power < 0) {
			power = 0;
		}

		if (mouseDown) {
			power = Vector2.Distance(circlePos, mousePosition);
		}

		
		if (hide == true) {
			if (power < 2 && mouseDown == false) {
				if (timer.GetMillisecs() > 30) {
					return;
				}
			}
		}

	
	
		rotation = (float)Vector2D.Atan2(mousePosition, circlePos);

		UpdateTapping();

		Draw();
	}

	public void Draw() {
		float size = GetLength();

		Vector2 circlePos = new Vector2((position.x / 100) * Screen.width, (position.y / 100) * Screen.height);

		Color color1  = new Color(0.0f, 0.0f, 0.0f, 0.125f);
		Color color2 = new Color(0.5f, 0.5f, 0.5f, 0.5f);
		Color color3 = new Color(0,0,0,0.25f);
		Color color4 = new Color(0,0,hitColor * 0.5f,0.25f+hitColor) * 0.5f;
			
		if (power >= size * 0.7f) {
			power = size * 0.7f;
			color2 = color;
		}

		if (mouseDown == false) {
			color2.a = Mathf.Min(GetPower() * 2, 0.5f);
		}

		if (hide == false) {
			color2.a = 0.5f;
			color4.a = 0.5f;
		}

		Rect r1 = new Rect(circlePos.x - power, Screen.height - circlePos.y - power, power * 2, power *2 );
		Rect r2 = new Rect(circlePos.x - size, Screen.height - circlePos.y - size, size * 2,size *2 );
		Rect r3 = new Rect(circlePos.x -size * 0.5f + Mathf.Cos(rotation) * power , Screen.height - circlePos.y - size * 0.5f - Mathf.Sin(rotation) * power, size, size );
		Rect r4 = new Rect(circlePos.x - size* 0.7f, Screen.height - circlePos.y - size * 0.7f, size * 2 * 0.7f, size *2 * 0.7f);
	
		GUI.DrawTexture(r1, texture1, ScaleMode.StretchToFill, true, 1, color1, 0, 0);
		GUI.DrawTexture(r2, texture2, ScaleMode.StretchToFill, true, 1, color2, 0, 0);
		GUI.DrawTexture(r3, texture3, ScaleMode.StretchToFill, true, 1, color3, 0, 0);
		GUI.DrawTexture(r4, texture1, ScaleMode.StretchToFill, true, 1, color4, 0, 0);

		mouseHit = false;
	}

	public void UpdateTapping() {
		if (power >= GetLength() * 0.7f) {

		} else {
			if (mouseHit) {
				tapping ++;
				timer = TimerHelper.Create();
				mouseHit = false;
			}
		}

		if (tapping > 1) {
			tapping = 0;

			trippleTap = true;
		}

		if (timer.GetMillisecs() > 5) {
			if (tapping == 1) {
				 doubleTap = true;
			}
			tapping = 0;
		}
	}
}
