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

[RequireComponent(typeof(AudioSource))]
public class SoundBoard : MonoBehaviour
{

	private class EffectState {
		public int[] order;
		public int nextIndex;
		
		private static void swap(int[] list, int i, int j) {
			var tmp = list[i];
			list[i] = list[j];
			list[j] = tmp;
		}
		public void shuffle() {
			if(order.Length<=1)
				return;
			else if(order.Length==2) {
				if(Random.value>=0.5f) {
					swap(order, 0,1);
				}
				return;
			}
			
			// shuffel [0 - count-1]
			var count = order.Length - 1;
			var last = count - 1;
			for (var i = 0; i < last; ++i) {
				var r = Random.Range(i, count);
				swap(order, i,r);
			}

			// swap last with random element
			swap(order, count, Random.Range(1, count));
		}

		public int take() {
			if(nextIndex>=order.Length) {
				nextIndex = 0;
				shuffle();
			}

			return order[nextIndex++];
		}
	}
	private static Dictionary<string, EffectState> states = new Dictionary<string, EffectState>();

	[System.Serializable]
	public struct Effect {
		public string key;
		public AudioClip[] clips;

		public AudioClip take(string boardKey) {
			if(clips.Length==0)
				return null;
			
			EffectState state;

			if (!states.TryGetValue(boardKey+"#"+key, out state)) {
				state = new EffectState();
				state.nextIndex = 0;
				state.order = new int[clips.Length];
				for(int i=0; i<clips.Length; i++)
					state.order[i] = i;
				
				states.Add(boardKey+"#"+key, state);
			}

			return clips[state.take()];
		}
	}

	[SerializeField]
	public string boardKey;

	[SerializeField]
	public Effect[] effects;

	private AudioSource audioSource;

	void Start() {
		audioSource = GetComponent<AudioSource>();
	}

	public void play(string key) {
		var effectIdx = System.Array.FindIndex(effects, e => e.key==key);
		if(effectIdx>=0 && effects[effectIdx].clips.Length>0) {
			audioSource.PlayOneShot(effects[effectIdx].take(boardKey));
		}
	}
}
