import { Marker, Coordinate } from 'maptalks'
import { mapGoto } from './statusManagement'
import { threeLayer, vector } from './initScene3D'

function structText(args) {
  var point = new Marker(args.point,
    {
      properties: {
        altitude: args.top
      },
      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': args.name,
        'textFill': '#000000',
        'textHaloFill': '#fff',
        'textHaloRadius': 2,
        'textHorizontalAlignment': 'center',
        'textVerticalAlignment': 'top',
        'textSize': 12
      }
    }
  );
  point.on('click', () => {
    mapGoto({ center: args.point, zoom: 19 })
  })
  point.__id = args.id
  return point
}

function addToAttr(args) {
  var point = new Coordinate(args.point),
    containerPoint  = map.coordinateToContainerPoint(point).round();

  args.position = [
    Number(containerPoint.x),
    Number(containerPoint.y)
  ]
}


function checkIsAdd(texts, args) {
  addToAttr(args)

  let tMinX = args.position[0] - args.width / 2
  let tMaxX = args.position[0] + args.width / 2
  let tMinY = args.position[1]
  let tMaxY = args.position[1] + args.height

  let index = texts.findIndex(text => {
    let minX = text._struct_attribute.position[0] - text._struct_attribute.width / 2
    let minY = text._struct_attribute.position[1]
    let maxX = text._struct_attribute.position[0] + text._struct_attribute.width / 2
    let maxY = text._struct_attribute.position[1] + text._struct_attribute.height

    return !(
      (tMinX < minX && tMaxX < minX) || 
      (tMinX > maxX && tMaxX > maxX) || 
      (tMinY < minY && tMaxY < minY) || 
      (tMinY > maxY && tMaxY > maxY)
    )
  })
  
  return !~index
}


function addText(mesh, textjsons) {
  if (textjsons.length === 0) return;
  let children = threeLayer.getScene().children
  let texts = []
  let newTexts = []

  children.forEach(mesh => {
    mesh.texts && texts.push(...mesh.texts)
  })

  textjsons.forEach(item => {
    if (checkIsAdd(texts, item)) {
      let text = structText(item)
      newTexts.push(text)
      text._struct_attribute = item
      texts.push(text)
    }
  })

  vector.addGeometry(newTexts)
  mesh.texts = newTexts
  mesh.textjsons = textjsons
}



function referText() {
  let children = threeLayer.getScene().children
  let checkTexts = []
  
  children.forEach(mesh => {
    
    if (mesh.texts) {
      for (let i = 0; i < mesh.texts.length; i++) {
        let text = mesh.texts[i]
        if (checkIsAdd(checkTexts, text._struct_attribute)) {
          checkTexts.push(text)
        } else {
          vector.removeGeometry(text)
          mesh.texts.splice(i, 1)
          --i
        }
      }
    }
    
    
    if (mesh.textjsons) {
      mesh.textjsons.map(item => {
        let index = mesh.texts.findIndex(text => text.__id === item.id)
        if (!~index && checkIsAdd(checkTexts, item)) {
          let text = structText(item)
          checkTexts.push(text)
          text._struct_attribute = item
          vector.addGeometry(text)
          mesh.texts.push(text)
        }
      })
    }
  })
}

export { referText }
export default addText