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

public class AudioManager : MonoBehaviour {

    public enum AudioChannel { Music, SoundEffects };

    float musicVolume = .2f;
    float soundEffectsVolume = 1f;

    AudioSource soundEffectsSource;
    AudioSource[] musicSources;
    int activeMusicSourceIndex;

    public Transform audioListenerT;
    public Transform playerT;

    SoundLibrary library;

    private void Awake() {
        library = GetComponent<SoundLibrary>();

        // two music sources so we can fade in and out into each when we switch songs
        musicSources = new AudioSource[2];
        for(int i = 0; i < 2; i++) {
            GameObject newMusicSource = new GameObject("Music Source " + (i + 1));
            musicSources[i] = newMusicSource.AddComponent<AudioSource>();
            newMusicSource.transform.parent = transform;
        }

        GameObject newSoundEffectsSource = new GameObject("Sound Effects Source");
        soundEffectsSource = newSoundEffectsSource.AddComponent<AudioSource>();
        newSoundEffectsSource.transform.parent = transform;

        musicVolume = PlayerPrefs.GetFloat("MusicVolume", musicVolume);
        soundEffectsVolume = PlayerPrefs.GetFloat("SoundEffectsVolume", soundEffectsVolume);
    }

    private void Start() {
        TryToGetTransforms();
    }

    private void Update() {
        if (!playerT)
            TryToGetTransforms();

        if (!playerT)
            return;

		audioListenerT.position = new Vector3 (Mathf.RoundToInt (playerT.position.x), Mathf.RoundToInt (playerT.position.y), Mathf.RoundToInt (playerT.position.z));
    }

    public void SetVolume(float volume, AudioChannel channel) {
        switch (channel) {
            case AudioChannel.Music:
                musicVolume = volume;
                break;
            case AudioChannel.SoundEffects:
                soundEffectsVolume = volume;
                break;
        }

        for(int i = 0; i < musicSources.Length; i++) {
            musicSources[i].volume = musicVolume;
        }

        PlayerPrefs.SetFloat("MusicVolume", musicVolume);
        PlayerPrefs.SetFloat("SoundEffectsVolume", soundEffectsVolume);
    }

    public float GetVolume(AudioChannel channel) {
        switch (channel) {
            case AudioChannel.Music:
                return musicVolume;
            case AudioChannel.SoundEffects:
                return soundEffectsVolume;
        }
        return 0;
    }

    public void PlayMusic(AudioClip clip, float fadeDuration = 1) {
        activeMusicSourceIndex = 1 - activeMusicSourceIndex;
        musicSources[activeMusicSourceIndex].clip = clip;
        musicSources[activeMusicSourceIndex].loop = true;
        musicSources[activeMusicSourceIndex].Play();


        // StartCoroutine(AnimateMusicCrossfade(fadeDuration));
    }

    public void StopMusic() {
        musicSources[activeMusicSourceIndex].loop = false;
        musicSources[activeMusicSourceIndex].Stop();
    }

    public void PlaySound(AudioClip clip, Vector3 position) {
        if (!clip)
            return;
        AudioSource.PlayClipAtPoint(clip, position, soundEffectsVolume);
    }

    public void PlaySound(string soundName, Vector3 position) {
        PlaySound(library.GetClipFromName(soundName), position);
    }

    public void PlaySound2D(string soundName) {
        soundEffectsSource.PlayOneShot(library.GetClipFromName(soundName), soundEffectsVolume);
    }

    public void PlaySound2D(AudioClip clip) {
        soundEffectsSource.PlayOneShot(clip, soundEffectsVolume);
    }

    void TryToGetTransforms() {
        if (!playerT) {
            GameObject player_obj = GameObject.FindWithTag("Player");

            if (!player_obj)
                return;

            playerT = player_obj.GetComponent<Transform>();
        }
        if (!audioListenerT) {
            audioListenerT = GetComponentInChildren<AudioListener>().transform;
        }
    }

    IEnumerator AnimateMusicCrossfade(float duration) {
        float percent = 0;
        while(percent < 1) {
            percent += Time.unscaledDeltaTime * 1 / duration;
            musicSources[activeMusicSourceIndex].volume = Mathf.Lerp(0, musicVolume, percent);
            musicSources[1-activeMusicSourceIndex].volume = Mathf.Lerp( musicVolume, 0, percent);
            yield return null;
        }
    }
}
