import LocalStorageData from "../../Data/LocalStorageData";

export default class CSAudio {
	private static _instance: CSAudio = null;
	public static get Instance(): CSAudio { return this._instance; }
	private _idToClip: Map<number, cc.AudioClip> = new Map<number, cc.AudioClip>();
	private _idToPath: Map<number, string> = new Map<number, string>();
	private _idToAudioId: Map<number, number> = new Map<number, number>();
	private _currentMusic: number = -1;
	/**判斷音效播放太過頻繁不疊加 */
	private _lastPlaySoundTime: Map<string, number> = new Map<string, number>();
	private readonly _canPlaySoundCutTime: number = 10;

	constructor() {
		CSAudio._instance = this;
		if (LocalStorageData.Instance.MusicType) {
			this.SetMusicVolume(+LocalStorageData.Instance.MusicType);
		} else {
			this.SetMusicVolume(0.3);
		}
		if (LocalStorageData.Instance.SoundType) {
			this.SetSoundVolume(+LocalStorageData.Instance.SoundType);
		} else {
			this.SetSoundVolume(0.3);
		}
	}

	public AddClipsInfo(clips: Map<number, cc.AudioClip>, pathes: Map<number, string>): void {
		this._idToClip = clips;
		this._idToPath = pathes;
	}

	/**
	 * 設定AudioID
	 * @param id
	 * @param audioId
	 */
	private _setAudioId(id: number, audioId: number): void {
		this._idToAudioId.set(id, audioId);
	}

	/**
	 * 取得AudioID
	 * @param id
	 */
	private _getAudioId(id: number): number {
		if (this._idToAudioId.has(id)) {
			return this._idToAudioId.get(id);
		} else {
			return -1;
		}
	}

	/**
	 * 打開音效音量
	 */
	public OpenSound(): void {
		this.SetSoundVolume(0.3);
	}
	/**
	 * 關閉音效音量
	 */
	public CloseSound(): void {
		this.SetSoundVolume(0.0);
	}

	/**
	 * 設定音效音量
	 * @param volume
	 */
	public SetSoundVolume(volume: number): void {
		LocalStorageData.Instance.SoundType = volume.toString();
		cc.audioEngine.setEffectsVolume(volume);
	}

	/**
	 * 播放音效
	 * @param id
	 * @param loop
	 */
	public PlaySound(id: number, loop: boolean = false): void {
		// 靜音後有一禎仍然會撥放的問題:音量>0才撥放
		if (cc.audioEngine.getEffectsVolume() <= 0) {
			return;
		}
		if (this._idToClip.has(id)) {
			let path: string = this._idToPath.get(id);
			let timenum: number = new Date().getTime();
			if (!this._lastPlaySoundTime.has(path)) {
				this._lastPlaySoundTime.set(path, timenum);
				let audioId: number = cc.audioEngine.playEffect(this._idToClip.get(id), loop);
				this._setAudioId(id, audioId);
			} else {
				let lastTime: number = this._lastPlaySoundTime.get(path);
				if (timenum - lastTime > this._canPlaySoundCutTime) {
					this._lastPlaySoundTime.set(path, timenum);
					let audioId: number = cc.audioEngine.playEffect(this._idToClip.get(id), loop);
					this._setAudioId(id, audioId);
				}
			}
		} else {
			cc.error("未知的Sound Id: ", id);
		}
	}

	/**
	 * 停止音效
	 * @param id
	 */
	public StopSound(id: number): void {
		let audioId = this._getAudioId(id);
		if (audioId >= 0) {
			cc.audioEngine.stopEffect(audioId);
		}
	}

	/**
	 * 打開音樂音量
	 */
	public OpenMusic(): void {
		this.SetMusicVolume(0.3);
	}
	/**
	 * 關閉音樂音量
	 */
	public CloseMusic(): void {
		this.SetMusicVolume(0.0);
	}

	/**
	 * 設定音樂音量
	 * @param volume
	 */
	public SetMusicVolume(volume: number): void {
		cc.audioEngine.setMusicVolume(volume);
		LocalStorageData.Instance.MusicType = volume.toString();
		// 靜音後有一禎仍然會撥放的問題:背景音樂要回復
		if (this._currentMusic != -1 && volume > 0 && !cc.audioEngine.isMusicPlaying()) {
			this._ccMusicPlayId = cc.audioEngine.playMusic(this._idToClip.get(this._currentMusic), true);
		}
	}

	/**
	 * 撥放音樂
	 * @param id
	 * @param loop
	 */
	public PlayMusic(id: number, loop: boolean = true): void {
		if (this._currentMusic != id) {
			if (this._idToClip.has(id)) {
				// 靜音後有一禎仍然會撥放的問題:音量>0才撥放
				if (cc.audioEngine.getMusicVolume() > 0) {
					this._ccMusicPlayId = cc.audioEngine.playMusic(this._idToClip.get(id), loop);
				}
				this._currentMusic = id;
			}
			else {
				cc.error("未知的Music Id: ", id);
			}
		}
	}
	private _ccMusicPlayId: number = -1;
	private _currentMusicTime: number = -1;
	public pauseOrResume(isPause?: boolean) {
		if (isPause) {
			this._currentMusicTime = cc.audioEngine.getCurrentTime(this._ccMusicPlayId);
			cc.audioEngine.pauseAll();
			cc.audioEngine.stopMusic();
		} else {
			cc.audioEngine.resumeAll();
			cc.audioEngine.setCurrentTime(this._ccMusicPlayId, this._currentMusicTime);
		}
	}

	/**
	 * 停止音樂
	 * @param id
	 */
	public StopMusic(): void {
		cc.audioEngine.stopMusic();
		this._currentMusic = -1;
	}

}