import GuideBase from "../evnet/guide/GuideBase";
import FF from "../FF";
import FSprite from "../object/FSprite";

const { ccclass, property } = cc._decorator;

@ccclass
export default class FMap extends cc.Component {
    
    @property(cc.Node)
    mSprites: cc.Node = null;//精灵层

    @property(cc.Node)
    mInit: cc.Node = null;//初始位置

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

    @property(cc.AudioClip)
    mBgm: cc.AudioClip = null;//背景音乐

    @property(GuideBase)
    mGuide: GuideBase = null;//地图进入场景时候的引导

    @property(cc.TiledLayer)
    mColliderTiled: cc.TiledLayer = null;//地图碰撞层

    public ff:FF;
    shoot: cc.Vec2 = cc.v2();//摄像机位置

    public mCamera: cc.Camera = null//地图上的摄像机

    /**
     * 所有房间
     */
    public rooms:Array<cc.Node> = null

    private midWidth = 360;
    private midHeidht = 640;
    //当前所处房间
    private curRoom:cc.Node = null;

    /**
     * 单元格尺寸
     */
    private cellSize = 64;

    onLoad() {
        this.midWidth = cc.winSize.width/2;
        this.midHeidht = cc.winSize.height/2;

        this.rooms = this.mRooms.children



        this.addCollider()
    }
    /**
     * 添加碰撞
     */
    private addCollider(){
        //地图边界碰撞墙
        let width   = this.node.width;
        let height  = this.node.height;
        let node = new cc.Node();
        node.group = 'map'
        let body = node.addComponent(cc.RigidBody);
        body.type = cc.RigidBodyType.Static;
        this._addBound(node, width/2, height, width, 20);
        this._addBound(node, width/2, 0, width, 20);
        this._addBound(node, 0, height/2, 20, height);
        this._addBound(node, width, height/2, 20, height);
        node.parent = this.node;
        
        //地形碰撞处理
        if(this.mColliderTiled){
            let size = this.mColliderTiled.getLayerSize();
            for (let i = size.height - 1; i >= 0; i--) {
                let count = 0;
                let isEnd = true;
                let startX = 0;
                let startY = size.height - i - 1;
                for (let j = 0; j < size.width; j++) {
                    let t = this.mColliderTiled.getTileGIDAt(j,i);
                    if(t > 0){
                        if(count <= 0){
                            startX = j;
                        }
                        count ++
                        isEnd = false;
                    }else{
                        isEnd = true
                    }
                    if(count > 0 && isEnd){
                        isEnd = true;
                        let node = new cc.Node();
                        node.x = startX*this.cellSize
                        node.y = startY*this.cellSize
                        node.group = 'map'
                        let body = node.addComponent(cc.RigidBody);
                        body.type = cc.RigidBodyType.Static;
                        let cwidth = this.cellSize*count
                        this._addBound(node,cwidth/2,32,cwidth,this.cellSize);
                        node.parent = this.node;

                        count = 0;
                    }
                }
                if(count > 0){
                    let node = new cc.Node();
                    node.x = startX*this.cellSize
                    node.y = startY*this.cellSize
                    node.group = 'map'
                    let body = node.addComponent(cc.RigidBody);
                    body.type = cc.RigidBodyType.Static;
                    let cwidth = this.cellSize*count
                    this._addBound(node,cwidth/2,32,cwidth,this.cellSize);
                    node.parent = this.node;
                }
                
            }

        }
    }


    
    private _addBound (node, x, y, width, height) {
        // cc.log('nodeXY:',node.x,node.y)
        // cc.log(x,y,width,height)
        let collider:cc.PhysicsBoxCollider = node.addComponent(cc.PhysicsBoxCollider);
        collider.offset.x = x;
        collider.offset.y = y;
        collider.size.width = width
        collider.size.height = height;
        collider.tag = 100;
    }

    /**
     * 获取当前所在房间
     */
    private getRoom(){
        for (let i = 0; i < this.rooms.length; i++) {
            const element = this.rooms[i];
            if(this.inRoom(element)){
                return element;
            }
        }
        return null;
    }

    private inRoom(node:cc.Node):boolean{
        if (this.shoot.x <= node.x 
            || this.shoot.y <= node.y
            || this.shoot.x >= node.x + node.width
            || this.shoot.y >= node.y + node.height
            ) {
            return false;
        }
        return true;
    }
    
    
    public setFF(ff:FF){
        this.ff = ff;
        let nodes = this.mSprites.children;
        nodes.forEach(node => {
            if(this.checkIn(node.name)){
                node.destroy();
            }
        });
        if(this.mBgm){
            ff.main.playMusicByClip(this.mBgm);
        }
        
    }
    public checkIn(name:string):boolean{
        let stage = this.ff.main.player.stage;
        return stage.element.indexOf(name) >= 0;
    }
    /**
     * 初始化摄像机位置
     */
    public initCamera(){
        let winSize = cc.winSize;
        let targetPos = this.shoot;//摄像机的目标位置
        let targetX = targetPos.x - this.midWidth;
        if (targetX != this.mCamera.node.x) {
            this.mCamera.node.x = targetX;
            if (this.mCamera.node.x < 0) {
                this.mCamera.node.x = 0;
            }
            if (this.mCamera.node.x > this.node.width - winSize.width) {
                this.mCamera.node.x = this.node.width - winSize.width;
            }
        }
        let targetY = targetPos.y - this.midHeidht;
        if (targetY != this.mCamera.node.y) {
            this.mCamera.node.y = targetY;
            if (this.mCamera.node.y < 0) {
                this.mCamera.node.y = 0;
            }
            if (this.mCamera.node.y > this.node.height - winSize.height) {
                this.mCamera.node.y = this.node.height - winSize.height;
            }
        }

        if(this.mGuide){
            this.mGuide.ff = this.ff;
            this.mGuide.run();
        }
    }
    private pauseFF(){
        this.ff.mainSprite.setPause(true);
        cc.tween(this).sequence(
            cc.delayTime(0.6),
            cc.callFunc(()=>{
                this.ff.mainSprite.setPause(false);
            })
        ).start()
    }
    lateUpdate(dt) {
        this.spriteOrder();
        this.ff.mMu.x = this.mCamera.node.x + this.midWidth
        this.ff.mMu.y = this.mCamera.node.y + this.midHeidht
        if(!this.ff.lockCamera){
            return;
        }
        let room = this.getRoom();
        if(!room){
            return;
        }
        if(this.curRoom != room){
            if(this.curRoom != null){
                this.pauseFF();
            }
            this.curRoom = room;
        }

        let winSize = cc.winSize;
        let targetPos = this.shoot;//摄像机的目标位置
        if(room.width > winSize.width){
            let targetX = targetPos.x - this.midWidth;
            let sideWidth = room.x + room.width - winSize.width;
            if(targetX < room.x){
                targetX = room.x
            }else if(targetX > sideWidth){
                targetX = sideWidth
            }
            if (targetX != this.mCamera.node.x) {
                let offsetx = targetX - this.mCamera.node.x;
                if (offsetx >= -5 && offsetx <= 5) {
                    this.mCamera.node.x = targetX;
                } else {
                    let dx = offsetx / 10;
                if(Math.abs(dx) < 5){
                        if(dx > 0){
                            dx = 5;
                        }else{
                            dx = -5;
                        }
                    }
                    dx = dx*(1+dt)
                    this.mCamera.node.x += dx;
                }
            }
        }else{
            let targetX = targetPos.x - this.midWidth;
            if(targetX < room.x){
                targetX = room.x
            }
            if (targetX != this.mCamera.node.x) {
                let offsetx = targetX - this.mCamera.node.x;
                if (offsetx >= -5 && offsetx <= 5) {
                    this.mCamera.node.x = targetX;
                } else {
                    let dx = offsetx / 10;
                if(Math.abs(dx) < 5){
                        if(dx > 0){
                            dx = 5;
                        }else{
                            dx = -5;
                        }
                    }
                    dx = dx*(1+dt)
                    this.mCamera.node.x += dx;
                }
            }

        }
        if(room.height > winSize.height){
            let targetY = targetPos.y - this.midHeidht;
            let sideHeight = room.y + room.height - winSize.height;
            if(targetY < room.y){
                targetY = room.y
            }else if(targetY > sideHeight){
                targetY = sideHeight
            }
            if (targetY != this.mCamera.node.y) {
                let offsety = targetY - this.mCamera.node.y;
                if (offsety >= -5 && offsety <= 5) {
                    this.mCamera.node.y = targetY;
                } else {
                    let dy = offsety / 10;
                    if(Math.abs(dy) < 5){
                        if(dy > 0){
                            dy = 5;
                        }else{
                            dy = -5;
                        }
                    }
                    dy = dy*(1+dt)
                    this.mCamera.node.y += dy;
                }
            }
        }else{
            let targetY = targetPos.y - this.midHeidht;
            if(targetY < room.y){
                targetY = room.y
            }
            if (targetY != this.mCamera.node.y) {
                let offsety = targetY - this.mCamera.node.y;
                if (offsety >= -5 && offsety <= 5) {
                    this.mCamera.node.y = targetY;
                } else {
                    let dy = offsety / 10;
                    if(Math.abs(dy) < 5){
                        if(dy > 0){
                            dy = 5;
                        }else{
                            dy = -5;
                        }
                    }
                    dy = dy*(1+dt)
                    this.mCamera.node.y += dy;
                }
            }
        }
    }
    /**
     * 地图上所有精灵显示排序
     */
    private spriteOrder() {
        let children = this.mSprites.children;
        for (let i = 0; i < children.length; i++) {
            const e = children[i];
            if(e.zIndex == 9999 || e.zIndex == -9999){
            }else{
                let zIndex = (cc.macro.MAX_ZINDEX - e.y) / 10;
                e.zIndex = zIndex;
            }
        }
    }
    public addSprite(sprite:FSprite) {
        sprite.ff = this.ff;
        sprite.map = this;
        this.mSprites.addChild(sprite.node);
    }
    public setCamera(mCamera: cc.Camera) {
        this.mCamera = mCamera;
    }
    public updateShoot(x, y):boolean {
        if(this.shoot.x == x && this.shoot.y == y){
            return false;
        }
        this.shoot.x = x;
        this.shoot.y = y;
        return true;
    }
    public getSprites(): Array<cc.Node> {
        return this.mSprites.children;
    }
    /**
     * 当前摄像机是否停止
     */
    public cameraStop():boolean{

        return false;
    }
}
