class 'shoutAndMakeEvent' (interface)

--
-- configuration variables
shoutAndMakeEvent.baseName = ""								-- appearance of the customer
shoutAndMakeEvent.pool = {}									-- product pool
shoutAndMakeEvent.chances = {}								-- product chances
shoutAndMakeEvent.timeUntilNextOrder = 0					-- interval at which the orders come
shoutAndMakeEvent.timeUntilEnd = 0							-- time allowed to make all products
shoutAndMakeEvent.timeTransfer = 400						-- time it takes to transfer the order
shoutAndMakeEvent.waitX = 0									-- position the mailman waits inside
shoutAndMakeEvent.waitY = 0
shoutAndMakeEvent.workX = 0									-- position emily will be to deliver the order
shoutAndMakeEvent.workY = 0
shoutAndMakeEvent.numProductsPerOrder = 0					-- number of products ordered each order
shoutAndMakeEvent.numOrders = 0								-- total number of orders
shoutAndMakeEvent.workAnim = "IDLE"							-- animation played by customer
shoutAndMakeEvent.workAnimEmily = "WORK_RIGHT"				-- animation played by Emily
shoutAndMakeEvent.sequenceStart = nil
shoutAndMakeEvent.sequenceDone = nil
shoutAndMakeEvent.sequenceWin = nil
shoutAndMakeEvent.sequenceLose = nil
shoutAndMakeEvent.sequenceDayEnd = nil						-- sequence played when the day ends
shoutAndMakeEvent.score = 0									-- score per product
shoutAndMakeEvent.maxBalloonSize = 0

shoutAndMakeEvent.bubbleOffsetX = 0
shoutAndMakeEvent.bubbleOffsetY = 0
shoutAndMakeEvent.barOffsetY = 0

shoutAndMakeEvent.timeUntilArrivalMin = 0 * 1000			-- min time before the customer arrives
shoutAndMakeEvent.timeUntilArrivalMax = 1 * 1000			-- max time before the customer arrives

-- internal variables
-- don't change unless you know what you're doing
shoutAndMakeEvent.owner = nil
shoutAndMakeEvent.order = nil
shoutAndMakeEvent.countOrders = 0
shoutAndMakeEvent.countHanded = 0
shoutAndMakeEvent.timer = 0
shoutAndMakeEvent.totalTimer = 0
shoutAndMakeEvent.started = false
shoutAndMakeEvent.completed = false
shoutAndMakeEvent.state = "waiting"
shoutAndMakeEvent.chanceTotal = 0

function shoutAndMakeEvent:__init() super()
end

function shoutAndMakeEvent:onLevelInited()

	self.owner = pm:createPerson("shoutcustomer")
	if (self.owner ~= nil) then
		
		self.timer = getRandomRange(self.timeUntilArrivalMin, self.timeUntilArrivalMax)
		self.started = false
		
		-- create order
		self.order = createOrder()
		
		-- place order
		self.order:setX(self.bubbleOffsetX)
		self.order:setY(self.bubbleOffsetY)
		self.order:setAnchorPointType(BOTTOMCENTER)		
		self.order:setPivotPointType(BOTTOMCENTER)		
		self.order:setMoneyOrder(false)
		self.order:setMaxBalloonSize(self.maxBalloonSize)
		self.order:setVisible(false)
		self.owner:addChild(self.order)
		
		-- calculate total chance
		self.chanceTotal = 0
		for index, value in ipairs(self.chances) do
			self.chanceTotal = self.chanceTotal + value
		end  
		
		-- initialize progress bar
		self.owner.pb = createDefaultFillProgressBar();
		self.owner.pb:setProgress(1)	
		self.owner.pb:setY(self.barOffsetY)
		self.owner.pb:setVisible(false)
		self.owner:addChild(self.owner.pb)
		
		-- initialize event bar
		eventBar:setStartAmount(0)
		eventBar:setTargetAmount(self.timeUntilEnd / 1000)
		eventBar:setProgress(self.timeUntilEnd / 1000)				
		eventBar:setDescriptionText(getText("EVENTBAR"))		
		
		self:updateProgress()

	else
	
		warn("shoutAndMakeEvent - no order owner found")	
	
	end

end

function shoutAndMakeEvent:calcProduct()

	local random = getRandomRange(0, self.chanceTotal)
	
	local counter = 0
	for index, value in ipairs(self.chances) do
		counter = counter + value
		
		if (random <= counter) then
			return self.pool[index]
			
		end
		
	end
	
	return "error"		

end

function shoutAndMakeEvent:endEvent()

	if (self.order ~= nil) then
		-- get rid of the order
		self.order:setObsolete(true)
		self.order = nil
	end
	
	if (self.owner.pb ~= nil) then
		-- hide the progress shizzle and disable selection
		self.owner.pb:setVisible(false)
		self.owner.pb = nil
	end
	self.owner:getHighlight():clear()    
	self.owner:getHighlight():setActive(false)
end

function shoutAndMakeEvent:onDayEnd()
	
	self.state = "day over"
	self:endEvent()
	if (self.sequenceDayOver ~= nil) then
		qSequence(self.sequenceDayOver)
	end
	
end

function shoutAndMakeEvent:onStart()

	if (self.started == false) then
		
		self.state = "waiting"
		self.started = true
		self.timer = 0
		self.totalTimer = self.timeUntilEnd
		self:updateProgress()
		eventBar:animateToActive()
		
		if (self.sequenceStart ~= nil) then
			qSequence(self.sequenceStart)
			
		else
			-- just go straight into ordering
			self.state = "ordering"
		end
	end
	
end

function shoutAndMakeEvent:onTick(time)

	if (scene:isStartingMovie() or scene:isPlayingMovie()) then
		return
	end
	
	if (self.started == false) then
		self.timer = self.timer - time
		if (self.timer <= 0) then
			self:onStart()
		end
		return
	end
	
	if (self.completed == true) then
		return
	end
	
	if (self.state == "waiting") then
		-- do nothing
		
	elseif (self.state == "ordering") then
	
		self.timer = self.timer - time
		if (self.timer < 0) then
			self.timer = 0
		end
		
		if (self.timer <= 0) then
		
			-- add a new order
			for i = 1, self.numProductsPerOrder do
				self.order:addProduct(self:calcProduct())
			end
			
			-- increase order counter
			self.countOrders = self.countOrders + 1
			
			-- pop
			if (self.countOrders == 1) then
				self.order:setVisible(true)
				self.order:popIn()
				emily:playSound("SOUND_EVENT_ATTENTION")
			
			end			
			
			-- reset timer
			self.timer = self.timeUntilNextOrder
	
		end
		
		self.totalTimer = self.totalTimer - time
		self:updateProgress()
		
		-- handle state
		if (self.countOrders == self.numOrders) then
			self.state = "waiting until end"
			
		end
		
	elseif (self.state == "waiting until end") then
		
		self.totalTimer = self.totalTimer - time
		if (self.totalTimer < 0) then
			self.totalTimer = 0
		end
		
		self:updateProgress()
		
		if (self.totalTimer <= 0) then

			-- event failed
			self:onDone()
		
		end
		
	else
		
		-- do nothing	
			
	end
	
end

function shoutAndMakeEvent:updateProgress()
	
	eventBar:setProgress(self.totalTimer/1000)
	self.owner.pb:setProgress(self.totalTimer / self.timeUntilEnd)
	
end

function shoutAndMakeEvent:onDone()

	-- check the order
	if (self.order:isCompleted()) then
		self.state = "win"
		emily:playSound(self.soundEventCompleteAll)
	
	else
		self.state = "lose"
		
	end

	-- kill the event
	self:endEvent()

	-- done sequence
	if (self.sequenceDone ~= nil) then
		qInsertSequence(self.sequenceDone)	
	end

	-- state
	self.completed = true	
	
	-- eventbar
	eventBar:animateToDeactive()

end

function shoutAndMakeEvent:onNotify(notification)

	if (notification == "start ordering") then
		self.state = "ordering"
		self.timer = 0
		eventBar:animateToActive()
		self.owner.pb:setVisible(true)
	
	elseif (notification == "win lose") then
		
		if (self.state == "win") then
			if (self.sequenceWin ~= nil) then
				qInsertSequence(self.sequenceWin)
			end
		
		elseif (self.state == "lose") then
			if (self.sequenceLose ~= nil) then
				qInsertSequence(self.sequenceLose)
			end
		
		end
	
	end

end

function shoutAndMakeEvent:createPerson(class)
	
	local result = nil
	if (class == "shoutcustomer") then
	
		result = orderOwner(self.baseName)
		result:setPosition(entryNode)
		result:setType(class)
		result.event = self
		
	end
	
	return result
end

-- an order mailman
class 'orderOwner' (npc)

-- internal variables
-- don't change unless you know what you're doing
orderOwner.event = nil
orderOwner.pb = nil

function orderOwner:__init(baseName) super(baseName)
end

function orderOwner:onCreate()

	npc.onCreate(self)
	self:createHighlight()
	
end

function orderOwner:onClick()

	if (self:isSelected() == false) then
  
		emily:qWorkOn(self)
		self:setSelected(true)
    
	end
	
end

function orderOwner:onWorkStart(task)

	self:setSelected(false)

	-- time it takes to transfer the order
	task:setDuration(self.event.timeTransfer)
	
	-- hand over products
	n = tray:distributeProducts(self.event.order)
	if (n > 0) then
		
		-- draw order
		self.event.order:draw()	

		-- animate emily
		emily:animate(self.event.workAnimEmily, 1)
	  
		-- animate mailman
		self:animate(self.event.workAnim, 1)
		
		-- update count
		self.event.countHanded = self.event.countHanded + n
  		
		-- check end
		if (self.event.state == "waiting until end") then
			if (self.event.order:isCompleted()) then
				self.event:onDone()
				
			end
		end
		
		-- score
		incScore(self.event.score * n, self:getScreenX(), self:getScreenY() + scorePersonFloaterOffsetY)
		emily:playSound(self.event.soundEventCompleteOne)
		
	end
	
	return true
	
end

function orderOwner:onWorkComplete(task)

	self:animate("IDLE", 0)
	emily:animate("IDLE", 0)

end

function orderOwner:getWorkNode()
  
	return grid:getNode(self.event.workX, self.event.workY)
  
end
