/*
 * @Author: YeeChan
 * @Date: 2020-12-23 11:50:28
 * @Description:
 */

import FMSkeletonExtend from "./FMSkeletonExtend";
import FMComponentExtend from "../Base/FMComponentExtend";
import SoundMgr from "../Mgr/SoundMgr";

/****************************************************
* spine对象的处理
*****************************************************/
const { ccclass, property, menu, disallowMultiple, executionOrder, requireComponent, executeInEditMode, playOnFocus } = cc._decorator;
@ccclass
@requireComponent(FMSkeletonExtend)
@disallowMultiple() //防止多个相同类型(或子类型)的组件被添加到同一个节点
@menu('FM组件/FMSpine')
export default class FMSpine extends FMComponentExtend {

    //当前的spine
    private spine: FMSkeletonExtend;
    //事件的集合
    private arrayEvent: Array<{ "name": string, "listener": FMListener }> = [];

    //槽对应的节点
    private arraySlotEvent: {} = {};

    protected EventEnumView_custom: { [key: string]: string; } = {};

    protected initView_custom() {
        //事件 监听
        this.getSpine().setEventListener((trackEntry, event) => {
            let animation = trackEntry.animation;
            let animationName = trackEntry.animation.name;
            let eventName = event.data && event.data.name;
            let eventStringValue = event.stringValue;
            let eventIntValue = event.intValue;
            let eventFloatValue = event.floatValue;

            if (eventName == "sound") {//声音事件
                SoundMgr.playSpineSound_custom(eventStringValue, animationName);
            }
            this.arrayEvent.forEach(element => {
                let name = element.name;
                let listener = element.listener;
                if (name == eventName) {
                    callFM_custom(listener, animation, animationName, eventName);
                }
            });
        });

        //this.spine.dumpSpineInfo_custom();

        //this.getSpine().debugBones = true;
    }


    /**
     * 添加槽的受影响动作及对应添加的子节点
     * @param slotName 槽名字
     * @param arrarAction 所受影响的动作
     * @param childNode 动作里的自定义子节点
     */
    addSlotByNodeEvent(slotName: string, arrarAction: string[], childNode: cc.Node[]) {
        this.arraySlotEvent[slotName] = {
            "slot": this.getSpine().findSlot(slotName),
            "arrayAction": arrarAction,
            "childNode": childNode
        }
        // console.log(slotName)
        // console.log(this.getSpine().findSlot(slotName))
    }
    /**
     * 添加事件监听
     * @param eventName 事件的名字
     * @param listener  事件的回调
     */
    addEvent(eventName: string, listener: FMListener) {
        this.arrayEvent.push({
            "name": eventName,
            "listener": listener
        })
    }

    /**
     * 移除所有的事件监听
     */
    removeEventAll() {
        this.arrayEvent = [];
    }


    /**
     * 当前播放的动画名称
     */
    animation(): string {
        return this.getSpine().animation
    }

    /**
     * 当前骨骼中所有动画的时间缩放率
     * @param scale 
     */
    setTimeScale(scale: number) {
        this.getSpine().timeScale = scale;
    }


    /**
     * 获取spine对象
     */
    getSpine(): FMSkeletonExtend {
        if (this.spine == null) {
            this.spine = this.node.getComponent(FMSkeletonExtend)
        }
        return this.spine;
    }

    update(dt: number) {
        // for (const key in this.arraySlotEvent) {
        //     if (this.arraySlotEvent.hasOwnProperty(key)) {
        //         const element = this.arraySlotEvent[key];
        //         let slot = element.slot
        //         let arrayAction: string[] = element.arrayAction;
        //         let childNode: cc.Node[] = element.childNode;
        //         for (let index = 0; index < arrayAction.length; index++) {
        //             const actionName = arrayAction[index];
        //             if (this.getSpine().animation != actionName) {//不一样
        //                 childNode.forEach(element2 => {
        //                     element2.active = false;
        //                 });
        //             }
        //         }
        //     }
        // }

        // for (const key in this.arraySlotEvent) {
        //     if (this.arraySlotEvent.hasOwnProperty(key)) {
        //         const element = this.arraySlotEvent[key];
        //         let slot = element.slot
        //         let arrayAction: string[] = element.arrayAction;
        //         let childNode: cc.Node[] = element.childNode;
        //         for (let index = 0; index < arrayAction.length; index++) {
        //             const actionName = arrayAction[index];
        //             if (this.getSpine().animation == actionName) {//不一样
        //                 childNode.forEach(element2 => {
        //                     element2.active = true;

        //                     element2.x = slot.bone.worldX;
        //                     element2.y = slot.bone.worldY;
        //                     element2.scaleX = slot.bone.scaleX;
        //                     element2.scaleY = slot.bone.scaleY;
        //                     element2.angle = slot.bone.getWorldRotationX();

        //                     element2.color = cc.color(slot.color.r * 255, slot.color.g * 255, slot.color.b * 255);
        //                     element2.opacity = slot.color.a * 255;
        //                 });
        //             }
        //         }
        //     }
        // }
        //this.getSpine()
        // vconsole.min.js:11 `cc.Node.rotationX` is deprecated since v2.1.0, please set `eulerAngles` instead. (`this.node.rotationX = x` -> `this.node.is3DNode = true; this.node.eulerAngles = cc.v3(x, 0, 0)`

    }

    /**
     * 设置当前动画。队列中的任何的动画将被清除
     * @param name 动画名字
     * @param loop 是否循环
     * @param trackIndex 队列
     */
    setAnimation(name: string, loop: boolean = false, trackIndex: number = 0) {
        this.getSpine().setAnimation(trackIndex, name, loop);
    }

    /**
     * 为所有关键帧设定混合及混合时间(从当前值开始差值)。
     * @param fromAnimation 开始动作
     * @param toAnimation 结束动作
     * @param duration 时间 
     */
    setMix(fromAnimation: string, toAnimation: string, duration: number) {
        this.getSpine().setMix(fromAnimation, toAnimation, duration);
    }

    /**
     * 按名称查找皮肤,激活该皮肤
     * @param skinName 
     */
    setSkin(skinName: string) {
        this.getSpine().setSkin(skinName);
    }

}