import FMap from "./map/FMap";
import ViewObject from "../../main/ViewObject";
import FSprite from "./object/FSprite";
import FLiteMap from "./map/FLiteMap";
import CMath from "../../util/CMath";
import FExitBox from "./box/FExitBox";
import FObject, { GroupType } from "./object/FObject";
import AIPet from "./object/AI/AIPet";
import FControl from "./FControl";
import { HttpStateType, ReveData } from "../../util/CHttp";
import FFHeader from "./FFHeader";
import FPanel from "./object/FPanel";
import { RewardData } from "../data/sdata/SManage";
import FObjectFly from "./FObjectFly";
import MSprite from "./object/MSprite";
import PSprite from "./object/PSprite";
import FCountDown from "./FCountDown";
import Joystick from "../../util/Joystick";
import FFRes from "./FFRes";
import FPanelIcon from "./object/FPanelIcon";
import { EquipAttr, PetAttr } from "../data/udata/Player";
import FFCalAttr from "../data/FFCalAttr";
import { AudioMgr, GameViewType } from "../../main/ViewManage";
import FTmpGood from "./evnet/FTmpGood";
import TapSetMusic from "../setting/TapSetMusic";
import RedPoint from "../data/RedPoint";
import Joystick_mag from "../../joystick/Joystick_mag";

/**
 * 战斗控制器
 */
const { ccclass, property } = cc._decorator;

export const FF_Result_Type = cc.Enum({
    none: 0,//还没有结果
    fail: 1,//被打败
    win: 2,//胜利
});

@ccclass
export default class FF extends ViewObject {

    @property(cc.Node)
    mBlockInputEvents: cc.Node = null;//顶层遮罩

    @property(cc.Node)
    mMapLayer: cc.Node = null;//地图层

    // @property(Joystick_8d)
    // mJoystick: Joystick_8d = null;//操纵杆

    @property(Joystick_mag)
    mJoystick: Joystick_mag = null;//操纵杆

    @property(FLiteMap)
    mLietMap: FLiteMap = null;//小地图

    @property(cc.Node)
    mControl: cc.Node = null;//控制器

    @property(cc.Font)
    mRed: cc.Font = null;//红色字

    @property(cc.Font)
    mBjFont: cc.Font = null;//暴击掉血字

    @property(cc.Font)
    mSkillFont: cc.Font = null;//技能掉血字

    @property(cc.Node)
    mMu: cc.Node = null;//迷雾

    @property(cc.Prefab)
    mExitBox: cc.Prefab = null;//退出

    @property(cc.Prefab)
    mMapDialog: cc.Prefab = null;//地图中对话框

    @property(cc.SpriteFrame)
    mActiveIcon: cc.SpriteFrame = null;//怪物未激活头顶图片

    @property(cc.SpriteFrame)
    mDeadIcon: cc.SpriteFrame = null;//角色死亡怪物头顶图片

    @property(FFHeader)
    mFFheader: FFHeader = null;//表头显示

    @property(FPanel)
    mSmailHP: FPanel = null;//小怪

    @property(FPanel)
    mBossHP: FPanel = null;//boss

    @property(cc.Node)
    mTop: cc.Node = null;//顶部的菜单

    // @property(cc.Node)
    // mTmpTask: cc.Node = null;//临时任务道具显示

    @property(FCountDown)
    mCountDown: FCountDown = null;//倒计时

    @property(cc.AudioClip)
    mWalk: cc.AudioClip = null;//行走音乐

    @property(cc.AudioClip)
    mRun: cc.AudioClip = null;//跑步音乐

    /**
     * 控制器
     */
    public control: FControl = null;

    /**
     * 资源管理器
     */
    public fres: FFRes = null;
    /**
     * 主角
     */
    public mainSprite: MSprite = null;

    mMap: FMap = null;//地图
    /**
     * 战斗结果
     */
    public ffResultType = 0;
    /**
     * 顶层遮罩点击消息
     */
    public blockInputCallback: () => void;
    /**
     * 监听精灵移除事件,全局监听
     */
    public clearCallback: (result: FObject) => void;

    /**
     * 监听精灵移除事件,全局监听
     */
    public removeCallback: (result: FObject) => void;
    /**
     * 走到退出点回调
     */
    public exitCallback: () => void;
    /**
     * 是否不锁摄像机
     */
    public lockCamera = true;

    /**
     * 是否复活过
     */
    public isBack = false;

    onLoad() {
        cc.director.getPhysicsManager().enabled = true;

        this.control = this.mControl.getComponent(FControl);
        this.fres = this.node.getComponent(FFRes);
        this.mCountDown.setCallback(() => {
            this.clearCallback(this.mainSprite);
        });
    }
    onDestroy() {
        // this.main.stopAll();
    }

    public stopRuning() {
        this.mJoystick.stop();
    }
    public startRuning() {
    }
    /**
     * 监听精灵移除事件
     * @param resultCallback 
     */
    public regClearCallback(clearCallback: (result: FObject) => void) {
        this.clearCallback = clearCallback;
    }
    /**
     * 监听事件中对象移除
     * @param resultCallback 
     */
    public regRemoveCallback(clearCallback: (result: FObject) => void) {
        this.removeCallback = clearCallback;
    }
    /**
     * 退出副本监听
     * @param exitCallback 
     */
    public regExitCallback(exitCallback: () => void) {
        this.exitCallback = exitCallback;
    }
    public loadMap(map: FMap) {
        this.mMap = map;
        this.mMap.mCamera = this.main.mMapCamera;
        this.mMap.mCamera.zoomRatio = 1;

        this.mMap.setFF(this);
        this.mMap.node.parent = this.mMapLayer;
        map.node.zIndex = 0;

        this.mMapLayer.x = -cc.winSize.width / 2
        this.mMapLayer.y = -cc.winSize.height / 2;
        this.mMu.zIndex = 9999;
        this.mMu.width = cc.winSize.width * 2;
        this.mMu.height = cc.winSize.height * 2;
        this.mMu.active = true;


        this.mLietMap.initMap(this);

        let nodes = this.mMap.getSprites();

        nodes.forEach(node => {
            let fobj = node.getComponent(FObject);
            if (fobj) {
                fobj.ff = this;
                fobj.map = this.mMap;
            }
        });
    }
    public update(dt) {
        //更新摄像机位置
        if (this.lockCamera && this.mainSprite) {
            let node = this.mainSprite.node;
            this.mMap.updateShoot(node.x, node.y);
            this.mLietMap.clearMask(node.getPosition());
        }
    }
    /**
     * 载入角色
     */
    public loadRole(sprites: Array<FSprite>) {
        for (let i = 0; i < sprites.length; i++) {
            const element = sprites[i];
            if (element instanceof MSprite) {
                this.mainSprite = element;
                element.setPosition(this.mMap.mInit.getPosition());
            }
        }
        this.mainSprite.setJoystick(this.mJoystick);

        let leader = this.mainSprite;
        for (let i = 0; i < sprites.length; i++) {
            const element = sprites[i];
            if (element instanceof PSprite) {
                (element as PSprite).setLeader(leader);
                leader.setNext(element);
                leader = element as any;
                element.addComponent(AIPet);
            }
            element.node.group = GroupType.A;
            this.mMap.addSprite(element);

            element.addPanelHUD();
        }

        let node = this.mainSprite.node;
        this.mMap.updateShoot(node.x, node.y);
        this.mLietMap.clearMask(node.getPosition());
        this.mMap.initCamera();
        this.control.updateSkill()
    }
    /**
     * 添加角色
     * @param sprite 
     */
    public addRole(sprite: PSprite) {
        let sp = this.mainSprite as any;
        while (sp.nextSprite) {
            sp = sp.nextSprite;
        }
        sprite.setLeader(sp);
        sp.setNext(sprite);
        sprite.node.group = GroupType.A;
        this.mMap.addSprite(sprite);
        sprite.addPanelHUD();
    }
    /**
     * 更新面板中的角色
     */
    public updateRole() {
        let res = this.fres;
        let nodes = res.mHudNode.children

        for (let i = 0; i < nodes.length; i++) {
            const element = nodes[i];
            let panelIcon = element.getComponent(FPanelIcon)
            let sprite = panelIcon.sprite

            let ffAttr = sprite.attrData

            let petAttr: PetAttr = this.main.player.pet[ffAttr.id]

            let newAttr = FFCalAttr.getAttr(this.main, petAttr)

            sprite.flushAttrData(newAttr)
            panelIcon.setIcon()
        }
        if (this.mainSprite && this.mainSprite.isValid) {
            this.mainSprite.setAttrData(this.mainSprite.attrData)
            this.control.updateSkill()
        }
    }

    public getRandInit(): cc.Vec2 {
        let pos = cc.v2();
        pos.x = CMath.getRandom(this.mMap.mInit.x - 100, this.mMap.mInit.x + 100);
        pos.y = CMath.getRandom(this.mMap.mInit.y - 100, this.mMap.mInit.y + 100);
        return pos;
    }
    /**
     * 当前存活的数量
     */
    public activeCount(): number {
        let sprites = this.mMap.getSprites();
        let count = 0;
        for (let i = 0; i < sprites.length; i++) {
            const node = sprites[i];
            if (node.group == GroupType.A) {
                count++;
            }
        }
        return count;
    }
    public getGroupBy(group: string): Array<FSprite> {
        let ffs = [];
        let sprites = this.mMap.getSprites();
        for (let i = 0; i < sprites.length; i++) {
            const node = sprites[i];
            if (node.group == group) {
                ffs.push(node.getComponent(FSprite));
            }
        }
        return ffs;
    }
    /**
     * 点击退出按钮
     */
    public onclickExit() {
        let node = cc.instantiate(this.mExitBox);
        let exitBox = node.getComponent(FExitBox);
        exitBox.main = this.main;
        exitBox.endType = 1
        exitBox.init(this.mFFheader.stageData);

        exitBox.show();
        exitBox.setOKCallback(() => {
            this.exitDistroy();
            this.main.topNode.active = true;
            this.main.playMusicByPath(AudioMgr.homeMusic);
        });
        this.pauseSprite(true)
        exitBox.setCloseCallback(() => {
            this.pauseSprite(false)
        })
    }
    /**
     * 捡起地图上的物品
     * @param objectId 
     */
    public getMapObject(objectId: string) {
        let msg = {
            objectId: objectId
        }
        this.main.gameHttp.sendJson('stage/v1/stageObject', msg, (state, reve: ReveData) => {
            this.main.stopLoad();
            if (state == HttpStateType.SUCCESS) {
                if (reve.retCode == 0) {
                    //"_stage":{"good":{"1001":1}}
                    let player = this.main.player;
                    let stage = player.stage;
                    stage.element.push(objectId);
                    stage.data[this.mFFheader.stageData.id] = reve.data._stage;
                    this.mFFheader.flush();

                    this.main.showTips1(reve)
                } else {
                    this.main.showTips(reve.message);
                }
            } else {
                this.main.showTips('网络异常');
            }
        });
    }
    /**
     * 暂停所有精灵
     */
    public pauseSprite(pause: boolean) {
        this.lockCamera = !pause;
        let nodes = this.mMap.getSprites();
        nodes.forEach(node => {
            let sprite = node.getComponent(FSprite);
            if (sprite) {
                sprite.setPause(pause)
            }
        });
        if (pause) {
            this.mJoystick.stop();
            if (this.mainSprite) {
                this.mainSprite.setShooting(false);
            }
            this.uiOutAction();
            cc.director.getPhysicsManager().enabled = false
        } else {
            this.uiInAction();
            cc.director.getPhysicsManager().enabled = true;
        }
    }
    /**
     * ui离场
     */
    private uiOutAction() {
        this.mJoystick.node.active = false;
        // this.mLietMap.node.active = false;
        this.mControl.active = false;
        this.mTop.active = false;
        // this.mTmpTask.active = false;
    }
    /**
     * ui显示
     */
    private uiInAction() {
        this.mJoystick.node.active = true;
        // this.mLietMap.node.active = true;
        this.mControl.active = true;
        this.mTop.active = true;
        // this.mTmpTask.active = true;
    }
    /**
     * 刷新当前攻击的对象
     * @param sprite 
     */
    public flushHP(sprite: FSprite) {
        this.mBossHP.node.active = false;
        this.mSmailHP.node.active = false;
        if (sprite.hp <= 0) {
            return;
        }
        let panelHP: FPanel = null;
        if (sprite.attrData.type == 2) {//boss
            panelHP = this.mBossHP;
        } else {
            panelHP = this.mSmailHP;
        }
        panelHP.node.active = true;
        panelHP.sprite = sprite;
        panelHP.updatePanel();
        panelHP.setCancel();
    }
    /**
     * 更新气血
     * @param sprite 
     */
    public updateHP(sprite: FSprite) {
        let panelHP: FPanel = null;
        if (this.mBossHP.node.active) {
            panelHP = this.mBossHP;
        } else if (this.mSmailHP.node.active) {
            panelHP = this.mSmailHP;
        }
        if (panelHP && sprite == panelHP.sprite) {
            panelHP.updatePanel();
        }
    }
    /**
     * 添加到地图上,飞到背包
     * @param icons 
     */
    public addGoods(list: Array<RewardData>, pos: cc.Vec2) {
        list.forEach(element => {
            cc.resources.load(element.icon, cc.SpriteFrame, (err, spriteFrame: cc.SpriteFrame) => {
                if (err) {
                    cc.error(err);
                } else {
                    let node = new cc.Node();
                    node.group = 'map';
                    let sprite = node.addComponent(cc.Sprite);
                    sprite.spriteFrame = spriteFrame;

                    node.x = pos.x;
                    node.y = pos.y;
                    node.parent = this.mMap.mSprites;

                    let fly = node.addComponent(FObjectFly);
                    fly.ff = this;
                    node.setScale(1.5);
                    let jumpDis = CMath.getRandom(-100, 100);
                    let jumpBy = cc.jumpBy(0.5, cc.v2(jumpDis, 0), 100, 1);
                    cc.tween(node).sequence(
                        jumpBy,
                        cc.delayTime(0.5),
                        cc.callFunc(() => {
                            this.main.playerEffectByPath(AudioMgr.getCoin);
                            fly.move = true;
                            cc.tween(node).repeatForever(
                                cc.rotateBy(1, 360)
                            ).start()
                        })
                    ).start()

                }
            });

        });
    }
    /**
     * 道具掉地上
     * @param goodId 
     * @param goodCount 
     * @param pos 
     */
    public addGoodToMap(goodId, pos: cc.Vec2) {
        let manage = this.main.sManage
        let _good = manage.getGoodById1(goodId)
        cc.resources.load('icon/good/' + _good.icon, cc.SpriteFrame, (err, spriteFrame: cc.SpriteFrame) => {
            if (err) {
                cc.error(err);
            } else {
                let node = new cc.Node();
                node.group = 'map';
                let sprite = node.addComponent(cc.Sprite);
                sprite.spriteFrame = spriteFrame;
                let tmpGood = node.addComponent(FTmpGood)
                tmpGood.goodId = goodId

                let rigidBody = node.addComponent(cc.RigidBody)
                rigidBody.enabledContactListener = true
                rigidBody.type = cc.RigidBodyType.Static

                let physicsBoxCollider = node.addComponent(cc.PhysicsBoxCollider)
                physicsBoxCollider.sensor = true
                physicsBoxCollider.size.width = spriteFrame.getRect().width
                physicsBoxCollider.size.height = spriteFrame.getRect().height

                node.x = pos.x;
                node.y = pos.y;
                node.parent = this.mMap.mSprites;
                node.setScale(1.5);
                let jumpDis = CMath.getRandom(-100, 100);
                let jumpBy = cc.jumpBy(0.5, cc.v2(jumpDis, 0), 100, 1);
                cc.tween(node).sequence(
                    jumpBy,
                    cc.delayTime(0.5),
                    cc.callFunc(() => {
                        cc.tween(node).repeatForever(
                            cc.rotateBy(1, 360)
                        ).start()
                    })
                ).start()

            }
        });
    }

    public setBlockInputCallback(callback: () => void) {
        this.blockInputCallback = callback;
    }

    public blockInputEvents() {
        if (this.blockInputCallback) {
            this.blockInputCallback();
        }
    }
    /**
     * 地图震动
     */
    public shockMap() {
        // cc.tween(this.mMapLayer).sequence(
        //     cc.moveBy(0.05, 0, 15).easing(cc.easeBackOut()),
        //     cc.moveBy(0.05, 0, -15).easing(cc.easeBackOut())
        // ).start();
    }
    //移除伙伴
    public removePet(id) {
        let sprite = this.mainSprite.nextSprite as PSprite
        while (true) {
            if (!sprite) {
                return
            }
            if (sprite.attrData.id == id) {
                if (sprite.nextSprite) {
                    let next = sprite.nextSprite as PSprite
                    next.setLeader(sprite.inFront);
                }
                sprite.node.destroy();
                return
            } else {
                sprite = sprite.nextSprite as PSprite
            }
        }

    }

    public openSet() {
        this.pauseSprite(true)
        this.main.viewManage.loadFunc(GameViewType.tap_set, (viewObject: ViewObject) => {
            let setView = viewObject as TapSetMusic
            setView.setCloseCallback(() => {
                this.pauseSprite(false)
            })
            viewObject.show();
        });
    }

    /**
     * 复活所有角色
     */
    public fuhuo() {
        this.ffResultType = FF_Result_Type.none;
        let sprite: Array<FSprite> = this.getGroupBy('A')
        for (let i = 0; i < sprite.length; i++) {
            const element = sprite[i];
            if (element.hp <= 0) {//已经死亡的，进行复活
                element.isActive = true
                element.wudi(2)
                element.hp = element.attrData.hp
                let spriteNode = element.node.getChildByName('juese01');
                let spineNode0 = spriteNode.getChildByName('spineRight');
                let spine = spineNode0.getComponent(sp.Skeleton);
                if (!spine.node.active) {
                    element.spine.destroy()
                    element.spine = spine;
                    spine.node.active = true
                }
            } else {
                element.hp = element.attrData.hp
            }
            element.updatePanel()
        }
    }

    /**
     * 第一次获得技能提示
     */
    firstGetSkillTips() {
        let tips = this.mControl.getChildByName("1");
        tips.active = true;
        this.mBlockInputEvents.active = true;
        this.setBlockInputCallback(() => {
            tips.active = false;
            this.mBlockInputEvents.active = false;
        })
    }

    /**
     * 第一次拾取物品提示
     */
     firstGetGoodsTips() {
        let tips = this.mControl.parent.getChildByName("goodAbout");
        console.log("======", tips)
        tips.active = true;
        this.mBlockInputEvents.active = true;
        this.setBlockInputCallback(() => {
            tips.active = false;
            this.mBlockInputEvents.active = false;
        })
    }


    /**
     * 监听网络
     * @param reveData 
     */
    public httpEvent(reveData: ReveData) {
        // cc.log('ff reve : ',this);
        let data = reveData.data;
        //获得了新的装备
        if (data._equip != undefined) {
            if (data._equip.length > 0) {
                //刷新红点
                let res = this.fres;
                let nodes = res.mHudNode.children;
                for (let i = 0; i < nodes.length; i++) {
                    const node = nodes[i];
                    let fpi: FPanelIcon = node.getComponent(FPanelIcon)
                    let petId = fpi.sprite.attrData.id
                    let petAttr: PetAttr = this.main.player.getPet(petId)
                    if (RedPoint.petRedPoint(this.main, petAttr)) {
                        RedPoint.addRed(this.main, node, true)
                    }
                }
            }
        }

    }

}
