define([
  'bulk_create_units/mouse_tracking',
  'bulk_create_units/unit_size',
  'bulk_create_units/wrap_grid',
], function(
  mouse,
  unit_size,
  wrap_grid
) {
  mouse.setTracking(model.cheatAllowCreateUnit())
  model.cheatAllowCreateUnit.subscribe(mouse.setTracking)

  armyIndex = ko.computed(function() {
    return model.playerControlFlags().indexOf(true)
  })

  // keep puppetmaster's special effects if it's present
  model.pasteUnits = model.pasteUnits || function(n) {
    if (!model.cheatAllowCreateUnit()) return
    if (n < 1) return
    if (armyIndex() == -1) return

    var drop = {
      army: model.players()[armyIndex()].id,
      what: selectedUnit(),
    }

    mouse.raycast().then(function(result) {
      //console.log(result)
      pasteUnits3D(n, drop, result)
    })
  }

  var pasteUnits3D = function(n, config, center) {
    if (!model.cheatAllowCreateUnit()) return
    if (n < 1) return
    if (!config.what || config.what == '') return

    var size = unit_size.updateFootprint(config.what)

    var locations = wrap_grid(n, size.footprint, center)

    mouse.hdeck.view.fixupBuildLocations(config.what, center.planet, locations).then(function(fixup) {
      //console.log(fixup)

      config.planet = center.planet

      fixup.forEach(function(loc) {
        //console.log(loc.ok, loc.desc, loc.pos, loc.orient)

        if (size && size.feature_requirements && !loc.ok) {
          console.log(loc.desc)
          return
        }
        config.location = loc.pos || center.pos
        config.orientation = loc.orient || center.orient
        model.send_message('create_unit', config)
      })
    })
  }

  model.bulkPasteCount = ko.observable(10)
  model.bulkPaste = function() {
    model.pasteUnits(model.bulkPasteCount())
  }

  handlers.bulk_paste_count = model.bulkPasteCount

  var lastHover = ''
  var selectedUnit = ko.observable(lastHover)

  selectedUnit.subscribe(function(spec) {
    api.Panel.message('sandbox', 'bulkCreateUnitSpec', spec)
    unit_size.load()
  })

  handlers.bulkCreateUnitSelected = function(spec) {
    selectedUnit(spec)
  }

  var liveGameHover = handlers.hover
  handlers.hover = function(payload) {
    liveGameHover(payload)

    if (payload) {
      lastHover = payload.spec_id || ''
    }
  }

  var engineCall = engine.call
  engine.call = function(method) {
    var promise = engineCall.apply(this, arguments);

    if (method == 'unit.debug.copy') {
      selectedUnit(lastHover)
    } else if (method == 'unit.debug.setSpecId') {
      var spec = arguments[1]
      var unit = model.unitSpecs[spec]
      selectedUnit(spec)
    }

    return promise
  }

  handlers.bulkCreateUnitSandboxExpanded = function(open) {
    if (open) {
      unit_size.load()
    }
  }
})

@@ -791,24 +791,340 @@
     %7D)%0A  %7D%0A%0A
+  var isOk = function(loc) %7B%0A    if (!loc.ok) %7B%0A      console.log(loc.desc)%0A      return false%0A    %7D else %7B%0A      return true%0A    %7D%0A  %7D%0A%0A  var validLocations = function(size, locations) %7B%0A    if (size && size.feature_requirements) %7B%0A      return locations.filter(isOk)%0A    %7D else %7B%0A      return locations%0A    %7D%0A  %7D%0A%0A
   var pasteU
@@ -1335,17 +1335,16 @@
 g.what)%0A
-%0A
     var 
@@ -1391,16 +1391,50 @@
  center)
+%0A    config.planet = center.planet
 %0A%0A    mo
@@ -1526,16 +1526,17 @@
 on(fixup
+s
 ) %7B%0A    
@@ -1556,16 +1556,17 @@
 og(fixup
+s
 )%0A%0A     
@@ -1570,50 +1570,36 @@
     
-config.planet = center.planet%0A%0A     
+validLocations(size,
  fixup
+s)
 .for
@@ -1683,128 +1683,8 @@
 ent)
-%0A%0A        if (size && size.feature_requirements && !loc.ok) %7B%0A          console.log(loc.desc)%0A          return%0A        %7D
 %0A   

refactor point validation