dofile("script/objects/ProgressBar.lua")

-- ************************************ FixEvent ************************************ --
FixEvent = deriveLuaClass("FixEvent", "Event")

-- ###### Configuration variables ######
-- FixEvent.scoreOneDone = 10		-- score for fixing one item
-- FixEvent.scoreAllDone = 100		-- bonus for fixing all items
FixEvent.completed = false
FixEvent.scoreAllDone = 10
FixEvent.hideOnLose = false

function FixEvent:init(desc)
	FixEvent.superInit(desc)
	self.itemsDone = 0
	self.itemCount = table.count(self.items)
	assert(self.itemCount >= 1)
	if (self.trackProgress == nil) then
		self.trackProgress = (self.itemCount == 1)
	end
end

function FixEvent:onInitialized()
	FixEvent.super.onInitialized(self)
	local i = 1
	for _,v in pairs(self.items) do
		if (v.obj) then
			v.obj = level:getChild(v.obj)
			if (v.obj) then
				v.obj.event = self
				v.obj.index = i
			end
		end
		if (v.activate) then
			v.activate = level:getChild(v.activate)
			if (v.activate) then
				v.activate.visible = false
			end
		end
		i = i + 1
	end

	eventBar.progress = 0
	eventBar.startValue = 0
	if (self.trackProgress) then
		eventBar.targetValue = 1
		eventBar.soundOnProgress = false
	else
		eventBar.targetValue = math.max(1, self.itemCount)
	end
	eventBar.showValue = not self.trackProgress
	eventBar.showTarget = not self.trackProgress
end

function FixEvent:onShiftFinish()
	hintManager:removeArrows({id="FixEvent"})
	self.completed = true
    
    if (self.hideOnLose) then
		for _,v in pairs(self.items) do
			v.obj.clickable = false
			v.obj.visible = false
		end
	end
end

function FixEvent:onStart()
    for _,v in pairs(self.items) do
		v.obj.clickable = true
		v.obj.visible = true
		hintManager:placeArrow({type="down", name="FixEvent", parent=level.dragLayer, x=v.obj.x + v.obj.width/2, y=v.obj.y})
	end

	eventBar:activate()
	self.hintFired = false
end

function FixEvent:onTick(time)
	if (not self.hintFired) then
		local frac = 0
		if (level.levelDuration > 0) then
			frac = level.elapsedTime / level.levelDuration
		end
		if (frac > 0.85 and self:getProgress() == 0) then
			hintManager:handle({id="fixed_nothing", sprite=self.items[1].obj})
			self.hintFired = true
		end
	end
end

function FixEvent:onStepDone(index)
	self.completed = true
	self.won = true
	local v = self.items[index]
	level:addHeartScoreWithFloater(self.scoreAllDone, v.obj.location.x + v.obj.width, v.obj.location.y, false)

	if (v.obj) then
		v.obj.visible = false
	end
	if (v.activate) then
		v.activate.visible = true
	end

	if (not self.trackProgress) then
		eventBar:incValue(1)
	end

	if (not v.done) then
		v.done = true
		self.itemsDone = self.itemsDone + 1
		if (self.itemsDone >= self.itemCount) then
			eventBar:deactivate()
			if (isTable(taskSystem:getAnimationDesc("eventWon"))) then
				return taskSystem:createAnimation("eventWon", self.sequenceWonParams)
			end
		else
			if (isTable(taskSystem:getAnimationDesc("eventThanks"))) then
				return taskSystem:createAnimation("eventThanks", self.sequenceThanksParams)
			end
		end
	end
end

function FixEvent:getProgress()
	local fixDuration = 0
	local progress = 0
	for _,v in pairs(self.items) do
		fixDuration = fixDuration + v.obj.fixDuration
		progress = progress + v.obj.progress
	end
	if (fixDuration == 0) then return 1 end
	return progress / fixDuration
end

function FixEvent:onProgress()
	if (self.trackProgress) then
		eventBar.progress = self:getProgress()
	end
end

-- ************************************ Fixable Object ************************************ --
FixableObject = deriveLuaClass("FixableObject", "Object")

function FixableObject:init(desc)
	self.bar = "progressbar_big"
	self.workAnimationFrameTime = 200

	FixableObject.superInit(desc)

	self.fixDuration = desc.fixDuration or 10000
	self.progress = 0 -- We cannot use the task's timer!
	self.fixState = "broken"
	self.bar = self:newChild(blueprints[desc.bar or "progressbar_big"])
	self.bar.location = desc.barPos
	self.bar.alpha = 0
end

function FixableObject:onClick()
	if (self.fixState == "broken") then
		if (not self.selected) then
			self.selected = true
			hero:addTask({class="SetTask", positionLock=self})
			hero:addTask({class="WorkTask", target=self})
		end
	end
end

function FixableObject:onWorkCancel(task)
	FixableObject.super.onWorkCancel(self, task)
	self.selected = false
end

function FixableObject:onWorkStart(task)
	FixableObject.super.onWorkStart(self, task)
	hintManager:removeArrows({id="FixEvent"})
	self.selected = false
	task.actor:playAnimation(self.workAnimation, nil, nil, self.workAnimationFrameTime)
	task.duration = self.fixDuration
	self.bar:animate({alpha=1, duration=600})
	return (self.fixState == "broken")
end

function FixableObject:onWorkUpdate(task, time)
	if (self.fixState == "broken") then
		self.progress = self.progress + time -- We cannot use the task's timer!
		if (self.progress >= self.fixDuration) then
			self.fixState = "fixed"
			self.event:onStepDone(self.index)
			self.bar:setProgress(1)
		else
			self.bar:setProgress(self.progress / self.fixDuration)
			self.event:onProgress()
		end
	end
	self.frame = math.min(self.bar.progress * self.frameCount, self.frameCount-1)
	return (self.fixState == "fixed") or taskSystem:hasTaskFor(hero) or level.event.completed
end

function FixableObject:calcImageName(input)
	local res = FixableObject.super.calcImageName(self, input)
	return res .. "_BROKEN_" .. (self.event.itemCount - 1)
end
