import {createTooltip } from "@/utils/mapCommon/tools";
import $ from 'jquery'
/**
 * 测量工具（包括忽略地形、距离测量、面积测量、角度测量、高度测量、清除测量）
 */
class MeasurementBar{
    activeView=null;
    currentEntities=[];
    toolTip=null;
    clampMode = 0;//0空间测量、1贴地/贴模型测量
    handlerDis=null;//距离测量
    handlerDisActive=false;
    handlerArea=null;//面积测量
    handlerAreaActive=false;
    handlerKj=null;//管间测量
    handlerKjActive=false;
    handlers=[];
    excavatename="toolclearevent";
    currentTarget=null;
    currentType="";

    /**
     * 构造函数
     */
    constructor(activeView) {
        this.activeView=activeView;       
        this.toolTip=createTooltip(document.querySelector("#mainMapContainer"));
    }

    /**
     * 测量工具初始化
     * @param type类型【hldx忽略地形，length距离，area面积，angle角度,dem高度,clear清除测量】
     */
    newMeasurement(type,currentTarget){
        //  if(AppX.runtimeConfig.autoRunAdaptor){
        //     AppX.runtimeConfig.autoRunAdaptor.addOperateEvents(this.excavatename,this.otherDestroy.bind(this),this);           
        // } 
        this.clearCurrentOperate();
        this.currentTarget=currentTarget;
        this.currentType=type;
        switch(type){
            case "hldx":
                if(this.clampMode==0)
                    this.clampMode=1;
                else
                    this.clampMode=0;
                break;
            case "measurelen":
                this.activeMeasureLine();
                break;
            case "measurearea":
                this.activeMeasureArea();
                break;
            case "measurekj":
                this.activeMeasureKj();
                break;
            case "measureangle":
                this.measureAngle(this.activeView);
                break;
            case "measurez":
                this.measureHeight(this.activeView);
                break;
            case "clear":
                this.clearMeasurement();
                break;
        }
    }

    /**
     * 操作完成清除操作
     */
    clearItemOperate(){
        //  var evens = AppX.runtimeConfig.runTimeTool;
        //  var tool = _.remove(evens, function (n) {
        //         return n != this.currentType;
        // }.bind(this));
        // AppX.runtimeConfig.runTimeTool = tool;
        // if (_.indexOf(AppX.runtimeConfig.runTimeTool, this.currentType) == -1) {
        //     if(this.currentTarget!=null){
        //         $(this.currentTarget).removeClass("itemcurrentselect");
        //     }
        // }
    }

    /**
     * 清除工具操作
     */
    otherDestroy(that){
        that.clearCurrentOperate();
        that.clearItemOperate();
    }

    /**
     * 清除当前所有操作
     */
    clearCurrentOperate(){ 
        if(this.handler && !this.handler.isDestroyed())
            this.handler.destroy();     
        if(this.handlerAngle && !this.handlerAngle.isDestroyed())   
            this.handlerAngle.destroy();  
        this.handler=null;
        this.handlerAngle=null;    
        for(var i=0;i<this.currentEntities.length;i++){
            this.activeView.entities.remove(this.currentEntities[i]);
        }
        this.currentEntities=[];
        if(this.handlerDisActive==true) 
            this.handlerDis  && this.handlerDis.clear();
        if(this.handlerAreaActive==true)  
            this.handlerArea && this.handlerArea.clear();    
        if(this.handlerKjActive==true)    
            this.handlerKj && this.handlerKj.clear(); 
        this.handlerDis=null;//距离测量
        this.handlerArea=null;//面积测量
        this.handlerKj=null;//管间测量
    }

    /**
     * 清除当前操作
     */
    clearMeasurement(){
        this.activeView.enableCursorStyle = true;
        $('body').removeClass('measureAngleCur').removeClass('measureLineCur').removeClass('measureAreaCur').removeClass('measureHeightCur').removeClass('measureKjCur');
        for(var i=0;i<this.handlers.length;i++){
            this.handlers[i] && this.handlers[i].clear();
            this.handlers[i]=null;
        }
        this.handlers=[];

        for(var i=0;i<this.heightEntities.length;i++){
            this.activeView.entities.remove(this.heightEntities[i]);
        }
        this.heightEntities=[];

        for(var i=0;i<this.angleEntities.length;i++){
            this.activeView.entities.remove(this.angleEntities[i]);
        }
        this.angleEntities=[];
    }

    /**
     * 距离测量激活
     */
    activeMeasureLine(){
        this.initMeasureLine();
        this.handlerDis.activate();
        this.handlerDisActive=true; 
    }

    /**
     * 获取symbol样式
     */
    getSymbol(type){
        var symbol={};
        switch(type){
            case "point":
                symbol={
                            pixelSize : 5,
                            color : Cesium.Color.RED,
                            outlineColor : Cesium.Color.WHITE,
                            outlineWidth : 2,
                            heightReference:Cesium.HeightReference.none 
                    };
                break;
            case "polyline":
                symbol={};
                break;
        }
        return symbol;
    }

    /**
     * 初始化距离测量工具
     */
    initMeasureLine(){
        this.handlerDis = new Cesium.MeasureHandler(this.activeView,Cesium.MeasureMode.Distance,this.clampMode);        
        //测距功能事件
        this.handlerDis.measureEvt.addEventListener(function(result){
            var dis = Number(result.distance);
            var distance = dis > 1000 ? (dis/1000).toFixed(2) + 'km' : dis.toFixed(2) + 'm';
            this.handlerDis.disLabel.text = '距离:' + distance; 
            this.handlerDis.epEntity.point = this.getSymbol("point");
            this.handlerDis.spEntity.point = this.getSymbol("point");
            if(this.handlerDis.tmpEntities && this.handlerDis.tmpEntities.length>0){
                this.handlerDis.tmpEntities[this.handlerDis.tmpEntities.length-1].point=this.getSymbol("point");
            }           
        }.bind(this));

        //鼠标样式修改
        this.handlerDis.activeEvt.addEventListener(function(isActive){
                if(isActive == true){
                    this.activeView.enableCursorStyle = false;
                    this.activeView._element.style.cursor = '';
                    $('body').removeClass('measureLineCur').addClass('measureLineCur');
                }
                else{
                    this.activeView.enableCursorStyle = true;
                    $('body').removeClass('measureLineCur');
                    this.handlers.push(this.handlerDis);  
                    this.handlerDisActive=false;   
                    this.clearItemOperate();                
                }
        }.bind(this));        
    }

     /**
     * 面积测量激活
     */
    activeMeasureArea(){
        this.initMeasureArea();
        this.handlerArea.activate();
        this.handlerAreaActive=true;
    }

    /**
     * 初始化面积测量工具
     */
    initMeasureArea(){
        this.handlerArea = new Cesium.MeasureHandler(this.activeView,Cesium.MeasureMode.Area,this.clampMode);       
        this.handlerArea.measureEvt.addEventListener(function(result){
            var mj = Number(result.area);
            var area = mj > 1000000 ? (mj/1000000).toFixed(2) + 'km²' : mj.toFixed(2) + '㎡'
            this.handlerArea.areaLabel.text = '面积:' + area;
            this.handlerArea.epEntity.point = this.getSymbol("point");
            this.handlerArea.spEntity.point = this.getSymbol("point");
            if(this.handlerArea.tmpEntities && this.handlerArea.tmpEntities.length>0){
                this.handlerArea.tmpEntities[this.handlerArea.tmpEntities.length-1].point=this.getSymbol("point");
            }   
        }.bind(this));
        this.handlerArea.activeEvt.addEventListener(function(isActive){
            if(isActive == true){
                this.activeView.enableCursorStyle = false;
                this.activeView._element.style.cursor = '';
                $('body').removeClass('measureAreaCur').addClass('measureAreaCur');
            }
            else{
                this.activeView.enableCursorStyle = true;
                $('body').removeClass('measureAreaCur');
                this.handlers.push(this.handlerArea);
                this.handlerAreaActive=false;
                this.clearItemOperate();
            }
        }.bind(this));
    }

    /**
     * 管间测量
     */
    activeMeasureKj(){
        this.initMeasureKj();
        this.handlerKj.activate();
        this.handlerKjActive=true;
    }

    /**
     * 初始化管间间距
     */
    initMeasureKj(){
        this.handlerKj = new Cesium.MeasureHandler(this.activeView,Cesium.MeasureMode.DVH);       
        this.handlerKj.measureEvt.addEventListener(function(result){
            var distance = result.distance > 1000 ? (result.distance/1000).toFixed(2) + 'km' : result.distance + 'm';
            var vHeight = result.verticalHeight > 1000 ? (result.verticalHeight/1000).toFixed(2) + 'km' : result.verticalHeight + 'm';
            var hDistance = result.horizontalDistance > 1000 ? (result.horizontalDistance/1000).toFixed(2) + 'km' : result.horizontalDistance + 'm';
            this.handlerKj.disLabel.text = '空间距离:' + distance;
            this.handlerKj.vLabel.text = '垂直高度:' + vHeight;
            this.handlerKj.hLabel.text = '水平距离:' + hDistance;
            this.handlerKj.epEntity.point = this.getSymbol("point");
            this.handlerKj.spEntity.point = this.getSymbol("point");
            if(this.handlerKj.tmpEntities && this.handlerKj.tmpEntities.length>0){
                this.handlerKj.tmpEntities[this.handlerKj.tmpEntities.length-1].point=this.getSymbol("point");
            } 
        }.bind(this));

        this.handlerKj.activeEvt.addEventListener(function(isActive){
            if(isActive == true){
                this.activeView.enableCursorStyle = false;
                this.activeView._element.style.cursor = '';
                $('body').removeClass('measureKjCur').addClass('measureKjCur');
            }
            else{
                this.activeView.enableCursorStyle = true;
                $('body').removeClass('measureKjCur');
                this.handlers.push(this.handlerKj);
                this.handlerKjActive=false;
                this.clearItemOperate();
            }
        }.bind(this));
    }
    

    handler=null;
    height = 0;
    positions = [];
    poly = null;
    cartesian = null;
    floatingPoint=null;
    heightEntities=[];
    /**
     * 高度测量
     */
    measureHeight(viewer){
        var that=this;
		this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);	
		this.positions = [];
		this.poly = null;
		this.height = 0;
		this.cartesian = null;
		this.floatingPoint=null;
		this.activeView.enableCursorStyle = false;
        this.activeView._element.style.cursor = '';
        $('body').removeClass('measureHeightCur').addClass('measureHeightCur');
		this.handler.setInputAction(function(movement){
            this.toolTip.showAt(movement.endPosition,'<p>单击开始，右键结束</p><p>高度：'+this.height+'m</p>');			
			this.cartesian = this.activeView.scene.pickPosition(movement.endPosition); 			
			if(this.positions.length >= 2){
				if (!Cesium.defined(this.poly)) {
					this.poly = new PolyLinePrimitive(this.positions);
				}else{
					this.positions.pop();					
					this.positions.push(this.cartesian);
				}
				this.height = getHeight(this.positions);                				
			}            
		}.bind(this),Cesium.ScreenSpaceEventType.MOUSE_MOVE);
		
		this.handler.setInputAction(function(movement){
            this.toolTip.setVisible(false);
			this.cartesian = this.activeView.scene.pickPosition(movement.position); 
	
			if(this.positions.length == 0) {
				this.positions.push(this.cartesian.clone());
				this.positions.push(this.cartesian); 
				this.floatingPoint = viewer.entities.add({
                    name : '高度',
                    position : this.positions[0],				
                    point : this.getSymbol("point")
				});
                this.currentEntities.push(this.floatingPoint);
			}						
			
		}.bind(this), Cesium.ScreenSpaceEventType.LEFT_CLICK);
		 
		this.handler.setInputAction(function(movement){
			this.handler.destroy();
			this.toolTip.setVisible(false);
            this.activeView.enableCursorStyle = true;
            $('body').removeClass('measureHeightCur');
			var textDisance = "高度："+this.height + "m";							
			var point1cartographic = Cesium.Cartographic.fromCartesian(this.positions[0]);
			var point2cartographic = Cesium.Cartographic.fromCartesian(this.positions[1]);					
			var point_temp= Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(point1cartographic.longitude), Cesium.Math.toDegrees(point1cartographic.latitude),point2cartographic.height);	
			
			this.currentEntities.push(this.activeView.entities.add({
				name : '直线距离',
				position : point_temp,			
				point : this.getSymbol("point"),
				label : {
					text : textDisance,
					font : '18px sans-serif',
					fillColor : Cesium.Color.GOLD,
					style: Cesium.LabelStyle.FILL_AND_OUTLINE,
					outlineWidth : 2,
					verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
					pixelOffset : new Cesium.Cartesian2(20, -20)
				}
			}));
            this.heightEntities.push.apply(this.heightEntities,this.currentEntities);
            this.currentEntities=[];
            this.clearItemOperate();	
		}.bind(this), Cesium.ScreenSpaceEventType.RIGHT_CLICK );		
	
		
        function getHeight(_positions){
            var cartographic = Cesium.Cartographic.fromCartesian(_positions[0]);
            var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[1]);
            var height_temp = cartographic1.height - cartographic.height;				
            return height_temp.toFixed(2);    			
        }

        function getEllipseHeight(_positions){
            var cartographic1 = Cesium.Cartographic.fromCartesian(_positions[1]);
            var height_temp = cartographic1.height;				
            return height_temp.toFixed(2);    			
        }

		var PolyLinePrimitive = (function(){
			function _(positions){
				this.options = {
					name:'直线',
					polyline : {					
						show : true,
						positions : [],
						material : Cesium.Color.AQUA,
						width : 2						
					},
					ellipse : {
						show : true,
						material : Cesium.Color.GREEN.withAlpha(0.5),
						outline : true 
					}
				};
				this.positions = positions;
				this._init();
			}
		
			_.prototype._init = function(){
				var _self = this;
				var _update = function(){	
					var temp_position =[];
					temp_position.push( _self.positions[0]);
					var point1cartographic = Cesium.Cartographic.fromCartesian(_self.positions[0]);
					var point2cartographic = Cesium.Cartographic.fromCartesian(_self.positions[1]);					
					var point_temp= Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(point1cartographic.longitude), Cesium.Math.toDegrees(point1cartographic.latitude),point2cartographic.height);			
					temp_position.push(point_temp);				
					return temp_position;
				};
				var _update_ellipse = function(){					
					return _self.positions[0];
				};
				var _semiMinorAxis = function(){
					var point1cartographic = Cesium.Cartographic.fromCartesian(_self.positions[0]);
					var point2cartographic = Cesium.Cartographic.fromCartesian(_self.positions[1]);
					/**根据经纬度计算出距离**/
					var geodesic = new Cesium.EllipsoidGeodesic();
					geodesic.setEndPoints(point1cartographic, point2cartographic);
					var s = geodesic.surfaceDistance;
					return s;
				};
				var _height =  function(){
					var height_temp = getEllipseHeight(_self.positions);
					return height_temp;
				};
				//实时更新polyline.positions
				this.options.polyline.positions = new Cesium.CallbackProperty(_update,false);
				this.options.position = new Cesium.CallbackProperty(_update_ellipse,false);
				this.options.ellipse.semiMinorAxis =new Cesium.CallbackProperty(_semiMinorAxis,false);
				this.options.ellipse.semiMajorAxis = new Cesium.CallbackProperty(_semiMinorAxis,false);
				this.options.ellipse.height =  new Cesium.CallbackProperty(_height,false);
				that.currentEntities.push(viewer.entities.add(this.options));
			};		
			return _;
		})();
	}

    handlerAngle=null;
    angle=0; 
    anglePositions=[];
    angleCartesian=null; 
    anglepoly=null;
    anglez=0.2;
    angleEntities=[];
    /**
     * 角度测量
     */
    measureAngle(viewer) {
        var that=this;
        this.handlerAngle = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        this.angle=0;
        this.anglez=0.2;
        this.anglePositions=[];
        this.angleCartesian=null;
        this.anglepoly=null;
        this.activeView.enableCursorStyle = false;
        this.activeView._element.style.cursor = '';
        $('body').removeClass('measureAngleCur').addClass('measureAngleCur');
        this.handlerAngle.setInputAction(function(movement){
            this.toolTip.showAt(movement.endPosition,'<p>单击开始，绘制三个点结束</p>');			
			this.angleCartesian = this.activeView.scene.pickPosition(movement.endPosition); 			
			if(this.anglePositions.length >= 2){
				if (!Cesium.defined(this.anglepoly)) {
					this.anglepoly = new PolyLinePrimitive(this.anglePositions);
				}else{
					this.anglePositions.pop();	
                    this.angleCartesian.z=this.angleCartesian.z+this.anglez;				
					this.anglePositions.push(this.angleCartesian);
				}				             				
			}

            if(this.anglePositions.length>=3){
                this.angle = getAngle(this.anglePositions);
                this.toolTip.showAt(movement.endPosition,'<p>单击开始，绘制三个点结束</p><p>角度：'+this.angle+'°</p>');
            }            
		}.bind(this),Cesium.ScreenSpaceEventType.MOUSE_MOVE);	
        
        this.handlerAngle.setInputAction(function (movement) {
                this.angleCartesian = this.activeView.scene.pickPosition(movement.position);
                if (this.anglePositions.length == 0) {
                    var pt=this.angleCartesian.clone();
                    pt.z=pt.z+this.anglez;
                    this.anglePositions.push(pt);
                }
                this.angleCartesian.z=this.angleCartesian.z+this.anglez;
                this.anglePositions.push(this.angleCartesian);
                this.currentEntities.push(this.activeView.entities.add({
                        name: '水平角度',
                        position: this.anglePositions[this.anglePositions.length-1],
                        point: this.getSymbol("point")
                }));
            if(this.anglePositions.length>3){                    
                    var textAngle = "角度："+this.angle + "°";
                    this.currentEntities.push(this.activeView.entities.add({
                        name: '水平角度',
                        position: this.anglePositions[1],                   
                        label: {
                            text: textAngle,
                            font: '18px sans-serif',
                            fillColor: Cesium.Color.GOLD,
                            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                            outlineWidth: 2,
                            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                            pixelOffset: new Cesium.Cartesian2(20, -20)
                        }
                    }));
                    this.handlerAngle.destroy();
			        this.toolTip.setVisible(false);
                    this.activeView.enableCursorStyle = true;
                     $('body').removeClass('measureAngleCur');
                    this.angleEntities.push.apply(this.angleEntities,this.currentEntities);
                    this.currentEntities=[];
                    this.clearItemOperate();
            }            
        }.bind(this), Cesium.ScreenSpaceEventType.LEFT_CLICK);

        function getAngle(positions) {
            var angle = 0;
            var a = getDistance(positions[0], positions[1]);
            var b = getDistance(positions[2], positions[1]);
            var c = getDistance(positions[0], positions[2]);
            var angle = Math.acos((a * a + b * b - c * c) / (2 * a * b)) * 180.0 / Math.PI;           
            return angle.toFixed(2);
        }

        function getDistance(positions0,positions1) {
            var distance = 0;
            var point1cartographic = Cesium.Cartographic.fromCartesian(positions0);
            var point2cartographic = Cesium.Cartographic.fromCartesian(positions1);                
            var geodesic = new Cesium.EllipsoidGeodesic();
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            var s = geodesic.surfaceDistance;               
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            distance = distance + s;
            return distance;
        }

        var PolyLinePrimitive = (function () {
            function _(positions) {
                this.options = {
                    name: '直线',
                    polyline: {
                        show: true,
                        positions: [],
                        material: Cesium.Color.AQUA,
                        width: 2
                    }
                };
                this.positions = positions;
                this._init();
            }

            _.prototype._init = function () {
                var _self = this;
                var _update = function () {
                    return _self.positions;
                };
                this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
                that.currentEntities.push(viewer.entities.add(this.options));
            };
            return _;
        })();
    }    
}
export default MeasurementBar;