import { defineComponent, getCurrentInstance, watch, onUnmounted, createCommentVNode } from 'vue';
import '../../../composables/index.mjs';
import { scene } from '../../../utils/cesium-props.mjs';
import { kebabCase } from '../../../utils/util.mjs';
import { commonEmits } from '../../../utils/emits.mjs';
import '../../../shared/index.mjs';
import { makeColor } from '../../../utils/cesium-helpers.mjs';
import fragmentShader from '../../../shared/shaders/Viewshed.mjs';
import useCommon from '../../../composables/use-common/index.mjs';
import Viewshed from '../../../shared/analyses/Viewshed.mjs';

const viewshedProps = {
  ...scene,
  fovH: {
    type: Number,
    default: 90
  },
  fovV: {
    type: Number,
    default: 60
  },
  offsetHeight: {
    type: Number,
    default: 1.8
  },
  visibleColor: {
    type: [Object, Array, String],
    default: "#00ff00"
  },
  invisibleColor: {
    type: [Object, Array, String],
    default: "#ff0000"
  },
  showGridLine: {
    type: Boolean,
    default: true
  },
  lineColor: {
    type: [Object, Array, String],
    default: "rgba(255,255,255,0.4)"
  },
  faceColor: {
    type: [Object, Array, String],
    default: "rgba(255,255,255,0.1)"
  },
  show: {
    type: Boolean,
    default: true
  },
  startPosition: {
    type: Object
  },
  endPosition: {
    type: Object
  },
  fragmentShader: {
    type: String,
    default: fragmentShader
  },
  uniforms: Object
};
var PrimitiveViewshed = defineComponent({
  name: "VcViewshed",
  props: viewshedProps,
  emits: commonEmits,
  setup(props, ctx) {
    const instance = getCurrentInstance();
    instance.cesiumClass = "VcViewshed";
    const commonState = useCommon(props, ctx, instance);
    if (commonState === void 0) {
      return;
    }
    const unwatchFns = [];
    let attachedViewshedStage;
    unwatchFns.push(watch([() => props.startPosition, () => props.endPosition], ([newStartPosition, newEndPosition]) => {
      if (!instance.mounted) {
        return;
      }
      updateViewshed(newStartPosition, newEndPosition);
    }, {
      deep: true
    }));
    unwatchFns.push(watch(() => props.fovH, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.fovH = val;
    }));
    unwatchFns.push(watch(() => props.fovV, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.fovV = val;
    }));
    unwatchFns.push(watch(() => props.fovV, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.fovV = val;
    }));
    unwatchFns.push(watch(() => props.offsetHeight, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.offsetHeight = val;
    }));
    unwatchFns.push(watch(() => props.visibleColor, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.visibleColor = makeColor(val);
    }));
    unwatchFns.push(watch(() => props.invisibleColor, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.invisibleColor = makeColor(val);
    }));
    unwatchFns.push(watch(() => props.showGridLine, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.showGridLine = val;
    }));
    unwatchFns.push(watch(() => props.show, (val) => {
      if (!instance.mounted) {
        return;
      }
      const viewshed = instance.cesiumObject;
      viewshed.enabled = val;
    }));
    onUnmounted(() => {
      unwatchFns.forEach((item) => item());
      unwatchFns.length = 0;
    });
    instance.createCesiumObject = async () => {
      const viewer = commonState.$services.viewer;
      const viewshed = new Viewshed(viewer.scene, {
        fovH: 120,
        fovV: 60,
        offsetHeight: 1.8,
        visibleColor: makeColor(props.visibleColor),
        invisibleColor: makeColor(props.invisibleColor),
        showGridLine: props.showGridLine
      });
      viewshed._viewshedShadowMap.cascadesEnabled = false;
      viewshed._viewshedShadowMap.softShadows = false;
      viewshed._viewshedShadowMap.normalOffset = false;
      viewshed._viewshedShadowMap.fromLightSource = false;
      viewshed._viewshedShadowMap.enabled = false;
      viewshed.fovH = Cesium.Math.toRadians(props.fovH);
      viewshed.fovV = Cesium.Math.toRadians(props.fovV);
      viewshed.offsetHeight = props.offsetHeight;
      viewshed.showGridLine = props.showGridLine;
      viewshed.enabled = props.show;
      viewshed.lineColor = makeColor(props.lineColor);
      viewshed.faceColor = makeColor(props.faceColor);
      return viewshed;
    };
    instance.mount = async () => {
      const viewer = commonState.$services.viewer;
      const viewshed = instance.cesiumObject;
      const { Cartesian4, PostProcessStage, Cartesian2 } = Cesium;
      updateViewshed(props.startPosition, props.endPosition);
      attachedViewshedStage = new PostProcessStage({
        fragmentShader: props.fragmentShader,
        uniforms: props.uniforms || {
          u_color1: function() {
            return viewshed.visibleColor;
          },
          u_color2: function() {
            return viewshed.invisibleColor;
          },
          u_isShed: function() {
            return viewshed.shadowMap.enabled;
          },
          u_radius: function() {
            return viewshed.lightCamera.frustum.far;
          },
          shadowMap_depthTexture: function() {
            return viewshed.shadowMap.enabled ? viewshed.shadowMap._shadowMapTexture : viewer.scene.context.defaultTexture;
          },
          shadowMap_matrix: function() {
            return viewshed.shadowMap._shadowMapMatrix;
          },
          shadowMap_cascadeSplits: function() {
            return viewshed.shadowMap._cascadeSplits;
          },
          shadowMap_cascadeMatrices: function() {
            return viewshed.shadowMap._cascadeMatrices;
          },
          shadowMap_lightDirectionEC: function() {
            return viewshed.shadowMap._lightDirectionEC;
          },
          shadowMap_lightPositionEC: function() {
            return viewshed.shadowMap._lightPositionEC;
          },
          shadowMap_cascadeDistances: function() {
            return viewshed.shadowMap._cascadeDistances;
          },
          shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness: function() {
            const e = viewshed.shadowMap._pointBias;
            return Cartesian4.fromElements(e.normalOffsetScale, viewshed.shadowMap._distance, viewshed.shadowMap.maximumDistance, 0, new Cartesian4());
          },
          shadowMap_texelSizeDepthBiasAndNormalShadingSmooth: function() {
            const e = viewshed.shadowMap._pointBias;
            const t = new Cartesian2();
            t.x = 1 / viewshed.shadowMap._textureSize.x;
            t.y = 1 / viewshed.shadowMap._textureSize.y;
            return Cartesian4.fromElements(t.x, t.y, e.depthBias, e.normalShadingSmooth, new Cartesian4());
          },
          czzj: function() {
            return viewshed.lightCamera.frustum.fov;
          },
          spzj: function() {
            return viewshed.lightCamera.frustum.fov;
          },
          mixNum: function() {
            return 0.5;
          },
          shadowMap_lightUp: function() {
            return viewshed.lightCamera.up;
          },
          shadowMap_lightDir: function() {
            return viewshed.lightCamera.direction;
          },
          shadowMap_lightRight: function() {
            return viewshed.lightCamera.right;
          }
        }
      });
      viewer.scene.postProcessStages.add(attachedViewshedStage);
      const primitives = commonState.$services.primitives;
      return primitives && primitives.add(viewshed);
    };
    instance.unmount = async () => {
      const viewer = commonState.$services.viewer;
      attachedViewshedStage && viewer.scene.postProcessStages.remove(attachedViewshedStage);
      const primitives = commonState.$services.primitives;
      const viewshed = instance.cesiumObject;
      return primitives && primitives.remove(viewshed);
    };
    const updateViewshed = (startPosition, endPosition) => {
      const viewshed = instance.cesiumObject;
      const { Cartesian3 } = Cesium;
      let diffrence = Cartesian3.subtract(endPosition, startPosition, new Cartesian3());
      const magnitudeSquared = Cartesian3.magnitudeSquared(diffrence);
      const distance = Cartesian3.distance(endPosition, startPosition);
      if (magnitudeSquared < 0.01 || viewshed.frustum.near > distance) {
        viewshed.enabled = false;
      } else {
        viewshed.enabled = true;
        diffrence = Cartesian3.normalize(diffrence, diffrence);
        const up = Cartesian3.normalize(endPosition, new Cartesian3());
        viewshed.setView({
          destination: startPosition,
          orientation: {
            direction: diffrence,
            up
          }
        });
        viewshed.frustum.far = Math.max(distance, 1.1);
      }
    };
    return () => {
      var _a;
      return createCommentVNode(kebabCase(((_a = instance.proxy) == null ? void 0 : _a.$options.name) || ""));
    };
  }
});

export { PrimitiveViewshed as default, viewshedProps };
//# sourceMappingURL=index.mjs.map
