using System;
using UnityEngine;
using unity = UnityEngine;

namespace Cryville.Common.Unity.Input {
	public class UnityMouseHandler : InputHandler {
		GameObject receiver;

		public UnityMouseHandler() {
			if (!unity::Input.mousePresent) {
				throw new NotSupportedException("Unity mouse is not supported on this device");
			}
		}

		protected override void ActivateImpl() {
			receiver = new GameObject("__mouserecv__");
			receiver.AddComponent<UnityMouseReceiver>().SetHandler(this);
		}

		protected override void DeactivateImpl() {
			if (receiver) GameObject.Destroy(receiver);
		}

		public override void Dispose(bool disposing) {
			if (disposing) {
				DeactivateImpl();
			}
		}

		public override bool IsNullable(int type) {
			if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
			return false;
		}

		public override byte GetDimension(int type) {
			if (type != 0) throw new ArgumentOutOfRangeException(nameof(type));
			return 2;
		}

		public override string GetTypeName(int type) {
			switch (type) {
				case 0: return "Mouse Position";
				default: throw new ArgumentOutOfRangeException(nameof(type));
			}
		}

		public override double GetCurrentTimestamp() {
			return Time.realtimeSinceStartupAsDouble;
		}

		public class UnityMouseReceiver : MonoBehaviour {
			UnityMouseHandler handler;
			public void SetHandler(UnityMouseHandler h) {
				handler = h;
			}
			void Update() {
				double time = Time.realtimeSinceStartupAsDouble;
				Vector3 pos = UnityCameraUtils.ScreenToWorldPoint(unity::Input.mousePosition);
				handler.Feed(0, 0, new InputVector(time, pos));
			}
		}
	}
}
