import ModuleBase from '../Module/ModuleBase';
import GameData from '../GameData';
import ConfigMgr from '../ConfigMgr';
import ResMgr from '../ResMgr';

interface ItemInfo {
    itemID: number,
    tile: cc.Vec2;
}

export default class TiledMapCtrl extends ModuleBase {
    private tiledMap: cc.TiledMap = null;
    private _arrBirthPos: cc.Vec2[] = [];
    private _arrLayer: cc.TiledLayer[] = [];
    private _arrItemInfo: ItemInfo[] = []; //{tile:,itemID:3001}
    onInit() {

        this._initMap();
        this._initLayers();
        this._initBirthPos();
        this._initItemInfo();
        this._initAllPos();
    }
    //像素坐标转化为格子坐标
    getTiledByPos(worldPos: cc.Vec2) {
        let pos = this.tiledMap.node.convertToNodeSpaceAR(worldPos);
        let tilePos = cc.v2(0, 0);
        let tileSize = this.tiledMap.getTileSize();
        let mapSize = this.tiledMap.getMapSize();
        tilePos.x = Math.floor(pos.x / tileSize.width);
        tilePos.y = Math.floor((tileSize.height * mapSize.height - pos.y) / tileSize.height);
        return tilePos;
    }
    //格子坐标转化为像素坐标
    getPosByTile(tile: cc.Vec2) {
        let tileSize = this.tiledMap.getTileSize();
        let mapSize = this.tiledMap.getMapSize();
        let x = tile.x * tileSize.width + tileSize.width / 2;
        let y = tileSize.height * mapSize.height - tile.y * tileSize.height - tileSize.height / 2;
        return cc.v2(x, y);
    }
    getBirthPos() {
        return this._arrBirthPos;
    }
    checkOutOf(tile: cc.Vec2) {
        let mapSize = this.tiledMap.getMapSize();
        if (tile.x < 0 || tile.x > (mapSize.width - 1) || tile.y <= 0 || tile.y > mapSize.height - 1) {
            return true;
        }
        return false;
    }
    pushBox(tile: cc.Vec2, dir: cc.Vec2) {
        let layer = this._arrLayer[tile.y - 1];
        let gid = layer.getTileGIDAt(tile);
        if (0 === gid) {
            return;
        }
        let tileTile = layer.getTiledTileAt(tile.x, tile.y, true);
        let tileSize = this.tiledMap.getTileSize();
        let offset = cc.v3(dir.x * tileSize.width, dir.y * tileSize.height, 0);
        let nextTile = cc.v2(tile.x + dir.x, tile.y - dir.y);
        let nextLayer = this._arrLayer[nextTile.y - 1];
        //推箱子时，要更新道具信息
        let itemInfo = this.getItemInfo(tile);
        itemInfo.tile.x = nextTile.x;
        itemInfo.tile.y = nextTile.y;

        cc.tween(tileTile.node)
            .by(0.5, { position: offset })
            .call(() => {
                layer.setTileGIDAt(0, tile.x, tile.y);
                nextLayer.setTileGIDAt(gid, nextTile.x, nextTile.y);
            })
            .start();
    }

    _initLayers() {
        for (let i = 1; i <= 13; i++) {
            let layer = this.tiledMap.getLayer('obstacle' + i);
            layer.node.zIndex = 2 * i;
            this._arrLayer.push(layer);
        }
    }
    public IsExistTiled(v2TiledPos: cc.Vec2) {
        if (v2TiledPos.y - 1 < 0) {
            return false;
        }
        let layer = this._arrLayer[v2TiledPos.y - 1];
        let gid = layer.getTileGIDAt(v2TiledPos);
        if (0 === gid) {
            return false;
        }
        return true;
    }

    //通过格子坐标获取该格子的图块的属性信息
    getTiledInfo(tile: cc.Vec2) {
        if (tile.y - 1 < 0) {
            return null;
        }
        let layer = this._arrLayer[tile.y - 1];
        let gid = layer.getTileGIDAt(tile);
        if (0 === gid) {
            return null;
        }
        let proper = this.tiledMap.getPropertiesForGID(gid);
        let info = {
            colli: proper['colli'],
            blast: proper['blast'],
            push: proper['push'],
            visible: proper['visible']
        };
        return info;
    }

    removeTiles(arrTiles: cc.Vec2[]) {
        for (let tile of arrTiles) {
            let layer = this._arrLayer[tile.y - 1];
            if (!layer) {
                continue;
            }
            this._removeItemInfo(tile);
            layer.setTileGIDAt(0, tile.x, tile.y);
        }
    }

    _initMap() {
        let tiledMapN = cc.find('Game/tileMap');
        this.tiledMap = tiledMapN.getComponent(cc.TiledMap);
        let levelID = GameData.getInstance().getData('LevelID');
        let levelDt = ConfigMgr.getInstance().getData('LevelDt').getDataByID(levelID);
        this.tiledMap.tmxAsset = ResMgr.getInstance().getTiledMap(levelDt.tiledMap);
    }
    //获取所有出生点
    _initBirthPos() {
        let objectGroup = this.tiledMap.getObjectGroup('initPos');
        let arrObj = objectGroup.getObjects();
        for (let obj of arrObj) {
            let pos = cc.v2(0, 0);
            pos.x = obj['x'];
            pos.y = obj['y'];
            this._arrBirthPos.push(pos);
        }
    }

    private _lAllPos: cc.Vec2[] = [];
    //获取所有出生点
    _initAllPos() {
        let objectGroup = this.tiledMap.getObjectGroups(); //getObjectGroup('initPos');
        // let arrObj = objectGroup.getObjects();
        for (let obj of objectGroup) {
            console.log("========", obj);
            // let pos = cc.v2(0, 0);
            // pos.x = obj['x'];
            // pos.y = obj['y'];
            // this._lAllPos.push(pos);
        }
    }

    getItemInfo(tile: cc.Vec2) {
        for (let i = 0; i < this._arrItemInfo.length; i++) {
            let info = this._arrItemInfo[i];
            if (tile.equals(info.tile)) {
                return info;
            }
        }
        return null;
    }

    _removeItemInfo(tile: cc.Vec2) {
        for (let i = 0; i < this._arrItemInfo.length; i++) {
            let info = this._arrItemInfo[i];
            if (tile.equals(info.tile)) {
                //创建item
                this.sendMsg('ItemMgr', 'addItem', info);
                this._arrItemInfo.splice(i, 1);
                break;
            }
        }
    }

    _initItemInfo() {
        //获取所有可以炸掉的格子
        let arrBlastTile: cc.Vec2[] = [];
        let mapSize = this.tiledMap.getMapSize();
        for (let i = 0; i < mapSize.width; i++) {
            for (let j = 1; j < mapSize.height; j++) {
                let tile = cc.v2(i, j);
                let tileInfo = this.getTiledInfo(tile);
                if (tileInfo && tileInfo.blast) {
                    arrBlastTile.push(tile);
                }
            }
        }

        let levelID = GameData.getInstance().getData('LevelID');
        let levelDt = ConfigMgr.getInstance().getData('LevelDt').getDataByID(levelID);
        for (let key in levelDt.item) {
            let count = levelDt.item[key];
            for (let i = 0; i < count; i++) {
                let index = Math.floor(Math.random() * arrBlastTile.length);
                let blastTile = arrBlastTile[index];
                arrBlastTile.splice(index, 1);
                let info: ItemInfo = {
                    itemID: parseInt(key),
                    tile: cc.v2(blastTile.x, blastTile.y)
                };
                this._arrItemInfo.push(info);
            }
        }

        let arrKey = Object.keys(levelDt.item);//levelDt.item.keys;
        for (let i = 0; i < 15; i++) {
            let index = Math.floor(Math.random() * arrKey.length);
            let blastIndex = Math.floor(Math.random() * arrBlastTile.length);
            let blastTile = arrBlastTile[blastIndex];
            arrBlastTile.splice(blastIndex, 1);
            let info: ItemInfo = {
                itemID: parseInt(arrKey[index]),
                tile: cc.v2(blastTile.x, blastTile.y)
            };
            this._arrItemInfo.push(info);
        }
    }
}