import * as Cesium from "cesium";

// A demo showing how to style elements of an architectural design dynamically based on embedded metadata and UI input
// Snowdon Towers sample data courtesy of Autodesk Revit.
const viewer = new Cesium.Viewer("cesiumContainer", {
  globe: false,
});

// Enable rendering the sky
viewer.scene.skyAtmosphere.show = true;

// Configure Ambient Occlusion
if (Cesium.PostProcessStageLibrary.isAmbientOcclusionSupported(viewer.scene)) {
  const ambientOcclusion = viewer.scene.postProcessStages.ambientOcclusion;
  ambientOcclusion.enabled = true;
  ambientOcclusion.uniforms.intensity = 2.0;
  ambientOcclusion.uniforms.bias = 0.1;
  ambientOcclusion.uniforms.lengthCap = 0.5;
  ambientOcclusion.uniforms.directionCount = 16;
  ambientOcclusion.uniforms.stepCount = 32;
}

// Set to 1 PM Philadelphia time in UTC
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601(
  "2024-11-22T18:00:00Z",
);

// Set the initial camera view
viewer.camera.setView({
  destination: Cesium.Cartesian3.fromDegrees(-79.886626, 40.021649, 235.65),
  orientation: {
    heading: 0,
    pitch: Cesium.Math.toRadians(-20),
    roll: 0,
  },
});

// Add Photorealistic 3D tiles
let googleTileset;
try {
  googleTileset = await Cesium.Cesium3DTileset.fromIonAssetId(2275207);
  viewer.scene.primitives.add(googleTileset);
} catch (error) {
  console.log(`Error loading tileset: ${error}`);
}

// Add clipping for the site
const positions = Cesium.Cartesian3.fromDegreesArray([
  -79.887735, 40.022564, -79.886341, 40.023087, -79.886161, 40.023087,
  -79.885493, 40.022032, -79.88703, 40.021456, -79.887735, 40.022564,
]);

const polygon = new Cesium.ClippingPolygon({
  positions: positions,
});

const polygons = new Cesium.ClippingPolygonCollection({
  polygons: [polygon],
});

googleTileset.clippingPolygons = polygons;

// Add the architectural tileset as a semi-transparent ghost
try {
  const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(2887123);
  viewer.scene.primitives.add(tileset);
  tileset.style = new Cesium.Cesium3DTileStyle({
    color: "color('lightblue', 0.05)",
  });
} catch (error) {
  console.log(`Error loading tileset: ${error}`);
}

// Add the site tileset
try {
  const tileset = await Cesium.Cesium3DTileset.fromIonAssetId(2887129);
  viewer.scene.primitives.add(tileset);
} catch (error) {
  console.log(`Error loading tileset: ${error}`);
}

// Add the HVAC tileset which will be styled by metadata
let pipeTileset;
try {
  pipeTileset = await Cesium.Cesium3DTileset.fromIonAssetId(2887126);
  pipeTileset.maximumScreenSpaceError = 4;
  viewer.scene.primitives.add(pipeTileset);
} catch (error) {
  console.log(`Error loading tileset: ${error}`);
}

// Configure the UI
const minSlider = document.getElementById("minSlider");
const maxSlider = document.getElementById("maxSlider");
const minValueDisplay = document.getElementById("minValue");
const maxValueDisplay = document.getElementById("maxValue");

minSlider.oninput = function () {
  if (parseInt(minSlider.value) > parseInt(maxSlider.value)) {
    maxSlider.value = minSlider.value; // Adjust max to be the same as min if min exceeds max
  }
  minValueDisplay.textContent = minSlider.value;
  maxValueDisplay.textContent = maxSlider.value;
  updateHighlighting();
};

maxSlider.oninput = function () {
  if (parseInt(maxSlider.value) < parseInt(minSlider.value)) {
    minSlider.value = maxSlider.value; // Adjust min to be the same as max if max is smaller than min
  }
  maxValueDisplay.textContent = maxSlider.value;
  minValueDisplay.textContent = minSlider.value;
  updateHighlighting();
};

// Update the highlighting of the pipe tileset based on metadata and UI elements
function updateHighlighting() {
  const min = minSlider.value;
  const max = maxSlider.value;
  pipeTileset.style = new Cesium.Cesium3DTileStyle({
    color: {
      conditions: [
        [
          `(\${length} !== undefined && \${length} >= ${min}) && (\${length} <= ${max})`,
          'color("red")',
        ],
      ],
    },
  });
}

updateHighlighting();
