import CCGIF from "./lib/gif/CCGIF";
import { GIFCache } from "./lib/gif/GIF";


const { ccclass, property } = cc._decorator;

@ccclass
export default class GameManager extends cc.Component {

    public static Instance: GameManager = null;

    @property(cc.Node)
    CharaNode: cc.Node = null;
    @property(cc.Node)
    TargetCharaNode: cc.Node = null;
    @property(cc.Prefab)
    CharaPre: cc.Prefab = null;
    @property(cc.Node)
    lineNode: cc.Node = null;
    @property(cc.Label)
    scoreLabel: cc.Label = null;
    @property(cc.Node)
    GifNode: cc.Node = null;
    @property(cc.Prefab)
    CharaNumber: cc.Prefab = null;
    @property(cc.Node)
    CharaNumberList: cc.Node = null;

    TargetChara: cc.Node = null;

    @property(cc.SpriteFrame)
    AllChara: cc.SpriteFrame[] = [];

    score: number = 0;
    endOne: number = 0;//限制次数
    CharaHeigth: number = 0;//下面水果中最高的高度

    CharaSize:number = 1.5
    CharaNumberRec:number[] = [];

    // LIFE-CYCLE CALLBACKS:

    onLoad() {
        cc.view.enableAutoFullScreen(false);
        if (GameManager.Instance != null) {
            GameManager.Instance.destroy();
        }
        GameManager.Instance = this;
        cc.director.getPhysicsManager().enabled = true;//物理游戏，开启物理
    }

    start() {
        this.GifNode.getComponent(CCGIF).preload().then(()=>this.GifNode.getComponent(CCGIF).play(true));
        cc.tween(this.lineNode.children[0])
            .to(0.3, { opacity: 255 })
            .to(0.3, { opacity: 0 })
            .union()
            .repeatForever()
            .start()
        this.lineNode.children[0].active = false;
        for (const index in this.AllChara) {
            if (Object.prototype.hasOwnProperty.call(this.AllChara, index)) {
                const Chara = this.AllChara[index];
                var CharaNum = cc.instantiate(this.CharaNumber);
                CharaNum.setParent(this.CharaNumberList);
                CharaNum.children[0].getComponent(cc.Sprite).spriteFrame = Chara;
                this.CharaNumberRec[index]=0
            }
        }
        this.updateCharaNumber();
        this.createOneChara(0, cc.v2(0, 550))
    }

    update(dt) {
        GameManager.Instance.CharaHeigth = GameManager.Instance.findHighestChara();
        this.scoreLabel.string = this.score.toString();
        this.checkRedLineAlert();
    }

    /**
     * 生成一个水果
     * @param _CharaNum 水果类型 0是葡萄 以此类推
     */
    createOneChara(_CharaNum: number, _pos: cc.Vec2 ) {
        for (const index in this.TargetCharaNode.children) {
            if (Object.prototype.hasOwnProperty.call(this.TargetCharaNode.children, index)) {
                const childNode = this.TargetCharaNode.children[index];
                if(childNode.position.y>=500) childNode.destroy();
            }
        }
        let Chara = cc.instantiate(this.CharaPre);//实例化一个预制体
        Chara.setParent(this.TargetCharaNode)//更改Chara父节点
        Chara.getComponent(cc.Sprite).spriteFrame = this.AllChara[_CharaNum];//更改Chara的图片
        Chara.getComponent("CharaCollision").CharaNumber = _CharaNum;//Chara碰撞回调脚本，里面有一个当前水果类型 如果是葡萄 CharaNumber为0 用于相同合成检测
        Chara.setPosition(_pos);//设置坐标
        Chara.setScale(0)//出生时scale设置为0
        Chara.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static;//刚体类型设置为Static防止下落
        Chara.getComponent(cc.PhysicsCircleCollider).radius = 0;//碰撞器半径先设置位0，下落时再改到相应水果大小
        Chara.setContentSize(this.resizeChara(Chara.getContentSize(),_CharaNum));
        Chara.getComponent(cc.PhysicsCircleCollider).apply();//保存碰撞器更改的参数

        //水果生成时执行一个缩放动作
        cc.tween(Chara)
            .to(0.5, { scale: 1 }, { easing: 'backOut' })
            .call(() => {
                this.TargetChara = Chara;//将我们控制的水果TargetChara设置为刚生成的Chara
            })
            .start()
    }

    /**
     * 生成高一级的水果
     * @param _CharaNum 水果
     */
    createLevelUpChara(_CharaNum , _pos) {
        //AudioManager.Instance.Play(6, false, 1)
        let Chara = cc.instantiate(this.CharaPre);
        Chara.parent = this.CharaNode;

        Chara.getComponent(cc.Sprite).spriteFrame = this.AllChara[_CharaNum];
        Chara.getComponent("CharaCollision").CharaNumber = _CharaNum;
        Chara.position = _pos;
        Chara.scale = 0;
        Chara.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, -100);
        Chara.getComponent(cc.PhysicsCircleCollider).radius = Chara.height / 2;
        Chara.setContentSize(this.resizeChara(Chara.getContentSize(),_CharaNum));
        Chara.getComponent(cc.PhysicsCircleCollider).apply();
        cc.tween(Chara)
            .to(0.5, { scale: 1 }, { easing: 'backOut' })
            .call(() => {
                if (Chara.getComponent(cc.PhysicsCircleCollider) != null) {
                    if (Chara.getComponent(cc.PhysicsCircleCollider).radius != Chara.height / 2) Chara.getComponent(cc.PhysicsCircleCollider).radius = Chara.height / 2;
                    if (Chara.getComponent(cc.RigidBody).type != cc.RigidBodyType.Dynamic) Chara.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;
                    Chara.getComponent(cc.PhysicsCircleCollider).apply();
                }

            })
            .start()
    }

    randomOneChara(){
        let randomIndexArray:number[] = [];
        for (let index = 0; index < GameManager.Instance.AllChara.length*0.5; index++) {
            randomIndexArray.push(index);
            for (let i = 0; i < GameManager.Instance.CharaNumberRec[index]; i++) {
                randomIndexArray.push(index)
                randomIndexArray.push(index)
            }
        }
        // GameManager.Instance.createOneChara(Math.floor(Math.random() * GameManager.Instance.AllChara.length*0.5), cc.v2(0, 550));
        GameManager.Instance.createOneChara(randomIndexArray[Math.floor(Math.random() * randomIndexArray.length)], cc.v2(0, 550));
    }

    resizeChara(size: cc.Size,_CharaNum: number){
        return new cc.Size(size.width*this.CharaSize*Math.pow((_CharaNum+1)/this.AllChara.length,4/5),size.height*this.CharaSize*Math.pow((_CharaNum+1)/this.AllChara.length,4/5))
    }

    updateCharaNumber(){
        for (const index in this.CharaNumberRec) {
            if (Object.prototype.hasOwnProperty.call(this.CharaNumberRec, index)) {
                const value = this.CharaNumberRec[index];
                console.log(this.CharaNumberList.children[index].children[1].getComponent(cc.Label).string);
                this.CharaNumberList.children[index].children[1].getComponent(cc.Label).string=value.toString();
            }
        }
    }

    checkRedLineAlert(){
        //  红线是否开启预警
        if (this.lineNode.children[0].y - GameManager.Instance.CharaHeigth < 200 && this.lineNode.children[0].y - GameManager.Instance.CharaHeigth >= 0) {
            this.lineNode.children[0].active = true;
        }
        if (this.lineNode.children[0].y - GameManager.Instance.CharaHeigth > 200) {
            this.lineNode.children[0].active = false;
        }
    }

    //  结束
    end() {
        if (this.endOne == 0) {
            let i = 0;
            for (let j = this.CharaNode.children.length - 1; j >= 0; j--) {
                i++;
                setTimeout(() => {
                    GameManager.Instance.score += this.CharaNode.children[j].getComponent("CharaCollision").CharaNumber + 1;
                    this.CharaNode.children[j].active = false;
                }, i * 100);
            }

            this.TargetCharaNode.active = true;
            for (let i = 0; i < this.TargetCharaNode.children.length; i++) {
                this.TargetCharaNode.children[i].active = false;
            }
            this.endOne++;
        }

    }

    //  获取下落水果中位置最高的
    findHighestChara() {
        if(this.CharaNode.children.length>0){
            let highest = this.CharaNode.children[0].y;
            for (let i = 1; i < this.CharaNode.children.length; i++) {
                let high = this.CharaNode.children[i].y + this.CharaNode.children[i].width / 2;
                if (highest < high) {
                    highest = high;
                }
            }
            return highest;
        }else{
            return 0;
        }
    }

}
