import { _decorator, Button, Component, easing, EventHandler, EventTouch, js, Node, Tween, tween, Vec3 } from 'cc';
import { uiMgr } from '../manager/UIManager';
import { eventEmitter } from '../event/EventEmitter';
import Utils from '../utils/Utils';
import { GameConst } from '../common/GameConst';
import { Logger } from '../extend/Logger';
import { initAutoBindings } from '../extend/AutoBind';
const { ccclass, property } = _decorator;

@ccclass('BaseExp')
export class BaseExp extends Component {
    layer: number = GameConst.WIN_LAYER.POPUP;
    winType: number = GameConst.WIN_TYPE.NORMAL;
    destroyAfterClose: boolean = false//关闭后销毁资源
    //事件数组
    private events:any[] = [];
    
    //是否有出场动画
    private _hasAnim: boolean = true;
    public set hasAnim(value: boolean) {
        if(value){
           this.showAnim();
        }
        this._hasAnim = value;
    }
    
    public onLoad() {
        this.events = [];
        //加入按钮点击
        this._addClickEvent(this.node);
        //自动绑定属性
        initAutoBindings(this);
        
    }

    /**
     * 展示加载缓动动画
     */
    public showAnim(){
        let uiBG: Node = this.node.getChildByName("UI");
        if(uiBG){
            Tween.stopAllByTarget(uiBG);
            uiBG.scale = new Vec3(0.95,0.95,0.95);
            tween(uiBG)
            .to(0.12, {scale: new Vec3(1.04,1.04,1.04)}, {easing: easing.backOut})
            .to(0.2, {scale: new Vec3(1,1,1)}, { easing: easing.backOut })
            .call(()=> {
            })
            .start();
        }
    }

    /**
     * 关闭页面
     * @param cb 关闭页面的回调
     */
    private close(cb?: Function){
        let pagePath: string = this.node["_uiPath"];
        if(!Utils.isNull(pagePath)){
            uiMgr.hide(pagePath,cb);
        }else{
            Logger.log(`请检查该: ${this.node.name}页面路径信息，不存在`);
        }
    }

    /**
     * 点击事件
     * @param event 事件
     * @param customEventData 数据
     */
    public onBtnClicked(event:EventTouch, customEventData:any) {
        let btnName = event.target.name;
        if(btnName === 'close_btn'){
           this.close();
        }
    }

    /**
     * 是否允许添加
     * @param node 添加的节点
     */
    private _isSkipNode(node: Node): boolean {
        if(this.node == node) {
           return false;
        }
        let b = node.getComponent(BaseExp);
        if (b) Logger.log("跳过", b.name)
        return b != null;
    }

    /**
     * 加入点击事件
     * @param node 加入点击的节点
     */
    private _addClickEvent(node: Node) {
        if (this._isSkipNode(node)) return;
        for (let i = 0; i < node.children.length; i++) {
            let n:Node = node.children[i];
            if(this._isSkipNode(n)) continue;
            if(n.getComponent(Button)) {
                this.addClickEvent(n, this.node, js.getClassName(this), "onBtnClicked", n);
            }
            this._addClickEvent(n);
        }
    }

    /**
     * 加入按钮点击事件
     * @param node 点击的节点
     * @param target 点击的对象
     * @param component 组建的类名
     * @param handler 处理的具柄
     * @param customEventData 传递的数据
     */
    private addClickEvent(node, target, component, handler, customEventData) {
        let eventHandler = new EventHandler()
        eventHandler.target = target;
        eventHandler.component = component;
        eventHandler.handler = handler;               
        if(customEventData){
           eventHandler.customEventData = customEventData;
        }
        let clickEvents = node.getComponent(Button).clickEvents;
        if (clickEvents.length > 0) {
            Logger.log(`${node.name}按钮已经存在绑定，跳过自动绑定`);
            return;
        }
        clickEvents.push(eventHandler);
    }

    //销毁的时候注销所有的事件
    public onDestroy() {
        for(let i = 0; i < this.events.length; i++){
            eventEmitter.unregister(this, this.events[i]);
        }
    }

    //注册事件
    public register(type: any, cb: Function) {
        this.events.push(type);
        eventEmitter.register(this, type, cb);
    }

    //取消注册的时间
    public unregister(type: any) {
        eventEmitter.unregister(this, type);
    }

    //事件派发
    public dispatch(type: any, ...data: any[]) {
        eventEmitter.dispatch(type, ...data);
    }
}

