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

[RequireComponent(typeof(Light))]
public class Star : MonoBehaviour
{
    [Header("Phisical properties")]
    public float temperature = 5778.0f;
    public float luminosity = 1.0f;
    public float size = 1.0f;
    [Header("Draw properties")]
    public float distanceFactor = 1.0f;
    public Mesh mesh;
    public Material material;
    private Transform star;
    private bool createdStar = false;
    private Camera camera;
    private UnityEngine.Gradient gradient;

    void Start()
    {
        if (!createdStar) {
            CreateStar();
        }
    }

    void OnEnable() {
        if (!createdStar) {
            CreateStar();
        }
    }

    private void CreateStar() {
        createdStar = true;
        camera = Camera.main;
        GameObject starGo = new GameObject("Star_mesh");
        star = starGo.transform;
        star.parent = transform;
        MeshFilter mf = starGo.AddComponent<MeshFilter>();
        mf.mesh = mesh;
        MeshRenderer mr = starGo.AddComponent<MeshRenderer>();
        mr.material = material;
        material = mr.material;
        mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
        SetColor();
        SetPositionAndSize();
    }

    private void SetColor() {
        material.SetColor("_EmissiveColor", temperatureToColor(temperature) * luminosity * 8 * Mathf.Pow(Random.Range(1.0f, 1.05f), 2));
    }

    private Color temperatureToColor(float temperature) {
        float max = 10000f;
        if (gradient == null) {
            gradient = new UnityEngine.Gradient();
            GradientColorKey[] gck = new GradientColorKey[8];
            GradientAlphaKey[] gak = new GradientAlphaKey[2];
            //Color
            gck[0].color = new Color(0, 0, 0);
            gck[0].time = 0.0f;
            gck[1].color = new Color(255, 50, 30);
            gck[1].time = 1800.0F / max;
            gck[2].color = new Color(255, 204, 111);
            gck[2].time = 3050.0f / max;
            gck[3].color = new Color(255, 220, 161);
            gck[3].time = 4450.0F / max;
            gck[4].color = new Color(255, 255, 255);
            gck[4].time = 5200.0F / max;
            gck[5].color = new Color(234, 244, 255);
            gck[5].time = 6750.0F / max;
            gck[6].color = new Color(100, 220, 255);
            gck[6].time = 8750.0f / max;
            gck[7].color = new Color(51, 150, 255);
            gck[7].time = max;
            //Alpha
            gak[0].alpha = 0.0F;
            gak[0].time = 0.0F;
            gak[1].alpha = 0.0F;
            gak[1].time = 10000.0F;
            gradient.SetKeys(gck, gak);
        }
        return gradient.Evaluate(temperature / max);
    }

    private void SetPositionAndSize() {
        star.position = camera.transform.position + this.transform.rotation * new Vector3(0.0f, 0.0f, -0.99f * camera.farClipPlane * distanceFactor);
        star.rotation = Quaternion.LookRotation(star.position - camera.transform.position);
        star.localScale = Vector3.one * camera.farClipPlane * 0.03f * size;
    }

    void LateUpdate()
    {
        SetColor();
        SetPositionAndSize();
    }
}
