import { Button, Camera, Component, dragonBones, EditBox, Graphics, Label, Mask, MotionStreak, Node, PageView, ProgressBar, RichText, ScrollView, Slider, sp, Sprite, TiledMap, TiledTile, Toggle, VideoPlayer, WebView } from "cc";
import List from "../list/List";
import { AnimEvent } from "./AnimEvent";
import { RollingNumber } from "./RollingNumber";

let SYS_STANDARD_Separator = '.';
let SeparatorMap: { [key: string]: string } = {
    "Node": "cc.Node",
    "Label": "cc.Label",
    "Button": "cc.Button",
    "Sprite": "cc.Sprite",
    "RichText": "cc.RichText",
    "Mask": "cc.Mask",
    "MotionStreak": "cc.MotionStreak",
    "TiledMap": "cc.TiledMap",
    "TiledTile": "cc.TiledTile",
    "Skeleton": "sp.Skeleton",
    "Graphics": "cc.Graphics",
    "Animation": "cc.Animation",
    "WebView": "cc.WebView",
    "EditBox": "cc.EditBox",
    "ScrollView": "cc.ScrollView",
    "VideoPlayer": "cc.VideoPlayer",
    "ProgressBar": "cc.ProgressBar",
    "PageView": "cc.PageView",
    "Slider": "cc.Slider",
    "Toggle": "cc.Toggle",
    "DragonBon": "dragonBones.ArmatureDisplay",
    "List": "List",
    "AnimEvent": "AnimEvent",
    "Camera": "cc.Camera",
    "RollingNumber": "RollingNumber",
};

export class AutoBind extends Component {
    $collector: string;
    protected Node: { [name: string]: Node } = {};
    protected Label: { [name: string]: Label } = {};
    protected Button: { [name: string]: Button } = {};
    protected Sprite: { [name: string]: Sprite } = {};
    protected RichText: { [name: string]: RichText } = {};
    protected Mask: { [name: string]: Mask } = {};
    protected MotionStreak: { [name: string]: MotionStreak } = {};
    protected TiledMap: { [name: string]: TiledMap } = {};
    protected TiledTile: { [name: string]: TiledTile } = {};
    protected Skeleton: { [name: string]: sp.Skeleton } = {};
    protected Graphics: { [name: string]: Graphics } = {};
    protected Animation: { [name: string]: Animation } = {};
    protected WebView: { [name: string]: WebView } = {};
    protected EditBox: { [name: string]: EditBox } = {};
    protected VideoPlayer: { [name: string]: VideoPlayer } = {};
    protected ScrollView: { [name: string]: ScrollView } = {};
    protected ProgressBar: { [name: string]: ProgressBar } = {};
    protected Slider: { [name: string]: Slider } = {};
    protected DragonBon: { [name: string]: dragonBones.ArmatureDisplay } = {}
    protected Toggle: { [name: string]: Toggle } = {};
    protected PageView: { [name: string]: PageView } = {};
    protected List: { [name: string]: List } = {};
    protected AnimEvent: { [name: string]: AnimEvent } = {};
    protected Camera: { [name: string]: Camera } = {};
    protected RollingNumber: { [name: string]: RollingNumber } = {};


    __preload() {
        this.bindComponent(this);
    }

    // 绑定组件
    bindComponent(component: AutoBind) {
        this.bindNode(component.node, component);
    }

    // 绑定node
    bindNode(node: Node, component: AutoBind) {
        if (component.$collector === node.uuid) {
            console.warn(`重复绑定退出.${node.name}`)
            return;
        }
        component.$collector = node.uuid;
        this._bindSubNode(node, component);
    }

    // 绑定子节点
    private _bindSubNode(node: Node, component) {
        // 检测前缀是否符合绑定规范
        let name = node.name;
        if (this.checkNodePrefix(name)) {
            // 获得这个组件的类型 和 名称
            let names = this.getPrefixNames(name);
            if (names === null || names.length !== 2 || !SeparatorMap[names[0]]) {
                console.log(`${name} 命令不规范,请使用Label.xxx的格式!`);
                return;
            }
            // 未定义的类型
            if (!component[`${names[0]}`]) {
                console.log(`${name[0]} 没有在BaseUIForm中定义,并不会影响运行`);
                component[`${names[0]}`] = {};
            }
            if (component[`${names[0]}`][names[1]]) {
                console.log(`${name} 已经被绑定了,请检查您是否出现了重名的情况!`);
            }
            if (SeparatorMap[names[0]] === 'cc.Node') {
                component[`${names[0]}`][names[1]] = node;
            } else {
                component[`${names[0]}`][names[1]] = node.getComponent(SeparatorMap[names[0]]);
            }
        }
        //绑定子节点
        node.children.forEach((target: Node) => {
            this._bindSubNode(target, component);
        });
    }

    //寻找子节点
    FindChildInNode(nodeName: string, rootNode: Node): Node {
        if (rootNode.name == nodeName) {
            return rootNode;
        }
        for (let i = 0; i < rootNode.children.length; i++) {
            let node = this.FindChildInNode(nodeName, rootNode.children[i]);
            if (node) {
                return node;
            }
        }
        return null;
    }

    //检测前缀是否符合绑定规范
    checkNodePrefix(name: string) {
        if (name.indexOf(SYS_STANDARD_Separator) == -1) {
            return false;
        }
        return true;
    }

    //获得类型和Name
    getPrefixNames(name: string) {
        if (name === null) {
            return;
        }
        return name.split(SYS_STANDARD_Separator);
    }

    private _getComponentName(component: Component) {
        return component.name.match(/<.*>$/)[0].slice(1, -1);
    }
}