import FSprite from "../object/FSprite";
import CMath from "../../../util/CMath";
import FMap from "../map/FMap";
import { __SkillData } from "../../data/sdata/SManage";
import BEffect from "./BEffect";

/**
 * 子弹
 */
const { ccclass, property } = cc._decorator;

@ccclass
export default class BObject extends cc.Component {

    @property({
        displayName: '子弹速度'
    })
    speed: number = 2000;//子弹速度

    distance: number = 500;//子弹攻击距离

    @property({
        type: cc.Prefab,
        displayName: '施法特效'
    })
    mStartEffect: cc.Prefab = null;

    @property({
        type: cc.Prefab,
        displayName: '击中目标特效'
    })
    mHitEffect: cc.Prefab = null;

    @property({
        type: cc.Material,
        displayName: '击中目标材质'
    })
    mHitMaterial: cc.Material = null;

    @property({
        displayName: '材质颜色'
    })
    mHitColor: cc.Color = new cc.Color();

    private mRigidBody: cc.RigidBody;//刚体

    private map: FMap;
    /**
     * 子弹所属角色
     */
    public sprite: FSprite;
    /**
     * 子弹附带的技能
     */
    public _skillData: __SkillData
    /**
     * 子弹发射的位置
     */
    private origin: cc.Vec2;

    private img: cc.Node;
    private shadow: cc.Node;

    onLoad() {
        this.mRigidBody = this.node.getComponent(cc.RigidBody);

        this.img = this.node.children[0];
        if (this.node.children.length > 1) {
            this.shadow = this.node.children[1];
        }
    }
    public setSprite(sprite: FSprite) {
        this.sprite = sprite;
        this.map = sprite.map;
    }
    /**
     * 向目标发射
     * @param node 
     */
    public fire(node: cc.Node) {
        let p1 = this.node.getPosition();
        let p2 = node.getPosition();
        let p3 = p2.clone();
        p3.y += node.height / 2;
        this.fireAB(p1, p3);
    }
    public firePos(p2: cc.Vec2) {
        let p1 = this.node.getPosition();
        this.fireAB(p1, p2);
    }
    /**
    * 向某方向发射
    * @param dir 
    */
    public fireDir(dir) {
        this.fireAB(cc.Vec2.ZERO_R, dir);
    }
    /**
     * @param p1 坐标原点
     * @param p2 瞄准的坐标
     */
    public fireAB(p1, p2) {
        this.origin = this.node.getPosition();
        let angle = CMath.getAngle(p1, p2);
        this.img.angle = angle * 180 / Math.PI;

        let pos = cc.v2();
        pos.x = Math.cos(angle) * this.speed;
        pos.y = Math.sin(angle) * this.speed;

        this.mRigidBody.applyLinearImpulse(
            pos,
            this.mRigidBody.getWorldCenter(),
            true
        );
    }
    //弧度
    public fireAngle(angle) {
        this.origin = this.node.getPosition();
        this.img.angle = angle * 180 / Math.PI;

        let pos = cc.v2();
        pos.x = Math.cos(angle) * this.speed;
        pos.y = Math.sin(angle) * this.speed;

        this.mRigidBody.applyLinearImpulse(
            pos,
            this.mRigidBody.getWorldCenter(),
            true
        );
    }
    //弧度
    public fireAngle2(angle) {
        this.origin = this.node.getPosition();
        // this.node.angle = angle*180/Math.PI;

        let pos = cc.v2();
        pos.x = Math.cos(angle) * this.speed;
        pos.y = Math.sin(angle) * this.speed;

        this.mRigidBody.applyLinearImpulse(
            pos,
            this.mRigidBody.getWorldCenter(),
            true
        );
    }
    //角度
    public fireAngle1(angle) {
        this.origin = this.node.getPosition();
        this.img.angle = angle;
        let hd = angle * Math.PI / 180
        let pos = cc.v2();
        pos.x = Math.cos(hd) * this.speed;
        pos.y = Math.sin(hd) * this.speed;

        this.mRigidBody.applyLinearImpulse(
            pos,
            this.mRigidBody.getWorldCenter(),
            true
        );
    }
    public fireAngleV2(v2: cc.Vec2) {
        if (v2.x == 0 && v2.y == 0) {
            v2.x = 1;
        }
        this.origin = this.node.getPosition();
        let pos = cc.v2();
        pos.x = v2.x * this.speed;
        pos.y = v2.y * this.speed;

        this.img.angle = Math.atan2(v2.y, v2.x) * 180 / Math.PI;

        this.mRigidBody.applyLinearImpulse(
            pos,
            this.mRigidBody.getWorldCenter(),
            true
        );
    }


    update(dt) {
        if (this.sprite && this.sprite.isValid && this.sprite.hp > 0) {
            let dis = cc.Vec2.distance(this.origin, this.node.getPosition());
            if (dis >= this.distance) {
                this.node.destroy();
            }
        } else {
            this.node.destroy();
        }
    }


    public __destroy() {
        let node = cc.instantiate(this.mHitEffect);
        node.addComponent(BEffect)
        node.x = this.node.x;
        node.y = this.node.y;
        node.parent = this.map.node;
        this.node.destroy();
    }
    private isMaterial = false;
    public updateMaterial(sprite: FSprite) {
        if (this.isMaterial) {
            return
        }
        this.isMaterial = true;
        if (this.mHitMaterial) {
            sprite.spine.setMaterial(0, this.mHitMaterial)
            let _material = sprite.spine.getMaterial(0);
            _material.setProperty("u_rate", 1);
            _material.setProperty("u_color", this.mHitColor);
            sprite.spine.setMaterial(0, _material)
            let rate = 1;
            sprite.schedule(() => {
                rate -= 0.1
                if (rate <= 0.3) {
                    rate = 0.3;
                    _material.setProperty("u_rate", 1);
                    sprite.spine.setMaterial(0, _material)
                    this.isMaterial = false;
                } else {
                    // cc.log('============= rate',rate);
                    _material.setProperty("u_rate", rate);
                    sprite.spine.setMaterial(0, _material)
                }
            }, 0.01, 8)
        }
    }

    smokeEffect(pos: cc.Vec3) {
        cc.loader.loadRes("icon/effect_sj/effect/effect_smoke.json", sp.SkeletonData, (err, res)=>{
            if(err){
                console.log("===load smokeEffect err====", err)
                return
            }
            let node = new cc.Node();
            node.name = "smokeEffect";
            node.parent = this.map.node;
            node.setPosition(pos);
            let spine = node.addComponent(sp.Skeleton);
            spine.skeletonData = res;
            spine.setAnimation(0, "animation", false);
            spine.setCompleteListener(()=>{
                node.destroy();
            })
        })
    }

    onBeginContact(contact: cc.PhysicsContact, self: cc.PhysicsCollider, other: cc.PhysicsCollider) {
        if (self.node == this.node) {
            if (other.tag != 0) {
                if (other.tag == 103 || other.tag == 100) {   // 箱子
                    this.smokeEffect(self.node.position);
                    this.node.destroy();
                }else if (other.tag == 104) {//树不用碰撞

                }
            } else if (other.node.group == 'map') {//撞到地图
                this.__destroy();
            } else {
                if (this.sprite && this.sprite.isValid && this.sprite.hp > 0 &&
                    this.sprite.node.group != other.node.group) {
                    if (self.isValid && other.node.isValid) {
                        let otherNode = other.node as cc.Node;
                        let target = otherNode.getComponent(FSprite);
                        if (target.hp > 0) {
                            if (target != null && target.isActive) {
                                this.sprite.atkjs(target, this._skillData);
                                this.__destroy();
                                this.updateMaterial(target)
                            }
                        }
                    }

                }
            }
        }
    }
}
