class 'GameLock' (Script)

function GameLock:__init() super()

end

function GameLock:on_attach() --zapolnyu masiv elementami sceni i danimi,i pozicionirovanie
    local xplas           = -19
    local yplas           = -15

    self.timeRotate       =1
    self.current          =nil
    self.timeCount        =1

    self.countComplete    =0
    self.countCompleteMemory=6

    self.countGreen=0
    self.countBlue=0

    self.alphaBlue=0
    self.alphaGreen=0

    self.timeAlpha_grow=1
    self.timeAlpha_regres=0.5
    self.timeAlpha_efGrow=0.5

    self.arrEffect={}


    self.data =
    {{colorElement ='blue',colorTarget='blue', column=7,row=1, coord =Position(1003+xplas,226+yplas)} ,
        {colorElement ='blue',colorTarget='green',column=2,row=1, coord =Position(404+xplas,242+yplas)},
        {colorElement ='blue',colorTarget='green',column=3,row=1, coord =Position(535+xplas,230+yplas)},
        {colorElement ='blue',colorTarget='blue',column=7,row=2, coord =Position(1001+xplas,344+yplas)},
        {colorElement ='blue',colorTarget='green',column=2,row=2, coord =Position(367+xplas,366+yplas)},
        {colorElement ='blue',colorTarget='green',column=3,row=2, coord =Position(502+xplas,355+yplas)},
        {colorElement ='blue',colorTarget='blue',column=7,row=3, coord =Position(997+xplas,459+yplas)} ,
        {colorElement ='blue',colorTarget='green',column=2,row=3, coord =Position(416+xplas,464+yplas)},
        {colorElement ='blue',colorTarget='green',column=3,row=3, coord =Position(546+xplas,477+yplas)},
        {colorElement ='green',colorTarget='blue',column=5,row=1, coord =Position(728+xplas,225+yplas)},
        {colorElement ='green',colorTarget='blue',column=6,row=1, coord =Position(862+xplas,242+yplas)},
        {colorElement ='green',colorTarget='green',column=1,row=1, coord =Position(254+xplas,247+yplas)},
        {colorElement ='green',colorTarget='blue',column=5,row=2, coord =Position(763+xplas,354+yplas)},
        {colorElement ='green',colorTarget='blue',column=6,row=2, coord =Position(884+xplas,361+yplas)},
        {colorElement ='green',colorTarget='green',column=1,row=2, coord =Position(248+xplas,378+yplas)},
        {colorElement ='green',colorTarget='blue',column=5,row=3, coord =Position(754+xplas,477+yplas)},
        {colorElement ='green',colorTarget='blue',column=6,row=3, coord =Position(861+xplas,463+yplas)},
        {colorElement ='green',colorTarget='green',column=1,row=3, coord =Position(284+xplas,499+yplas)},
        {colorElement ='empty',colorTarget='empty',column=4,row=2, coord =Position(635+xplas,356+yplas)}}




  local scene          = self:scene()
  local data           = self.data
  local oven           ='oven'
  local no_oven        = 'no_oven'
  local eff_comm      ='eff_comm'
  local arrObjectData  ={}
  local arrData_eff={}

  self.lightBlue= scene:object('light_blue')
  self.lightGreen= scene:object('light_green')
  
  
  self.arrElements     ={}

  rawset(self.arrElements,'object',arrObject)
  rawset(self.arrElements,'data',arrData)
  for j=1,19 do
    arrData_eff={}

    rawset(self.arrEffect,j,arrData_eff)
    rawset(arrData_eff,'object',scene:object(eff_comm..j))
    rawset(arrData_eff,'count',0)
    rawset(arrData_eff,'alpha',0)
  end
  for i=1,18 do
    arrObjectData={}


    rawset(self.arrElements,i,arrObjectData)
    rawset(arrObjectData,'data',data[i])
    if i<10 then
      rawset(arrObjectData,'object',scene:object(no_oven..i))
    else
      rawset(arrObjectData,'object',scene:object(oven..(i-9)))
    end
    self.arrElements[i]['object']:set_position(self.arrElements[i]['data'].coord)
  end
 -- self.arrElements[19]['object']=scene:object('empty')     dopustima li takaya zapis
 -- self.arrElements[19]['data']  =data[19]
  arrObjectData={}
  rawset(self.arrElements,19,arrObjectData)
  rawset(arrObjectData,'data',data[19])
  rawset(arrObjectData,'object',scene:object('empty2'))
  self.arrElements[19]['object']:set_position(self.arrElements[19]['data'].coord)

  self:initCogvils()
  self:initBolts()
  for i=1,19 do
     if self:admissionAction(self.arrElements[i],self.arrElements[19]) then
       self:effect_active_go(self.arrElements[i],self.arrEffect[i],-5,-7)
     end
  end
end


function GameLock:initCogvils()     --sozdau rabochiy masiv danih i elementov shesterenki
  local scene     = self:scene()
  local c1        =scene:object('c1')
  local c2        =scene:object('c2')
  local c3        =scene:object('c3')
  local c4        =scene:object('c4')

  local arrObjectC ={c1,c2,c3,c4}
  local arrObjectDataC={}
  self.cogwheels  ={}
  self.dataCogwheels={{center=Position(c1:dimensions():lx()/2,c1:dimensions():ly()/2),angle=0,direction=1,speed=40},
                     {center=Position(c2:dimensions():lx()/2,c2:dimensions():ly()/2),angle=0,direction=-1,speed=40},
                     {center=Position(c3:dimensions():lx()/2,c3:dimensions():ly()/2),angle=0,direction=1,speed=40},
                     {center=Position(c4:dimensions():lx()/2,c4:dimensions():ly()/2),angle=0,direction=-1,speed=40} }

  for i=1,4 do
    arrObjectDataC={}
    rawset(self.cogwheels,i,arrObjectDataC)
    rawset(arrObjectDataC,'object',arrObjectC[i])
    rawset(arrObjectDataC,'data',self.dataCogwheels[i])
  end
end

function GameLock:initBolts()
  local scene=self:scene()
  local bolt1=scene:object('leftzasov')
  local bolt2=scene:object('rightzasov')
  local xb1=bolt1:position():x()
  local xb2=bolt2:position():x()
  local arrData={{posX=xb1,direction=1,speed=10},{posX=xb2,direction=-1,speed=10} }
  local arrObject={bolt1,bolt2}
  local arrDataObject={}
  self.arrBolts={}
  for i=1,2 do
    arrDataObject={}
    rawset(self.arrBolts,i,arrDataObject)
    rawset(arrDataObject,'object',arrObject[i])
    rawset(arrDataObject,'data',arrData[i])
  end
end

function GameLock:on_lb_down()

  local scene     =self:scene()
  local empty     =self.arrElements[19]
  local selection =scene:overed_object()

 -- if empty['object']:name()==selection:name() then
  --  if self.current~=nil then
    --    if  self:admissionAction(self.current,empty) then
           
	--	   self:scene():execute_action('movement_go')
	--	  self:exchangeValues(self.current,empty)

     --       self.current['object']:set_position(self.current['data'].coord)
         --   empty['object']:set_position(empty['data'].coord)
         --   self.current['object']:set_alpha(1)

		--	self:effect_go(self.current)
            
          --  self.current=nil
          --  self:endGame()
          --  self:changeDirection()   --izmeneniya napravleniya povorota shesterenok i pereinicializaciya necotorih elementov
        --
      --  end
   -- end
  --else
   if selection then
    for i=1,19 do
       if self.arrElements[i]['object']:name()==selection:name() then
          if  self:admissionAction(self.arrElements[i],empty) then
            for i=1,19 do
              self.arrEffect[i]['alpha']=0
              self.arrEffect[i]['object']:set_alpha(self.arrEffect[i]['alpha'])
             --self.arrEffect[i]['count']=100000
            end
            self:exchangeValues(self.arrElements[i],empty)
            self.arrElements[i]['object']:set_position(self.arrElements[i]['data'].coord)
            self:endGame()
            self:changeDirection()
            self:effect_go(self.arrElements[i],-30,-30)
            self:scene():execute_action('movement_go')
            for i=1,19 do
              if self:admissionAction(self.arrElements[i],empty) then
                 self:effect_active_go(self.arrElements[i],self.arrEffect[i],-5,-7)
              end
            end
            break
          end
       end
    end
   end

end

function GameLock:effect_active_go(object,object_ef,x_shift,y_shift)
  local pos=object['data'].coord
  local x=pos:x()
  local y=pos:y()
  local new_pos=Position(x+x_shift,y+y_shift)
     object_ef['object']:set_position(new_pos)
     object_ef['alpha']=0
     object_ef['count']=0
end

function GameLock:effect_go(object,x_shift,y_shift)
	
  local pos=object['data'].coord
  local x=pos:x()
  local y=pos:y()
  local new_pos=Position(x+x_shift,y+y_shift)
	
  if object['data'].colorElement== object['data'].colorTarget then
     if object['data'].colorElement=='green'	then
        self.lightBlue:set_position(new_pos)
        self.alphaBlue=0
		self.countBlue=0		
     end
     if object['data'].colorElement=='blue'	then
        self.lightGreen:set_position(new_pos)
        self.alphaGreen=0
		self.countGreen=0
     end
  end
end


function GameLock:changeDirection()
 if  self.countComplete~=self.countCompleteMemory then
        if self.countComplete>self.countCompleteMemory then
        self:scene():execute_action('cogwils_go')
           self.cogwheels[1]['data'].direction=-1
           self.cogwheels[2]['data'].direction=1
           self.cogwheels[3]['data'].direction=-1
           self.cogwheels[4]['data'].direction=1
           self.arrBolts[1]['data'].direction=-1
          self.arrBolts[2]['data'].direction=1
        else
        self:scene():execute_action('cogwils_go')
           self.cogwheels[1]['data'].direction=1
           self.cogwheels[2]['data'].direction=-1
           self.cogwheels[3]['data'].direction=1
           self.cogwheels[4]['data'].direction=-1
          self.arrBolts[1]['data'].direction=1
          self.arrBolts[2]['data'].direction=-1
        end

       self.countCompleteMemory=self.countComplete
       self.timeCount=0
 end
end


function GameLock:on_update(dt)
  local timeAlpha_grow=self.timeAlpha_grow/dt
  local timeAlpha_reg= self.timeAlpha_regres/dt
  local timeEf       =self.timeAlpha_efGrow/dt

  if self.countBlue<timeAlpha_grow then
  	self.alphaBlue=self.alphaBlue+1/(timeAlpha_grow/0.7)
    self.lightBlue:set_alpha(self.alphaBlue)	    
	self.countBlue=self.countBlue+1
	
  else
  	if  self.countBlue<timeAlpha_grow+timeAlpha_reg then  	 	
		self.alphaBlue=self.alphaBlue-1/(timeAlpha_reg/0.7)     	
		self.lightBlue:set_alpha(self.alphaBlue)
		self.countBlue=self.countBlue+1
    end
  end
  
  
  if self.countGreen<timeAlpha_grow then
    self.alphaGreen=self.alphaGreen+1/(timeAlpha_grow/0.7)
    self.lightGreen:set_alpha(self.alphaGreen)
    self.countGreen=self.countGreen+1
  else
 	if self.countGreen<timeAlpha_grow+timeAlpha_reg then	
  	   self.alphaGreen=self.alphaGreen-1/(timeAlpha_reg/0.7)
       self.lightGreen:set_alpha(self.alphaGreen)
       self.countGreen=self.countGreen+1
    end     
  end

  for i=1,18 do                                                        -- proishodit rost alpha u elementov kotorimi mogno hodit
     if self.arrEffect[i]['count']<timeEf then
      self.arrEffect[i]['alpha']=self.arrEffect[i]['alpha']+1/(timeEf/0.7)
      self.arrEffect[i]['object']:set_alpha(self.arrEffect[i]['alpha'])
      self.arrEffect[i]['count']=self.arrEffect[i]['count']+1
     end
  end

  if self.timeCount<self.timeRotate then
    for i=1,4 do
      self.cogwheels[i]['data'].angle= self.cogwheels[i]['data'].angle +
                                     self.cogwheels[i]['data'].speed*self.cogwheels[i]['data'].direction*dt/self.timeRotate

      self.cogwheels[i]['object']:set_angle(self.cogwheels[i]['data'].angle,self.cogwheels[i]['data'].center)
    end
    for i=1,2 do
      self.arrBolts[i]['data'].posX=self.arrBolts[i]['data'].posX +
                                   self.arrBolts[i]['data'].speed*self.arrBolts[i]['data'].direction*dt/self.timeRotate
      self.arrBolts[i]['object']:set_position(Position(self.arrBolts[i]['data'].posX,self.arrBolts[i]['object']:position():y()))
    end
    self.timeCount = self.timeCount+dt
  end
 end



function GameLock:endGame()
  local countEnd=0
  for i=1,18 do
   if self.arrElements[i]['data'].colorElement==self.arrElements[i]['data'].colorTarget then
    countEnd=countEnd+1
   end
  end

  if countEnd==18 then
       self:scene():execute_action('gamelock_complete')
  end
  self.countComplete=countEnd
end


function GameLock:exchangeValues(myObject,emptyObject)    --obmen danimi pustogo elementa s tekushim
    local vertObject
	local gorizontObject
	local coordinatObject
	local positionObject
    local colorTargetObject

	local vertempty
	local gorizontempty
	local coordinatempty
	local positionempty
    local colorTargetempty

	vertObject     			= myObject['data'].row
	gorizontObject 			= myObject['data'].column
    coordinatObject			= myObject['data'].coord
    colorTargetObject       = myObject['data'].colorTarget

	vertempty      			= emptyObject['data'].row
    gorizontempty  			= emptyObject['data'].column
    coordinatempty          = emptyObject['data'].coord
    colorTargetempty        = emptyObject['data'].colorTarget

    myObject['data'].row    	    = vertempty
    myObject['data'].column	        = gorizontempty
    myObject['data'].coord          = coordinatempty
    myObject['data'].colorTarget    = colorTargetempty

    emptyObject['data'].row         = vertObject
    emptyObject['data'].column       = gorizontObject
    emptyObject['data'].coord        = coordinatObject
    emptyObject['data'].colorTarget  = colorTargetObject
end


function GameLock:admissionAction(myObject,emptyObject) --funkciya opredelyet dopustimost peremesheniya elementov

	local vertObject      = myObject['data'].row
	local gorizontObject  = myObject['data'].column
	local vertempty       =emptyObject['data'].row
	local gorizontempty   =emptyObject['data'].column


	if  (vertObject-vertempty==0)and (gorizontObject-gorizontempty==2 or gorizontObject-gorizontempty==-2) then
		 if vertObject~=2 and gorizontObject==3 then
		    if gorizontempty==1 then
		    	return true
		    else
		 		return false
		 	end
		 end
	end
	if  (vertObject-vertempty==0)and (gorizontObject-gorizontempty==2 or gorizontObject-gorizontempty==-2) then
		 if vertObject~=2 and gorizontObject==5  then
            if gorizontempty==7 then
		    	return true
		    else
		 		return false
		 	end
		 end
	end

	if 	(vertObject-vertempty==1 or vertObject-vertempty==-1) and (gorizontObject-gorizontempty==1 or gorizontObject-gorizontempty==-1) then
	     return true
	end
	if  (vertObject-vertempty==1 or vertObject-vertempty==-1) and (gorizontObject-gorizontempty==0)  then
	     return true
	end
 	if  (vertObject-vertempty==2 or vertObject-vertempty==-2) and (gorizontObject-gorizontempty==0)   then
	     return true
	end
	if  (vertObject-vertempty==0)and (gorizontObject-gorizontempty==2 or gorizontObject-gorizontempty==-2)  then
	     return true
	end
    if  (vertObject-vertempty==0 )and (gorizontObject-gorizontempty==1 or gorizontObject-gorizontempty==-1)  then
	     return true
	end

	return false
end