import { Asset, Component } from "cc";
import { FrameworkConf } from "../config/FrameworkConf";
import { Framework } from "../Framework";
import { resLoader } from "./ResLoader";

class ResQueue {

    private _load_timer_uuid = 0;
    private _load_task_quene: { priority: number, bundle: string, url: string, type: typeof Asset, completed: (error: Error, res: Asset) => void, target: Component }[] = [];
    private _preload_timer_uuid = 0;
    private _preload_task_quene: { priority: number, bundle: string, url: string, type: typeof Asset }[] = [];

    constructor() {
        this._load_timer_uuid = 0;
        this._load_task_quene = [];
        this._preload_timer_uuid = 0;
        this._preload_task_quene = [];
    }

    /**
     * 添加加载任务
     * @param priority 任务优先级
     * @param bundle 包名
     * @param url 路径
     * @param type 类型
     * @param completed 完成回调
     * @param target 任务目标
     */
    pushLoad(priority: number, bundle: string, url: string, type: typeof Asset, completed: (error: Error, res: Asset) => void, target: Component) {
        this._load_task_quene.push({ priority: priority, bundle: bundle, url: url, type: type, completed: completed, target: target });
        this._load_task_quene.sort((a, b) => {
            return b.priority - a.priority;
        });
        if (this._load_timer_uuid <= 0) {
            this._load_timer_uuid = Framework.time.schedule(() => {
                for (let i = 0; i < FrameworkConf.frame_load_count; ++i) {
                    let task = this._load_task_quene.shift();
                    if (task) {
                        resLoader.load(task.bundle, task.url, task.type, task.completed.bind(task.target));
                    } else {
                        (this._load_timer_uuid > 0) && Framework.time.unschedule(this._load_timer_uuid);
                        this._load_timer_uuid = -1;
                        break;
                    }
                }
            });
        }
    }

    /**
     * 添加预加载任务
     * @param priority 任务优先级
     * @param bundle 包名
     * @param url 路径
     * @param type 类型
     */
    pushPreload(priority: number, bundle: string, url: string, type: typeof Asset) {
        this._preload_task_quene.push({ priority: priority, bundle: bundle, url: url, type: type });
        this._preload_task_quene.sort((a, b) => {
            return b.priority - a.priority;
        });
        // if (this._preload_timer_uuid <= 0) {
        //     this._preload_timer_uuid = Framework.time.schedule(() => {
        //         for (let i = 0; i < FrameworkConf.frame_preload_count; ++i) {
        //             let task = this._preload_task_quene.shift();
        //             if (task) {
        //                 resLoader.preload(task.bundle, task.url, task.type);
        //             } else {
        //                 (this._preload_timer_uuid > 0) && Framework.time.unschedule(this._preload_timer_uuid);
        //                 this._preload_timer_uuid = -1;
        //                 break;
        //             }
        //         }
        //     });
        // }
    }
    // AB包总数量
    private totalAb: number = 0;
    // AB包当前已加载数量
    private nowAb: number = 0;

    // 资源当前数量
    private now: number = 0;
    // 资源总计数量
    private total: number = 0;
    /**
     * 加载预加载任务
     * @param 
     */
    loadPreload(progress: Function, endFunc: Function) {
        this.total = this._preload_task_quene.length - 1
        if (this._preload_timer_uuid <= 0) {
            this._preload_timer_uuid = Framework.time.schedule(() => {
                for (let i = 0; i < FrameworkConf.frame_preload_count; ++i) {
                    let task = this._preload_task_quene.shift();
                    this.now++
                    if (task) {
                        resLoader.preload(task.bundle, task.url, task.type);
                        progress(this.now, this.total)
                    } else {
                        (this._preload_timer_uuid > 0) && Framework.time.unschedule(this._preload_timer_uuid);
                        this._preload_timer_uuid = -1;
                        endFunc()
                        break;
                    }
                }
            });
        }
    }
}

export let LoadQueue = new ResQueue();