import {
  DynamicWallMaterialProperty
} from "./DynamicWallMaterialProperty";
//地图工具类
const adu = {};

//添加-点
adu.addPoint = function(point, viewer) {

  //id
  let id = point.id ? point.id : Math.random();

  //大小
  let size = point.size ? point.size : 8;
  //颜色
  let color = point.color ? point.color : adu.getColor("#ff0000", 0.6);
  //边线颜色
  let outlineColor = point.outlineColor ?
    point.outlineColor :
    adu.getColor("#fff", 0.5);
  //线宽
  let outlineWidth = point.outlineWidth ? point.outlineWidth : 3;

  // 添加广告牌实体
  return viewer.entities.add({
    id: id,
    position: Cesium.Cartesian3.fromDegrees(
      Number(point.lng),
      Number(point.lat),
      Number(point.alt)
    ),
    point: {
      pixelSize: size,
      color: color,
      outlineColor: outlineColor,
      outlineWidth: outlineWidth,
      zIndex: 1,
    },
  });
};

//添加-标注点
adu.addMarker = function(point, viewer) {
  //debugger
  //id
  let id = point.id ? point.id : Math.random();

  //图标
  let icon = "./assets/marker/m0.png";
  //let icon = "@/utils/drawer/assets/marker/m0.png";

  //let icon = "https://profile-avatar.csdnimg.cn/edc7201ea86b4c6a8a208f6af65bdda2_citadel1.jpg";

  if (point.icon) {
    icon = point.icon;
    //debugger
    //icon="http://111.15.191.198:8780/forestplus/base/file/down?id=aa2136b5-5b1f-4870-b655-e3cb78cd78f7";
    // icon="http://192.168.1.103:8888/forestplus/base/file/down?id=fd321759-8e87-402e-bba8-df7d13913a7b";
  }

  // 添加广告牌实体
  return viewer.entities.add({
    id: id,
    position: Cesium.Cartesian3.fromDegrees(
      Number(point.lng),
      Number(point.lat),
      Number(point.alt)
    ),
    billboard: {
      id: id,
      image: icon,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      scale: 1,
      zIndex: 1,
    },
  });
};

//修改-标注点坐标
adu.updateMarker = function(point, viewer) {
  //id
  let id = point.id ? point.id : Math.random();
  let entity = viewer.entities.getById(id);
  entity.position = Cesium.Cartesian3.fromDegrees(
    Number(point.lng),
    Number(point.lat),
    Number(point.alt)
  );
  return entity;
};

//添加-线 实现
adu.addLine = function(opts, viewer) {
  if (!opts.points || opts.points.length < 2) {
    return null;
  }
  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("#ff0000", 0.8);
  //线宽
  let width = opts.width ? opts.width : 3;
  let outlineColor = opts.outlineColor ?
    adu.getColor(opts.outlineColor, 1) :
    adu.getColor("#000", 1);
  // debugger
  //位置格式变换
  let positions = adu.points2Arr(opts.points);
  //添加线
  return viewer.entities.add({
    id: id,
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(positions),
      //width: width,
      //material: color,
      width: 6,
      material: new Cesium.PolylineOutlineMaterialProperty({
        color: color,
        outlineWidth: 2,
        outlineColor: outlineColor,
      }),
      clampToGround: true,
      zIndex: 1,
    },
  });
};

//添加-线 虚线
adu.addDashLine = function(opts, viewer) {
  if (!opts.points || opts.points.length < 2) {
    return null;
  }
  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("#ff0000", 0.8);
  //线宽
  let width = opts.width ? opts.width : 3;
  let outlineColor = opts.outlineColor ?
    adu.getColor(opts.outlineColor, 1) :
    adu.getColor("#000", 1);
  // debugger
  //位置格式变换
  let positions = adu.points2Arr(opts.points);
  //添加线
  return viewer.entities.add({
    id: id,
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(positions),
      //width: width,
      //material: color,
      width: 6,
      material: new Cesium.PolylineDashMaterialProperty({
        color: color,
        outlineWidth: 2,
        outlineColor: outlineColor,
      }),
      clampToGround: true,
      zIndex: 1,
    },
  });
};
//添加-区域
adu.addPolygon = function(opts, viewer) {
  // debugger
  if (!opts.points || opts.points.length < 3) {
    return null;
  }
  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("#ff0000", 0.8);

  //位置格式变换
  let positions = adu.points2Arr(opts.points);

  color.alpha = 0.5; //透明度
  //添加线
  return viewer.entities.add({
    id: id,
    polygon: {
      hierarchy: new Cesium.PolygonHierarchy(
        Cesium.Cartesian3.fromDegreesArray(positions)
      ),
      clampToGround: true,
      show: true,
      fill: true,
      material: color,
      zIndex: 1,
    },
  });
};

adu.addWater = function(opts, viewer) {
  if (!opts.points || opts.points.length < 3) {
    return null;
  }
  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("#ff0000", 0.8);

  //位置格式变换
  let positions = adu.points2Arr(opts.points);

  return viewer.scene.primitives.add(
    new Cesium.GroundPrimitive({
      show: true,
      vertexCacheOptimize: true,
      allowPicking: false,
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.PolygonGeometry({
          polygonHierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray(positions)
          ),
          vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
          extrudedHeight: 10,
          height: 1,
          zIndex: 1,
          //clampToGround: true
        }),
        id: id,
      }),
      appearance: new Cesium.EllipsoidSurfaceAppearance({
        material: new Cesium.Material({
          fabric: {
            type: "Water",
            uniforms: {
              baseWaterColor: new Cesium.Color(
                64 / 255.0,
                157 / 255.0,
                253 / 255.0,
                0.3
              ),
              // normalMap: "./waterNormals.jpg",
              frequency: 4000.0,
              animationSpeed: 0.1,
              amplitude: 5,
              specularIntensity: 8,
            },
          },
        }),
      }),
    })
  );
};

//添加-预警范围
adu.addWarn = function(opts, viewer) {
  if (!opts.points || opts.points.length < 3) {
    return null;
  }
  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("rgb(213, 77, 43)", 0.8);

  //位置格式变换
  opts.points.push(opts.points[0]);
  let positions = adu.points2Arr(opts.points);
  //positions.push(positions[0])
  //positions.push(positions[1])

  //添加面实例
  return viewer.entities.add({
    id: id,
    /* polygon: {
            hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(positions)),
            material: Cesium.Color.fromCssColorString('#9b9bdd').withAlpha(0.35),
            classificationType: Cesium.ClassificationType.BOTH,
            fill: false,
            //classificationType: ClassificationType.TERRAIN,
        }, */
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray(positions),
      width: 3,
      //material: color,
      material: new Cesium.PolylineDashMaterialProperty({
        color: Cesium.Color.YELLOW,
      }),
      //outlineColor: Cesium.Color.BLACK,
      clampToGround: true,
      zIndex: 1,
    },
  });
};

adu.addPersons = function(point, viewer) {
  //id
  let id = point.id ? point.id : Math.random();

  // 添加实体
  return viewer.entities.add({
    id: id,
    position: Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.alt),
    /* model: {
            uri: '../../../../../assets/marker/Man.glb',
            minimumPixelSize: 50,
        }, */
    billboard: {
      id: id,
      image: "./assets/marker/single.png",
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      scale: 1,
    },
  });
};

//添加-墙
adu.Wall = function(opts, viewer) {
  // console.log('墙')
  if (!opts.points || opts.points.length < 2) {
    return null;
  }

  //id
  let id = opts.id ? opts.id : Math.random();

  //颜色
  let color = opts.color ? opts.color : adu.getColor("#ff0000", 0.8);
  //线宽
  let width = opts.width ? opts.width : 3;

  for (let index = 0; index < opts.points.length; index++) {
    opts.points[index].alt = opts.points[index].alt + 6;
  }

  //位置格式变换
  let positions = adu.points3Arr(opts.points);
  let heightArr = [];
  if (Array.isArray(opts.points)) {
    opts.points.forEach((data) => {
      heightArr.push(data.alt);
    });
  }

  return viewer.entities.add({
    id: id,
    wall: {
      positions: Cesium.Cartesian3.fromDegreesArrayHeights(positions),
      material: new DynamicWallMaterialProperty({
        color: Cesium.Color.FORESTGREEN,
        duration: 2000,
        viewer: viewer,
      }),
      maximumHeights: new Array(positions.length / 3).fill(77), //墙顶高度
      // minimunHeights: heightArr,
    },
  });
};

function computeModelMatrix(position) {
  const center = Cesium.Cartesian3.fromDegrees(
    position.lng,
    position.lat,
    position.alt
  );
  const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
  return matrix;
}

function computeEmitterModelMatrix() {
  let hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);
  let trs = new Cesium.TranslationRotationScale();
  trs.translation = Cesium.Cartesian3.fromElements(0, 0, 0);
  trs.rotation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);
  let result = Cesium.Matrix4.fromTranslationRotationScale(trs);
  return result;
}

adu.addFire = function(point, viewer) {
  var particle = new Cesium.ParticleSystem({
    image: "./assets/marker/fireMark.png",
    /* startColor: Cesium.Color.RED.withAlpha(0.1),
        endColor: Cesium.Color.YELLOW.withAlpha(0.5), */
    startColor: Cesium.Color.RED.withAlpha(0.1),
    endColor: Cesium.Color.BLACK.withAlpha(0.5),
    startScale: 10,
    endScale: 5,
    minimumParticleLife: 1.5,
    maximumParticleLife: 2,
    minimumSpeed: 29,
    maximumSpeed: 30,
    imageSize: new Cesium.Cartesian2(1, 1),
    sizeInMeters: true,
    // Particles per second.
    emissionRate: 100,
    // lifetime: 60.0,
    emitter: new Cesium.CircleEmitter(10.0),
    modelMatrix: computeModelMatrix(point),
    emitterModelMatrix: computeEmitterModelMatrix(),
  });

  viewer.scene.primitives.add(particle);
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(point.lng, point.lat, 1000),
  });
};

adu.editColor = function(point, viewer) {
  let id = point ? point : Math.random();
  let entity = viewer.entities.getById(id); //根据id获取预警范围实体
  entity.polyline.material = Cesium.Color.YELLOW.withAlpha(0.5); //修改预警范围material属性
  return entity;
};

//点转数组
adu.points2Arr = function(points) {
  if (!points) {
    return [];
  }
  let arr = [];
  if (Array.isArray(points)) {
    // debugger
    points.forEach((item) => {
      if (typeof item.lng === "string") return;
      arr.push(item.lng);
      arr.push(item.lat);

    });
  }
  return arr;
};

//点转数组 + height
adu.points3Arr = function(points) {
  if (!points) {
    return [];
  }
  let arr = [];
  if (Array.isArray(points)) {
    points.forEach((item) => {
      if (typeof item.lng === "string") return;
      arr.push(item.lng);
      arr.push(item.lat);
      arr.push(item.alt);
    });
  }
  return arr;
};

//位置坐标
adu.getPos = function(position, viewer) {
  position = viewer.camera.getPickRay(position);
  const cartesian = viewer.scene.globe.pick(position, viewer.scene);
  if (!cartesian) {
    return null;
  }
  const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  const lng = Cesium.Math.toDegrees(cartographic.longitude);
  const lat = Cesium.Math.toDegrees(cartographic.latitude);
  const alt = cartographic.height;

  return {
    lng: lng,
    lat: lat,
    alt: alt,
  };
};

// 获取颜色
adu.getColor = function(color, alpha) {
  if (!alpha) {
    alpha = 1;
  }
  return Cesium.Color.fromCssColorString(color).withAlpha(alpha);
};

// 移除-按id
adu.removeById = function(id, viewer) {
  viewer.entities.removeById(id);
  //viewer.entities.remove(viewer.entities.getById(id));
};
// 移除-按entity
adu.remove = function(entity, viewer) {
  if (!entity) {
    return;
  }
  viewer.entities.remove(entity);
};
// 移除-所有
adu.removeAll = function(viewer) {
  viewer.entities.removeAll();
};

//航向角heading
//这个计算的是逆时针,如果需要顺时针,可以在返回的结果里+360即可.
adu.getHeading = function(a, b) {
  const pointA = new Cesium.Cartesian3.fromDegrees(a.lng, a.lat, a.alt);
  const pointB = new Cesium.Cartesian3.fromDegrees(b.lng, b.lat, b.alt);
  /* //以a点为原点建立局部坐标系（东方向为x轴,北方向为y轴,垂直于地面为z轴），得到一个局部坐标到世界坐标转换的变换矩阵
    var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(lng_a, lat_a));
    //求世界坐标到局部坐标的变换矩阵
    var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix,new Cesium.Matrix4());       
    //a点在局部坐标的位置，其实就是局部坐标原点
    var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix,new Cesium.Cartesian3.fromDegrees(lng_a, lat_a),new Cesium.Cartesian3());
    //B点在以A点为原点的局部的坐标位置
    var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix,new Cesium.Cartesian3.fromDegrees(lng_b, lat_b),new Cesium.Cartesian3());
    //弧度
    var angle = Math.atan2((localPosition_B.y-localPosition_A.y), (localPosition_B.x-localPosition_A.x))
    //角度
    var theta = angle*(180/Math.PI);
    theta = 90 - theta;  // by durton 
    if (theta < 0) {
        theta = theta + 360;
    }
    return theta; */
  //建立以点A为原点，X轴为east,Y轴为north,Z轴朝上的坐标系
  const transform = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
  //向量AB
  const positionvector = Cesium.Cartesian3.subtract(
    pointB,
    pointA,
    new Cesium.Cartesian3()
  );
  //因transform是将A为原点的eastNorthUp坐标系中的点转换到世界坐标系的矩阵
  //AB为世界坐标中的向量
  //因此将AB向量转换为A原点坐标系中的向量，需乘以transform的逆矩阵。
  const vector = Cesium.Matrix4.multiplyByPointAsVector(
    Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()),
    positionvector,
    new Cesium.Cartesian3()
  );
  //归一化
  const direction = Cesium.Cartesian3.normalize(
    vector,
    new Cesium.Cartesian3()
  );
  //heading
  const heading =
    Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO;
  const angle = Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading);
  //角度
  let theta = angle * (180 / Math.PI);
  if (theta < 0) {
    theta = theta + 360;
  }
  return theta;
};
//获取俯仰角(pitch)
adu.getPitch = function(a, b) {
  // //以a点为原点建立局部坐标系（东方向为x轴,北方向为y轴,垂直于地面为z轴），得到一个局部坐标到世界坐标转换的变换矩阵
  // var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(lng_a, lat_a, alt_a));
  // //求世界坐标到局部坐标的变换矩阵
  // var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix,new Cesium.Matrix4());
  // //a点在局部坐标的位置，其实就是局部坐标原点
  // var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix,new Cesium.Cartesian3.fromDegrees(lng_a, lat_a, alt_a),new Cesium.Cartesian3());
  // //B点在以A点为原点的局部的坐标位置
  // var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix,new Cesium.Cartesian3.fromDegrees(lng_b, lat_b, alt_b),new Cesium.Cartesian3());
  // //弧度
  // var angle = Math.atan2((localPosition_B.z-localPosition_A.z), (localPosition_B.x-localPosition_A.x))
  // //角度
  // var theta = angle*(180/Math.PI);
  // //theta = 90 - theta;  // by durton
  // if (theta < 0) {
  //     theta = theta + 360;
  // }
  // return theta;

  const pointA = new Cesium.Cartesian3.fromDegrees(a.lng, a.lat, a.alt);
  const pointB = new Cesium.Cartesian3.fromDegrees(b.lng, b.lat, b.alt);

  let transfrom = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
  const vector = Cesium.Cartesian3.subtract(
    pointB,
    pointA,
    new Cesium.Cartesian3()
  );
  let direction = Cesium.Matrix4.multiplyByPointAsVector(
    Cesium.Matrix4.inverse(transfrom, transfrom),
    vector,
    vector
  );
  Cesium.Cartesian3.normalize(direction, direction);
  //因为direction已归一化，斜边长度等于1，所以余弦函数等于direction.z
  const angle = Cesium.Math.PI_OVER_TWO - Cesium.Math.acosClamped(direction.z);
  //角度
  let theta = angle * (180 / Math.PI);
  if (theta < 0) {
    theta = theta + 360;
  }
  return theta;
};

export {
  adu
};