import Bot from "../../Game/Bot";

/**
 * 游戏逻辑系统（游戏逻辑和显示分离）
 */
export default class GameSystem {
    public masterId: number = -1;
    public playerInfos: Map<number, any>;
    public leavingPlayerIds: number[] = []
    public boys: BoyEntity[] = [];
    public countDown: number = 120 * 1000;
    public isGameStart: boolean = false;
    public isGameOver: boolean = false;

    public onMatchComplete(id, playerInfos, uuid, timestamp) {
        this.isGameStart = true;
        this.masterId = id;
        this.playerInfos = playerInfos;
    }

    public onGameStart() {
        this._createBoys();
        window.gm.createBoys();
    }

    public onFrameSync(frames: any[]) {
        for (let frame of frames) {
            if (frame.t === 1) {
                this._handleBoyState(frame);
                continue;
            }
            if (frame.t === 2) {
                this._handleBoyBeKilled(frame);
                continue;
            }
            if (frame.t === 100) {
                this._handlePlayerLeave(frame)
                continue;
            }
            if (frame.t === 101) {
                this._handleTimePass(frame);
                continue;
            }
        }
    }

    /**帧同步处理-角色状态 */
    private _handleBoyState(frame) {
        let id = frame.id;
        let boy = this.boys.find(boy => boy.id === id);
        if (boy) {
            boy.position = cc.v2(parseFloat(frame.x), parseFloat(frame.y));
            boy.angle = parseFloat(frame.a);
            boy.scaleX = parseFloat(frame.sx);
        }
    }

    /**帧同步处理-角色被杀 */
    private _handleBoyBeKilled(frame) {
        let id = frame.id;
        let killerId = frame.ki;
        let deadPosition = cc.v2(parseFloat(frame.x), parseFloat(frame.y));
        let boy = this.boys.find(boy => boy.id === id);
        if (killerId === 100 && !boy.dead) { //被大锯子杀死
            boy.dead = true;
            boy.deadPosition = deadPosition;
            if (this._isOnlyOneAlive()) this._setGameOver();
        } else { //被其他角色杀死
            let killer = this.boys.find(boy => boy.id === killerId);
            if (!killer.dead && !boy.dead) {
                boy.dead = true;
                boy.deadPosition = deadPosition;
                if (this._isOnlyOneAlive()) this._setGameOver();
            }
        }
    }
    
    /**帧同步处理-玩家离开 */
    private _handlePlayerLeave(frame) {
        let playerId = frame.pi;
        this.leavingPlayerIds.push(playerId);
        console.log("Player Leave", playerId);
        /**
         * 如果我现在是机器人支持者
         * 将对（离开的玩家角色，机器人角色）检测并添加机器人脚本
         */
        if (this.isBotSupporter()) {
            window.gm.boys.forEach(boy => {
                if (this.leavingPlayerIds.indexOf(boy.index) > -1 || !this.playerInfos[boy.index]) {
                    if (!boy.getComponent(Bot)) boy.addComponent(Bot);
                }
            });
        }
    }

    /**帧同步处理-时间流逝 */
    private _handleTimePass(frame) {
        if (this.isGameOver) return;
        this.countDown -= frame.dt;
        if (this.countDown <= 0) {
            this.countDown = 0;
            this._setGameOver();
        }
    }

    /**我是不是机器人支持者 */
    public isBotSupporter() {
        for (let i = 0; i < this.masterId; i++) {
            if (this.leavingPlayerIds.indexOf(i) === -1) return false;
        }
        return true;
    }

    /**创建游戏角色 */
    private _createBoys() {
        for (let i = 0; i < 4; i++) {
            let boy = new BoyEntity();
            boy.id = i;
            let box = window.gc.boxs[i];
            boy.position = box.position.add(cc.v2(0, box.height/2+10));
            boy.angle = 0;
            boy.scaleX = 1.8;
            boy.dead = false;
            this.boys.push(boy);
        }
    }
    
    /**是不是只有一个人活着 */
    private _isOnlyOneAlive() {
        let aliveCount = 0;
        this.boys.forEach(boy => {
            if (!boy.dead) aliveCount++; 
        });
        return aliveCount === 1;
    }

    /**设置游戏结束 */
    private _setGameOver() {
        if (this.isGameOver) return;
        this.isGameOver = true;
        window.gm.gameOver();
    }
}
class BoyEntity {
    id: number;
    position: cc.Vec2;
    angle: number;
    scaleX: number;
    dead: boolean;
    deadPosition: cc.Vec2;
}