class 'GameDiscs' (Script)

function GameDiscs:__init() super()
--    self.discs   = {  {1, 2, 3, 4, 5, 6, 7 ,8},
--                    {9, 10, 3, 4, 5, 11, 12, 13} }
--
--    self.common = { 3, 4, 5 }
--
--    self.center = { Position(545,300),
--                    Position(766,300) }
--
--    self.angle  = { {value=0, left=-180, right=180},
--                    {value=0, left=-90,  right=90} }
--
--
--    self.activeDisc         = nil
--    self.activeDiscIndex    = nil
--    self.currentDirection   = nil
--
--    self.startAngle         = 0
--    self.angleShift         = 90
--    self.currentAngle       = 0
--    self.angleLimit         = 0
--
--    self.initOne=true
--    self.lastTick           = false
end

function GameDiscs:on_attach()
    local scene = self:scene()
 -- if self.initOne then
      self.discs   = {  {1, 2, 3, 4, 5, 6, 7 ,8},
          {9, 10, 3, 4, 5, 11, 12, 13} }

      self.common = { 3, 4, 5 }

      self.center = { Position(545,300),
          Position(766,300) }

      self.angle  = { {value=0, left=-180, right=180},
          {value=0, left=-90,  right=90} }


      self.activeDisc         = nil
      self.activeDiscIndex    = nil
      self.currentDirection   = nil

      self.startAngle         = 0
      self.angleShift         = 90
      self.currentAngle       = 0
      self.angleLimit         = 0

      self.initOne=true
      self.lastTick           = false
    self.needRotate=false

    self.parts = {  {obj=scene:object('stone14'), disc=1},--1
                    {obj=scene:object('stone10'), disc=1},--2
                    {obj=scene:object('stone7'), disc=1},--3
                    {obj=scene:object('stone8'), disc=1},--4
                    {obj=scene:object('stone9'), disc=1},--5
                    {obj=scene:object('stone11'), disc=1},--6
                    {obj=scene:object('stone13'), disc=1},--7
                    {obj=scene:object('stone12'), disc=1},--8
                    
                    {obj=scene:object('stone1'), disc=2},--9
                    {obj=scene:object('stone6'), disc=2},--10
                    {obj=scene:object('stone5'), disc=2},--11
                    {obj=scene:object('stone4'), disc=2},--12
                    {obj=scene:object('stone2'), disc=2} }--13

    local part
    for i=1,#self.parts do
        part = self.parts[i]
        
        rawset(part, 'startPosition',   part.obj:position())
        rawset(part, 'selfCorrection',  0)
        rawset(part, 'discCorrection',  0)
    end
                    
    self.buttonsActive = {    scene:object('arrow1'),
                        scene:object('arrow2'),
                        scene:object('arrow3'),
                        scene:object('arrow4')}
                        
    self.buttons = {      scene:object('arrow1active'),
                                scene:object('arrow2active'),
                                scene:object('arrow3active'),
                                scene:object('arrow4active')}
                        
    for i=1,#self.buttonsActive do
      self.buttonsActive[i]:hide()
      self.buttons[i]:show()
    end

    self.activeButton   = nil
    
    self:prepareForUser()
 -- end
   -- self.initOne=false
end

function GameDiscs:prepareForUser()
    self.angle  = { {value=-180, left=-180, right=180},
                    {value=180, left=-90,  right=90} }    

    self.discs   = {    {5,6,12,13,9,2,3,4},
                        {1,11,12,13,9,10,7,8} }    
                    
    self.activeDisc         = self.discs[2]
    self.activeDiscIndex    = 2
    self.currentDirection   = 'right'
    
    self.startAngle         = 90
    self.angleShift         = 90 
    self.currentAngle       = 0
    self.angleLimit         = 180
    
    local values = {{2,-180,0,Position(768,496)},
                    {1,0,0,Position(435,78)},
                    {1,0,0,Position(572,106)},
                    {1,0,0,Position(543,189)},
                    {1,0,0,Position(571,300)},
                    {1,0,0,Position(432,301)},
                    {2,-180,0,Position(768,302)},
                    {2,-180,0,Position(757,415)},
                    {2,0,0,Position(768,106)},
                    {2,0,0,Position(655,78)},
                    {2,0,0,Position(658,312)},
                    {2,0,0,Position(768,300)},
                    {2,0,0,Position(773,193)} }
    
    local part
    for i=1,#self.parts do
        part = self.parts[i]
        
        part.disc           = values[i][1]
        part.startPosition  = values[i][4]
        part.selfCorrection = values[i][2]
        part.discCorrection = values[i][3]
        
        part.obj:set_angle(self.angle[part.disc].value + part.selfCorrection - part.discCorrection, Position(0,0))
       
        part.obj:set_position(rotate_point(     self.center[part.disc],
                                                part.startPosition, 
                                                self.angle[part.disc].value - part.discCorrection))
    end

end

function GameDiscs:on_lb_down()
    local scene = self:scene()
  if   scene:have_mark('start_minigame') then
    if self.activeButton then
        return
    end


    local selection = scene:overed_object()
    
    if selection then    
        if selection:name() == self.buttons[1]:name() then
            self:rotateDisc('left', 1)
            self:pressButton(self.buttonsActive[1])
        elseif selection:name() == self.buttons[2]:name() then
            self:rotateDisc('right', 2)
            self:pressButton(self.buttonsActive[2])
        elseif selection:name() == self.buttons[3]:name() then
            self:rotateDisc('left', 2)
            self:pressButton(self.buttonsActive[3])
        elseif selection:name() == self.buttons[4]:name() then
            self:rotateDisc('right', 1)
            self:pressButton(self.buttonsActive[4])
        end
    end
   end
end

function GameDiscs:pressButton(obj)
    self.activeButton = obj
    obj:show()
end


function GameDiscs:releaseActiveButton()
    if self.activeButton then
        self.activeButton:hide()
        
        self.activeButton = nil
    end
end

function GameDiscs:on_update(dt)
--print(dt)
    if self.needRotate then
        local part    
        for i=1,#self.activeDisc do
            part = self.parts[self.activeDisc[i]]
            
            part.obj:set_angle(self.currentAngle + part.selfCorrection - part.discCorrection, Position(0,0))
           
            part.obj:set_position(rotate_point(     self.center[part.disc], 
                                                    part.startPosition, 
                                                    self.currentAngle - part.discCorrection))
        end
        
        if self.lastTick then
            self.needRotate = false
            
            self.angle[self.activeDiscIndex].value = self.currentAngle
            
            self:correctArrays()
            
            self:releaseActiveButton()

            self:checkComplete()
          
            self.lastTick = false
            return
        end
        
        self.currentAngle = self.currentAngle + dt*self.angleShift
        
        if self.angleShift > 0 then
            if self.currentAngle >= self.angleLimit then            
                self.currentAngle = self.angleLimit
                self.lastTick = true
            end
        else 
            if self.currentAngle <= self.angleLimit then            
                self.currentAngle = self.angleLimit
                self.lastTick = true
            end
        end
    end
end

function GameDiscs:rotateDisc(direction, discIndex)
    local disc = self.discs[discIndex]

    self.activeDisc = disc
    self.activeDiscIndex    = discIndex
    self.currentDirection   = direction
    
    if direction == 'left' then
        self.angleShift = -90
    else
        self.angleShift = 90
    end
    
    self.currentAngle       = self.angle[discIndex].value
    self.startAngle         = self.angle[discIndex].value
    self.angleLimit         = self.currentAngle + self.angle[discIndex][direction]

    local part
    for i=1,#self.common do
        part = self.parts[self.activeDisc[self.common[i]]]
        
        if part.disc ~= discIndex then
            part.disc               = discIndex
            part.startPosition      = part.obj:position()
            part.selfCorrection     = part.obj:angle()
            part.discCorrection     = self.startAngle
        end
    end
    
    self.needRotate = true
end
    
function GameDiscs:correctArrays()
    local oldDiscIndex  
    local discIndex     = self.activeDiscIndex
    local direction     = self.currentDirection
    local disc          = self.activeDisc

    if discIndex == 1 then
        oldDiscIndex = 2
        
        local tmp
        if direction == 'left' then
            for i=1,4 do
                tmp         = disc[i]
                disc[i]     = disc[i+4]
                disc[i+4]   = tmp
            end
        else
            for i=5,8 do
                tmp         = disc[i]
                disc[i]     = disc[i-4]
                disc[i-4]   = tmp
            end
        end
    else
        oldDiscIndex = 1
        
        if direction == 'right' then
            table.insert(disc,disc[1])
            table.remove(disc,1)
            table.insert(disc,disc[1])
            table.remove(disc,1)
        else
            table.insert(disc,1,disc[#disc])
            table.remove(disc,#disc)
            table.insert(disc,1,disc[#disc])
            table.remove(disc,#disc)
        end
    end
    
    -- swap common
    for i=1,#self.common do
        self.discs[oldDiscIndex][self.common[i]] = self.discs[discIndex][self.common[i]]           
    end
end

function GameDiscs:checkComplete()
    local isComplete = true;
    
    for i=2,#self.discs[1] do
        if self.discs[1][i] ~= self.discs[1][i-1]+1 then
            isComplete = false;
            break
        end
    end
    
    if isComplete and (self.discs[2][2] == self.discs[2][1]+1) then
        for i=7,#self.discs[2] do
            if self.discs[2][i] ~= self.discs[2][i-1]+1 then
                isComplete = false;
                break
            end
        end
    end
    
    if isComplete then
       self:scene():execute_action('complete_gamediscs')
       self:remove()
    end
end