class 'mailmanEvent' (interface)

-- configuration variables
mailmanEvent.sequenceStart = nil
mailmanEvent.sequenceComplete = nil
mailmanEvent.baseName = ""							-- appearance of the mailman
mailmanEvent.baseSection = "characters"
mailmanEvent.timeUntilEnterMin = 0					-- minimum time the mailman waits outside
mailmanEvent.timeUntilEnterMax = 1					-- maximum time the mailman waits outside
mailmanEvent.timeUntilAngry = 0						-- time until the mailman gets angry
mailmanEvent.timeUntilLeave = 0						-- time until the mailman leaves
mailmanEvent.timeTransfer = 400						-- time it takes to transfer the package
mailmanEvent.numPackages = 0						-- number of packages mailman will deliver
mailmanEvent.entryX = 0								-- position he waits outside
mailmanEvent.entryY = 0
mailmanEvent.waitX = 0								-- position he waits inside
mailmanEvent.waitY = 0
mailmanEvent.workX = 0								-- position emily will be to get the package
mailmanEvent.workY = 0
mailmanEvent.angryAnim = ""							-- animation played by mailman when he gets angry
mailmanEvent.angryAnimFPS = -1
mailmanEvent.workAnim = ""							-- animation played by mailman when handing over package
mailmanEvent.workAnimEmily = ""						-- animation played by emily when receiving package
mailmanEvent.scoreGotOne = 0						-- score for finding one item
mailmanEvent.scoreGotAll = 0						-- bonus for finding all items
mailmanEvent.package = ""							-- package the mailman carries

-- internal variables
-- don't change unless you know what you're doing
mailmanEvent.started = false
mailmanEvent.completed = false
mailmanEvent.packageObject =  nil

function mailmanEvent:__init() super()
end

function mailmanEvent:onLevelInited()
	
  	-- create the mailman
	self.person = pm:createPerson("mailman")
	self.person:setBaseName(self.baseName)
	self.person:setPosition(grid:getNode(self.entryX, self.entryY))
	
	-- initialize event bar
	eventBar:setStartAmount(0)
	eventBar:setTargetAmount(math.max(1, self.numPackages))
	eventBar:setProgress(0)	
	eventBar:setSubjectImage(self.package .. "_BAR", player:getCurrentResourceSection())
	eventBar:setDescriptionText(getText("EVENTBAR"))
	
	-- start sequence
	if (self.sequenceStart ~= nil) then
		qSequence(self.sequenceStart)
	end			
	
end

function mailmanEvent:createPerson(class)

	if (class == "mailman") then
		m = mailman(self.baseName)
		m.event = self
		m:setType(class)
		return m
		
	end
		
	return nil
		
end

function mailmanEvent:createObject(desc)

	if (desc:getType() == "Package") then
		self.packageObject = packageObject()
		self.packageObject.event = self		
		self.packageObject:setType("Package")
		self.packageObject:setVisible(false)
		return self.packageObject
				
	end
	
	return nil

end

function mailmanEvent:onDayBegin()

	self.started = true
	
	-- raise the curtain
	eventBar:animateToActive()

end

-- a mailman
class 'mailman' (npc)

-- internal variables
-- don't change unless you know what you're doing
mailman.timer = 0
mailman.counter = 0
mailman.handed = 0
mailman.state = "wait to enter"
mailman.target = nil			
mailman.carry = true
mailman.event = nil	

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

function mailman:onCreate()

	self:setDefaultSection(self.event.baseSection)
	D2Person.onCreate(self)	
	self:createHighlight()
	self:setPosition(grid:getNode(self.event.entryX, self.event.entryY))
	self:setVisible(false)
		
	self.state = "wait to enter"
	self.timer = getRandomRange(self.event.timeUntilEnterMin, self.event.timeUntilEnterMax)
	
end

function mailman:onTick(time)

	if (self.event.started == false) then
		return
	end
	
	if (self.event.completed == true) then
		return
	end

  	if (self.state == "walking out") then
  
		-- check if we arrived at our spot
		if (self:getPosition():getGridX() == self.target:getGridX()) then
			if (self:getPosition():getGridY() == self.target:getGridY()) then
	    
				if (self.counter < self.event.numPackages - 1) then

					self.state = "wait to enter"			    
					self.counter = self.counter + 1
			    	self.timer = getRandomRange(self.event.timeUntilEnterMin, self.event.timeUntilEnterMax)
			      
			  	else
			  
			    	-- all packages done
			    	-- set person in done mode
			    	self.state = "done"
			    	-- set event to completed
			    	self.event.completed = true
			    	-- lower the curtain
			    	eventBar:animateToDeactive()
			  
			  	end	      
			end
		end    
  
	elseif (self.state == "walking in") then
  
		-- check if we arrived at our spot
		if (self:getPosition():getGridX() == self.target:getGridX()) then
			if (self:getPosition():getGridY() == self.target:getGridY()) then
	    
				self.state = "wait to angry"
				-- wait time until we get angry
				self.timer = self.event.timeUntilAngry	      
				-- enable highlight so we can click the mailman
				self:getHighlight():setActive(true)		
				-- get attention
				self:playSound("SOUND_EVENT_ATTENTION")
				-- raise curtain
				eventBar:raiseCurtain()
				
				if (self.counter == 0) then
					self:createOverhead("INGAME_ARROW")
					
				end	      
			end
		end  
  
	elseif (self.state == "wait to enter") then
  
		-- wait until we can enter
		self.timer = self.timer - time
		if (self.timer < 0) then
    
    		self.state = "walking in"
    		
    		-- Make sure we can change the appearance of the 'mailman' between
    		-- visits. NOTE: setBaseName is called with the previous baseName!
    		self:qNotify("about to enter")
			self:setBaseName(self.event.baseName)
			
			-- walk to our 'wait' position
			self.target = grid:getNode(self.event.waitX, self.event.waitY)
			self:qSetVisible(true)
			self:qWalkToNode(self.target)      
			
			-- do it with a package
			self.carry = true
			self:setAppearance("")
			
    	end  
    
	elseif (self.state == "wait to angry") then
    
    	-- wait until we get annoyed
    	self.timer = self.timer - time
		if (self.timer < 0) then
      
			self.state = "wait to leave"
			-- wait time until we leave
			self.timer = self.event.timeUntilLeave
			-- animate mailman
			self:setAppearance("ANNOYED")
			self:animate(self.event.angryAnim, 1, self.event.angryAnimFPS)
      
    	end
    
	elseif (self.state == "wait to leave") then
  
		-- wait until we leave pissed
		self.timer = self.timer - time
		if (self.timer < 0) then
	  
			self.state = "walking out"
			-- disable highlight so we can't click the mailman anymore
			self:getHighlight():clear()    
			self:getHighlight():setActive(false)	    
			-- walk to exit
			self:playSound(self.event.soundEventBad)
			self:setAppearance("")
			self:qWalkToXY(self.event.entryX, self.event.entryY)
			self:qSetVisible(false)
	    
		end  
  
	elseif (self.state == "done") then
  
		-- do nothing 

	elseif (self.state == "handing over") then
  
		-- do nothing
  
	end

end

function mailman:onClick()

	-- if the mailman is already selected then the player already
	-- clicked on him. in that case we ignore the click.
	if (self:isSelected() == false) then
  
		-- change the mailman state. this makes sure
    	-- he doesn't run away while emily is trying to retrieve
		-- the package
		self.state = "handing over"
    
		-- make emily get the package
		emily:qWorkOn(self)
    
		-- select the mailman
		-- this makes sure that we can't receive multiple packages
		-- from him at once
		self:setSelected(true)
		self:clearOverhead()
    
	end
	
end

function mailman:onWorkStart(task)

	-- disable selection
	self:setSelected(false)
	-- disable highlight so we can't click the mailman anymore
	self:getHighlight():clear()    
	self:getHighlight():setActive(false)	 

	-- animate emily
	emily:animate(self.event.workAnimEmily, 1)
  
	-- animate mailman
	self:animate(self.event.workAnim, 1)
  		
	-- time it takes to transfer the package
	task:setDuration(self.event.timeTransfer)
	
	return true
	
end

function mailman:onWorkComplete(task)

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

	-- the mailman leaves after handing over the package
	self.state = "walking out"
	self.carry = false
	-- walk to exit
	self:qWalkToXY(self.event.entryX, self.event.entryY)
	self:qSetVisible(false)
	
	-- increase score and pop a floater
	incScore(self.event.scoreGotOne, self:getScreenX(), self:getScreenY() + scorePersonFloaterOffsetY, 0)

	self:playSound(self.event.soundEventCompleteOne)	
	
	-- update the event bar
	self.handed = self.handed + 1
	eventBar:setProgress(self.handed)
	eventBar:lowerCurtain()
	
	-- show package
	if (self.event.packageObject ~= nil) then
		self.event.packageObject:setVisible(true)
		self.event.packageObject:setCurrentFrame(self.handed - 1)
	end

	-- bonus for finding all
	-- increase score and pop a floater	
	if (self.handed == self.event.numPackages) then
		self:playSound(self.event.soundEventCompleteAll)	
		incScore(self.event.scoreGotAll, self:getScreenX(), self:getScreenY() + scorePersonFloaterOffsetY, scoreBonusFloaterDelay, "BONUS")
		
		-- complete sequence
		if (self.event.sequenceComplete ~= nil) then
			qInsertSequence(self.event.sequenceComplete)
		end				
		
	end

end

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

function mailman:calcImageName(input)

	res = D2Person.calcImageName(self, input)
  
	if (self.carry) then
		res = res .. "_CARRY"
	end

	return res
  
end

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

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

function packageObject:__init() super()
end

function packageObject:onCreate()

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

end