﻿//----------------------------------------------
// UTAGE: Unity Text Adventure Game Engine
// Copyright 2014 Ryohei Tokimura
//----------------------------------------------

using System.Collections.Generic;
using System.IO;
using System;
using UnityEngine;
using UtageExtensions;

namespace Utage
{

	/// <summary>
	/// サウンド管理
	/// </summary>
	public class Adx2LeSoundManagerSystem : SoundManagerSystemInterface
	{
		//サウンドマネージャー
		public SoundManager SoundManager { get; set; }

		Transform CachedTransform { get; set; }
		internal Adx2LeForUtage Adx2LeForUtage { get; set; }

		//グループリスト
		Dictionary<string, Adx2Group> groupTbl = new Dictionary<string, Adx2Group>();

		public Adx2LeSoundManagerSystem(Adx2LeForUtage adx2LeForUtage)
		{
			this.Adx2LeForUtage = adx2LeForUtage;
		}

		public void Init(SoundManager soundMangaer, List<string> saveStreamNameList)
		{
			SoundManager = soundMangaer;
			CachedTransform = SoundManager.transform;
		}

		public bool IsLoading
		{
			get
			{
				return false;
			}
		}

		public void Play(string groupName, string label, SoundData soundData, float fadeInTime, float fadeOutTime)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.Play(label, soundData, fadeInTime, fadeOutTime);
		}

		//指定の名前のストリームを取得。なければ作成。
		Adx2Group GetGroupOrCreateIfMissing(string groupName)
		{
			Adx2Group group;
			if (!groupTbl.TryGetValue(groupName, out group))
			{
				group = CachedTransform.AddChildGameObjectComponent<Adx2Group>(groupName);
				group.Init(this);
				groupTbl.Add(groupName, group);

				switch (groupName)
				{
					case SoundManager.IdBgm:
						group.DuckGroups.Add(GetGroupOrCreateIfMissing(SoundManager.IdVoice));
						break;
					case SoundManager.IdAmbience:
						group.DuckGroups.Add(GetGroupOrCreateIfMissing(SoundManager.IdVoice));
						break;
					case SoundManager.IdVoice:
						group.AutoDestoryPlayer = true;
						break;
					case SoundManager.IdSe:
						group.AutoDestoryPlayer = true;
						group.MultiPlay = true;
						break;
				}
			}
			return group;
		}

		public void Stop(string groupName, string label, float fadeTime)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.Stop(label, fadeTime);
		}

		public void StopAll(float fadeTime)
		{
			foreach (var keyValue in groupTbl)
			{
				keyValue.Value.StopAll(fadeTime);
			}
		}

		public bool IsPlaying(string groupName, string label)
		{
			if (!CriWareInitializer.IsInitialized()) return false;
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			return group.IsPlaying(label);
		}

		public float GetSamplesVolume(string groupName, string label)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			return group.GetSamplesVolume(label);
		}

		public void StopGroup(string groupName, float fadeTime)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.StopAll(fadeTime);
		}

		public void StopGroupIgnoreLoop(string groupName, float fadeTime)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.StopAllIgnoreLoop(fadeTime);
		}

		public float GetMasterVolume(string groupName)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			return group.MasterVolume;
		}

		public void SetMasterVolume(string groupName, float volume)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.MasterVolume = volume;
		}

		public bool IsMultiPlay(string groupName)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			return group.MultiPlay;
		}

		public void SetMultiPlay(string groupName, bool multiPlay)
		{
			Adx2Group group = GetGroupOrCreateIfMissing(groupName);
			group.MultiPlay = multiPlay;
		}

		const int Version = 0;
		//セーブデータ用のバイナリ書き込み
		public void WriteSaveData(BinaryWriter writer)
		{
			writer.Write(Version);
			writer.Write(groupTbl.Count);
			foreach (var keyValue in groupTbl)
			{
				writer.Write(keyValue.Key);
			}
			foreach (var keyValue in groupTbl)
			{
				writer.WriteBuffer(keyValue.Value.Write);
			}
		}

		//セーブデータ用のバイナリ読み込み
		public void ReadSaveDataBuffer(BinaryReader reader)
		{
			int version = reader.ReadInt32();
			if (version <= Version)
			{
				int count = reader.ReadInt32();
				//グループは初期化前にすべて作成済みである必要があるので、いったん実行
				List<Adx2Group> list = new List<Adx2Group>();
				for (int i = 0; i < count; ++i)
				{
					string name = reader.ReadString();
					list.Add(GetGroupOrCreateIfMissing(name));
				}
				for (int i = 0; i < count; ++i)
				{
					reader.ReadBuffer(list[i].Read);
				}
			}
			else
			{
				Debug.LogError(LanguageErrorMsg.LocalizeTextFormat(ErrorMsg.UnknownVersion, version));
			}
		}
	}
}