const Cesium = window.Cesium;

function TrajectoryPolylineTrailLinkMaterialProperty(viewer) {
  this.viewer = viewer;
  this._definitionChanged = new Cesium.Event();
  this._uTime = 0;
}

Object.defineProperties(TrajectoryPolylineTrailLinkMaterialProperty.prototype, {
  isConstant: {
    get() {
      return false;
    },
  },
  definitionChanged: {
    get() {
      return this._definitionChanged;
    },
  },
  uTime: Cesium.createPropertyDescriptor("uTime"),
});

TrajectoryPolylineTrailLinkMaterialProperty.prototype.getType = function () {
  return "CustomMaterial";
};

TrajectoryPolylineTrailLinkMaterialProperty.prototype.getValue = function (
  time,
  result,
) {
  if (!Cesium.defined(result)) {
    result = {};
  }

  this._uTime += 0.005;
  if (this._uTime > 1.0) {
    this._uTime = 0;
  }

  result.uTime = this._uTime;
  this.viewer.scene.requestRender();
  return result;
};

TrajectoryPolylineTrailLinkMaterialProperty.prototype.equals = function (
  other,
) {
  return (
    this === other
    || (other instanceof TrajectoryPolylineTrailLinkMaterialProperty
      && this._uTime === other._uTime)
  );
};

Cesium.Material.CustomMaterialType = "CustomMaterial";
Cesium.Material.CustomMaterialSource = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
  czm_material material = czm_getDefaultMaterial(materialInput);
  float progress = mod(1.0 - materialInput.st.s + uTime, 1.0);
  float head = smoothstep(0.95, 1.0, progress) * 2.0;
  vec3 baseColor = vec3(1, 0, 0);
  float tailFade = smoothstep(0.3, 0.0, progress);
  vec3 tailColor = mix(vec3(0), vec3(1), tailFade);
  material.diffuse = baseColor + tailColor * 0.8 + vec3(head);
  material.emission = material.diffuse * 0.5;
  return material;
}`;

Cesium.Material._materialCache.addMaterial(Cesium.Material.CustomMaterialType, {
  fabric: {
    type: Cesium.Material.CustomMaterialType,
    uniforms: {
      uTime: 0,
    },
    source: Cesium.Material.CustomMaterialSource,
  },
});

Cesium.TrajectoryPolylineTrailLinkMaterialProperty
  = TrajectoryPolylineTrailLinkMaterialProperty;
