﻿
/**
 * 进度条调用类
 */
export class Loading {
    // 单例模式
    private static _instance: Loading
    public static get instance() {
        if (Loading._instance == null) {
            Loading._instance = new Loading()
            Loading._instance.loadingUI = new LoadingUI()
        }
        return Loading._instance
    }

    /**加载UI */
    private loadingUI: LoadingUI

    /**阶段总数 */
    private total: number
    /**当前加载到第几阶段 */
    private current: number

    /**
     * 开始加载（调用即显示加载UI）
     * @param count 共有几个加载阶段
     * @param titleStr 大标题
     */
    public start(count: number, titleStr: string) {
        this.current = 0
        this.total = count
        this.loadingUI.startLoading(titleStr)
    }

    /**
     * 完成一个阶段并更新提示
     * @param tips 提示内容
     */
    public handleComplete(tips: string) {
        this.current++
        if (this.current >= this.total) {
            this.loadingUI.finishLoading()
        } else {
            this.loadingUI.setTips(tips)
        }
        this.loadingUI.setProgress(this.current / this.total)
    }

}

class LoadingUI {
    /**UI实体 */
    private userWidget: UserWidget
    /**标题文本 */
    private titleText: TextBlock
    /**提示文本 */
    private tipsText: TextBlock
    /**进度条 */
    private progressBar: ProgressBar
    /**进度条数字 */
    private progressText: TextBlock
    /**确认按钮 */
    private sureBtn: StaleButton

    constructor() {
        this.init()
    }

    private init() {
        // 创建加载UI
        this.userWidget = mw.createUIByName("LoadingUI")
        // 获取UI上的组件
        this.titleText = this.userWidget.findChildByPath("RootCanvas/TitleText") as TextBlock
        this.tipsText = this.userWidget.findChildByPath("RootCanvas/TipsText") as TextBlock
        this.progressBar = this.userWidget.findChildByPath("RootCanvas/ProgressBar") as ProgressBar
        this.progressText = this.userWidget.findChildByPath("RootCanvas/ProgressText") as TextBlock
        this.sureBtn = this.userWidget.findChildByPath("RootCanvas/SureBtn") as StaleButton
        // 将UI显示到屏幕上
        this.userWidget.addToViewport(0)
        this.userWidget.zOrder = 999999
        // 给按钮绑定点击事件
        this.sureBtn.onClicked.add(() => {
            // 点击确定按钮后，隐藏加载UI
            this.userWidget.visibility = SlateVisibility.Hidden
        })
    }

    /**
     * 设置提示内容
     * @param str 
     */
    public setTips(str: string) {
        this.tipsText.text = str
    }

    /**
     * 设置进度条
     * @param percent 
     */
    public setProgress(percent: number) {
        this.playProgressAnim(percent)
    }

    /**
     * 开始加载
     * @param str 
     */
    public startLoading(str: string) {
        this.titleText.text = str
        this.progressBar.percent = 0
        this.progressText.text = "0%"
        this.sureBtn.visibility = SlateVisibility.Hidden
        this.tipsText.visibility = SlateVisibility.Visible
    }

    /**
     * 完成加载
     */
    public finishLoading() {
        this.sureBtn.visibility = SlateVisibility.Visible
        this.tipsText.visibility = SlateVisibility.Hidden
    }


    /**用来播放插值动画的间隔函数 */
    animInter: any

    /**
     * 播放进度条动画
     * @param targetPercent 目标百分比（0~1）
     * @param time 动画时长（毫秒）
     */
    private playProgressAnim(targetPercent: number, time: number = 500) {
        // 清除上一个正在播放的动画，防止冲突
        clearInterval(this.animInter)
        // 时长不能小于30毫秒
        if (time <= 30) { time = 30 }

        // 当前百分比
        const curPercent = this.progressBar.percent
        // 根据时长计算，每次tick需要更新多少百分比
        const tickPercent = (targetPercent - curPercent) / (time / 30)

        // 记录时间的变量
        let sum = 0
        // 开启一个间隔函数
        this.animInter = setInterval(() => {
            // 每次执行间隔函数，累加时间
            sum += 30
            // 当时间大于动画时长，停止动画
            if (sum > time) {
                clearInterval(this.animInter)
            }
            // 更新进度条进度以及进度条文本
            this.progressBar.percent = this.progressBar.percent + tickPercent
            this.progressText.text = (this.progressBar.percent * 100).toFixed(0) + "%"
        }, 30)
    }

}