/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import * as THREE from 'three';
import TileMesh from "../Core/TileMesh.js";
import LayeredMaterial from "../Renderer/LayeredMaterial.js";
import newTileGeometry from "../Core/Prefab/TileBuilder.js";
import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
import { geoidLayerIsVisible } from "../Layer/GeoidLayer.js";
const dimensions = new THREE.Vector2();
function setTileFromTiledLayer(tile, tileLayer) {
  if (tileLayer.diffuse) {
    tile.material.diffuse = tileLayer.diffuse;
  }
  if (tileLayer.isGlobeLayer) {
    // Computes a point used for horizon culling.
    // If the point is below the horizon,
    // the tile is guaranteed to be below the horizon as well.
    tile.horizonCullingPoint = tile.extent.center().as('EPSG:4978').toVector3();
    tile.extent.planarDimensions(dimensions).multiplyScalar(THREE.MathUtils.DEG2RAD);

    // alpha is maximum angle between two points of tile
    const alpha = dimensions.length();
    const h = Math.abs(1.0 / Math.cos(alpha * 0.5));
    tile.horizonCullingPoint.setLength(h * tile.horizonCullingPoint.length());
    tile.horizonCullingPointElevationScaled = tile.horizonCullingPoint.clone();
  }
}
export default {
  convert(requester, extent, layer) {
    const builder = layer.builder;
    const parent = requester;
    const level = parent !== undefined ? parent.level + 1 : 0;
    const paramsGeometry = {
      extent,
      level,
      segments: layer.segments || 16,
      disableSkirt: layer.disableSkirt,
      hideSkirt: layer.hideSkirt
    };
    return newTileGeometry(builder, paramsGeometry).then(result => {
      // build tile mesh
      result.geometry._count++;
      const crsCount = layer.tileMatrixSets.length;
      const material = new LayeredMaterial(layer.materialOptions, crsCount);
      ReferLayerProperties(material, layer);
      const tile = new TileMesh(result.geometry, material, layer, extent, level);
      if (parent && parent.isTileMesh) {
        // get parent extent transformation
        const pTrans = builder.computeSharableExtent(parent.extent);
        // place relative to his parent
        result.position.sub(pTrans.position).applyQuaternion(pTrans.quaternion.invert());
        result.quaternion.premultiply(pTrans.quaternion);
      }
      tile.position.copy(result.position);
      tile.quaternion.copy(result.quaternion);
      tile.visible = false;
      tile.updateMatrix();
      setTileFromTiledLayer(tile, layer);
      if (parent) {
        tile.geoidHeight = parent.geoidHeight;
        const geoidHeight = geoidLayerIsVisible(layer) ? tile.geoidHeight : 0;
        tile.setBBoxZ({
          min: parent.obb.z.min,
          max: parent.obb.z.max,
          geoidHeight
        });
        tile.material.geoidHeight = geoidHeight;
      }
      return tile;
    });
  }
};