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

public class CombustibleProcessor : MonoBehaviour {
    
    private static List<Combustible> Combustibles = new List<Combustible>();
    public static void AddCombustible(Combustible a)
    {
        Combustibles.Add(a);
        a.Destroyed += A_Destroyed;
    }

    private static void A_Destroyed(object sender, System.EventArgs e)
    {
        Combustibles.Remove(sender as Combustible);
    }

    private void Start()
    {
        RebuildAllNeighbourTables();
    }

    private void RebuildNeighbourTableForCombustible(Combustible c)
    {
        c.Neighbours.Clear();

        // Get all the combustibles in range
        
        Vector3 wind = Quaternion.Euler(0.0f, GetComponent<WindProcessor>().WindAngle, 0.0f) * new Vector3(0.0f, 0.0f, GetComponent<WindProcessor>().WindSpeed);
        Vector3 centerPoint = c.transform.position + wind;

        Collider[] nearbyColliders = Tree.GetGameLogicObjectsInRange(centerPoint, c.SpreadRange);
        foreach (Collider col in nearbyColliders)
        {
            Combustible other = col.GetComponent<Combustible>();

            float distSquared = (centerPoint - other.transform.position).sqrMagnitude;
            float effectiveContribution = 1.0f - (distSquared / (c.SpreadRange * c.SpreadRange));

            c.Neighbours.Add(new CombustibleNeighbour(other, effectiveContribution));
        }
    }

    public void RebuildAllNeighbourTables()
    {
        foreach (Combustible c in Combustibles)
        {
            RebuildNeighbourTableForCombustible(c);
        }
    }

    // FixedUpdate is called once per frame
    void FixedUpdate () {
        foreach(Combustible c in Combustibles)
        {
            // Check if we're burning
            if (c.IsBurning)
            {
                foreach(CombustibleNeighbour neighbour in c.Neighbours)
                {
                    if (neighbour.other.Fuel > 0.0f && neighbour.effectiveContribution > 0.0f && !neighbour.other.IsSuppressed)
                    {
                        neighbour.other.CurrentTemperature += c.TemperatureOutputPerSecondPerDegree * c.CurrentTemperature * Time.fixedDeltaTime * neighbour.effectiveContribution;
                    }

                    if (neighbour.other.CurrentTemperature > neighbour.other.MaximumTemperature)
                    {
                        neighbour.other.CurrentTemperature = neighbour.other.MaximumTemperature;
                    }
                }

                // Burn fuel
                c.Fuel -= c.FuelBurnRate * (c.CurrentTemperature - c.CombustionTemperature) * Time.fixedDeltaTime;

                // Check if we have burned out all of our fuel
                if (c.Fuel <= Mathf.Epsilon)
                {
                    c.Fuel = 0.0f;
                }
            }
            else
            {
                if (c.CurrentTemperature > 0.0f)
                {
                   c.CurrentTemperature = Mathf.Max(c.CurrentTemperature - c.CoolingRatePerSecond * Time.fixedDeltaTime, 0.0f);
                }
            }
        }
    }
}
