import {
    Stroke,
    Style,
    Icon,
} from 'ol/style'
import {
    Vector as VectorLayer
} from 'ol/layer'
import {
    Vector as VectorSource
} from 'ol/source'
import Feature from 'ol/Feature'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { findByIdToLayer } from '../base/poiQuery'
import rbush from 'rbush'
class constantSpeedObj {
    constructor(moveCarObject, now) { //name,version不需要传,在初始化对象的时候会把值传给
        this.moveCarObject = moveCarObject; //仓库名称
        this.now = now; //数据库名称
    }
    startAnimation(moveCarObject, flag, carType) { //start的时候设置flag为true
            //如果小车刚开始没有跑动
            let routeCoords = moveCarObject.routeCoords; //获取全部坐标
            let receiveObj = moveCarObject
            let routeLength = routeCoords.length;
            if (routeLength == undefined) {
                alert("请等待路网渲染完毕");
                return;
            }
            if (routeCoords.length == 0) {
                // alert("请先绘制车辆路径");
            } else {
                if (flag) {
                    this.stopAnimation(false, flag, moveCarObject);
                } else { //开始跑的时候走这里
                    flag = true;
                    let targetLayer = findByIdToLayer(carType, moveCarObject.map);
                    targetLayer.getSource().getFeatures()[0].setStyle(null);
                    // just in case you pan somewhere else
                    // this.map.getView().setCenter(center);
                    // let now = new Date().getTime();
                    // var _this = this;
                    receiveObj.map.on('postcompose', this.moveFeature); //地图渲染中
                    receiveObj.map.render();
                }
            }
        }
        //函数内调用
    moveFeature(event) {
        // let now = new Date().getTime();
        // this.speed = document.getElementById('constantSpeed').value;
        let speed = this.moveCarObject.speed;
        // this.routeCoords = this.receiveObj.routeCoords
        var vectorContext = event.vectorContext; //HTML5 Canvas context，ol.render.canvas.Immediate的对象
        var frameState = event.frameState; //frame 的状态
        if (flag) {
            var elapsedTime = Math.abs(frameState.time - this.now);
            var index = Math.round(speed * elapsedTime / 1000);
            if (index >= this.moveCarObject.routeCoords.length) {
                _this.initObject_car(this.moveCarObject, this.moveCarObject.routeCoords.length - 1, this.moveCarObject.routeCoords.length - 2, this.moveCarObject.map) //初始化点
                _this.stopAnimation(true, true, this.moveCarObject);
            }
            var dx, dy, rotation, carStyle;
            if (this.moveCarObject.routeCoords[index] && this.moveCarObject.routeCoords[index + 1]) {
                // lineShowDistant(this.receiveObj.redLineId,[this.routeCoords[index][0],this.routeCoords[index][1]],[this.routeCoords[index+1][0],this.routeCoords[index+1][1]],{"lineWidth":this.receiveObj.redLineWidth,"lineColor":this.receiveObj.redLineColor},this.receiveObj.redLinezIndex,this.receiveObj.map)
                dx = this.moveCarObject.routeCoords[index][0] - this.moveCarObject.routeCoords[index + 1][0];
                dy = this.moveCarObject.routeCoords[index][1] - this.moveCarObject.routeCoords[index + 1][1];
                rotation = Math.atan2(dy, dx);
                carStyle = new Style({
                    image: new Icon({
                        src: this.moveCarObject.carImage,
                        rotateWithView: false,
                        rotation: -rotation,
                        scale: this.moveCarObject.carScale,
                    })
                });
                var currentPoint = new Point(this.moveCarObject.routeCoords[index]);
                var feature = new Feature(currentPoint);
                vectorContext.drawFeature(feature, carStyle);
            }
        }
        // tell OpenLayers to continue the postcompose animation
        this.moveCarObject.map.render();
        return true
    }
    stopAnimation(ended, flag, moveCarObject) {
        if (ended == undefined) return;
        if (moveCarObject.routeCoords.length == 0) return;
        flag = false;
        // this.$refs.startButton.textContent = '开始回放';
        // if animation cancelled set the marker at the beginning
        let targetLayer = findByIdToLayer(moveCarObject.initCarPosId, moveCarObject.map)
        if (targetLayer.getSource().getFeatures()[0].getGeometry != undefined) {
            var coord = ended ? moveCarObject.routeCoords[moveCarObject.routeCoords.length - 1] : moveCarObject.routeCoords[0];
            /** @type {ol.geom.Point} */
            (targetLayer.getSource().getFeatures()[0].getGeometry())
            .setCoordinates(coord);
            //remove listener
            moveCarObject.map.un('postcompose', this.moveFeature);
            // //函数内调用
        }
    }
    initObject_car(initRouteObj, startIndex, endIndex, map, carType) { //初始化点
        // this.geoMaker = {};
        let geoMarker = new Feature({ //第一个坐标值
            geometry: new Point(initRouteObj.initPosArr[startIndex])
        })
        let p_style = new Style({
            // 设置一个标识
            image: new Icon({
                src: initRouteObj.carImage,
                // 这个是相当于是进行切图了
                // size: [50,50],
                // 注意这个，竟然是比例 左上[0,0]  左下[0,1]  右下[1，1]
                anchor: [0.5, 0.5],
                // 这个直接就可以控制大小了
                scale: initRouteObj.carScale,
                rotation: -Math.atan2(initRouteObj.initPosArr[startIndex][1] - initRouteObj.initPosArr[endIndex][1], initRouteObj.initPosArr[startIndex][0] - initRouteObj.initPosArr[endIndex][0]),
                // 开启转向
                rotateWithView: true,
                // rotation: 0,
            }),
        })
        geoMarker.setStyle(p_style)
        var vectorLayer = new VectorLayer({
            id: initRouteObj.initCarPosId,
            source: new VectorSource({ //一次放入四个feature
                features: [geoMarker]
            })
        });
        vectorLayer.setZIndex(initRouteObj.carAndNodeIndex)
            //将图层vectorLayer加入到map地图中
        map.addLayer(vectorLayer);
    }
    styleLineFunction(feature, res) {
        var trackLine = feature.getGeometry(); //轨迹线图形
        var styles = [
            new Style({ // 线串的样式
                stroke: new Stroke({ //箭头标识
                    width: this.initRouteObj.routeWidth,
                    color: this.initRouteObj.routeColor,
                })
            })
        ];
        //对segments建立btree索引
        let tree = new rbush(); //路段数
        trackLine.forEachSegment(function(start, end) {
            var dx = end[0] - start[0];
            var dy = end[1] - start[1];
            //计算每个segment的方向，即箭头旋转方向
            let rotation = Math.atan2(dy, dx);
            let geom = new LineString([start, end]);
            let extent = geom.getExtent();
            var item = {
                minX: extent[0],
                minY: extent[1],
                maxX: extent[2],
                maxY: extent[3],
                geom: geom,
                rotation: rotation
            };
            tree.insert(item);
        });
        //轨迹地理长度
        let length = trackLine.getLength();
        let stpes = 40; //像素步长间隔
        //将像素步长转实际地理距离步长
        let geo_steps = stpes * res;
        //箭头总数
        let arrowsNum = parseInt(length / geo_steps);
        for (let i = 1; i < arrowsNum; i++) {
            let arraw_coor = trackLine.getCoordinateAt(i * 1.0 / arrowsNum);
            let tol = 0.0001; //查询设置的点的容差，测试地图单位是米。如果是4326坐标系单位为度的话，改成0.0001.
            let arraw_coor_buffer = [arraw_coor[0] - tol, arraw_coor[1] - tol, arraw_coor[0] + tol, arraw_coor[1] + tol];
            //进行btree查询
            var treeSearch = tree.search({
                minX: arraw_coor_buffer[0],
                minY: arraw_coor_buffer[1],
                maxX: arraw_coor_buffer[2],
                maxY: arraw_coor_buffer[3]
            });
            let arrow_rotation;
            //只查询一个，那么肯定是它了，直接返回
            if (treeSearch.length == 1)
                arrow_rotation = treeSearch[0].rotation;
            else if (treeSearch.length > 1) {
                let results = treeSearch.filter(function(item) {
                    //箭头点与segment相交，返回结果。该方法实测不是很准，可能是计算中间结果
                    //保存到小数精度导致查询有点问题
                    // if(item.geom.intersectsCoordinate(arraw_coor))
                    //   return true;
                    //换一种方案，设置一个稍小的容差，消除精度问题
                    let _tol = 1; //消除精度误差的容差
                    if (item.geom.intersectsExtent([arraw_coor[0] - _tol, arraw_coor[1] - _tol, arraw_coor[0] + _tol, arraw_coor[1] + _tol]))
                        return true;
                })
                if (results.length > 0)
                    arrow_rotation = results[0].rotation;
            }
            styles.push(new Style({
                geometry: new Point(arraw_coor),
                image: new Icon({
                    src: this.initRouteObj.arrowImage,
                    anchor: [0.75, 0.5],
                    scale: this.initRouteObj.arrowScale,
                    rotateWithView: true,
                    rotation: -arrow_rotation
                })
            }));
        }
        return styles;
    }
    initRoute(initRouteObj, map, carType) {
        this.initObject_car(initRouteObj, 0, 1, map, carType); //渲染路径的时候加入小车
    }
}
export default constantSpeedObj;