using UnityEngine;
using System;

[DisallowMultipleComponent]
public class ParticleDestroyer : MonoBehaviour {

    private Action callback = ActionExtensions.EmptyAction;

    void Start(){
        float lifetime = 0.0f;
        transform.FindComponent<ParticleSystem>(ps => {
            lifetime = Mathf.Max(GetLifeTime(ps), lifetime);
        });
        transform.FindAllChildrensComponent<ParticleSystem>(ps => {
            lifetime = Mathf.Max(GetLifeTime(ps), lifetime);
        });

        this.CallWaitForSeconds(lifetime, () => {
            callback();
            Destroy(gameObject);
        });
    }

    private float GetLifeTime(ParticleSystem ps){
        var lifeTime = 0.0f;
        switch(ps.main.startLifetime.mode){
        case ParticleSystemCurveMode.Constant:
            lifeTime = ps.main.startLifetime.constant;
            break;
        case ParticleSystemCurveMode.TwoConstants:
            lifeTime = ps.main.startLifetime.constantMax;
            break;
        case ParticleSystemCurveMode.Curve:
            lifeTime = ps.main.startLifetime.curve.GetMax();
            break;
        case ParticleSystemCurveMode.TwoCurves:
            lifeTime = Mathf.Max(ps.main.startLifetime.curveMin.GetMax(), ps.main.startLifetime.curveMax.GetMax());
            break;
        }
        if(ps.trails.enabled){
            var trailLifeTime = 0.0f;
            switch(ps.trails.lifetime.mode){
            case ParticleSystemCurveMode.Constant:
                trailLifeTime = ps.trails.lifetime.constant;
                break;
            case ParticleSystemCurveMode.TwoConstants:
                trailLifeTime = ps.trails.lifetime.constantMax;
                break;
            case ParticleSystemCurveMode.Curve:
                trailLifeTime = ps.trails.lifetime.curve.GetMax();
                break;
            case ParticleSystemCurveMode.TwoCurves:
                trailLifeTime = Mathf.Max(ps.trails.lifetime.curveMin.GetMax(), ps.trails.lifetime.curveMax.GetMax());
                break;
            }
            lifeTime += trailLifeTime;
        }
        lifeTime += ps.main.duration;
        if(ps.subEmitters.enabled){
            for(int i = 0; i < ps.subEmitters.subEmittersCount; ++i){
                switch(ps.subEmitters.GetSubEmitterType(i)){
                case ParticleSystemSubEmitterType.Birth:
                    lifeTime = Mathf.Max(GetLifeTime(ps.subEmitters.GetSubEmitterSystem(i)), lifeTime);
                    break;
                case ParticleSystemSubEmitterType.Death:
                    lifeTime += GetLifeTime(ps.subEmitters.GetSubEmitterSystem(i));
                    break;
                }
            }
        }
        return lifeTime;
    }

    public void SetCallback(Action callback){
        this.callback = callback;
    }
}
