class 'brokenObjectEvent' (interface)

-- configuration variables
brokenObjectEvent.animFix = ""					-- Animation played while fixing
brokenObjectEvent.soundFix = ""					-- Sound played while fixing
brokenObjectEvent.targetType = ""				-- Type of the object which is broken
brokenObjectEvent.targetId = ""
brokenObjectEvent.nrTargets = 1
brokenObjectEvent.targetGridX = -1				-- (optional) x location of the object
brokenObjectEvent.targetGridY = -1				-- (optional) y location of the object
brokenObjectEvent.targetWorkX = -1				-- (optional) x location of the object's worknode
brokenObjectEvent.targetWorkY = -1				-- (optional) y location of the object's worknode
brokenObjectEvent.workAnimationFrameRate = -1	-- (optional) frame rate of the work animation
brokenObjectEvent.timeUntilFixed = 1			-- Time it takes to fix the object
brokenObjectEvent.score = 0						-- Score for fixing the object
brokenObjectEvent.overheadX = 0					-- Overhead X offset
brokenObjectEvent.overheadY = 0					-- Overhead Y offset
brokenObjectEvent.pbY = 30						-- Progress bar Y offset
brokenObjectEvent.sequenceStart = nil			-- Start animation
brokenObjectEvent.sequenceWin = nil				-- Win animation
brokenObjectEvent.replaceWhenReady = true		-- Should we replace broken objects by real objects when fixed?
brokenObjectEvent.manual = false
brokenObjectEvent.alwaysShowBar = true
brokenObjectEvent.scoreGotAll = 0

-- internal variables
-- don't change unless you know what you're doing
brokenObjectEvent.brokenObjects = {}
brokenObjectEvent.started = false
brokenObjectEvent.completed = false
-- brokenObjectEvent.desc = nil

brokenObjectEvent.totalTime = 1
brokenObjectEvent.countObjects = 0

function brokenObjectEvent:__init() super()
end

function brokenObjectEvent:onLevelInited()

	if (self.countObjects > 0) then
	
		for index, value in ipairs(self.brokenObjects) do
			-- init object
			value:setOverheadX(self.overheadX)
			value:setOverheadY(self.overheadY)
			value:removeHighlight()
			value.timer = self.timeUntilFixed
			
			-- initialize progress bar
			value.pb = createDefaultFillProgressBar();
			value.pb:setProgress(0)	
			value.pb:setY(self.pbY)
			value.pb:setVisible(false)
			value:addChild(value.pb)
		end
		
		self.totalTime = self.countObjects * self.timeUntilFixed
	
		-- start sequence
		if (self.sequenceStart ~= nil) then
			qSequence(self.sequenceStart)			
		end
		
		-- initialize event bar
		eventBar:setStartAmount(0)
		eventBar:setTargetAmount(100)
		eventBar:setProgress(0)	
		eventBar:setSubjectImage(self.brokenObjects[1]:calcImageName(self.brokenObjects[1]:getBaseName()) .. "_BAR", player:getCurrentResourceSection())
		eventBar:setDescriptionText(getText("EVENTBAR"))

	else
	
		warn("brokenObjectEvent - no target object found")		
	
	end

end

function brokenObjectEvent:onTick()

	if (not self.completed) then
		if (self.started) then
			local timeRemaining = 0
			for index, value in ipairs(self.brokenObjects) do
				timeRemaining = timeRemaining + value.timer
			end
			eventBar:setProgress((self.totalTime - timeRemaining) / self.totalTime * 100)
			
		end
	end

end

function brokenObjectEvent:createObject(desc)

	result = nil
	
	if (self.countObjects < self.nrTargets) then
		if (desc:getType() == self.targetType or desc:getObjectId() == self.targetId) then
			if (self.targetGridX == desc:getGridX() or self.targetGridX == -1) then
				if (self.targetGridY == desc:getGridY() or self.targetGridY == -1) then
					result = brokenObject()
					result.event = self		
					result:setType("brokenObject")
					result.desc = desc
					
					self.brokenObject = result
				
				end
			end			
		end
	end

	if (result ~= nil) then
		result.index = self.countObjects + 1
		self.brokenObjects[ result.index ] = result;
		self.countObjects = result.index
  
	end
	
	return result

end

function brokenObjectEvent:onDayBegin()

	self.started = true
	
	if (self.manual == false) then
		for index, value in ipairs(self.brokenObjects) do			
			value.pb:setVisible(self.alwaysShowBar)
			value:createHighlight()
		end
	end
	
	eventBar:animateToActive()
	eventBar:raiseCurtain()

end

function brokenObjectEvent:onDone(objectIndex)

	local nrFixed = 0
	for index, value in ipairs(self.brokenObjects) do
		if (value.state == "fixed") then
			nrFixed = nrFixed + 1

		end
	end
	
	-- are all objects fixed?
	if (nrFixed == self.countObjects) then
	
		if (self.scoreGotAll > 0) then
			incScore(self.scoreGotAll, emily:getScreenX(), emily:getScreenY() + scorePersonFloaterOffsetY, scoreBonusFloaterDelay, "BONUS")
		end

		if (self.sequenceWinAfterSwap ~= nil) then
			qInsertSequence(self.sequenceWinAfterSwap)
		end	
		
	end
	
	insert()
	scene:qNotify("swap" .. objectIndex)
	append()
			
	-- are all objects fixed?
	if (nrFixed == self.countObjects) then

		emily:playSound(self.soundEventCompleteAll)	

		if (self.sequenceWin ~= nil) then
			qInsertSequence(self.sequenceWin)
		end
		
		-- lower curtain
		eventBar:animateToDeactive()
		
		self.completed = true
		
	end
	
end

function brokenObjectEvent:onNotify(notification)

	if (notification == "swap1") then
		self:onSwap(1)	
	
	elseif (notification == "swap2") then
		self:onSwap(2)
	
	elseif (notification == "swap3") then
		self:onSwap(3)	
	
	elseif (notification == "swap4") then
		self:onSwap(4)	

	elseif (notification == "swap5") then
		self:onSwap(5)	

	elseif (notification == "swap6") then
		self:onSwap(6)	
	
	end

end

function brokenObjectEvent:onSwap(objectIndex)

	if (self.countObjects > 1) then
		emily:playSound(self.soundEventCompleteOne)	
		
	end

	-- increase score
	local x = self.brokenObjects[objectIndex]:getScreenX()
	local y = self.brokenObjects[objectIndex]:getScreenY()
	incScore(self.score, x, y)

	self.brokenObjects[objectIndex]:fix()
	
end

-- a broken object
class 'brokenObject' (D2Object)

-- internal variables
-- don't change unless you know what you're doing
brokenObject.event = nil
brokenObject.timer = 0
brokenObject.state = "broken"
brokenObject.pb = nil
brokenObject.index = -1
brokenObject.pbY = brokenObjectEvent.pbY						-- Progress bar Y offset

function brokenObject:__init() super()
end

function brokenObject:onCreate()

	self:animate(self:getBaseName(), 0)

end

function brokenObject:onClick()

	if (self.state == "broken") then
		self:playSound("SOUND_OBJECT_CLICK")
		if (self:isSelected() == false) then
			self:setSelected(true)
			self:clearOverhead()			
			emily:qWorkOn(self)
		
		end
	end
	
end

function brokenObject:onWorkStart(task)

	self:setSelected(false)
	
	if (self.event.workAnimationFrameRate == -1) then
		emily:animate(self.event.animFix, -1)
	else
		emily:animate(self.event.animFix, -1, self.event.workAnimationFrameRate)
	end
	
	if (self.event.soundFix ~= "") then
		emily:playSound(self.event.soundFix, true)
	end
	
	self.pb:setVisible(true)
	
	return (self.state == "broken")

end

function brokenObject:onWorkUpdate(task, time)

	self.timer = self.timer - time
	if (self.timer <= 0) then
	
		self.timer = 0
		self.state = "fixed"
		self.event:onDone(self.index)
		return true
	
	end
	
	self.pb:setProgress((self.event.timeUntilFixed - self.timer) / self.event.timeUntilFixed)
	
	return emily:hasTasksToDo()

end

function brokenObject:fix()
	local desc = self.desc
	
	-- remove the broken object
	self:setVisible(false)
	self:qDestroy()
	
	if (self.event.replaceWhenReady) then
		-- add the original object
		om:addObject(desc)
	end
end

function brokenObject:getWorkNode()

	if (self.event.targetWorkX == -1 or self.event.targetWorkY == -1) then
		return D2Object.getWorkNode(self)
	else
		return grid:getNode(self.event.targetWorkX, self.event.targetWorkY)
	end

end

function brokenObject:onWorkComplete(task)

	self.pb:setVisible(self.event.alwaysShowBar)
	if (self.event.soundFix ~= "") then
		emily:stopSound(self.event.soundFix)
	end

end

function brokenObject:calcImageName(input)

	res = D2Object.calcImageName(self, input)
	return "BROKEN_" .. res

end