class 'GameBugs' (Script)

function GameBugs:__init() super()
  self.tweens = {}
  self.items = {}

  self._correct = nil
  self._arr = nil
  self._pnts = nil

  self._lockControl = false

  self.activeInput = nil
end

function GameBugs:on_attach()
    local scene = self:scene()
    local item

    self.a1 = scene:object('input1')
    self.a2 = scene:object('input2')
    self.a3 = scene:object('input3')
    self.a4 = scene:object('input4')

    self.inputs = {self.a1, self.a2, self.a3, self.a4}


    for i=1,9 do
        item = self.items[i]
        table.insert(self.items, scene:object('item'..i))
    end

    self._correct = {}
    self._arr     = {}
    self._pnts    = {{},{},{}}
--
    table.insert(self._correct, {'item7', 'item8', 'item6'})
    table.insert(self._correct, {'item4', 'item5', 'item9'})
    table.insert(self._correct, {'item1', 'item2', 'item3'})
--
    table.insert(self._arr, {self.items[7], self.items[8], self.items[9]})
    table.insert(self._arr, {self.items[4], self.items[5], self.items[6]})
    table.insert(self._arr, {self.items[1], self.items[2], self.items[3]})
--
    for i=1,3 do
        for j=1,3 do
          table.insert(self._pnts[i], self._arr[i][j]:position())
        end
    end
end

function GameBugs:onTweenFinish(obj)
   wnd_print('ready '..obj:name())

    self._lockControl = false

    self:checkComplete()
end


function GameBugs:on_lb_down()
    local scene     = self:scene()
    local selection = scene:overed_object()

    if selection then
      for i=1,#self.inputs do
        if selection:name() == self.inputs[i]:name() then
           self:activate(selection:name())
           break
        end
      end
    end
end

function GameBugs:on_mouse_move()
    local scene     = self:scene()
    local selection = scene:overed_object()

    if selection then
      for i=1,#self.inputs do
        if selection:name() == self.inputs[i]:name() then
          if self.activeInput and self.activeInput:name() ~= selection:name() then
            self:updateAlpha(self.activeInput:name(), 1)
            self.activeInput = selection
            self:updateAlpha(self.activeInput:name(), 0.5)
          else
            self.activeInput = selection
            self:updateAlpha(self.activeInput:name(), 0.5)
          end
          break
        end
      end
    elseif self.activeInput then
      self:updateAlpha(self.activeInput:name(), 1)
      self.activeInput = nil
    end
end


function GameBugs:activate(objName)
  if objName == self.a1:name() then
     self:replace(Position(1,1), Position(1,2), Position(2,1), Position(2,2))
  elseif objName == self.a2:name() then
     self:replace(Position(1,2), Position(1,3), Position(2,2), Position(2,3))
  elseif objName == self.a3:name() then
     self:replace(Position(2,1), Position(2,2), Position(3,1), Position(3,2))
  elseif objName == self.a4:name() then
     self:replace(Position(2,2), Position(2,3), Position(3,2), Position(3,3))
  end

end

function GameBugs:updateAlpha(objName, value)
  local c1
  local c2
  local c3
  local c4

  if objName == self.a1:name() then
     c1 = Position(1,1)
     c2 = Position(1,2)
     c3 = Position(2,1)
     c4 = Position(2,2)
  elseif objName == self.a2:name() then
     c1 = Position(1,2)
     c2 = Position(1,3)
     c3 = Position(2,2)
     c4 = Position(2,3)
  elseif objName == self.a3:name() then
     c1 = Position(2,1)
     c2 = Position(2,2)
     c3 = Position(3,1)
     c4 = Position(3,2)
  elseif objName == self.a4:name() then
     c1 = Position(2,2)
     c2 = Position(2,3)
     c3 = Position(3,2)
     c4 = Position(3,3)
  end

 self._arr[c1:x()][c1:y()]:set_alpha(value)
 self._arr[c2:x()][c2:y()]:set_alpha(value)
 self._arr[c3:x()][c3:y()]:set_alpha(value)
 self._arr[c4:x()][c4:y()]:set_alpha(value)

end


function GameBugs:on_update(dt)
  local i = 1
   if self.tweens and #self.tweens > 0 then
     while (self.tweens[i]) do
       if self:move(self.tweens[i].object, self.tweens[i].target, self.tweens[i].callback) then
        table.remove(self.tweens, i)
       else
        i = i + 1
       end
     end
   end
end


function GameBugs:move(obj, target, callback)
  local dx    = target:x() - obj:position():x()
  local dy    = target:y() - obj:position():y()
  local dist  = math.sqrt (dx * dx + dy * dy);

  local vX = dx * 2 / dist;
  local vY = dy * 2 / dist;

  if dist <= 1 or math.abs(dist) - 2 < 0 then
    if callback then
      self:onTweenFinish(obj)
    end

    return true
  end

  obj:set_position(Position(obj:position():x()+vX, obj:position():y()+vY))

  return false
end

function GameBugs:addTween(obj, startValue, endValue, needCallback)
   obj:set_position(startValue)
   table.insert(self.tweens, {object = obj, target = endValue, callback = needCallback})
end


function GameBugs:replace(c1, c2, c3, c4)
    if self._lockControl then
      return
    end

--     1 2
--     3 4
--    <>
--     3 1
--     4 2
--
    local tmp = self._arr[c1:x()][c1:y()]
    self._arr[c1:x()][c1:y()] = self._arr[c3:x()][c3:y()]
    self._arr[c3:x()][c3:y()] = self._arr[c4:x()][c4:y()]
    self._arr[c4:x()][c4:y()] = self._arr[c2:x()][c2:y()]
    self._arr[c2:x()][c2:y()] = tmp
--
--
    self._lockControl = true
--
    self:addTween(self._arr[c1:x()][c1:y()], self._arr[c1:x()][c1:y()]:position(), self._pnts[c1:x()][c1:y()],false)
    self:addTween(self._arr[c2:x()][c2:y()], self._arr[c2:x()][c2:y()]:position(), self._pnts[c2:x()][c2:y()],false)
    self:addTween(self._arr[c3:x()][c3:y()], self._arr[c3:x()][c3:y()]:position(), self._pnts[c3:x()][c3:y()],false)
    self:addTween(self._arr[c4:x()][c4:y()], self._arr[c4:x()][c4:y()]:position(), self._pnts[c4:x()][c4:y()],true)
end


function GameBugs:checkComplete()
    if self._lockControl then
      return
    end

    local i=2

    for j=1,3 do
       if self._correct[i][1] ~= self._arr[i][j]:name() and
          self._correct[i][2] ~= self._arr[i][j]:name() and
          self._correct[i][3] ~= self._arr[i][j]:name()
          then
         return
       end
    end

    self:scene():execute_action('complete_GameBugs')
    self:remove()

end

