include("scripts/helperfunctions.lua")
include("scripts/interface.lua")
include("scripts/persons/npc.lua")
include("scripts/persons/cleaner.lua")
include("scripts/persons/fakecustomer.lua")

-- global variables and behavior we might need accross multiple restaurants
dayEnded = false
dayEndTick = false

-- object manager
om = nil

-- trophy manager
tm = nul

-- upgrade manager
um = nil

-- people manager
pm = nil

-- product manager
prm = nil

-- hint manager
hm = nil

-- emily
emily = nil

-- cleaner
-- if no cleaner, this will stay nil. so check for it!
cleaner = nil

-- entertainer
-- if no entertainer, this will stay nil. so check for it!
entertainer = nil

-- player
player = getPlayer()

-- level
level = nil

-- input
input = nil

-- scene
scene = nil

-- tray
tray = nil

-- event gui
eventBar = nil

-- register
register = nil

-- telephone
telephone = nil

-- handlers
event = interface()
restaurant = interface()
day = interface()

-- anchor points
TOPLEFT 		= 0
TOPCENTER 		= 1
TOPRIGHT 		= 2
LEFT 			= 3
CENTER 			= 4
RIGHT 			= 5
BOTTOMLEFT 		= 6
BOTTOMCENTER 	= 7
BOTTOMRIGHT 	= 8

-- table states
PLATES_FULL			= 0
PLATES_EMPTY		= 1
PLATES_CLEANING		= 2
PLATES_INVISIBLE	= 3

-- grid
GRID_SPACING_X = 16
GRID_SPACING_Y = 16
GRID_SIZE_X = 50
GRID_SIZE_Y = 35

-- direction
DIRECTION_UP = 0
DIRECTION_DOWN = 1
DIRECTION_LEFT = 2
DIRECTION_RIGHT = 3
DIRECTION_COUNT = 4

-- level layers
LAYER_BACKGROUND = 0
LAYER_GRID_ELEMENTS = 1
LAYER_FEATURES = 2
LAYER_FLOATERS = 3
LAYER_ENGINE = 4
LAYER_INPUT = 5
LAYER_COUNT = 6

-- General
HINT_MOOD_DROP = 0
HINT_LEAVING = 1
HINT_REMOVE_TRAY_ITEM = 2
HINT_SHOP = 3
-- Drive Thru
HINT_EVENT_HEIMLICH = 4
HINT_WAFFLE_DONE = 5
HINT_SHAKE = 6
HINT_SHAKE_READY = 7
HINT_DRIVE_THRU = 8
HINT_JUKEBOX = 9
HINT_CLOTH = 10
-- Farm
HINT_CHURNER = 11
HINT_JAM2APPLES = 12
HINT_PIE3APPLES = 13
HINT_PIEDONE = 14
HINT_TEACHTASHI = 15
-- Candy Shop
HINT_CHARLESREFILLING = 16
HINT_CAKEDONE = 17
-- Town Fair
HINT_PANCAKE_READY = 18
HINT_BALLOON_READY = 19
HINT_COTTONCANDY_READY = 20
HINT_KARAOKE = 21
-- General
ARROW_HINT_REGISTER = 22
ARROW_HINT_ENTERTAINER = 23
ARROW_HINT_TABLE_TO_BE_ENTERTAINED = 24
-- DriveThru
ARROW_HINT_BOTTOM_BUN = 25
ARROW_HINT_HAMBURGER = 26
ARROW_HINT_TOP_BUN = 27
ARROW_HINT_WAFFLE_ON_PLATE = 28
ARROW_HINT_SAUCE = 29
ARROW_HINT_CAR_COUNTER = 30
ARROW_HINT_BATTER = 31
ARROW_HINT_SHAKE = 32
ARROW_HINT_SHAKE_INDICATOR = 33
ARROW_HINT_JUKEBOX = 34
-- Farm
ARROW_HINT_EGG = 35
ARROW_HINT_EGG_TASHI = 36
ARROW_HINT_APPLE = 37
ARROW_HINT_APPLETREE = 38
ARROW_HINT_JAM = 39
ARROW_HINT_JAM_APPLE = 40
ARROW_HINT_CAKEMOLD = 41
ARROW_HINT_CAKEMOLD_APPLE = 42
ARROW_HINT_PIE = 43
ARROW_HINT_PIE_READY = 44
ARROW_HINT_CHURNER = 45
ARROW_HINT_COW = 46
-- Candy shop
ARROW_HINT_CHARLES = 47
ARROW_HINT_STICK_APPLE = 48
ARROW_HINT_STICK_SAUCE = 49
ARROW_HINT_STICK_TOPPING = 50
ARROW_HINT_CAKE_OVEN = 51
ARROW_HINT_ONEGUMBALL_MACHINE = 52
ARROW_HINT_ONEGUMBALL_BAG = 53
ARROW_HINT_THREEGUMBALLS_MACHINE = 54
ARROW_HINT_THREEGUMBALLS_BAG = 55
-- TV Studio
ARROW_HINT_OREGANO_OUT = 56
ARROW_HINT_GREEN_ONION_OUT = 57
ARROW_HINT_FIRST_CARPACCIO_HERB = 58
ARROW_HINT_FIRST_CARPACCIO_HERB_CONTINUE = 59
ARROW_HINT_FIRST_OVEN_PRODUCT = 60
ARROW_HINT_FIRST_OVEN_PRODUCT_CONTINUE = 61
ARROW_HINT_FIRST_OVEN_FINISHED = 62
ARROW_HINT_FIRST_PAN_PRODUCT = 63
ARROW_HINT_PAN_PRODUCT_READY = 64
ARROW_HINT_PAN_PRODUCT_READY_CONTINUE = 65
ARROW_HINT_PRODUCTTABLE = 66
-- Town Fair
ARROW_HINT_PANCAKE_BATTER = 67
ARROW_HINT_PANCAKE_READY = 68
ARROW_HINT_PANCAKE_TOPPING = 69
ARROW_HINT_POPCORN = 70
ARROW_HINT_POPCORN_TOPPING = 71
ARROW_HINT_POPCORN_MACHINE = 72
ARROW_HINT_BALLOON = 73
ARROW_HINT_COTTONCANDY = 74

-- customer
CUSTOMER_READING_MIN_INTERVAL = 1200
CUSTOMER_READING_RND_INTERVAL = 1200
CUSTOMER_ORDERING_MIN_INTERVAL = 1600
CUSTOMER_ORDERING_RND_INTERVAL = 1600
CUSTOMER_EATING_MIN_INTERVAL = 1000
CUSTOMER_EATING_RND_INTERVAL = 1500

-- score
scoreTableFloaterOffsetY = -75
scorePersonFloaterOffsetY = -75
scoreBonusFloaterDelay = 1500

-- configuration
autoStartGame = true
autoAllPeopleWalkIn = true
autoAllPeopleWalkOut = true
makeProgressBarsSmall = false

function onLevelGlobals()

	om = getObjectManager()
	tm = getDeliciousTrophyManager()
	um = getUpgradeManager()
	pm = getPeopleManager()
	prm = getProductManager()
	hm = getHintManager()
	emily = pm:getEmily()
	cleaner = pm:getCleaner()
	entertainer = pm:getEntertainer()
	grid = getGrid()
	level = getLevel()
	input = getInput()
	scene = getScene()
	tray = getTray()
	eventBar = getEventBar()
	register = om:getRegister()
	telephone = om:getTelephone()
	
	if (entryX ~= nil and entryY ~= nil) then
		entryNode = grid:getNode(entryX, entryY)
	end
	if (exitX ~= nil and exitY ~= nil) then
		exitNode = grid:getNode(exitX, exitY)
	end
	if (movieX ~= nil and movieY ~= nil) then
		movieNode = grid:getNode(movieX, movieY)	
	end
	
	event:onLevelGlobals()
	day:onLevelGlobals()
	restaurant:onLevelGlobals()

end

function onLevelInited()

	event:onLevelInited()
	day:onLevelInited()
	restaurant:onLevelInited()

	if (autoStartGame == true) then
		scene:startGame()
		
	end
	
end

function onDayBegin()

	tm:setLevelHasEggs(false)	-- Needed for Trophy 'Break an egg' (overwritten in restaurant1.lua::onDayBegin())
	
	event:onDayBegin()
	day:onDayBegin()	
	restaurant:onDayBegin()

	if (autoAllPeopleWalkIn == true) then
		pm:allPeopleWalkIn()
	end
	
end

function onDayEnd()

	event:onDayEnd()
	day:onDayEnd()
	restaurant:onDayEnd()
	
	if (autoAllPeopleWalkOut == true) then
		pm:allPeopleWalkOut()
	else
		if (cleaner) then
			cleaner:setReturnHome(false)
		end
		
		if (entertainer) then
			entertainer:setReturnHome(false)
		end	
	end
	
    dayEnded = true

end

function onTick(time)

    if ((not dayEnded) or dayEndTick) then
    	event:onTick(time)
	    day:onTick(time)
	    restaurant:onTick(time)
	    
    end
	
end

function onClickProduct(product)

	if (event:onClickProduct(product) == true) then
		return true
	end

	if (day:onClickProduct(product) == true) then
		return true
	end
	
	if (restaurant:onClickProduct(product) == true) then
		return true
	end	
	
	return false

end


function onClickRegister(register)

	if (event:onClickRegister(register) == true) then
		return true
	end

	if (day:onClickRegister(register) == true) then
		return true
	end
	
	if (restaurant:onClickRegister(register) == true) then
		return true
	end		
	
	return false

end


function onClickPerson(person)
	
	if (event:onClickPerson(person) == true) then
		return true
	end

	if (day:onClickPerson(person) == true) then
		return true
	end
	
	if (restaurant:onClickPerson(person) == true) then
		return true
	end		
	
	return false	
	
end

function onClickObject(object)

	if (event:onClickObject(object) == true) then
		return true
	end

	if (day:onClickObject(object) == true) then
		return true
	end
	
	if (restaurant:onClickObject(object) == true) then
		return true
	end		
	
	return false

end


function onClickTable(table)

	if (event:onClickTable(table) == true) then
		return true
	end

	if (day:onClickTable(table) == true) then
		return true
	end
	
	if (restaurant:onClickTable(table) == true) then
		return true
	end			
	
	return false

end

function onClickMessage(text, result)

	event:onClickMessage(text, result)
	day:onClickMessage(text, result)
	restaurant:onClickMessage(text, result)

end

function onClickButton(button)

	event:onClickButton(button)
	day:onClickButton(button)
	restaurant:onClickButton(button)

end

function onLockToNode(actor, node)

	event:onLockToNode(actor, node)
	day:onLockToNode(actor, node)
	restaurant:onLockToNode(actor, node)
	
	-- Start Trophy code
	if (actor:getType() == "emily") then
		tm:checkWalkDistance(1)
	end
	-- End Trophy code
	
end

function onTaskHook(actorType, taskType, p0, p1)

	if (event:onTaskHook(actorType, taskType, p0, p1) == true) then
		return true
	end

	if (day:onTaskHook(actorType, taskType, p0, p1) == true) then
		return true
	end
	
	if (restaurant:onTaskHook(actorType, taskType, p0, p1) == true) then
		return true
	end	
	
	return false

end

function onTaskStart(actorType, taskType, p0, p1)

	event:onTaskStart(actorType, taskType, p0, p1)
	day:onTaskStart(actorType, taskType, p0, p1)
	restaurant:onTaskStart(actorType, taskType, p0, p1)
	
end

function onTaskComplete(actorType, taskType, p0, p1)

	event:onTaskComplete(actorType, taskType, p0, p1)
	day:onTaskComplete(actorType, taskType, p0, p1)
	restaurant:onTaskComplete(actorType, taskType, p0, p1)

end

function onTaskCancel(actorType, taskType, p0, p1)

	event:onTaskCancel(actorType, taskType, p0, p1)
	day:onTaskCancel(actorType, taskType, p0, p1)
	restaurant:onTaskCancel(actorType, taskType, p0, p1)
	
end

function onNotify(notification)

	event:onNotify(notification)
	day:onNotify(notification)
	restaurant:onNotify(notification)

end

function createPerson(class)

	p = event:createPerson(class)
	if (p ~= nil) then
		return p
	end  

	p = day:createPerson(class)
	if (p ~= nil) then
		return p
	end
	
	p = restaurant:createPerson(class)
	if (p ~= nil) then
		return p
	end  	
	
	if (class == "francois") then
		f = npc("INGAME_PERSON_FRANCOIS")
		f:setType("francois")
		f:setButtX(20)
		f:animate("IDLE", 0)
		return f
		
	elseif (class == "fakecustomer") then
		fc = fakecustomer("INGAME_CUSTOMER_MALE_REGULAR")
		fc:setType("fakecustomer")
		fc:animate("IDLE", 0)
		return fc
		
	elseif (class == "npc") then
		n = npc("")
		n:setType("npc")
		return n
		
	end
		
  
	return nil
  
end

function createObject(desc)

	o = event:createObject(desc)
	if (o ~= nil) then
		return o
	end  

	o = day:createObject(desc)
	if (o ~= nil) then
		return o
	end  	
	
	o = restaurant:createObject(desc)
	if (o ~= nil) then
		return o
	end  	
	
  	return nil

end

function createProduct(base)

	p = event:createProduct(base)
	if (p ~= nil) then
		return p
	end  

	p = day:createProduct(base)
	if (p ~= nil) then
		return p
	end  	
	
	p = restaurant:createProduct(base)
	if (p ~= nil) then
		return p
	end  	
	
  	return nil

end