import * as d3 from "d3-scale";
import { formatDefaultLocale } from "d3-format";
import "@kitware/vtk.js/Rendering/Profiles/Geometry";
import vtkFullScreenRenderWindow from "@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
import vtkScalarBarActor from "@kitware/vtk.js/Rendering/Core/ScalarBarActor";
import vtkColorTransferFunction from "@kitware/vtk.js/Rendering/Core/ColorTransferFunction";
import { Representation } from "@kitware/vtk.js/Rendering/Core/Property/Constants";
import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";

import { throttle } from '@kitware/vtk.js/macros';
import {
  FieldDataTypes,
  FieldAssociations,
} from '@kitware/vtk.js/Common/DataModel/DataSet/Constants';


import vtkSphereSource from '@kitware/vtk.js/Filters/Sources/SphereSource';
import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';

import vtkSphereMapper from '@kitware/vtk.js/Rendering/Core/SphereMapper';

export class VtkModel {
  constructor() {
    this.renderWindowWith = vtkFullScreenRenderWindow.newInstance();
    this.renderer = this.renderWindowWith.getRenderer();
    this.renderWindow = this.renderWindowWith.getRenderWindow();

    //模板数据
    this.polyData = vtkPolyData.newInstance();
    this.mapper = vtkMapper.newInstance();
    this.actor = vtkActor.newInstance();
    this.actor.getProperty().setRepresentation(Representation.SURFACE); //线    
    this.actor.getProperty().setColor([0,0.0,1]);
    this.mapper.setInputData(this.polyData);
    this.actor.setMapper(this.mapper);
    // this.renderer.addActor(this.actor);


 

    //点数据
    // this.actor2 = vtkActor.newInstance();
    // this.actor2.getProperty().setRepresentation(Representation.POINTS); //点   
    // this.actor2.getProperty().setColor([2,0,0]);
    // this.actor2.getProperty().setPointSize(2);
    // this.actor2.setMapper(this.mapper);  
    // this.renderer.addActor(this.actor2);

    // const sphereSource = vtkSphereSource.newInstance({
    //   center: [0, 0, 0],
    //   height: 1.0,
    // });
    // sphereSource.setThetaResolution(64);
    // sphereSource.setPhiResolution(32);



  
    // this.pointerSource = vtkSphereSource.newInstance({
    //   phiResolution: 15,
    //   thetaResolution: 15,
    //   radius: 0.01,
    // });
    // this.pointerMapper = vtkMapper.newInstance();
    // this.pointerActor = vtkActor.newInstance();
    // this.pointerActor.setMapper(this.pointerMapper);
    // this.pointerMapper.setInputConnection(this.pointerSource.getOutputPort());
    // this.renderer.addActor(this.pointerActor);


    //结果数据
    this.jgActor = vtkActor.newInstance();
    this.jgMapper = vtkMapper.newInstance();
    this.jgActor.getProperty().setRepresentation(Representation.SURFACE); //线    
    this.scalarBarActor = vtkScalarBarActor.newInstance();
    this.scalarBarActor.setGenerateTicks(this.generateTicks(5));
    this.scalarBarActor.setDrawAboveRangeSwatch(true);

    //修改设条颜色
    const ctf = vtkColorTransferFunction.newInstance();
    ctf.addRGBPoint(0.0, 0.0, 0.0, 1.0);
    ctf.addRGBPoint(1.0, 0.0, 1.0, 0.5);
    ctf.addRGBPoint(2.0, 0.0, 1.0, 0.0);
    ctf.addRGBPoint(3.0, 1.0, 0.5, 0.0);
    ctf.addRGBPoint(4.0, 1.0, 0.0, 0.0);
    this.jgMapper.setLookupTable(ctf);
    const lut = this.jgMapper.getLookupTable();
    this.scalarBarActor.setScalarsToColors(lut);

    //选取
    this.lastActor=null;
    this.nodeActors =[]; //节点actor 数据
    this.pipeActors =[]; //管道actor 数据
    this.interactor = this.renderer.getRenderWindow().getInteractor();
    this.apiSpecificRenderWindow = this.interactor.getView();
    this.hardwareSelector = this.apiSpecificRenderWindow.getSelector();
    this.hardwareSelector.setCaptureZValues(true);
    this.hardwareSelector.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_POINTS);
    // document.removeEventListener("mousemove", throttleMouseHandler);
    
  }
  generateTicks(numberOfTicks) {
    return (helper) => {
      const lastTickBounds = helper.getLastTickBounds();
      // compute tick marks for axes
      const scale = d3
        .scaleLinear()
        .domain([0.0, 1.0])
        .range([lastTickBounds[0], lastTickBounds[1]]);
      const samples = scale.ticks(numberOfTicks);
      const ticks = samples.map((tick) => scale(tick));
      // Replace minus "\u2212" with hyphen-minus "\u002D" so that parseFloat() works
      formatDefaultLocale({ minus: "\u002D" });
      const format = scale.tickFormat(ticks[0], ticks[ticks.length - 1], numberOfTicks);
      const tickStrings = ticks
        .map(format)
        .map((tick) => Number(parseFloat(tick).toPrecision(12)).toPrecision()); // d3 sometimes adds unwanted whitespace
      helper.setTicks(ticks);
      helper.setTickStrings(tickStrings);
    };
  }
  clearModeAddJg(){
    this.renderer.addActor(this.jgActor);
    this.renderer.addActor(this.scalarBarActor);

    this.nodeActors.forEach((nodeActor) => {
      this.renderer.removeActor(nodeActor.actor);
    });
    this.pipeActors.forEach((pipeActor) => {
      this.renderer.removeActor(pipeActor.actor);
   });
    this.renderer.removeActor(this.actor);
  }
  clearJgAddMode(){
    this.renderer.addActor(this.actor);
    this.nodeActors.forEach((nodeActor) => {
      this.renderer.addActor(nodeActor.actor);
    });
    this.pipeActors.forEach((pipeActor) => {
      this.renderer.addActor(pipeActor.actor);
   });
    this.renderer.removeActor(this.scalarBarActor);
    this.renderer.removeActor(this.jgActor);
  } 

}

function pickOnMouseEvent(event) {
  if (vtkmodel.interactor.isAnimating()) {
    // We should not do picking when interacting with the scene
    return;
  }
  const [x, y] = eventToWindowXY(event);
  // console.log([x,y]);
  // vtkmodel.pointerActor.setVisibility(false);
  vtkmodel.hardwareSelector
    .getSourceDataAsync(vtkmodel.renderer, x, y, x, y)
    .then((result) => {
      if (result) {
        processSelections(result.generateSelection(x, y, x, y));
        // processSelections(result.generateSelection(x, y, x, y));
      } else {
        // processSelections(null);
      }
    });
}
function eventToWindowXY(event) {
  // We know we are full screen => window.innerXXX
  // Otherwise we can use pixel device ratio or else...
  const { clientX, clientY } = event;
  const [width, height] = vtkmodel.apiSpecificRenderWindow.getSize();
  const x = Math.round((width * clientX) / window.innerWidth);
  const y = Math.round(height * (1 - clientY / window.innerHeight)); // Need to flip Y
  return [x, y];
}
function processSelections(selections) {
  if (!selections || selections.length === 0) {//没有选择
    if(vtkmodel.lastActor==null){

    }else{
      vtkmodel.lastActor.getProperty().setColor(WHITE);
      vtkmodel.renderWindow.render();
    }
    vtkmodel.lastActor=null;
    return;
  }
 
  const {
    worldPosition: rayHitWorldPosition,
    compositeID,
    prop,
    propID,
    attributeID,
  } = selections[0].getProperties();
  const input = prop.getMapper().getInputData();
  if(vtkmodel.lastActor!=null){
    vtkmodel.lastActor.getProperty().setColor(WHITE);
    vtkmodel.renderWindow.render();
  }
  vtkmodel.lastActor=prop;
  prop.getProperty().setColor(GREEN);
  vtkmodel.nodeActors.forEach((nodeActor) => {
     if(prop==nodeActor.actor){
      //  console.log(nodeActor.node);
    
     }
   });
   vtkmodel.pipeActors.forEach((pipeActor) => {
   if(prop==pipeActor.actor){
       console.log(pipeActor.pipe);
     }
  });
    vtkmodel.renderWindow.render();
}
const throttleMouseHandler = throttle(pickOnMouseEvent, 20);
const WHITE = [1, 1, 1];
const GREEN = [0.1, 0.8, 0.1];
const vtkmodel = new VtkModel();
export { vtkmodel };