import 'babel-core/register'
import 'babel-polyfill'
import featuresToPolygon from './featuresToPolygon'
import config from '../business/config'
import * as management from './dataManagement'
import grentText from './grentText'
import { mergeBigData, getMaxHeight, grentAnimationArray, extractType, fromGeometry } from './util'
import { toExtrudeGeometry, reductive, LatLngToPoint } from './PolygonToGeom'


function featureToAttribute(map, features, stepTotal) {
  let polygons = featuresToPolygon(features)
  let verticesArray = []
  let normalsArray = []

  polygons.forEach((polygon, index) => {
    let height = features[index].properties.height 
      || features[index].properties.levels * config.levelHeight
      || config.defaultHeight

    let geo = toExtrudeGeometry(polygon, map, height)

    if (!geo) return;

    features[index].height = height
    let { vertices, normals } = fromGeometry(geo)
    verticesArray.push(vertices)
    normalsArray.push(normals)
  })

  verticesArray = mergeBigData(verticesArray)
  normalsArray = mergeBigData(normalsArray)

  let maxHeight = getMaxHeight(verticesArray)
  let animateBuffArrays = grentAnimationArray(verticesArray, stepTotal, maxHeight)

  return {
    verticesBuffArrays: verticesArray,
    normalsBuffArrays: normalsArray,
    maxHeight,
    animateBuffArrays
  }
}

function featuresGrentAttribute(map, features) {
  let { typeFeatures, types } = extractType(features)
  let geoJsonArray = []

  reductive(map)

  typeFeatures.forEach((features, index) => {
    if (features.length) {
      geoJsonArray.push({
        ...featureToAttribute(map, features, config.stepTotal),
        texts: grentText(features),
        fids: features.map(f => f.id),
        type: index === 0 ? 'unknown' : types[index - 1]
      })
    }
  })
  
  let transArray = []
  geoJsonArray.forEach(geo => {
    transArray.push(
      geo.verticesBuffArrays.buffer,
      geo.normalsBuffArrays.buffer,
      geo.animateBuffArrays.buffer
    )
  })

  return {
    geoJsonArray,
    transArray
  }
}


let _interface = {
  getGeo: (function () {
    let ergodicIndex = 0
    return data => {
      ergodicIndex++
      let runing = 0
      let currErgodicIndex = ergodicIndex
      self.postMessage({
        incident: 'obsAddGeo'
      })

      for (let i = 0; i < data.tiles.length; i++) {
        if (currErgodicIndex !== ergodicIndex) return;
        let tile = data.tiles[i]
        let { x, y, z } = tile
        management.getFeatures(x, y, z)
          .then(features => {
            if (currErgodicIndex !== ergodicIndex) return;
            let { geoJsonArray, transArray } = featuresGrentAttribute(data.map, features)
            self.postMessage({
              incident: 'addGeo',
              geoJsonArray
            }, transArray)

            if (++runing === data.tiles.length) {
              self.postMessage({
                incident: 'addSuccess'
              })
            }
          })
      }

      // var point = new Point({ x: 160, y: 250 })
      // var center = map.containerPointToCoordinate(point)
      // console.log('----?', LatLngToPoint({ lat: 113.55792144367956, lng: 22.185834057437518}, data.map))
    }
  })(),

  clearFids: data => {
    management.clearGeos(data.fids)
  }
}


self.addEventListener('message', event => {
  let data = event.data
  if (typeof event.data === 'string') {
    data = JSON.parse(event.data)
  }
  _interface[data.thing] && _interface[data.thing](data)
})
