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

public class ChildrenCreator : MonoBehaviour
{
    CsoundUnity csound;
    public float radius = 10f;
    public GameObject ChildMeterPrefab;
    private Dictionary<string, Child3DMeter> _meters;

    // Start is called before the first frame update
    IEnumerator Start()
    {
        csound = GetComponent<CsoundUnity>();

        while (!csound.IsInitialized)
            yield return null;

        var n = csound.availableAudioChannels.Count;

        _meters = new Dictionary<string, Child3DMeter>();

        for (var i = 0; i < csound.availableAudioChannels.Count; i++)
        {
            var angle = i * Mathf.PI * 2 / n;
            var pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
            var go = Instantiate(ChildMeterPrefab, this.transform);

            // starting with the GameObject disabled or Unity won't calculate its 3D Volume correctly
            go.SetActive(false);
            go.transform.position = pos;
            var child = go.AddComponent(typeof(CsoundUnityChild)) as CsoundUnityChild;
            child.Init(csound, CsoundUnityChild.AudioChannels.MONO);
            child.SetAudioChannel(0, i);
            child.name = csound.availableAudioChannels[i];
            var meter = go.GetComponent<Child3DMeter>();
            _meters.Add(csound.availableAudioChannels[i], meter);
            var aS = go.GetComponent<AudioSource>();
            aS.dopplerLevel = 0;
            aS.rolloffMode = AudioRolloffMode.Custom;
            aS.spatializePostEffects = true;
            // this is useless if no Spatializer plugin is set in the AudioSettings: it will produce a warning at runtime
            aS.spatialize = true;
            //when the audio listener is 'radius' meters far from the audio source, there will be no sound, 
            // since the rolloff function will lower the volume accordingly to the custom curve, and at maxDistance the volume will be 0. 
            // Let's add 10 meters more to have some sound when the listener is equidistant from the created sources
            aS.maxDistance = radius + 10; 
            go.SetActive(true);

        }
    }


    // Update is called once per frame
    void Update()
    {
        foreach (var meter in _meters)
        {
            meter.Value.SetValue((float)csound.GetChannel(meter.Key + "Vol") / (float)csound.Get0dbfs());
        }
    }
}
