import * as THREE from 'three'
import { Marker, VectorLayer } from 'maptalks'
import { mapGoto } from './statusManagement'
global.THREE = THREE
require('three/examples/js/loaders/MTLLoader.js')
require('three/examples/js/loaders/OBJLoader.js')
require('three/examples/js/controls/OrbitControls')

let origin = 'http://www.4dage.com/maptest/module/'
let objs = []

function getMesh(base, name, cb) {
  var mtlLoader = new THREE.MTLLoader()
  var objLoader = new THREE.OBJLoader()

  mtlLoader.setPath(base)
  mtlLoader.load(`${name}.mtl`, materials => {
    materials.preload();
    
    objLoader.setMaterials(materials)
    objLoader.load(`${base}${name}.obj`, object => cb(object))
  })
}


let vector = new VectorLayer('vector', {
  enableAltitude: true,        // enable altitude
  altitudeProperty: 'altitude' // altitude property in properties, default by 'altitude'
})

// vector.addTo(map)
function addTet (text, lp, height = 40) {
  var point = new Marker(
    lp,
    {
      properties: {
        altitude: height
      },
      visible: true,
      editable: true,
      cursor: 'pointer',
      shadowBlur: 0,
      shadowColor: 'black',
      draggable: false,
      dragShadow: false, // display a shadow during dragging
      drawOnAxis: null,  // force dragging stick on a axis, can be: x, y
      symbol: {
        'textFaceName': 'sans-serif',
        'textName': text,
        'textFill': '#646464',
        'textHorizontalAlignment': 'center',
        'textSize': 20
      }
    }
  );

  vector.addGeometry([point], {
    enableAltitude: true,        // enable altitude
    altitudeProperty: 'altitude'
  })

  point.on('click', () => {
    mapGoto({ center: lp, zoom: 20})
  })

  // new VectorLayer('vector', point, {
  //   enableAltitude: true,        // enable altitude
  //   altitudeProperty: 'altitude' // altitude property in properties, default by 'altitude'
  // }).addTo(map);
}


addTet('荔园山庄', [108.33262462502444, 22.787011325474817])
addTet('南宁国际会展中心', [108.375425, 22.811005])
addTet('南宁东站', [108.411794, 22.844288], 180)

function addMeshHandle(obj) {
  objs.push(obj)

  threeLayer.getScene().add(obj)
  threeLayer.renderScene()
  // loadding(0.25)
}

getMesh(origin, 'huizhan1015', obj => {
  obj.position.set(
    84689605.67697768,
    -17021206.408467036,
    -86.84512329101562
  )
  obj.rotateX(-Math.PI/2)
  obj.rotateY(-0.4 * Math.PI)
  obj.scale.set(3.2,3.2,3.2)
  

  let checkMesh = obj.children.find(mesh => mesh.name === 'nanninghuizhanzhongxin_dquwuding_zhujinhua');
  function listenerZoom() {
    checkMesh.visible = map.getZoom() < 19
  }
  map.on('zoomend', listenerZoom);
  listenerZoom();

  addMeshHandle(obj)
})


// getMesh(origin, 'train station1016', obj => {
//   obj.rotateX(-Math.PI / 2)
//   // obj.rotateY(-0.03 * Math.PI)
//   obj.scale.set(7.7, 7.7, 7.7)
  
//   obj.position.set(
//     80836499.49249145,
//     -17504338.66642192,
//     -42.34257888793945
//   )

//   addMeshHandle(obj)
// })


// getMesh(origin, 'liyuan1016', obj => {
//   obj.rotateX(-Math.PI / 2)
//   obj.rotateY(-0.11 * Math.PI)
//   obj.scale.set(2.4, 2.4, 2.4)

//   obj.position.set(
//     80778803.47478871,
//     -17457809.756373115,
//     -42.33311080932617
//   )

//   addMeshHandle(obj)
// })



const frustum = new THREE.Frustum();
const cameraViewProjectionMatrix = new THREE.Matrix4();
let timeout
map.on('moving moveend zoomend dragrotating dragrotateend', () => {
  clearTimeout(timeout)
  timeout = setTimeout(() => {

    const camera = threeLayer.getCamera();
    camera.updateMatrixWorld();
    camera.matrixWorldInverse.getInverse(camera.matrixWorld);
    cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
    frustum.setFromMatrix(cameraViewProjectionMatrix);
    objs.forEach(obj => {
      let remove = true
      for (let i = 0; i < obj.children.length; i++) {
        let viewMesh = frustum.intersectsObject(obj.children[i])
        if (viewMesh) {
          remove = false;
          break;
        }
      }
      
      if (remove && !obj.isRemove) {
        scene.remove(obj)
        obj.isRemove = true
        threeLayer.renderScene()
      } else if (obj.isRemove && !remove) {
        threeLayer.getScene().add(obj)
        obj.isRemove = false
        threeLayer.renderScene()
      }
    })
  }, 500)
});









let dom = document.documentElement

dom.addEventListener('click', function clickHandle(ev) {
  dom.removeEventListener('click', clickHandle)
  let mouse = new THREE.Vector2()
  let raycaster = new THREE.Raycaster()
  let x = ev.offsetX
  let y = ev.offsetY
  mouse.x = (x / dom.offsetWidth) * 2 - 1
  mouse.y = -(y / dom.offsetHeight) * 2 + 1

  raycaster.setFromCamera(mouse, threeLayer.getCamera())

  let intersects = raycaster.intersectObjects(threeLayer.getScene().children)
  console.log(intersects)
}.bind(this))


// function listenerZoom() {
//   if (checkMesh && !runing) {
//     runing = true
//     let zoom = map.getZoom();
//     let opacity = Number(checkMesh.material[0].opacity)
//     opacity = isNaN(opacity) ? 1 : opacity
//     if (zoom >= 19) {
//       animation(Number(opacity), 0, setOpacity, c => {
//         runing = false
//         threeLayer.renderScene()

//       })
//     } else {
//       animation(Number(opacity), 1, setOpacity, c => {
//         runing = false
//         threeLayer.renderScene()
//       })
//     }


//     function setOpacity(opacity) {
//       checkMesh.material.forEach(material => {
//         material.transparent = true;
//         material.opacity = opacity;
//       })
//       threeLayer.renderScene()
//     }
//   }
// }

// function animation(start, end, deepFn, componentFn) {
//   let zx = start > end
//   let deep = zx ? -0.05 : 0.05

//   let frame = () => {
//     requestAnimationFrame(() => {
//       start = start + deep
//       if (zx) {
//         start = start < end ? end : start
//         deepFn(start)
//       } else {
//         start = start > end ? end : start
//         deepFn(start)
//       }
//       if (start === end) {
//         componentFn()
//       } else {
//         frame();
//       }
//     })
//   }
//   frame();
// }

// map.on('zoomend', listenerZoom);
