import * as Cesium from "cesium";

const viewer = new Cesium.Viewer("cesiumContainer", {
  shadows: true,
});
viewer.extend(Cesium.viewerCesium3DTilesInspectorMixin);
const inspectorViewModel = viewer.cesium3DTilesInspector.viewModel;

viewer.clock.currentTime = new Cesium.JulianDate(2457522.154792);

const scene = viewer.scene;
let tileset;

const viewModel = {
  tilesets: [
    {
      name: "Tileset",
      resource: "../../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json",
    },
    {
      name: "Translucent",
      resource:
        "../../SampleData/Cesium3DTiles/Batched/BatchedTranslucent/tileset.json",
    },
    {
      name: "Translucent/Opaque",
      resource:
        "../../SampleData/Cesium3DTiles/Batched/BatchedTranslucentOpaqueMix/tileset.json",
    },
    {
      name: "Multi-color",
      resource:
        "../../SampleData/Cesium3DTiles/Batched/BatchedColors/tileset.json",
    },
    {
      name: "Request Volume",
      resource:
        "../../SampleData/Cesium3DTiles/Tilesets/TilesetWithViewerRequestVolume/tileset.json",
    },
    {
      name: "Batched",
      resource:
        "../../SampleData/Cesium3DTiles/Batched/BatchedWithBatchTable/tileset.json",
    },
    {
      name: "Instanced",
      resource:
        "../../SampleData/Cesium3DTiles/Instanced/InstancedWithBatchTable/tileset.json",
    },
    {
      name: "Instanced/Orientation",
      resource:
        "../../SampleData/Cesium3DTiles/Instanced/InstancedOrientation/tileset.json",
    },
    {
      name: "Composite",
      resource:
        "../../SampleData/Cesium3DTiles/Composite/Composite/tileset.json",
    },
    {
      name: "PointCloud",
      resource:
        "../../SampleData/Cesium3DTiles/PointCloud/PointCloudRGB/tileset.json",
    },
    {
      name: "PointCloudConstantColor",
      resource:
        "../../SampleData/Cesium3DTiles/PointCloud/PointCloudConstantColor/tileset.json",
    },
    {
      name: "PointCloudNormals",
      resource:
        "../../SampleData/Cesium3DTiles/PointCloud/PointCloudNormals/tileset.json",
    },
    {
      name: "PointCloudBatched",
      resource:
        "../../SampleData/Cesium3DTiles/PointCloud/PointCloudBatched/tileset.json",
    },
    {
      name: "PointCloudDraco",
      resource:
        "../../SampleData/Cesium3DTiles/PointCloud/PointCloudDraco/tileset.json",
    },
  ],
  selectedTileset: undefined,
  splitDirections: [
    {
      name: "Left",
      value: Cesium.SplitDirection.LEFT,
    },
    {
      name: "None",
      value: Cesium.SplitDirection.NONE,
    },
    {
      name: "Right",
      value: Cesium.SplitDirection.RIGHT,
    },
  ],
  selectedSplitDirection: undefined,
  shadows: true,
};

Cesium.knockout.track(viewModel);

const toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);

Cesium.knockout
  .getObservable(viewModel, "shadows")
  .subscribe(function (enabled) {
    viewer.shadows = enabled;
  });

Cesium.knockout
  .getObservable(viewModel, "selectedSplitDirection")
  .subscribe(function (splitDirection) {
    if (Cesium.defined(tileset) && Cesium.defined(splitDirection)) {
      tileset.splitDirection = splitDirection.value;
    }
  });

let loadedResource;
Cesium.knockout
  .getObservable(viewModel, "selectedTileset")
  .subscribe(async function (options) {
    if (Cesium.defined(tileset)) {
      scene.primitives.remove(tileset);
    }
    if (!Cesium.defined(options)) {
      inspectorViewModel.tileset = undefined;
      loadedResource = undefined;
      return;
    }

    loadedResource = options.resource;
    tileset = await Cesium.Cesium3DTileset.fromUrl(options.resource, {
      enableDebugWireframe: true,
    });
    if (loadedResource !== options.resource) {
      // Another scenario was loaded. Discard result.
      return;
    }
    viewer.scene.primitives.add(tileset);

    if (Cesium.defined(viewModel.selectedSplitDirection)) {
      tileset.splitDirection = viewModel.selectedSplitDirection.value;
    }

    inspectorViewModel.tileset = tileset;
    viewer.zoomTo(
      tileset,
      new Cesium.HeadingPitchRange(
        0,
        -2.0,
        Math.max(100.0 - tileset.boundingSphere.radius, 0.0),
      ),
    );

    const properties = tileset.properties;
    if (Cesium.defined(properties) && Cesium.defined(properties.Height)) {
      tileset.style = new Cesium.Cesium3DTileStyle({
        color: {
          conditions: [
            ["${Height} >= 83", "color('purple', 0.5)"],
            ["${Height} >= 80", "color('red')"],
            ["${Height} >= 70", "color('orange')"],
            ["${Height} >= 12", "color('yellow')"],
            ["${Height} >= 7", "color('lime')"],
            ["${Height} >= 1", "color('cyan')"],
            ["true", "color('blue')"],
          ],
        },
      });
    }
  });

viewModel.selectedTileset = viewModel.tilesets[0];
viewModel.selectedSplitDirection = viewModel.splitDirections[1];

// Sync the position of the slider with the split position
const slider = document.getElementById("slider");
viewer.scene.splitPosition =
  slider.offsetLeft / slider.parentElement.offsetWidth;

const handler = new Cesium.ScreenSpaceEventHandler(slider);

let moveActive = false;

function move(movement) {
  if (!moveActive) {
    return;
  }

  const relativeOffset = movement.endPosition.x;
  const splitPosition =
    (slider.offsetLeft + relativeOffset) / slider.parentElement.offsetWidth;
  slider.style.left = `${100.0 * splitPosition}%`;
  viewer.scene.splitPosition = splitPosition;
}

handler.setInputAction(function () {
  moveActive = true;
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction(function () {
  moveActive = true;
}, Cesium.ScreenSpaceEventType.PINCH_START);

handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);

handler.setInputAction(function () {
  moveActive = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
handler.setInputAction(function () {
  moveActive = false;
}, Cesium.ScreenSpaceEventType.PINCH_END);
