import { Node, AudioSource, AudioClip, resources, director, _decorator, TextAsset, error, JsonAsset } from 'cc';
const { ccclass, property } = _decorator;

/**
 * @en
 * this is a sington class for audio play, can be easily called from anywhere in you project.
 * @zh
 * 这是一个用于播放音频的单件类，可以很方便地在项目的任何地方调用。
 */
export class GlobalAudio {

    AudioManager: object;

    //@zh 创建一个节点作为 GlobalAudio
    private static instance: GlobalAudio;

    public static getInstance(): GlobalAudio {
        if (!GlobalAudio.instance) {
            GlobalAudio.instance = new GlobalAudio();
        }
        return GlobalAudio.instance;
    }

    private _audioSource: AudioSource;
    constructor() {
        //@en create a node as GlobalAudio
        //@zh 创建一个节点作为 GlobalAudio
        let GlobalAudio = new Node();
        GlobalAudio.name = '__GlobalAudio__';

        //@en add to the scene.
        //@zh 添加节点到场景
        director.getScene().addChild(GlobalAudio);

        //@en make it as a persistent node, so it won't be destroied when scene change.
        //@zh 标记为常驻节点，这样场景切换的时候就不会被销毁了
        director.addPersistRootNode(GlobalAudio);

        //@en add AudioSource componrnt to play audios.
        //@zh 添加 AudioSource 组件，用于播放音频。
        this._audioSource = GlobalAudio.addComponent(AudioSource);
    }


    //初始化完成以后的回调方法
    LoadCallBack: Function;
    Init(Func: Function) {
        //储存回调
        this.LoadCallBack = Func;
        this.LoadAudioXml();
    }


    //加载音频Map
    LoadAudioXml() {
        resources.load("Sound/audio", (err, json: JsonAsset) => {
            if (err) {
                console.error(err);
            }
            this.AudioManager = json.json!;
            this.LoadCallBack();
        });
    }


    PlaySound(sound: string, volume: number = 1.0) {
        if (this.AudioManager.hasOwnProperty(sound)) {
            this.playOneShot(this.AudioManager[sound], volume);
        }
        else {
            console.error("音频不存在,路径: " + sound);
        }
    }


    public get audioSource() {
        return this._audioSource;
    }

    /**
     * @en
     * play short audio, such as strikes,explosions
     * @zh
     * 播放短音频,比如 打击音效，爆炸音效等
     * @param sound clip or url for the audio
     * @param volume 
     */
    playOneShot(sound: AudioClip | string, volume: number = 1.0) {
        if (sound instanceof AudioClip) {
            this._audioSource.playOneShot(sound, volume);
        }
        else {
            resources.load(sound, (err, clip: AudioClip) => {
                if (err) {
                    console.log(err);
                }
                else {
                    this._audioSource.playOneShot(clip, volume);
                }
            });
        }
    }

    /**
     * @en
     * play long audio, such as the bg music
     * @zh
     * 播放长音频，比如 背景音乐
     * @param sound clip or url for the sound
     * @param volume 
     */
    play(sound: AudioClip | string, volume: number = 1.0) {
        if (sound instanceof AudioClip) {
            this._audioSource.clip = sound;
            this._audioSource.play();
            this.audioSource.volume = volume;
        }
        else {
            resources.load(sound, (err, clip: AudioClip) => {
                if (err) {
                    console.log(err);
                }
                else {
                    this._audioSource.clip = clip;
                    this._audioSource.play();
                    this.audioSource.volume = volume;
                }
            });
        }
    }

    /**
     * stop the audio play
     */
    stop() {
        this._audioSource.stop();
    }

    /**
     * pause the audio play
     */
    pause() {
        this._audioSource.pause();
    }

    /**
     * resume the audio play
     */
    resume() {
        this._audioSource.play();
    }
}