import { mathUtil } from './MathUtil.js'
import { floorplanService } from './Service/FloorplanService.js'
import { stateService } from './Service/StateService.js'
import Constant from './Constant.js'
import VectorType from './enum/VectorType.js'
import SelectState from './enum/SelectState.js'

export default class ListenLayer {
    constructor() {
        this.wallInfo = {
            wallId: null,
            state: null, // 未选中null
        }

        this.pointInfo = {
            pointId: null,
            state: null,
        }

        this.tagInfo = {
            tagId: null,
            state: null,
        }

        this.tableInfo = {
            tableId: null,
            state: null,
        }

        this.rectangleInfo = {
            rectangleId: null,
            state: null,
        }

        this.circleInfo = {
            circleId: null,
            state: null,
        }

        this.arrowInfo = {
            arrowId: null,
            state: null,
        }

        this.iconInfo = {
            iconId: null,
            state: null,
        }

        this.signInfo = {
            signsId: null,
            state: null,
        }

        this.titleInfo = {
            titleId: null,
            state: null,
        };
        this.compassInfo = {
            compassId: null,
            state: null,
        };

        this.modifyPoint = null
    }

    //开始监听，exceptPointId表示不考虑的点，exceptWallIds表示不考虑的墙
    start(position, exceptPointId, exceptWallIds,startPosition) {
        let nearest = this.getNearForVectors(position, exceptPointId, exceptWallIds,startPosition)
        if (
            nearest.modifyPoint //&&
            // (nearest.modifyPoint.hasOwnProperty('linkedPointId') ||
            //     nearest.modifyPoint.hasOwnProperty('linkedPointIdX') ||
            //     nearest.modifyPoint.hasOwnProperty('linkedPointIdY') ||
            //     nearest.modifyPoint.hasOwnProperty('linkedWallId'))
        ) {
            this.modifyPoint = {
                x: nearest.modifyPoint.x,
                y: nearest.modifyPoint.y,
            }
            if (nearest.modifyPoint.hasOwnProperty('linkedPointId') && nearest.modifyPoint.linkedPointId != null) {
                this.modifyPoint.linkedPointId = nearest.modifyPoint.linkedPointId
            } else if (nearest.modifyPoint.hasOwnProperty('linkedWallId') && nearest.modifyPoint.linkedWallId != null) {
                this.modifyPoint.linkedWallId = nearest.modifyPoint.linkedWallId
            } else {
                if (nearest.modifyPoint.hasOwnProperty('linkedPointIdX') && nearest.modifyPoint.linkedPointIdX != null) {
                    this.modifyPoint.linkedPointIdX = nearest.modifyPoint.linkedPointIdX
                }
                if (nearest.modifyPoint.hasOwnProperty('linkedPointIdY') && nearest.modifyPoint.linkedPointIdY != null) {
                    this.modifyPoint.linkedPointIdY = nearest.modifyPoint.linkedPointIdY
                }
            }
        } else {
            this.modifyPoint = null
        }

        const flag = this.updateSelectInfos(nearest, Constant.minAdsorb)
        this.updateSelectItem()
        return flag
    }

    // 获得最近的墙面和墙角
    // 同时获得吸附的相关信息
    getNearForVectors(position, exceptPointId, exceptWallIds,startPosition) {
        let min1 = null // 与墙角的距离
        let min2 = null // 与墙面的距离
        // 纠正
        let modifyPoint = {}     //离墙角近，墙角的x/y近
        let _modifyPoint = null   //只与墙面相交，会截断墙
        const hasPointIds = []
        if (exceptPointId) {
            hasPointIds.push(exceptPointId)
        }

        const walls = floorplanService.getWalls()
        for (const wallId in walls) {
            if (exceptWallIds && exceptWallIds.hasOwnProperty(wallId)) {
                continue
            }

            const wall = floorplanService.getWall(wallId)

            const startPoint = floorplanService.getPoint(wall.start)
            const endPoint = floorplanService.getPoint(wall.end)
            let distance = null
            const line = mathUtil.createLine1(startPoint,endPoint)
            if (!line) {
                //删除墙
                floorplanService.deleteWall(wallId)
                continue
            }
            const join = mathUtil.getJoinLinePoint(position, line)

            if (hasPointIds.indexOf(wall.start) == -1) {
                hasPointIds.push(wall.start)
                distance = mathUtil.getDistance(position, startPoint)

                if (min1 == null || min1.distance > distance) {
                    min1 = {
                        distance: distance,
                        pointId: wall.start,
                    }

                    //start部分找到了墙的端点
                    if ((mathUtil.getDistance(join, position) < Constant.minAdsorb && mathUtil.getDistance(join, startPoint) < Constant.minAdsorb) || min1.distance < Constant.minAdsorb) {
                        modifyPoint.linkedPointId = wall.start
                        modifyPoint.x = startPoint.x
                        modifyPoint.y = startPoint.y

                        delete modifyPoint.linkedPointIdX
                        delete modifyPoint.linkedPointIdY
                        break
                    }
                }
                //start部分找到了与x接近的其他点
                if (Math.abs(position.x - startPoint.x) < Constant.minAdsorb) {
                    if (!modifyPoint.linkedPointIdX) {
                        modifyPoint.x = startPoint.x
                        modifyPoint.linkedPointIdX = wall.start
                    } else {
                        const linkedPointX = floorplanService.getPoint(modifyPoint.linkedPointIdX)
                        if (mathUtil.getDistance(position, linkedPointX) > mathUtil.getDistance(position, startPoint)) {
                            modifyPoint.x = startPoint.x
                            modifyPoint.linkedPointIdX = wall.start
                        }
                    }
                }
                //start部分找到了与y接近的其他点
                if (Math.abs(position.y - startPoint.y) < Constant.minAdsorb) {
                    if (!modifyPoint.linkedPointIdY) {
                        modifyPoint.y = startPoint.y
                        modifyPoint.linkedPointIdY = wall.start
                    } else {
                        const linkedPointY = floorplanService.getPoint(modifyPoint.linkedPointIdY)
                        if (mathUtil.getDistance(position, linkedPointY) > mathUtil.getDistance(position, startPoint)) {
                            modifyPoint.y = startPoint.y
                            modifyPoint.linkedPointIdY = wall.start
                        }
                    }
                }
            }

            if (hasPointIds.indexOf(wall.end) == -1) {
                hasPointIds.push(wall.end)
                distance = mathUtil.getDistance(position, endPoint)

                if (min1 == null || min1.distance > distance) {
                    min1 = {
                        distance: distance,
                        pointId: wall.end,
                    }
                    //end部分找到了墙的端点
                    if ((mathUtil.getDistance(join, position) < Constant.minAdsorb && mathUtil.getDistance(join, endPoint) < Constant.minAdsorb) || min1.distance < Constant.minAdsorb) {
                        modifyPoint.linkedPointId = wall.end
                        modifyPoint.x = endPoint.x
                        modifyPoint.y = endPoint.y
                        delete modifyPoint.linkedPointIdX
                        delete modifyPoint.linkedPointIdY
                        break
                    }
                }
                //end部分找到了与x接近的其他点
                if (Math.abs(position.x - endPoint.x) < Constant.minAdsorb) {
                    if (!modifyPoint.linkedPointIdX) {
                        modifyPoint.x = endPoint.x
                        modifyPoint.linkedPointIdX = wall.end
                    } else {
                        const linkedPointX = floorplanService.getPoint(modifyPoint.linkedPointIdX)
                        if (mathUtil.getDistance(position, linkedPointX) > mathUtil.getDistance(position, endPoint)) {
                            modifyPoint.x = endPoint.x
                            modifyPoint.linkedPointIdX = wall.end
                        }
                    }
                }
                //end部分找到了与y接近的其他点
                if (Math.abs(position.y - endPoint.y) < Constant.minAdsorb) {
                    if (!modifyPoint.linkedPointIdY) {
                        modifyPoint.y = endPoint.y
                        modifyPoint.linkedPointIdY = wall.end
                    } else {
                        const linkedPointY = floorplanService.getPoint(modifyPoint.linkedPointIdY)
                        if (mathUtil.getDistance(position, linkedPointY) > mathUtil.getDistance(position, endPoint)) {
                            modifyPoint.y = endPoint.y
                            modifyPoint.linkedPointIdY = wall.end
                        }
                    }
                }
            }

            distance = mathUtil.getDistance(position, join)
            //是否在墙上，可能在墙外
            const _flag = mathUtil.isContainForSegment(join, startPoint, endPoint)
            //找最近的
            if (_flag && (min2 == null || min2.distance > distance)) {
                min2 = {
                    distance: distance,
                    wallId: wallId,
                }
            }

            if (_flag && mathUtil.getDistance(position, join) < Constant.minAdsorb) {
                _modifyPoint = join
                _modifyPoint.linkedWallId = wallId
            }
        }

        const result = {
            minPoint: min1,
            minWall: min2,
            tableInfo: {},
            rectangleInfo: {},
            circleInfo: {},
            arrowInfo: {},
            iconInfo: {},
            tagInfo: {},
            signInfo: {},
            titleInfo: {},
            compassInfo: {},
        }

        if (_modifyPoint != null) {
            result.modifyPoint = JSON.parse(JSON.stringify(_modifyPoint))
        } else if (modifyPoint.hasOwnProperty('x') && modifyPoint.hasOwnProperty('y')) {
            result.modifyPoint = JSON.parse(JSON.stringify(modifyPoint))
        } else if (modifyPoint.hasOwnProperty('x')) {
            result.modifyPoint = JSON.parse(JSON.stringify(modifyPoint))
            result.modifyPoint.x = modifyPoint.x
            result.modifyPoint.y = position.y
        } else if (modifyPoint.hasOwnProperty('y')) {
            result.modifyPoint = JSON.parse(JSON.stringify(modifyPoint))
            result.modifyPoint.x = position.x
            result.modifyPoint.y = modifyPoint.y
        } else if(startPosition && mathUtil.getDistance(position, startPosition)>Constant.minAdsorb){
            if (Math.abs(position.x - startPosition.x) < Constant.minAdsorb) {
                result.modifyPoint = {}
                result.modifyPoint.x = startPosition.x
                result.modifyPoint.y = position.y
            }
            else if (Math.abs(position.y - startPosition.y) < Constant.minAdsorb) {
                result.modifyPoint = {}
                result.modifyPoint.y = startPosition.y
                result.modifyPoint.x = position.x
            }
        }

        const tags = floorplanService.getTags()
        for (const tagId in tags) {
            const tag = floorplanService.getTag(tagId)
            const location = tag.isContain(position)
            if (location) {
                result.tagInfo = {
                    tagId: tagId,
                    state: 'all',
                }
                break
            }
        }

        const tables = floorplanService.getTables()
        for (const tableId in tables) {
            const table = floorplanService.getTable(tableId)
            const location = table.isContain(position)
            if (location) {
                result.tableInfo = {
                    tableId: tableId,
                    state: 'all',
                }
                break
            }
        }

        const rectangles = floorplanService.getRectangles()
        for (const rectangleId in rectangles) {
            const rectangle = floorplanService.getRectangle(rectangleId)
            const location = rectangle.isContain(position)
            if (location) {
                result.rectangleInfo.rectangleId = rectangleId
                if(location == SelectState.All){
                    result.rectangleInfo.state = SelectState.All;
                }
                else if(location.hasOwnProperty('vertex')){
                    result.rectangleInfo.state = SelectState.Vertex;
                    result.rectangleInfo.index = location.vertex
                }
                else if(location.hasOwnProperty('side')){
                    result.rectangleInfo.state = SelectState.Side;
                    result.rectangleInfo.index = location.side
                }
                break
            }
        }

        const circles = floorplanService.getCircles()
        for (const circleId in circles) {
            const circle = floorplanService.getCircle(circleId)
            const location = circle.isContain(position)
            if (location) {
                result.circleInfo.circleId = circleId
                if(location == SelectState.All){
                    result.circleInfo.state = SelectState.All;
                }
                else if(location.hasOwnProperty('vertex')){
                    result.circleInfo.state = SelectState.Vertex;
                    result.circleInfo.index = location.vertex
                }
                break
            }
        }

        const arrows = floorplanService.getArrows()
        for (const arrowId in arrows) {
            const arrow = floorplanService.getArrow(arrowId)
            const location = arrow.isContain(position)
            if (location) {
                result.arrowInfo.arrowId = arrowId
                result.arrowInfo.state = location;
                break
            }
        }

        const icons = floorplanService.getIcons()
        for (const iconId in icons) {
            const icon = floorplanService.getIcon(iconId)
            const location = icon.isContain(position)
            if (location) {
                result.iconInfo.iconId = iconId
                if(location == SelectState.All){
                    result.iconInfo.state = SelectState.All;
                }
                else if(location.hasOwnProperty('vertex')){
                    result.iconInfo.state = SelectState.Vertex;
                    result.iconInfo.index = location.vertex
                }
                break
            }
        }

        const signs = floorplanService.getSigns()
        for (const signsId in signs) {
            const sign = floorplanService.getSign(signsId)
            const location = sign.isContain(position)
            if (location) {
                result.signInfo = {
                    signsId: signsId,
                    state: 'all',
                }
                break
            }
        }

        const title = floorplanService.getTitle();
        const titleFLag = title.isContain(position)
        if(titleFLag){
            result.titleInfo = {
                titleId: title.vectorId,
                state: 'all',
            }
        }

        const compass = floorplanService.getCompass();
        const compassFlag = compass.isContain(position)
        if(compassFlag){
            result.compassInfo = {
                compassId: compass.vectorId,
                state: 'all',
            }
        }

        return result
    }

    updateSelectInfos(nearest, minDistance) {
        // 墙角状态是否改变
        let flag1 = false
        if (nearest.minPoint != null) {
            if (nearest.minPoint.distance < minDistance) {
                flag1 = this.isChanged(nearest.minPoint.pointId, SelectState.Select, 1)
                this.pointInfo = {
                    pointId: nearest.minPoint.pointId,
                    state: SelectState.Select,
                }
            } else {
                flag1 = this.isChanged(nearest.minPoint.pointId, null, 1)
                this.pointInfo = {
                    pointId: nearest.minPoint.pointId,
                    state: null,
                }
            }
        } else {
            flag1 = this.isChanged(null, null, 1)
            this.pointInfo = {
                pointId: null,
                state: null,
            }
        }
        // 墙面状态是否改变
        let flag2 = false
        if (nearest.minWall != null) {
            if (nearest.minWall.distance < minDistance) {
                flag2 = this.isChanged(nearest.minWall.wallId, SelectState.Select, 2)
                this.wallInfo = {
                    wallId: nearest.minWall.wallId,
                    state: SelectState.Select,
                }
            } else {
                flag2 = this.isChanged(nearest.minWall.wallId, null, 2)
                this.wallInfo = {
                    wallId: nearest.minWall.wallId,
                    state: null,
                }
            }
        } else {
            flag2 = this.isChanged(null, null, 2)
            this.wallInfo = {
                wallId: null,
                state: null,
            }
        }

        const flag3 = this.isChanged(nearest.rectangleInfo.rectangleId, nearest.rectangleInfo.state, 3,nearest.rectangleInfo.index)
        this.rectangleInfo = {
            rectangleId: nearest.rectangleInfo.rectangleId,
            state: nearest.rectangleInfo.state,
        }
        if(nearest.rectangleInfo.hasOwnProperty('index')){
            this.rectangleInfo.index = nearest.rectangleInfo.index
        }

        const flag4 = this.isChanged(nearest.circleInfo.circleId, nearest.circleInfo.state, 4)
        this.circleInfo = {
            circleId: nearest.circleInfo.circleId,
            state: nearest.circleInfo.state,
        }
        if(nearest.circleInfo.hasOwnProperty('index')){
            this.circleInfo.index = nearest.circleInfo.index
        }

        const flag5 = this.isChanged(nearest.tagInfo.tagId, nearest.tagInfo.state, 5)
        this.tagInfo = {
            tagId: nearest.tagInfo.tagId,
            state: nearest.tagInfo.state,
        }

        const flag6 = this.isChanged(nearest.signInfo.signsId, nearest.signInfo.state, 6)
        this.signInfo = {
            signsId: nearest.signInfo.signsId,
            state: nearest.signInfo.state,
        }

        const flag7 = this.isChanged(nearest.arrowInfo.arrowId, nearest.arrowInfo.state, 7)
        this.arrowInfo = {
            arrowId: nearest.arrowInfo.arrowId,
            state: nearest.arrowInfo.state,
        }

        const flag8 = this.isChanged(nearest.iconInfo.iconId, nearest.iconInfo.state, 8)
        this.iconInfo = {
            iconId: nearest.iconInfo.iconId,
            state: nearest.iconInfo.state,
        }
        if(nearest.iconInfo.hasOwnProperty('index')){
            this.iconInfo.index = nearest.iconInfo.index
        }

        const flag9 = this.isChanged(nearest.tableInfo.tableId, nearest.tableInfo.state, 9)
        this.tableInfo = {
            tableId: nearest.tableInfo.tableId,
            state: nearest.tableInfo.state,
        }

        const flag10 = this.isChanged(nearest.titleInfo.titleId, nearest.titleInfo.state, 10)
        this.titleInfo = {
            titleId: nearest.titleInfo.titleId,
            state: nearest.titleInfo.state,
        }

        const flag11 = this.isChanged(nearest.compassInfo.compassId, nearest.compassInfo.state, 11)
        this.compassInfo = {
            compassId: nearest.compassInfo.compassId,
            state: nearest.compassInfo.state,
        }

        return flag1 || flag2 || flag3 || flag4  || flag5 || flag6 || flag7 || flag8 || flag9 || flag10 || flag11
    }

    isChanged(vectorId, state, type, index) {
        let flag = false
        if (type == 1) {
            if (state == null && state == this.pointInfo.state) {
                flag = false
            } else if (this.pointInfo.pointId == vectorId && state == this.pointInfo.state) {
                flag = false
            } else {
                flag = true
            }
        } else if (type == 2) {
            if (state == null && state == this.wallInfo.state) {
                flag = false
            } else if (this.wallInfo.wallId == vectorId && state == this.wallInfo.state) {
                flag = false
            } else {
                flag = true
            }
        } 
        else if (type == 3) {
            if (state == null && state == this.rectangleInfo.state) {
                flag = false
            } else if (this.rectangleInfo.rectangleId == vectorId && state == this.rectangleInfo.state) {
                if(this.rectangleInfo.hasOwnProperty('index')){
                    if(index == this.rectangleInfo.index){
                        flag = false
                    }
                    else{
                        flag = true;
                    }
                }
                else{
                    flag = false
                }
                
            } else {
                flag = true
            }
        } 
        else if (type == 4) {
            if (state == null && state == this.circleInfo.state) {
                flag = false
            } else if (this.circleInfo.circleId == vectorId && state == this.circleInfo.state) {
                if(this.circleInfo.hasOwnProperty('index')){
                    if(index == this.circleInfo.index){
                        flag = false
                    }
                    else{
                        flag = true;
                    }
                }
                else{
                    flag = false
                }
            } else {
                flag = true
            }
        } 
        else if (type == 5) {
            if (state == null && state == this.tagInfo.state) {
                flag = false
            } else if (this.tagInfo.tagId == vectorId && state == this.tagInfo.state) {
                flag = false
            } else {
                flag = true
            }
        } 
        else if (type == 6) {
            if (state == null && state == this.signInfo.state) {
                flag = false
            } else if (this.signInfo.signsId == vectorId && state == this.signInfo.state) {
                flag = false
            } else {
                flag = true
            }
        }
        else if (type == 7) {
            if (state == null && state == this.arrowInfo.state) {
                flag = false
            } else if (this.arrowInfo.arrowId == vectorId && state == this.arrowInfo.state) {
                flag = false
            } else {
                flag = true
            }
        }
        else if (type == 8) {
            if (state == null && state == this.iconInfo.state) {
                flag = false
            } else if (this.iconInfo.iconId == vectorId && state == this.iconInfo.state) {
                flag = false
            } else {
                flag = true
            }
        }
        else if (type == 9) {
            if (state == null && state == this.tableInfo.state) {
                flag = false
            } else if (this.tableInfo.tableId == vectorId && state == this.tableInfo.state) {
                flag = false
            } else {
                flag = true
            }
        } 
        else if (type == 10) {
            if (state == null && state == this.titleInfo.state) {
                flag = false
            }else {
                flag = true
            }
        }
        else if (type == 11) {
            if (state == null && state == this.compassInfo.state) {
                flag = false
            }else {
                flag = true
            }
        }

        return flag
    }

    updateSelectItem() {
        if (this.tagInfo.tagId != null && this.tagInfo.state != null) {
            const tag = floorplanService.getTag(this.tagInfo.tagId)
            stateService.setSelectItem(this.tagInfo.tagId, tag.geoType, this.tagInfo.state)
        } else if (this.signInfo.signsId != null && this.signInfo.state != null) {
            const sign = floorplanService.getSign(this.signInfo.signsId)
            stateService.setSelectItem(this.signInfo.signsId, sign.geoType, this.signInfo.state)
        } else if (this.pointInfo.pointId != null && this.pointInfo.state != null) {
            stateService.setSelectItem(this.pointInfo.pointId, VectorType.WallCorner, SelectState.Select)
        } else if (this.wallInfo.wallId != null && this.wallInfo.state != null) {
            stateService.setSelectItem(this.wallInfo.wallId, VectorType.Wall, SelectState.Select)
        } else if (this.rectangleInfo.rectangleId != null && this.rectangleInfo.state != null) {
            //stateService.setSelectItem(this.wallInfo.wallId, VectorType.Wall, SelectState.Select)
            if(this.rectangleInfo.state == SelectState.All){
                stateService.setSelectItem(this.rectangleInfo.rectangleId,VectorType.Rectangle,SelectState.All)
            }
            else if(this.rectangleInfo.state == SelectState.Vertex){
                stateService.setSelectItem(this.rectangleInfo.rectangleId,VectorType.Rectangle,SelectState.Vertex,this.rectangleInfo.index)
            }
            else if(this.rectangleInfo.state == SelectState.Side){
                stateService.setSelectItem(this.rectangleInfo.rectangleId,VectorType.Rectangle,SelectState.Side,this.rectangleInfo.index)
            }
        } else if (this.circleInfo.circleId != null && this.circleInfo.state != null) {
            if(this.circleInfo.state == SelectState.All){
                stateService.setSelectItem(this.circleInfo.circleId,VectorType.Circle,SelectState.All)
            }
            else if(this.circleInfo.state == SelectState.Vertex){
                stateService.setSelectItem(this.circleInfo.circleId,VectorType.Circle,SelectState.Vertex,this.circleInfo.index)
            }
        } else if (this.iconInfo.iconId != null && this.iconInfo.state != null) {
            if(this.iconInfo.state == SelectState.All){
                stateService.setSelectItem(this.iconInfo.iconId,VectorType.Icon,SelectState.All)
            }
            else if(this.iconInfo.state == SelectState.Vertex){
                stateService.setSelectItem(this.iconInfo.iconId,VectorType.Icon,SelectState.Vertex,this.iconInfo.index)
            }
        } else if (this.arrowInfo.arrowId != null && this.arrowInfo.state != null) {
            stateService.setSelectItem(this.arrowInfo.arrowId, VectorType.Arrow, this.arrowInfo.state)
        } else if (this.signInfo.signsId != null && this.signInfo.state != null) {
            const sign = floorplanService.getSign(this.signInfo.signsId)
            stateService.setSelectItem(this.signInfo.signsId, sign.geoType, this.signInfo.state)
        } else if (this.tableInfo.tableId != null && this.tableInfo.state != null) {
            const table = floorplanService.getTable(this.tableInfo.tableId)
            stateService.setSelectItem(this.tableInfo.tableId, table.geoType, this.tableInfo.state)
        } else if (this.titleInfo.titleId != null && this.titleInfo.state != null) {
            const title = floorplanService.getTitle()
            stateService.setSelectItem(this.titleInfo.titleId, title.geoType, this.titleInfo.state)
        } else if (this.compassInfo.compassId != null && this.compassInfo.state != null) {
            const compass = floorplanService.getCompass()
            stateService.setSelectItem(this.compassInfo.compassId, compass.geoType, this.compassInfo.state)
        }
        else {
            stateService.clearSelectItem()
        }
    }

    clear() {
        this.wallInfo = {
            wallId: null,
            state: null, 
        }

        this.pointInfo = {
            pointId: null,
            state: null,
        }

        this.tagInfo = {
            tagId: null,
            state: null,
        }

        this.tableInfo = {
            tableId: null,
            state: null,
        }

        this.rectangleInfo = {
            rectangleId: null,
            state: null,
        }

        this.circleInfo = {
            circleId: null,
            state: null,
        }

        this.arrowInfo = {
            arrowId: null,
            state: null,
        }

        this.iconInfo = {
            iconId: null,
            state: null,
        }

        this.signInfo = {
            signsId: null,
            state: null,
        }

        this.modifyPoint = null
    }
}
const listenLayer = new ListenLayer()
export { listenLayer }
