


import { EventDispatcher } from "../events/EventDispatcher";
import { Parser } from "../svga/parser";
import { VideoEntity } from "../svga/VideoEntity";

export class Loader extends EventDispatcher {

    /**
     * 记录原始数据，json和image，贴图在建立时会被缓存
     * 需要缓存的都用在回调里自行缓存，比如弄个RES
     */
    private caches = {};

    /**
     * svga用的加载器
     */
    private parser: Parser;

    /**
     * 
     */
    constructor() {
        super();
        this._instanceType = "Loader";
    }

    /**
     * 加载图集
     * @param callback 
     * @param url 图集一般是png格式,传的是json,在callback自行拆分
     */
    loadSheet(callback: Function, url: string) {
        let pngFile = url.substring(0, url.lastIndexOf('.')) + '.png';
        this.loadImage((suc, data) => {
            if (suc) {
                this.cache(pngFile, data);
                if (this.caches[url]) {
                    callback(true, { json: this.caches[url], img: data })
                    //已回调,释放置空
                    this.caches[url] = null;
                    this.caches[pngFile] = null;
                }
            } else {
                callback(false, data)
            }
        }, pngFile);


        this.loadJson((suc, data) => {
            if (suc) {
                this.cache(url, data);
                if (this.caches[pngFile]) {
                    callback(true, { json: data, img: this.caches[pngFile] });
                    //已回调,释放置空
                    this.caches[url] = null;
                    this.caches[pngFile] = null;
                }
            } else {
                callback(false, data)
            }
        }, url)

        //暂时先不用fetch。safari兼容问题
        // fetchAsync(url)
        //     .then((data) => {
        //         this.cache(url, data);
        //         if (this.caches[pngFile]) {
        //             callback(true, { json: data, img: this.caches[pngFile] })
        //         }
        //         // console.log(data)
        //     })
        //     .catch(reason => {
        //         callback(false, reason)
        //         // console.log(reason.message)
        //     })
    }

    loadRaw(callback: Function, url: string, type: 'text' | 'json') {
        //每次都要new
        let _req;
        if (window["XMLHttpRequest"]) {
            _req = new XMLHttpRequest();
        } else if (window["ActiveXObject"]) {
            _req = new window["ActiveXObject"]();
        } else {
            alert("请升级至最新版本的浏览器")
        }
        if (_req != null) {
            _req.open("GET", url, true);
            _req.responseType = type;
            _req.send();
            _req.onreadystatechange = () => {
                if (_req.readyState == 4 && _req.status == 200) {
                    callback(true, _req.response)
                }
            };
            _req.onerror = (reason): void => {
                callback(false, reason)
            }
        }
    }

    loadJson(callback: Function, url: string) {
        this.loadRaw(callback, url, 'json');
    }

    loadText(callback: Function, url: string) {
        this.loadRaw(callback, url, 'text');
    }
    /**
     * 加载图片
     * @param callback 
     * @param url 
     * @param crossOrigin 
     */
    loadImage(callback: Function, url: string, crossOrigin: boolean = true) {
        let img = new Image();
        if (crossOrigin && url.indexOf('data:') !== 0) {
            img.setAttribute('crossOrigin', 'anonymous');
        }
        img.onload = function (e) {
            callback(true, img);
        };
        img.onerror = function (e) {
            callback(false, e);
        };
        img.src = url;
    }
    /**
     * 加载svga文件，data是动画数据和图片数据
     * @param callback 
     * @param url 
     */
    loadSvga(callback: (suc: boolean, data: VideoEntity) => void, url: string) {
        if (!this.parser) this.parser = new Parser();
        this.parser.load(url, function (videoItem: VideoEntity) {
            callback(true, videoItem)
            //是否缓存
        }, function (error) {
            callback(false, error)
            // alert(error.message);
        })
    }
    /**
     * 加载音频，其实这个没啥用，多数用WebAudio,就是audioContext播放
     * @param callback 
     * @param url 
     */
    loadAudio(callback: (suc: boolean, audio?: any) => void, url: string) {
        let audio = new Audio(url);
        audio.addEventListener("canplaythrough", onAudioLoaded);
        audio.addEventListener("error", onAudioError);
        let ua: string = navigator.userAgent.toLowerCase();
        if (ua.indexOf("firefox") >= 0) {//火狐兼容
            audio.autoplay = !0;
            audio.muted = true;
        }
        if (ua.indexOf("edge") >= 0) {//Edge兼容
            document.body.appendChild(audio);
        }
        audio.load();
        function onAudioLoaded(): void {
            removeListeners();
            if (ua.indexOf("firefox") >= 0) {//火狐兼容
                audio.pause();
                audio.muted = false;
            }
            callback(true, audio)
        }

        function onAudioError(): void {
            removeListeners();
            callback(false)
        }

        function removeListeners(): void {
            audio.removeEventListener("canplaythrough", onAudioLoaded);
            audio.removeEventListener("error", onAudioError);
            if (ua.indexOf("edge") >= 0) {//Edge兼容
                document.body.removeChild(audio);
            }
        }
        // let audio = document.createElement("Audio");
        // audio.addEventListener("canplay", function () {//监听audio是否加载完毕，如果加载完毕，则读取audio播放时间
        //     // document.getElementById('audio_length_total').innerHTML = transTime(audio.duration);
        //     callback(true, audio)
        // });
    }

    private cache(name: string, data: any) {
        if (this.caches[name]) {
            console.log("覆盖原先数据：" + name);
        }
        this.caches[name] = data
    }


}

async function fetchAsync(url: string) {
    // await response of fetch call
    let response = await fetch(url);
    // only proceed once promise is resolved
    let data = await response.json();
    // only proceed once second promise is resolved
    return data;
}

// fetchAsync("")
//     .then(data => console.log(data))
//     .catch(reason => console.log(reason.message))

export const GlobalLoader = new Loader()