
import { _decorator, SpriteFrame, Node, Sprite, Button, Label, Toggle, EditBox, RichText, sp, isValid, Prefab, instantiate, assetManager, UITransform, UIOpacity, ImageAsset, Component, js, builtinResMgr, UIRenderer, Material, ProgressBar, Layers, view, NodeEventType, Color, tween, Tween } from 'cc';
import { Generate } from './components/Generate';

export class UtilsPanel {

    public static getAllNeedCom(sc: any, node: Node, recursive: boolean = false) {
        SC = sc;
        let children = node.children;
        if (recursive) {
            for (let i = 0, len = children.length; i < len; i++) {
                children[i].walk(getComByName);
            }
        }
        else {
            for (let i = 0, len = children.length; i < len; i++) {
                getComByName(children[i]);
            }
        }
    }
    public static getArrCom(node: Node, name: string, count: number, type = null) {
        let arr = new Array(count);
        let children = node.children;
        let cur_connt = 0;
        for (let i = 0; i < children.length; i++) {
            if (children[i].name.startsWith(name)) {
                cur_connt++;
                let index = parseInt(children[i].name.slice(name.length));
                arr[index] = type ? children[i].getComponent(type) : children[i];
                if (cur_connt >= count) break;
            }
        }
        return arr;
    }
    
    public static addBtnEvent(btn_node: Node, func: Function, target?: any) {
        let btn = btn_node.getComponent(Button);
        if (!btn) {
            btn = btn_node.addComponent(Button);
            btn.transition = Button.Transition.SCALE;
            btn.target = btn_node;
            btn.zoomScale = 0.9;
            btn.duration = 0.1;
        }
        btn_node.on("click", func, target);
        return btn;
    }
    public static addBtnEvent2(btn_node: Node, func: string, target: any, param: string | number) {
        let btn = btn_node.getComponent(Button);
        if (!btn) {
            btn = btn_node.addComponent(Button);
            btn.transition = Button.Transition.SCALE;
            btn.target = btn_node;
            btn.zoomScale = 0.9;
            btn.duration = 0.1;
        }
        let handler = new Component.EventHandler();
        handler.target = target.node;
        handler.component = js.getClassName(target);
        handler.handler = func;
        //@ts-ignore
        handler.customEventData = param;
        btn.clickEvents.push(handler);
        return btn;
    }
    public static clearBtnEvent(node: Node, remove_btn: boolean) {
        node.off("click");
        let btn = node.getComponent(Button);
        if (btn) {
            btn.clickEvents.length = 0;
            if (remove_btn) btn.destroy();
        }
    }
    public static removeBtns(node: Node) {
        node.walk(function (node1: Node) {
            let btn = node1.getComponent(Button);
            if (btn) btn.destroy();
            node1.off("click");
        })
    }
    public static setNodeGray(node_or_btn: Node | Button, state: boolean, recursive = false) {
        let node = node_or_btn;
        let btn = null;
        if (node_or_btn instanceof Button) {
            btn = node_or_btn;
            node = node_or_btn.node;
        }
        else {
            btn = (node as Node).getComponent(Button);
        }
        if (btn) btn.interactable = state;
        // let mat_name = state ? "ui-sprite-material" : "";
        let mat = state ? null : builtinResMgr.get("ui-sprite-gray-material");

        let func = function (node0: any) {
            let btn = node0.getComponent(Button)
            btn && (btn.interactable = state);
            let com_rendener = node0.getComponent(UIRenderer);
            if (com_rendener && !com_rendener.setAnimation) com_rendener.customMaterial = mat;
        }
        if (recursive) {
            (node as Node).walk(func);
        }
        else {
            func(node);
        }
    }
    public static setItemIcon(bundle_name: string, url: string, sp_icon: Sprite) {
        assetManager.getBundle(bundle_name)?.load(url, SpriteFrame, (err: any, sp: SpriteFrame) => {
            if (err) return;
            if (isValid(sp_icon)) {
                sp_icon.spriteFrame = sp;
            }
        })
    }
    
}

var SC = null;
function getComByName(node: Node) {
    let name = node.name;
    let com = null;
    switch (name[0]) {
        case "a":
            if (name.startsWith("auto_btn_")) {
                let click_name = name.slice(10);
                let func_name = "on" + name[9].toUpperCase() + click_name + "Click";
                if (SC[func_name]) UtilsPanel.addBtnEvent(node, SC[func_name], SC);
            }
            break;
        case "b":
            if (name.startsWith("btn_")) com = node.getComponent(Button);
            break;
        case "e":
            if (name.startsWith("edit_")) com = node.getComponent(EditBox);
            break;
        case "g":
            if (name.startsWith("gene_")) com = node.getComponent(Generate);
            break;
        case "l":
            if (name.startsWith("lb_")) com = node.getComponent(Label);
            break;
        case "n":
            if (name.startsWith("node_")) com = node;
            break;
        case "r":
            if (name.startsWith("rich_")) com = node.getComponent(RichText);
            break;
        case "s":
            if (name.startsWith("spine_")) com = node.getComponent(sp.Skeleton);
            else if (name.startsWith("sp_")) com = node.getComponent(Sprite);
            else if (name.startsWith("sc_")) {
                name = name.slice(3);
                //@ts-ignore
                com = node._components[0];//cocos creator 中组件排序 如果取不到留意顺序是否出错
            }
            break;
        case "t":
            if (name.startsWith("toggle_")) com = node.getComponent(Toggle);
            break;
        case "u":
            if (name.startsWith("uitrans_")) com = node.getComponent(UITransform);
            if (name.startsWith("uiopca_")) com = node.getComponent(UIOpacity);
            break;
    }
    if (com && SC.hasOwnProperty(name)) {
        if (SC[name]) console.warn("重复调用?", name);
        SC[name] = com;
    }
}
