using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

public class FloatingTextSpawner {
  private static GameObject GameObjectContainer = new GameObject($"Floating Text Container");
  private Transform Transform;
  private List<Transform> TextList = new List<Transform>();

  public FloatingTextSpawner(Transform transform) {
    Transform = transform;
  }

  public void SpawnFloatingText(string message, Color color, float duration = 1.5f) {
    try {

      GameObject textObj = new GameObject("FloatingText");
      textObj.transform.position = Transform.position + new Vector3(0, 1, 1); // offset above character

      TextMesh textMesh = textObj.AddComponent<TextMesh>();
      textMesh.text = message;
      textMesh.characterSize = 0.2f;
      textMesh.fontSize = 48;
      textMesh.fontStyle = FontStyle.Bold;
      textMesh.color = color;
      textMesh.alignment = TextAlignment.Center;
      textMesh.anchor = TextAnchor.MiddleCenter;

      Renderer renderer = textObj.GetComponent<Renderer>();
      renderer.sortingLayerName = "UI";
      renderer.sortingOrder = 0;

      textObj.AddComponent<FloatingText>().Init(duration, ref TextList);
      UnityEngine.Object.Instantiate(textObj, GameObjectContainer.transform);
    } catch (Exception e) { }
  }
}


public class FloatingText : MonoBehaviour {
  private float lifetime;
  private float speed = 1f;
  private Color originalColor;
  private TextMesh textMesh;


  public void Init(float duration, ref List<Transform> textList) {
    try {
      lifetime = duration;
      textMesh = GetComponent<TextMesh>();
      originalColor = textMesh.color;

      for (int i = textList.Count - 1; i >= 0; i--) {
        if (textList[i] == null)
          textList.RemoveAt(i);
        else
          textList[i].position += Vector3.up * 0.5f;
      }

      textList.Add(this.transform);
    } catch (Exception e) { }
  }

  void Update() {
    try {

      transform.position += Vector3.up * speed * Time.deltaTime;

      lifetime -= Time.deltaTime;
      if (lifetime <= 0) {
        Destroy(gameObject);
      } else {
        float alpha = Mathf.Clamp01(lifetime / 1.5f);
        textMesh.color = new Color(originalColor.r, originalColor.g, originalColor.b, alpha);
      }
    } catch (Exception e) { }

  }
}


