-- ----------------------------------------------------------------------------
-- Elevator appliance
-- ----------------------------------------------------------------------------
class 'elevator' (Appliance)

-- Appearance crap
elevator.shaftInfo = {}
elevator.cabinInfo = {}
elevator.fakeCustomerInfo = {}
elevator.doorInfo = {}
elevator.exteriorInfo = {}
elevator.indicatorInfo = {}

elevator.shaft = nil
elevator.cabin = nil
elevator.fakeCustomer = nil
elevator.doorL = nil
elevator.doorR = nil
elevator.exterior = nil
elevator.indicator = nil

-- cabin movement
elevator.targetFloor = 0
elevator.currentFloor = 0
elevator.floorDelta = 0
elevator.timePerFloor = 1000
elevator.moveTimer = 0
elevator.doorTimer = 0
elevator.doorMoveTime = 1000

-- 
elevator.score = 50

-- Customer details
elevator.doKeyCustomers = true
elevator.deliverKeyTimer = getRandomRange(45000, 60000)
elevator.getKeyTimer = elevator.deliverKeyTimer + getRandomRange(30000, 45000)
elevator.activeKeyCustomer = false
elevator.keyDeliverTrigger = false
elevator.keyGetTrigger = false
elevator.numDropKeys = 0
elevator.numGetKeys = 0

elevator.entranceGridX = 42
elevator.entranceGridY = 3
elevator.entranceNode = nil

elevator.inLiftGridX = 5
elevator.inLiftGridY = 10
elevator.inLiftNode = nil

elevator.waitForLiftGridX = 1
elevator.waitForLiftGridY = 12
elevator.waitForLiftNode = nil

elevator.waitForKeyGridX = 16
elevator.waitForKeyGridY = 28
elevator.waitForKeyNode = nil

elevator.customerArriving = nil
elevator.customerLeaving = nil

elevator.busy = false
elevator.pause = false

-- Request queue - just in case multiple people want to use the lift
-- fields are:
-- * floorPressed
-- * floorRequested
elevator.requestQueue = {}

function elevator:__init() super()
	self.state = "DOORS_CLOSED"
end

function elevator:onCreate()
	Appliance.onCreate(self)
	self:updatePointerPosition(0)
end

function elevator:onLevelInited()
	self.keyDeliverTrigger = pm:hasNotification("trigger key deliver")
	self.keyGetTrigger = pm:hasNotification("trigger key get")
end

function elevator:onDayEnd()
	self.requestQueue = nil
end

function elevator:checkNodes()
	if (entranceNode == nil) then
		entranceNode	= grid:getNode(self.entranceGridX, self.entranceGridY)
	end
	if (inLiftNode == nil) then
		inLiftNode = grid:getNode(self.inLiftGridX, self.inLiftGridY)
	end
	if (waitForLiftNode == nil) then
		waitForLiftNode = grid:getNode(self.waitForLiftGridX, self.waitForLiftGridY)
	end
	if (waitForKeyNode == nil) then
		waitForKeyNode	= grid:getNode(self.waitForKeyGridX, self.waitForKeyGridY)
	end
end

function elevator:onNotify(notification)

	if (notification == "trigger keyGetHint") then
		if (hm ~= nil and self.fakeCustomer ~= nil) then
			hm:placeArrow(getArrowIndex("ARROW_HINT_ROOM_REQUESTED"), self.fakeCustomer, 0, -35)			
		end
	end

	if (self.doKeyCustomers == false or self.activeKeyCustomer == true or self:checkKeyActive() or scene:isClosed()) then
		return
	end

	if (notification == "trigger key deliver") then
		self:doDropKeyPerson()

	elseif (notification == "trigger key get") then
		self:doGetKeyPerson()
		
	end
	
end

function elevator:onTick(time)
	
	-- check for the various nodes
	self:checkNodes()

	if (self.pause) then
		return
	end

	-- update movement
	self:moveElevator(time)
	
	if (scene:isStartingMovie() or scene:isPlayingMovie() or scene:isClosed()) then
		return
	end
		
	
	if (self.doKeyCustomers == false or self.activeKeyCustomer == true or self:checkKeyActive()) then
		return
	end

	if (self.keyDeliverTrigger == false) then
		self.deliverKeyTimer = self.deliverKeyTimer - time	
		if (self.deliverKeyTimer <= 0) then
			self:doDropKeyPerson()
			self.deliverKeyTimer = getRandomRange(45000, 60000)
		end
	end
	
	if (self.keyGetTrigger == false) then
		self.getKeyTimer = self.getKeyTimer - time
		if (self.getKeyTimer <= 0) then
			if (self.numGetKeys < self.numDropKeys) then		 	
				self:doGetKeyPerson()
			end
			self.getKeyTimer = getRandomRange(30000, 45000)
		end	
	end	
end

function elevator:checkKeyActive()
	return  getProduct("KEY_1_DROP"):isVisible() or
		getProduct("KEY_2_DROP"):isVisible() or
		getProduct("KEY_3_DROP"):isVisible()		
end

function elevator:doDropKeyPerson()

	if (self:hasCustomersWaiting()) then
		return
	end
	
	local person = pm:createPerson("elevatorCustomer")
	self.customerLeaving = person
	person:setBaseName(getSpecialRandomCustomerName())
	person:setPosition(inLiftNode)
	person:setVisible(false)
	person:setKeyName(self:getRandomKeyName())
	self:addFloorRequest(self.customerLeaving, self.customerLeaving:getRequestedFloor(), 0)
	self.activeKeyCustomer = true
	
end

function elevator:hasCustomersWaiting()

	return (entranceNode:isBlocked() or
			inLiftNode:isBlocked() or
			waitForLiftNode:isBlocked() or
			waitForKeyNode:isBlocked())
end

function elevator:doGetKeyPerson()
	--cout("doGetKeyPerson - enter\n")
	if (self:hasCustomersWaiting()) then
		--cout("doGetKeyPerson - blocked\n")
		return
	end

	self.numGetKeys = self.numGetKeys + 1

    local s = self.score
	--if (um:hasUpgrade("DECO_SLINGERS_L_UPGRADE")) then
		--s = s + getInteger("0_UPGRADE_HOTEL_GUEST_EXTRA_POINTS")
	--end

	local person = pm:createPerson("elevatorCustomer")
	self.customerArriving = person
	person.score = s
	person.arriving = true
	person:setBaseName(getSpecialRandomCustomerName())
	person.enterNode = entranceNode
	person.exitNode = entranceNode
	person.waitNode = waitForLiftNode
	person:initCustomer(self, self.onLiftCustomerWaiting)

	person:qWalkToNode(waitForKeyNode)
	person:qWait(300)
	person:qCallback(person, function(p) 
	    -- add an order for a room
		local keyId = self:getKeyId()
		p:createOrder(keyId)
		p:showOrder()
		
		local keyProduct = getProduct(keyId)
		
		-- no room available
		if (keyProduct:getStock() == 0 and not tray:hasProduct(keyId)) then
			p:qRemoveHighlight()
			emily:qWait(200)
			emily:qWalkToAppliance(getAppliance("rest2_reception"))
			emily:qSayTimed("RESTAURANT_0_HOTEL_FULL", 2500)
			emily:qCallback(p, function(p)
				p:removeOrder()
				p:qWait(300)
				p:qWalkToNode(entranceNode)
				p:qDestroy()
				self:clearCustomerArriving()
			end)
		--else
			-- add a hint arrow
		--	hm:placeArrow(getArrowIndex("ARROW_HINT_ROOM_REQUESTED"), p, 0, -35)
		--	hm:placeArrow(getArrowIndex("ARROW_HINT_KEY_ORDERED"), keyProduct, (keyProduct:getWidth() / 2), 0)
		end
		
	end)

	self.activeKeyCustomer = true
end

function elevator:onLiftCustomerWaiting()
	self:clearCustomerArriving()
end

function elevator:getRandomKeyName()
	
	local keyNum = getRandomRange(0, 3)
	
	--cout("getRandomKeyName - keyNum is " .. keyNum .. "\n")
	if (keyNum == 0) then
		return "KEY_1"
	elseif (keyNum == 1) then
		return "KEY_2"
	end
	return "KEY_3"
	
end

function elevator:onDropKey()
		
	--local r = getRandomRange(0, 3)
	if (self.customerLeaving ~= nil) then
		local r = self.customerLeaving:getRequestedFloor()
		local p = nil
		
		--cout("onDropKey: floor = " .. r .. "\n")
		if (r == 1) then
			p = getProduct("KEY_1_DROP")
		elseif (r == 2) then
			p = getProduct("KEY_2_DROP")
		else
			p = getProduct("KEY_3_DROP")
		end	

		p:setVisible(true)
		p:setClickable(true)
		self:clearCustomerLeaving()
	end
	
	self.activeKeyCustomer = false
	
	--hm:openHint(getHintIndex("HINT_KEY_DROPED"), p:getScreenX() + (p:getWidth() / 2), p:getScreenY())
end

function elevator:clearCustomerArriving()
	self.customerArriving = nil
	self.activeKeyCustomer = false
end

function elevator:clearCustomerLeaving()
	self.customerLeaving = nil
	self.activeKeyCustomer = false
end

function elevator:requestFloor(buttonBase)

	if (self:isBusy()) then
		return
	end
	
	--cout("Button base: " .. buttonBase .. "\n")
	local floorNumber = 3
	if (buttonBase == "ELEVATOR_01") then
		floorNumber = 1
	elseif (buttonBase == "ELEVATOR_02") then
		floorNumber = 2
	end
	
	--cout("Floor Nr: " .. floorNumber .. "\n")
	if (self.customerArriving ~= nil and
		self.customerArriving:getRequestedFloor() == floorNumber) and
		self.customerArriving:isWaitingForLift() then
		self.customerArriving:removeOrder()
		self:addFloorRequest(self.customerArriving, 0, floorNumber)
		--self:setTargetFloor(0)
	end
	
end

function elevator:addFloorRequest(customer, customerFloor, floorRequested)

	--cout("Adding floor request from floor: " .. customerFloor .. " to " .. floorRequested .. "\n")
	local nrRequests = table.getn(self.requestQueue)
	self.requestQueue[nrRequests + 1] = {}
	self.requestQueue[nrRequests + 1].customerFloor = customerFloor
	self.requestQueue[nrRequests + 1].floorRequested = floorRequested
	self.requestQueue[nrRequests + 1].customer = customer
end
--
function elevator:updateTargetFloor()
	
	if (self:isBusy() or self.requestQueue == nil) then
		return
	end
	
	local nrRequests = table.getn(self.requestQueue)
	if (nrRequests > 0) then
		local currRequest = self.requestQueue[1]
		if (currRequest.customerFloor > -1) then
			--cout("UpdateTargetFloor: set #1")
			self:setTargetFloor(currRequest.customerFloor)
			self:setBusy(true)
		elseif (currRequest.floorRequested > -1) then
			--cout("UpdateTargetFloor: set #1")
			self:setTargetFloor(currRequest.floorRequested)
			self:setBusy(true)
		else
			-- should get rid of this
		end
	end
end

function elevator:isBusy()
	return self.busy
end

function elevator:setBusy(busy)
	--if (busy) then
		--cout("Setting BUSY\n")
	--else
		--cout("Setting FREE\n")
	--end
	self.busy = busy
end

-- ----------------------------------------------------------------------------
-- Movement
-- ----------------------------------------------------------------------------
function elevator:setTargetFloor(floor)
	
	if (floor == self.targetFloor) then
		return
	end
	if (floor > self.targetFloor) then
		self:playSound("SOUND_LIFT_UP")
	end
	if (floor < self.targetFloor) then
		self:playSound("SOUND_LIFT_DOWN")
	end	
	
	self.targetFloor = floor
	local delta = self.targetFloor - self.currentFloor
	--cout("CurrFloor is: " .. self.currentFloor ..",  setting target floor to " .. self.targetFloor .. ", delta is: " .. delta .. "\n")
	if (delta == 0) then
		self.moveTimer = 0
		self.floorDelta = 0
	else
		self.moveTimer = self.timePerFloor
		if (delta > 0) then
			self.floorDelta = 1
		else
			self.floorDelta = -1
		end
	end
end

function elevator:handleTargetReached()

	if (self.requestQueue == nil) then
		return
	end
	
	local nrRequests = table.getn(self.requestQueue)
	if (nrRequests > 0) then
		local currRequest = self.requestQueue[1]
		
		if (self.targetFloor == currRequest.customerFloor) then
		
			--cout("!!!!!!!!!!! setting target floor to " .. currRequest.floorRequested .. "!!!!!!!!!!!\n")
			self:handleCustomerEnter(currRequest.customer)
			currRequest.customerFloor = -1
			
		elseif (self.targetFloor == currRequest.floorRequested) then
		
			--cout("!!!!!!!!!!! requested floor reached!!!!!!!!!!!\n")
			self:handleCustomerExit(currRequest.customer)
			currRequest.floorRequested = -1
			
			-- remove the request
			table.remove(self.requestQueue, 1)
			
		else
			-- ?
			--cout("!!!!!!!!!!! handleTargetReached !!!!!!!!!!!\n")
		end
	else
		--cout("handleTargetReached: setting FREE")
		self:setBusy(false)
	end
end
--
function elevator:handleCustomerEnter(customer)
	
	if (customer ~= nil) then
	
		if (customer == self.customerArriving) then
			customer:qWalkToNode(inLiftNode)
			customer:qCallback(self, self.onCustomerArrivingEntered)
			
		elseif (customer == self.customerLeaving) then
			-- create a copy of the leaving customer
			self:onCustomerLeavingEntered()
		--else
			--cout("!!!!!!!!!!! handleCustomerEnter #2 !!!!!!!!!!!\n")
		end
		
	--else
		--cout("!!!!!!!!!!! handleCustomerEnter #1 !!!!!!!!!!!\n")
	end
	
end

function elevator:handleCustomerExit(customer)
	
	--cout("handleCustomerExit\n")
	
	if (customer ~= nil) then
		--cout("handleCustomerExit - customer\n")
		if (customer == self.customerLeaving) then
			--cout("handleCustomerExit - customer leaving\n")
			self:onCustomerLeavingWait()
		else
			--cout("handleCustomerExit - customer arriving\n")
			self:onCustomerArrivingExit()
		end
	--else
	--	cout("handleCustomerExit - no customer\n")
	end
	
end

function elevator:moveElevator(time)

	if (self.state == "DOORS_OPENING") then
		-- Doors opening?  Keep opening
		self.doorTimer = self.doorTimer - time
		if (self.doorTimer <= 0) then
			self:setState("DOORS_OPEN")
		end
	elseif (self.state == "DOORS_CLOSING") then
		-- Doors closing?  Keep closing
		self.doorTimer = self.doorTimer - time
		if (self.doorTimer <= 0) then
			self:setState("DOORS_CLOSED")
		end
	else
		self:updateTargetFloor()
		if (self.targetFloor ~= self.currentFloor) then
			-- Target floor is different to current, so keep on moving
			if (self.state == "DOORS_CLOSED" or
				self.state == "STOPPED") then
				
				self.moveTimer = self.moveTimer - time
				if (self.moveTimer <= 0) then
					--cout("Adding " .. self.floorDelta .. " to current floor\n")
					self.currentFloor = self.currentFloor + self.floorDelta
					self.moveTimer = self.timePerFloor
				end
				self:updateCabinPosition()
			else
				-- Doors open?  close them
				self:setState("DOORS_CLOSING")
			end
		else
			if (self.currentFloor == 0 and self.state ~= "DOORS_OPEN") then
				self:setState("DOORS_OPENING")
			end
			self:handleTargetReached()
		end
	end
	
end

function elevator:onCustomerArrivingEntered()
	local cust = self.customerArriving
	if (cust ~= nil) then
		-- MAKE A COPY OF THE CUSTOMER IMAGE!
		local fake = self.fakeCustomer
		fake:setDefaultSection(cust:getDefaultSection())
		local imageName = cust:getBaseName() .. "_IDLE"
		fake:setX(cust:getScreenX())
		fake:setY(cust:getScreenY())
		local deltaX = cust:getScreenX() - fake:getScreenX()
		local deltaY = cust:getScreenY() - fake:getScreenY()
		fake:setX(fake:getX() + deltaX)
		fake:setY(fake:getY() + deltaY)		
		fake:setDefaultSection(cust:getDefaultSection())
		fake:animate(imageName, 0)
		fake:setVisible(true)
		--cout("onCustomerArrivingEntered: setting FREE")
		self:setBusy(false)
		self:setTargetFloor(cust:getRequestedFloor())
		
		--self:clearCustomerArriving()
		cust:setAlpha(0)
		cust:qDestroy()
	end
end

function elevator:onCustomerArrivingExit()
	if (self.fakeCustomer ~= nil) then
		self.fakeCustomer:setVisible(false)
	end
	if (self.customerArriving ~= nil and
		not self.customerArriving.doKey) then
		
		onNotify("onCustomerArrivingExit")
		
	end
	self:clearCustomerArriving()
end

function elevator:onCustomerLeavingEntered()
	local cust = self.customerLeaving
	if (cust ~= nil) then
		-- MAKE A COPY OF THE CUSTOMER IMAGE!
		local fake = self.fakeCustomer
		local imageName = cust:getBaseName() .. "_IDLE"
		fake:setDefaultSection(cust:getDefaultSection())
		

		-- Oooohh... horrible.  Move the cabin to the end position and sort
		-- out the fake customer position before moving back to where we were...
		local oldCabinY = self.cabin:getY()
		self.cabin:setY(self.cabinInfo.baseY)
		
		fake:setX(cust:getScreenX())
		fake:setY(cust:getScreenY())
		local deltaX = cust:getScreenX() - fake:getScreenX()
		local deltaY = cust:getScreenY() - fake:getScreenY()
		fake:setX(fake:getX() + deltaX)
		fake:setY(fake:getY() + deltaY)
		
		self.cabin:setY(oldCabinY)
		fake:setDefaultSection(cust:getDefaultSection())
		fake:animate(imageName, 0)
		fake:setVisible(true)
		self:setBusy(false)
	end
end

function elevator:onCustomerLeavingWait()
	
	local cust = self.customerLeaving
	if (cust ~= nil) then 
		cust:qWait(self.doorMoveTime)
		cust:qCallback(self, self.onCustomerLeavingExit)
	end
	
end

function elevator:onCustomerLeavingExit()
	
	local cust = self.customerLeaving
	if (cust ~= nil) then 
		self.fakeCustomer:setVisible(false)
		self:setBusy(false)
		
		-- This should be the action when the lift reaches the ground floor
		cust:setVisible(true)
		
		if (cust.doKey) then
			cust:qWalkToNode(waitForKeyNode)
			cust:qAnimateWait("IDLE", 1)
			cust:qCallback(self, self.onDropKey)
			cust:qWait(300)
			cust:qWalkToNode(entranceNode)
			cust:qDestroy()
		else
			onNotify("onCustomerLeavingExit")		
		end
	end

end

function elevator:doOpenDoorsAnim()
	
	if (self.doorL ~= nil) then
		--self.doorL:setScaleX(0.25, 1000)
		self.doorL:setLocation(-36, 0, 1000)
	end

	if (self.doorR ~= nil) then
		--self.doorR:setScaleX(0.25, 1000)
		self.doorR:setLocation(36, 0, 1000)
	end
	
	self:playSound("SOUND_LIFT_OPEN")
	
end

function elevator:doCloseDoorsAnim()
	if (self.doorL ~= nil) then
		--self.doorL:setScaleX(1, 1000)
		self.doorL:setLocation(36, 0, 1000)
	end

	if (self.doorR ~= nil) then
		--self.doorR:setScaleX(1, 1000)
		self.doorR:setLocation(-36, 0, 1000)
	end
	
	self:playSound("SOUND_LIFT_CLOSE")
end

function elevator:setState(newState)
	
	if (self.state ~= newState) then
		--cout("Current state is: " .. self.state .. ", trying to go to state: " .. newState .. "\n")
		if (newState == "STOPPED") then
			self.moveTimer = 0
			self.targetFloor = self.currentFloor
			
		elseif(newState == "DOORS_OPENING") then
			self.moveTimer = 0
			self.doorTimer = self.doorMoveTime
			self:doOpenDoorsAnim()
			
		elseif(newState == "DOORS_OPEN") then
			--self:checkCustomerWaitingForLift()
			
		elseif(newState == "DOORS_CLOSING") then
			self.moveTimer = self.timePerFloor
			self.doorTimer = self.doorMoveTime
			self:doCloseDoorsAnim()
			
		elseif(newState == "DOORS_CLOSED") then
			-- empty
			
		end
		self.state = newState
	end
	
end

function elevator:updateCabinPosition()

	if (self.cabinInfo == nil or
		self.cabin == nil) then
		return	
	end
	
	--local deltaY = 0
	local tempFloor = self.currentFloor
	local floorDelta = ((self.timePerFloor - self.moveTimer) / self.timePerFloor)
	
	if (self.floorDelta > 0) then
		tempFloor = tempFloor + floorDelta
	else
		tempFloor = tempFloor - floorDelta
	end
	--
	--local cabinSize = self.cabin:getHeight()
	local yPos = self.cabinInfo.baseY
	
	--cout("tempFlo: " .. tempFloor .. "\n")
	yPos = yPos - (self.cabin:getHeight() * tempFloor)
	
	--cout("    yPos #2: " .. yPos .. "\n")
	self.cabin:setY(yPos)
	
	-- now update the pointer position
	self:updatePointerPosition(tempFloor)

end

function elevator:updatePointerPosition(liftProgression)

	if (self.indicator ~= nil) then
		local maxFloor = 3
		local progression = liftProgression  * math.pi / maxFloor
		local rotation = (1.5 * math.pi) + progression
		self.indicator:setRotation(rotation)
	end
	
end

-- ----------------------------------------------------------------------------
-- Appearance
-- ----------------------------------------------------------------------------
function elevator:initAppearance()

	if (self.shaftInfo ~= nil and self.shaft == nil) then
		self.shaft = createSprite()
		self.shaft:setDefaultSection(player:getCurrentResourceSection())
		self.shaft:setX(self.shaftInfo.baseX)
		self.shaft:setY(self.shaftInfo.baseY)
		self.shaft:animate(self.shaftInfo.imageName, 0)
		self:addChild(self.shaft)
	end
	
	if (self.cabinInfo ~= nil and self.cabin == nil) then
		self.cabin = createSprite()
		self.cabin:setDefaultSection(player:getCurrentResourceSection())
		self.cabin:setX(self.cabinInfo.baseX)
		self.cabin:setY(self.cabinInfo.baseY)
		self.cabin:animate(self.cabinInfo.imageName, 0)
		self:addChild(self.cabin)
	end
	
	if (self.fakeCustomerInfo ~= nil and self.fakeCustomer == nil) then
		self.fakeCustomer = createSprite()
		self.fakeCustomer:setAnchorPointType(BOTTOMCENTER)
		self.fakeCustomer:setDefaultSection("customers")
		self.fakeCustomer:setVisible(false)
		self.cabin:addChild(self.fakeCustomer)
	end
	
	if (self.doorInfo ~= nil and self.doorL == nil and self.doorR == nil) then
		self.doorL = createSprite()
		self.doorL:setDefaultSection(player:getCurrentResourceSection())
		self.doorL:setX(self.doorInfo.baseLX)
		self.doorL:setY(self.doorInfo.baseLY)
		self.doorL:animate(self.doorInfo.imageNameL, 0)
		self:addChild(self.doorL)

		self.doorR = createSprite()
		self.doorR:setDefaultSection(player:getCurrentResourceSection())
		self.doorR:setX(self.doorInfo.baseRX)
		self.doorR:setY(self.doorInfo.baseRY)
		self.doorR:animate(self.doorInfo.imageNameR, 0)
		self:addChild(self.doorR)
	end
	
	if (self.exteriorInfo ~= nil and self.exterior == nil) then
		self.exterior = createSprite()
		self.exterior:setDefaultSection(player:getCurrentResourceSection())
		self.exterior:setX(self.exteriorInfo.baseX)
		self.exterior:setY(self.exteriorInfo.baseY)
		self.exterior:animate(self.exteriorInfo.imageName, 0)
		self:addChild(self.exterior)
	end
	
	if (self.indicatorInfo ~= nil and self.indicator == nil) then
		self.indicator = createSprite()
		--self.indicator:setAnchorPointType(BOTTOMCENTER)
		self.indicator:setAnchorPoint(4, 21)
		self.indicator:setDefaultSection(player:getCurrentResourceSection())
		self.indicator:setX(self.indicatorInfo.baseX)
		self.indicator:setY(self.indicatorInfo.baseY)
		self.indicator:animate(self.indicatorInfo.imageName, 0)
		self:addChild(self.indicator)
	end
	
end

-- ----------------------------------------------------------------------------
-- Helpers
-- ----------------------------------------------------------------------------
function elevator:getKeyId()

	local availableKeys = {}
	local availableIndex = 0

	if (getProduct("KEY_3"):getStock() >= 1 or tray:hasProduct("KEY_3")) then
		availableIndex = availableIndex + 1
		availableKeys[availableIndex] = "KEY_3"
	end
	if (getProduct("KEY_2"):getStock() >= 1 or tray:hasProduct("KEY_2")) then
		availableIndex = availableIndex + 1
		availableKeys[availableIndex] = "KEY_2"
	end
	if (getProduct("KEY_1"):getStock() >= 1 or tray:hasProduct("KEY_1")) then
		availableIndex = availableIndex + 1
		availableKeys[availableIndex] = "KEY_1"
	end	

	if (availableIndex > 0) then
		local keyIndex = getRandom(availableIndex) + 1
		return availableKeys[keyIndex]			
	else
		local r = getRandom(3)
		if (r == 0) then
			return "KEY_3"
		elseif (r == 1) then
			return "KEY_2"
		else
			return "KEY_1"
		end	
	end	
end


-- -------------------
-- OLD OLD OLD
-- -------------------
function elevator:checkCustomerWaitingForLift()

	local cust = self.customerArriving
	if (cust ~= nil and cust:isWaitingForLift() and self.currentFloor == 0) then
		cust:removeOrder()
		cust:qWalkToNode(inLiftNode)
		cust:qCallback(self, self.onCustomerEntered)
	end
end

function elevator:onCustomerEntered()
	local cust = self.customerArriving
	if (cust ~= nil) then
		-- MAKE A COPY OF THE CUSTOMER IMAGE!
		local fake = self.fakeCustomer
		local imageName = cust:getBaseName() .. "_IDLE"
		fake:setDefaultSection(cust:getDefaultSection())	
		fake:setX(cust:getScreenX())
		fake:setY(cust:getScreenY())
		local deltaX = cust:getScreenX() - fake:getScreenX()
		local deltaY = cust:getScreenY() - fake:getScreenY()
		fake:setX(fake:getX() + deltaX)
		fake:setY(fake:getY() + deltaY)
		fake:animate(imageName, 0)
		fake:setVisible(true)
		self:setTargetFloor(cust:getRequestedFloor())
		
		self:clearCustomerArriving()
		cust:setAlpha(0)
		cust:qDestroy()
		
	end
end