--------------------------------------------------------------------------------
-- SimNetwork
-- input.lua
-- Handles user input:	- rotation of 3D scene
--			- zoom in/out
--------------------------------------------------------------------------------
SimNetwork_INPUT = true

if not SimNetwork_SCENE then	dofile("scene.lua") end

-- Global variables
-- ----------------

input = {
	MouseX = 0,		-- Absolute location of mouse pointer in coordinates
	MouseY = 0,		-- of Electro's window (and 2D scene)
	
	MouseLDown = false,	-- Status of mouse buttons (false for up, true for down)
	MouseRDown = false,
	MouseMDown = false,

	scrollLeft = false,	-- Indicates whether left, right, up, or down
	scrollRight = false,	-- keys are pressed (for scrolling the map)
	scrollUp = false,
	scrollDown = false,
	
	rotateLeft = false,
	rotateRight = false,
	zoomIn = false,
	zoomOut = false,
	toggleWidget = false,	-- Indicates whether key to toggle widget is
				-- pressed or not
}	

zoomRate = 600

selection = {
	current = nil
}

--mouse cursor
mouse = {			
	imgNormal = "data/cursorNormal.png",
	imgCable = "data/cursorCable.png",
	imgRouter = "data/cursorRouter.png",
	imgDemolish = "data/cursorDemolish.png",
	normal = nil,
	cable = nil,
	router = nil,
	demolish = nil,
	cameraMouse = nil
}	

-- global time
globalTime = 0.0

function getTime()
	return globalTime
end

-- -----------------------------------------------------------------------------
-- Function: initializeCursors()
-- Inputs:	none
-- Returns:	none
-- Description: create all sprites necessary for mourse cursors, initializes the mouse cursors
-- -----------------------------------------------------------------------------
function initializeCursors()
	cameraMouse = E.create_camera(E.camera_type_orthogonal)
	E.set_entity_position(cameraMouse,0, -viewport.T*2,0)
	
	pivot = E.create_pivot()
	
	mouse.normal = create_overlay(mouse.imgNormal)
	mouse.cable = create_overlay(mouse.imgCable)
	mouse.router = create_overlay(mouse.imgRouter)
	mouse.demolish = create_overlay(mouse.imgDemolish)
	
	E.parent_entity(pivot,cameraMouse)
	E.parent_entity(mouse.normal,pivot)
	E.parent_entity(mouse.cable,pivot)
	E.parent_entity(mouse.router,pivot)
	E.parent_entity(mouse.demolish,pivot)
	
	E.set_entity_position(pivot,input.MouseX,-input.MouseY,0)
	
end

-- -----------------------------------------------------------------------------
-- Function: moveCursor()
-- Inputs:	cursor
-- Returns:	none
-- Description: moves cursor to where the mouse x and y position is on the screen
-- -----------------------------------------------------------------------------
function moveCursor(cursor)
	E.set_entity_position(cursor,input.MouseX,-input.MouseY,0)
end

-- -----------------------------------------------------------------------------
-- Function: showCursor()
-- Inputs:	cursor
-- Returns:	none
-- Description: shows the cursor on the screen
-- -----------------------------------------------------------------------------
function showCursor(cursor)
	E.set_entity_flags(cursor,E.entity_flag_hidden,false)
end

-- -----------------------------------------------------------------------------
-- Function: hideCursor()
-- Inputs:	cursor
-- Returns:	none
-- Description: hides the cursor on the screen
-- -----------------------------------------------------------------------------
function hideCursor(cursor)
	E.set_entity_flags(cursor,E.entity_flag_hidden,true)
end

-- -----------------------------------------------------------------------------
-- Function: hideCursors()
-- Inputs:	none
-- Returns:	none
-- Description: hides all cursors on the screen
-- -----------------------------------------------------------------------------
function hideCursors()
	E.set_entity_flags(mouse.normal,E.entity_flag_hidden,true)
	E.set_entity_flags(mouse.cable,E.entity_flag_hidden,true)
	E.set_entity_flags(mouse.router,E.entity_flag_hidden,true)
	E.set_entity_flags(mouse.demolish,E.entity_flag_hidden,true)
end

-- -----------------------------------------------------------------------------
-- Function: handle_3d_rotation
-- Inputs:	dx, dy (integer): relative pointer movement
-- Returns:	boolean: indicates whether screen needs refresh
-- Description: rotates 3D scene about X and Y, also restricts rotation
-- to (-360, 360) about Y, [0, 90] about X
-- -----------------------------------------------------------------------------
function handle_3d_rotation(dx, dy)
	local refresh = false
	local xRotation = 0
	local yRotation = 0
	
	if dx ~= 0 then
		-- Rotate 3D scene about Y axis 
		yRotation = dx
		refresh = true
	end
	
	if dy ~= 0 then
		-- Rotate 3D scene about X axis
		xRotation = dy
		refresh = true
	end
	
	if refresh then
		-- gameScene:registerRotation(0, yRotation)
		gameScene:rotate(xRotation, yRotation)	
	end
	
	return refresh
end

-- -----------------------------------------------------------------------------
-- Function: handle_3d_zoom (DEPRECATED)
-- Inputs:	dy (integer): relative pointer movement
-- Returns:	boolean: indicates whether screen needs refresh
-- Description: Zooms in/out
-- -----------------------------------------------------------------------------
--[[function handle_3d_zoom(dy)
	if dy ~= 0 then
		local zoom = (dy / 500) * zoomRate
		--gameScene:changeZoom(zoom)
		return true
	end
	return false
end]]

-- -----------------------------------------------------------------------------
-- Function: handle_scroll
-- Inputs:	 none
-- Returns:	 none
-- Description: handle left/right/up/down scrolling
-- -----------------------------------------------------------------------------
function handle_scroll()
	
	-- transV:	camera translation vector
	--		[1]: Horizontal scroll (negative for L, positive for R)
	--		[2]: Vertical scroll (negativce for D, positive for Up)
	--		[3]: Zoom In/Out (positive for Out, negative for In)
	--		[4]: Rotation (about Y)
	local transV = {0, 0, 0, 0}
	
	if input.scrollLeft then
		transV[1] = -1
	elseif input.scrollRight then
		transV[1] = 1
	end
	
	if input.scrollDown then
		transV[2] = 1
	elseif input.scrollUp then
		transV[2] = -1
	end
	
	if input.zoomOut then
		transV[3] = 1
	elseif input.zoomIn then
		transV[3] = -1
	end
	
	if input.rotateLeft then
		transV[4] = 1
	elseif input.rotateRight then
		transV[4] = -1
	end
	
	if transV[1] ~= 0 or transV[2] ~= 0 or transV[3] ~= 0 or transV[4] ~= 0 then
		gameScene:moveCamera(transV)
	end
end

-- -----------------------------------------------------------------------------
-- Function: do_click() (callback)
-- Inputs:	b: button clicked
--		s: status; true for pressed, false for released
-- Description: handle toolbar clicking (selecting tools) and 3D mouse picking
-- in 3D scene.
-- -----------------------------------------------------------------------------
function do_click(b, s)

	if b==1 then
		input.MouseLDown = s
		
		if gameState == GAME_STATE.playing then
			if	input.MouseLDown and input.MouseX > 0 and 
				input.MouseX < toolbarWidth and 
				input.MouseY > 0 and input.MouseY < 32 and s then
				-- left click within tool bar
				return handle_toolbar_click()
				
			elseif gameScene.gui.activeWidget ~= nil 
				and gameScene.map.selected.o:getElementType() == "customer" 
				and gameScene.map.selected.o.state == STATE.CUSTOMER.interested then
			    --handle clicks inside the customer widget
			    if input.MouseLDown and input.MouseX > 500 and 
					input.MouseX < 800 and 
					input.MouseY > 75 and input.MouseY < 235 and s then
					
					--handle click on currentFee button
					if input.MouseLDown and input.MouseX > 680 and 
						input.MouseX < 745 and 
						input.MouseY > 120 and input.MouseY < 139 and s then
						hide(enterFeeButton)
						hide(enterFeeHoverButton)
						show(enterFeeButtonInsert)
						inputEntry = true
					end
					
					-- handle click on negotiate button
					if input.MouseLDown and input.MouseX > 525 and 
						input.MouseX < 655 and 
						input.MouseY > 190 and input.MouseY < 220 and s then
						--E.print_console("negotiate button clicked!")
						
						if inputString == "" then
							--display message to enter supply fee first
							show(enterFeeString)
							E.play_sound(messageSound)
						else
						
							if gameSim:negotiate(tonumber(inputString), gameScene.map.selected.o) then
								hide(enterFeeString)
								hide(negotiateButton)
								inputString = ""
								inputEntry = false
								hide(negotiationFailedString)
								hide(enterFeeString)
								show(negotiationPassedString)
								show(negotiationPassedString2)
								show(negotiationPassedString3)
								local lostSound = E.load_sound("data/sounds/lost.ogg")
								E.play_sound(lostSound)
							else
								--negotiation failed
								hide(enterFeeString)
								show(negotiationFailedString)
								show(negotiationFailedString2)
								E.play_sound(messageSound)
							end
						end
						
					end
					refresh = true
					--E.print_console("handle click in customer's widget!")
					
				end
			elseif s then
				-- report left click to Scene
				gameScene:mouseClick("left")
				
			end
	    end
	
	elseif b==3 then
		input.MouseRDown = s
		
		if gameState == GAME_STATE.playing then
			if s then
				-- report right click to Scene
				gameScene:mouseClick("right")
			end
		end

	elseif b==4 then
	
		if gameState == GAME_STATE.playing then
			-- Mouse wheel down
			gameScene:moveCamera({0, 0, -7, 0})
		end
		return true
	elseif b==5 then
		if gameState == GAME_STATE.playing then
			-- Mouse wheel up
			gameScene:moveCamera({0, 0, 7, 0})
		end
		return true
	elseif b == 2 then
		input.MouseMDown = s
	end
	
	return false
	
end

-- -----------------------------------------------------------------------------
-- Function: do_point() (callback)
-- Inputs:	dx, dy: pointer movement, relative to last position
-- Description: Check whether Right/Middle button are down and perform
-- 3D rotation/zoom repspectively
-- -----------------------------------------------------------------------------
function do_point(dx, dy)

	input.MouseX = input.MouseX + dx
	input.MouseY = input.MouseY + dy
		
	local refresh = false

	--hide(enterFeeButtonHover)
	--hide(enterFeeButton)
	--hide(enterBandwidthButtonHover)
	--hide(enterBandwidthButton)

	if not input.MouseLDown and not input.MouseRDown then
	
		if gameState == GAME_STATE.playing then
			if	input.MouseX > 0 and 
				input.MouseX < toolbarWidth and 
				input.MouseY > 0 and input.MouseY < 32 then
			
				-- Mouse within toolbar range
				refresh = handle_toolbar_hover()
			--[[elseif gameScene.gui.activeWidget ~= nil 
				and gameScene.map.selected.o:getElementType() == "customer" 
				and gameScene.map.selected.o.state == STATE.CUSTOMER.interested then
				
				-- show hover states of buttons when above them	
				if input.MouseLDown and input.MouseX > 680 and 
					input.MouseX < 745 and 
					input.MouseY > 105 and input.MouseY < 124 and s then
					E.print_console("YES")
					hide(enterFeeButton)
					show(enterFeeButtonHover)
					
				else
					hide(enterFeeButtonHover)
					--show(enterFeeButton)
					hide(enterBandwidthButtonHover)
					--show(enterBandwidthButton)
				end
				refresh = true
				]]			
			else
				-- Mouse within 3D Scene
				refresh = handle_toolbar_leave()
					gameScene:mouseTrack()
				end
		end
	end
	
	return refresh
end

-- -----------------------------------------------------------------------------
-- Function: do_keyboard() (callback)
-- Inputs:	b: button, s: pressed/released
-- Description: keyboard handler
-- -----------------------------------------------------------------------------
function do_keyboard(b, s)
	
	if gameState == GAME_STATE.menuSelection then
		if b == E.key_down and s then
			
			if menuSelection == 1 then
				--move down to item 2
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-121,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection ==2 then
				--move down to item 3
				menuSelection = 3
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-174,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection == 3 then
				--move down to item 4
				menuSelection = 4
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-227,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_up and s then
			if menuSelection == 2 then
				--move up to item 1
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-68,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection == 3 then
				--move up to item 2
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-121,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection == 4 then
				--move up to item 3
				menuSelection = 3
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-174,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		
		elseif b == E.key_return and s then
			if menuSelection == 1 then
				--load level selection screen
				hide(selectionBox)
				E.set_entity_scale(selectionBox,4,1.7,1)
				E.set_entity_position(selectionBox,-230,-30,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 1
				gameState = GAME_STATE.levelSelection
			elseif menuSelection ==2 then
				--load help screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-255,-230,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 1
				gameState = GAME_STATE.help
			elseif menuSelection ==3 then
				--load credits screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-95,-265,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 1
				gameState = GAME_STATE.credits
			elseif menuSelection ==4 then
				--quit
				E.exit()
			end
		end
		
	elseif gameState == GAME_STATE.ended then
		
		if gameWinningState == "quit" then
			if b == E.key_n and s then
				quitAnswer = "no"
			elseif b == E.key_y and s then
				quitAnswer = "yes"
			end
		
		elseif gameWinningState == "won" then
			if b == E.key_return and s then
				--unload the logic and scenes
				gameScene:destroy()
				
				-- show menu screens
				hide(winWidget)
				winWidget = nil
				show(menuScreen)
				gameState = GAME_STATE.menuSelection
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_scale(selectionBox,1,1,1)
				E.set_entity_position(selectionBox,-230,-68,0)
				show(selectionBox)
			end
			
		elseif gameWinningState == "lost" then
			if b == E.key_return and s then
				--unload the logic and scenes
				gameScene:destroy()
				
				-- show menu screens
				hide(lostWidget)
				lostWidget = nil
				show(menuScreen)
				gameState = GAME_STATE.menuSelection
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_scale(selectionBox,1,1,1)
				E.set_entity_position(selectionBox,-230,-68,0)
				show(selectionBox)
			end
		end
		
	elseif gameState == GAME_STATE.help then
		--E.print_console("help screen key right pressed")
		if b == E.key_right and s then
			if menuSelection == 1 then
				-- select main menu
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_position(selectionBox,35,-230,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_left and s then
			if menuSelection == 2 then
				-- select main menu
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_position(selectionBox,-255,-230,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_return and s then
			if menuSelection == 1 then
				-- load help2 screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-255,-230,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 1
				gameState = GAME_STATE.help2
			elseif menuSelection == 2 then
				--load menu screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-121,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 2
				gameState = GAME_STATE.menuSelection
			end
		end
		
	elseif gameState == GAME_STATE.help2 then
		--E.print_console("help screen key right pressed")
		if b == E.key_right and s then
			if menuSelection == 1 then
				-- select main menu
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_position(selectionBox,35,-230,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_left and s then
			if menuSelection == 2 then
				-- select main menu
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_position(selectionBox,-255,-230,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_return and s then
			if menuSelection == 1 then
				-- load help screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-255,-230,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 1
				gameState = GAME_STATE.help
			elseif menuSelection == 2 then
				--load menu screen
				hide(selectionBox)
				E.set_entity_position(selectionBox,-230,-121,0)
				show(selectionBox)
				E.play_sound(selectedSound)
				menuSelection = 2
				gameState = GAME_STATE.menuSelection
			end
		end
	
	elseif gameState == GAME_STATE.credits then
		if b == E.key_return and s then
			-- select main menu
			menuSelection = 3
			hide(selectionBox)
			E.set_entity_position(selectionBox,-230,-174,0)
			show(selectionBox)
			E.play_sound(selectedSound)
			gameState = GAME_STATE.menuSelection
		end
		
	elseif gameState == GAME_STATE.levelSelection then
		--E.print_console("help screen key right pressed")
		if b == E.key_down and s then
			if menuSelection == 1 then
				--select medium level
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_scale(selectionBox,4,1.7,1)
				E.set_entity_position(selectionBox,-230,-130,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection == 2 then
				--select hard level
				menuSelection = 3
				hide(selectionBox)
				E.set_entity_scale(selectionBox,4,1.7,1)
				E.set_entity_position(selectionBox,-230,-225,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
			
		elseif b == E.key_up and s then
			if menuSelection == 2 then
				--select easy level
				menuSelection = 1
				hide(selectionBox)
				E.set_entity_scale(selectionBox,4,1.7,1)
				E.set_entity_position(selectionBox,-230,-30,0)
				show(selectionBox)
				E.play_sound(selectSound)
			elseif menuSelection == 3 then
				--select medium level
				menuSelection = 2
				hide(selectionBox)
				E.set_entity_scale(selectionBox,4,1.7,1)
				E.set_entity_position(selectionBox,-230,-130,0)
				show(selectionBox)
				E.play_sound(selectSound)
			end
		elseif b == E.key_return and s then
			if menuSelection == 1 then
				level = 1
			elseif menuSelection == 2 then
				level = 2
			elseif menuSelection == 3 then
				level = 3
			end
			gameState = GAME_STATE.readyToPlay
			globalTime = 0.0
			E.play_sound(selectedSound)
		end
		
	elseif gameState == GAME_STATE.playing then
	
		--pressing F4 key quits the game
		if b == E.key_F10 and s then
			gameState = GAME_STATE.ended
			gameWinningState = "quit"
		-- help screen
		elseif b == E.key_h and s then
			gameScene:toggleHelp()
		-- Scrolling
		elseif b == E.key_left and s then
			input.scrollLeft = true
		elseif b == E.key_left and not s then
			input.scrollLeft = false
		elseif b == E.key_down and s then
			input.scrollDown = true
		elseif b == E.key_down and not s then
			input.scrollDown = false
		elseif b == E.key_right and s then
			input.scrollRight = true
		elseif b == E.key_right and not s then
			input.scrollRight = false
		elseif b == E.key_up and s then
			input.scrollUp = true
		elseif b == E.key_up and not s then
			input.scrollUp = false
		--alternate scrolling
		elseif b == E.key_a and s then
			input.scrollLeft = true
		elseif b == E.key_a and not s then
			input.scrollLeft = false
		elseif b == E.key_s and s then
			input.scrollDown = true
		elseif b == E.key_s and not s then
			input.scrollDown = false
		elseif b == E.key_d and s then
			input.scrollRight = true
		elseif b == E.key_d and not s then
			input.scrollRight = false
		elseif b == E.key_w and s then
			input.scrollUp = true
		elseif b == E.key_w and not s then
			input.scrollUp = false
		
		-- Rotation about Y
		elseif b == E.key_e and s then		-- S
			input.rotateLeft = true
		elseif b == E.key_e and not s then
			input.rotateLeft = false
		elseif b == E.key_q and s then		-- A
			input.rotateRight = true
		elseif b == E.key_q and not s then
			input.rotateRight = false
		
		-- Zoom In/Out	
		elseif b == E.key_z and s then		-- W
			input.zoomIn = true
		elseif b == E.key_z and not s then
			input.zoomIn = false
		
		elseif b == E.key_x and s then		-- Z
			input.zoomOut = true
		elseif b == E.key_x and not s then
			input.zoomOut = false
		
		-- toggle widget of selected entity
		--elseif b == E.key_space and s then
		--	input.toggleWidget = true
		end
		
		--handle input for negotiating fee
		if gameScene.gui.activeWidget ~= nil 
			and gameScene.map.selected.o:getElementType() == "customer" 
			and gameScene.map.selected.o.state == STATE.CUSTOMER.interested 
			and inputEntry == true then
			
			if b == E.key_1 and s then
				inputString = inputString .. "1"
			elseif b == E.key_2 and s then
				inputString = inputString .. "2"
			elseif b == E.key_3 and s then
				inputString = inputString .. "3"
			elseif b == E.key_4 and s then
				inputString = inputString .. "4"
			elseif b == E.key_5 and s then
				inputString = inputString .. "5"
			elseif b == E.key_6 and s then
				inputString = inputString .. "6"
			elseif b == E.key_7 and s then
				inputString = inputString .. "7"
			elseif b == E.key_8 and s then
				inputString = inputString .. "8"
			elseif b == E.key_9 and s then
				inputString = inputString .. "9"
			elseif b == E.key_0 and s then
				inputString = inputString .. "0"
			elseif b== E.key_backspace and s then
				if string.len(inputString) ~= 0 then
					length = string.len(inputString) - 1
					--remove last character
					inputString = string.sub (inputString, 0, length)
				end
			end
			
			--only allow up to 7 characters
			if string.len(inputString) > 7 then
				inputString = string.sub (inputString, 0, 7)
			end
			
			E.set_string_text(feeInputString, inputString)
			show(feeInputString)
			
		end
	end
end

-- -----------------------------------------------------------------------------
-- Function: do_timer() (callback)
-- Inputs:	dt
-- Description: timer handler
-- -----------------------------------------------------------------------------

function do_timer(dt)
	
	if gameState == GAME_STATE.intro then
	
		introTimer = introTimer + dt
		
		if introTimer > INTRO_SCREEN_TIME then
			
			print("Removing splash screen")
			gameState = GAME_STATE.menuSelection
		end
		
	elseif gameState == GAME_STATE.menuSelection then
		hideIntroScreens()
		show(menuScreen)
		show(selectionBox)
	elseif gameState == GAME_STATE.help then
		hideIntroScreens()
		show(helpScreen)
	elseif gameState == GAME_STATE.help2 then
		hideIntroScreens()
		show(help2Screen)
	elseif gameState == GAME_STATE.credits then
		hideIntroScreens()
		show(creditsScreen)
	elseif gameState == GAME_STATE.levelSelection then
		hideIntroScreens()
		show(levelScreen)
	elseif gameState == GAME_STATE.readyToPlay then
		
		hideIntroScreens()
		hide(selectionBox)
		show(loadingScreen)
		
		globalTime = globalTime + dt
		
		--wait 1 second so that the loading screen will show up
		--removeMenuScreen()
		--removeIntroCamera()
		if globalTime > 1 then
			gameState = GAME_STATE.playing
			beginPlaying(level)
			globalTime = 0.0
		end
	elseif gameState == GAME_STATE.playing then
		
		hide(loadingScreen)
		
		-- increment global time
		globalTime = globalTime + dt
		
		-- respond to collision
		handle_scroll()
		gameScene:process_collisions()
		gameScene:endTestCollision()
		
		--handle mouse cursors
		hideCursors()
		moveCursor(mouse.normal)
		moveCursor(mouse.router)
		moveCursor(mouse.cable)
		moveCursor(mouse.demolish)
		
		-- handle tool selection
		--gameScene:toolSelection(selectedTool)
		
		if selectedTool == nil then
			showCursor(mouse.normal)
		elseif selectedTool == "demolish" then
			showCursor(mouse.demolish)
		elseif selectedTool == "cable1" then
			showCursor(mouse.cable)
		elseif selectedTool == "cable10" then
			showCursor(mouse.cable)
		elseif selectedTool == "cable100" then
			showCursor(mouse.cable)
		elseif selectedTool == "router4" then
			showCursor(mouse.router)
		elseif selectedTool == "router6" then
			showCursor(mouse.router)
		elseif selectedTool == "router8" then
			showCursor(mouse.router)
		end
		
		--handle widgets
		if input.toggleWidget then
			input.toggleWidget = false
			gameScene:toggleWidget()
		end
		
		-- animate scene
		gameScene:animate()
		
		-- wakeup fuzzy it its asleep
		if gameSim.waiting then
			gameSim:wakeup_fuzzy()
		end
		
		-- run simulation algorithm
		gameSim:simulate()
		
		local t = math.floor(globalTime)
		
		update_timer(t)
		
		if gameScene.gui.activeWidget ~= nil then
				gameScene:updateScene()
		end
		
	elseif gameState == GAME_STATE.ended then
		hideIntroScreens()
		-- based on winning or losing condition show the win or loose screen
		if gameWinningState == "quit" then
		
			if quitQuestion == nil then
				quitAnswer = "?"
				-- ask if user wants to quit
				local pivot = E.create_pivot()
				
				local background = make_sprite("data/widgets/quit.png")
				E.set_entity_alpha(background, 0.9)
				
				E.parent_entity(background, pivot)
					
				quitQuestion = pivot
				
				-- position widget in left top corner underneath the toolbar
				E.set_entity_position(quitQuestion, 0+400, 0-200, 0)
				
				-- add it to scene2d hierarchy
				E.parent_entity(quitQuestion, gameScene.gui.widgetsCamera)
			
			elseif quitQuestion ~= nil then
				if quitAnswer == "?" then
					-- do nothing
				elseif quitAnswer == "yes" then
					quitQuestion = nil
					
					--unload the logic and scenes
					gameScene:destroy()
					
					
					-- show menu screens
					show(menuScreen)
					gameState = GAME_STATE.menuSelection
					menuSelection = 1
					hide(selectionBox)
					E.set_entity_scale(selectionBox,1,1,1)
					E.set_entity_position(selectionBox,-230,-68,0)
					show(selectionBox)
				elseif quitAnswer == "no" then
					--hide quitQuestion
					hide(quitQuestion)
					quitQuestion = nil
					gameState = GAME_STATE.playing
				end
			end
				
		elseif gameWinningState == "won" then
			if winWidget == nil then
				winSound = E.load_sound("data/sounds/win.ogg")
				E.play_sound(winSound)
			end
			-- show win widget
			local pivot = E.create_pivot()
				
			local background = make_sprite("data/widgets/win.png")
			E.set_entity_alpha(background, 0.9)
			
			E.parent_entity(background, pivot)
				
			winWidget = pivot
			
			-- position widget in left top corner underneath the toolbar
			E.set_entity_position(winWidget, 0+400, 0-200, 0)
			
			-- add it to scene2d hierarchy
			E.parent_entity(winWidget, gameScene.gui.widgetsCamera)
			
		elseif gameWinningState == "lost" then
			if lostWidget == nil then
				lostSound = E.load_sound("data/sounds/lost.ogg")
				E.play_sound(lostSound)
			end
			-- show lost widget
			local pivot = E.create_pivot()
				
			local background = make_sprite("data/widgets/lost.png")
			E.set_entity_alpha(background, 0.9)
			
			E.parent_entity(background, pivot)
				
			lostWidget = pivot
			
			-- position widget in left top corner underneath the toolbar
			E.set_entity_position(lostWidget, 0+400, 0-200, 0)
			
			-- add it to scene2d hierarchy
			E.parent_entity(lostWidget, gameScene.gui.widgetsCamera)
		end
	end
	
	return true
end
