

local menu = {
	sprites = {},
	menuState = 0,
	fadeTime = .75,
	introTimers = { logo = nil, timer = .75, state = 0, timeState = 0, subTitle = "www.TIGSource.com",
		twinkles = {
				{x = 300, y = 150, wakeUpDelay = 2},
				{x = 370, y = 180, wakeUpDelay = 2.25},
				{x = 240, y = 284, wakeUpDelay = 3}
			}
		},
	menuTimers = { fadeTime = .75, fadeAction = nil },
	stars = {},
	starTarget = {x = 10, y = 190 },
	highlightedMenuItem = nil,
	menuItems = {
		single = { name = "Singleplayer Practice", left = 80, top = 126, right = 192, bottom = 244, hx = 44, hy = 112,
			action = function()
				_isMultiplayer, _localPlayer, _externalPlayer, _aiPlayer = false, 1, 2, 2
				unregisterMenuState()
				registerGameState()
			end
			},
		multi = { name = "Head-to-Head Multiplayer Action", left = 300, top = 170, right = 410, bottom = 300, hx = 254, hy = 162  },
		exit = { name = "Exit Game", left = 430, top = 424, right = 574, bottom = 480, hx = 348, hy = 390, action = function() daisy.exitGame() end },
		closeup = { name = "", left = 438, top = 214, right = 458, bottom = 272 }
	},
	consoleText = {  },
	consoleInput = "",
	consoleTimer = 0,
	consoleOptions = {}
}
menu.menuItems.closeup.action = function() menu.menuState = 3 end

local function updateStars(time)

	for index,star in pairs(menu.stars) do
	
		local dx, dy = menu.starTarget.x - star.x, menu.starTarget.y - star.y
		local angle = math.atan2(dy, dx)
		
		star.x = star.x + math.cos(angle) * star.velocity * time
		star.y = star.y + math.sin(angle) * star.velocity * time
		if math.abs(dx) < 2 and math.abs(dy) < 2 then
			star.x = math.random(640)
			star.y = math.random(480)
			local edge = math.random(1,4)
			if edge == 1 then
				star.x = 0
			elseif edge == 2 then
				star.y = 0
			elseif edge == 3 then
				star.x = 640
			else
				star.y = 480
			end
		end
	end
end

local function addConsoleText(text)

	local nextLine = nil
	local len = string.len(text)
	
	while len > 3 do
	
		local w,h = daisy.getTextSize(text, "double.fnt")
		--print(text .. ": len " .. len .. " w " .. w .. " h " .. h)
		if w > (640 - (200 * 2)) then
		
			if nextLine then
				nextLine = string.sub(text, -3) .. nextLine
			else
				nextLine = string.sub(text, -3)
			end
			text = string.sub(text, 1, len - 3)
			len = len - 3
		
		else
			break
		end
	
	end
	
	table.insert(menu.consoleText, text)
	
	if nextLine then
		addConsoleText(nextLine)
	end

end

menu.menuItems.multi.action = function()
	menu.menuState = 2
	
	addConsoleText("")
	addConsoleText("Communications station awaiting your command. Enter H to act as receiver (host). Enter C to act as transmitter (client).")
	addConsoleText("")
	addConsoleText("You can also enter R to watch a replay.")
	addConsoleText("")
	addConsoleText("Press Escape at any time to leave.")
	--addConsoleText("Enter H to act as receiver (host).")
	--addConsoleText("Enter C to act as transmitter (client).")
end

local function menuRun(time)

	if time > .06 then
		time = .06
	end

	if menu.menuState == 0 then
		menu.introTimers.timer = menu.introTimers.timer - time
		
		if menu.introTimers.timer <= 0 then
			menu.introTimers.timeState = menu.introTimers.timeState + 1
			
			if menu.introTimers.timeState == 1 then
				menu.introTimers.timer = 4
				if menu.introTimers.state == 2 then
					menu.introTimers.timer = 6
				end
			elseif menu.introTimers.timeState == 2 then
				menu.introTimers.timer = menu.fadeTime
			else
				menu.introTimers.timer = menu.fadeTime
				menu.introTimers.timeState = 0
				
				menu.introTimers.state = menu.introTimers.state + 1
				
				if menu.introTimers.state == 1 then
					menu.introTimers.logo = menu.sprites.artifact
					menu.introTimers.subTitle = "www.OxeyeGames.com"
				elseif menu.introTimers.state == 2 then
					menu.introTimers.logo = menu.sprites.logo
					menu.introTimers.subTitle = nil
					if _settings.enableMusic then
						daisy.playMusic("AdagioForStringsShort.ogg", .75)
					end
				else
					menu.menuState = 1
				end

				for index,twinkle in pairs(menu.introTimers.twinkles) do
					if twinkle.sprite then
						daisy.removeSpriteState(twinkle.sprite)
					end
				end
				menu.introTimers.twinkles = {}
			end
		end
		if menu.introTimers.timeState == 1 then
			daisy.updateSpriteState(menu.introTimers.logo, time)
		end
		
		for index,twinkle in pairs(menu.introTimers.twinkles) do
			twinkle.wakeUpDelay = twinkle.wakeUpDelay - time
			if twinkle.wakeUpDelay <= 0 and twinkle.sprite then
				if daisy.updateSpriteState(twinkle.sprite, time) then
					daisy.removeSpriteState(twinkle.sprite)
					twinkle.sprite = nil
				else
					twinkle.render = true
				end
			else
				twinkle.render = false
			end
		end
	elseif menu.menuState == 1 then
	
		updateStars(time)
		
		if menu.menuTimers.fadeTime > 0 then
			menu.menuTimers.fadeTime = menu.menuTimers.fadeTime - time
			
			if menu.menuTimers.fadeTime <= 0 and menu.menuTimers.fadeAction then
				menu.menuTimers.fadeAction()
				return
			end
		end
	
		menu.highlightedMenuItem = nil
		local mx, my = daisy.getMousePosition()
		for index, item in pairs(menu.menuItems) do
			if mx >= item.left and mx <= item.right and my >= item.top and my <= item.bottom then
				menu.highlightedMenuItem = item
				break
			end
		end
	elseif menu.menuState == 2 then
		menu.consoleTimer = menu.consoleTimer + time
		
		if menu.consoleOptions.activateTimer then
			
			if menu.consoleOptions.activateTimer > 0 then
				menu.consoleOptions.activateTimer = menu.consoleOptions.activateTimer - time
				if menu.consoleOptions.activateTimer <= 0 then
				
					if menu.consoleOptions.role == 1 then
						_isMultiplayer = true
						_localPlayer = 1
						_externalPlayer = 2
						_aiPlayer = -1
						_mapSeed = menu.consoleOptions.mapSeed
						_mapSize = menu.consoleOptions.mapSize
						_settings.hostPort = menu.consoleOptions.hostPort
						_settings.playerName = menu.consoleOptions.playerName
						
						--print("have " .. _mapSeed .. ", " .. _mapSize)
						
						multiplayer.hostGame(_settings.hostPort, 1, _settings.playerName)
					elseif menu.consoleOptions.role == 2 then
						_isMultiplayer = true
						_localPlayer = 2
						_externalPlayer = 1
						_aiPlayer = -1
						_settings.hostIp = menu.consoleOptions.hostIp
						_settings.hostPort = menu.consoleOptions.hostPort
						_settings.playerName = menu.consoleOptions.playerName
						
						--print("have " .. _mapSeed .. ", " .. _mapSize)
						
						multiplayer.joinGame(_settings.hostIp, _settings.hostPort, _settings.playerName)
						
					elseif menu.consoleOptions.role == 3 then
						_isMultiplayer = true
						_localPlayer = 1
						_externalPlayer = 2
						_aiPlayer = -1
						
						multiplayer.runReplay(menu.consoleOptions.replayName)
					end
				
				end
			elseif multiplayer.gameStarted then
				unregisterMenuState()
				registerGameState()
			end
		end
	end

end

local function menuRender()

	local w,h = daisy.getScreenSize()
	
	if menu.menuState == 0 then
	
		local sw,sh = daisy.getSpriteStateSize(menu.introTimers.logo)
		daisy.renderSpriteStateFixed(menu.introTimers.logo, (w - sw) / 2, (h - sh) / 2)
		
		local progress = nil
		if menu.introTimers.timeState == 0 then
			progress = math.ceil(16 * menu.introTimers.timer / menu.fadeTime) * 16
		elseif menu.introTimers.timeState == 2 then
			progress = math.ceil(16 * (1.0 - menu.introTimers.timer / menu.fadeTime)) * 16
		end
		
		if menu.introTimers.subTitle then
			daisy.renderText(menu.introTimers.subTitle, 320, 420, 1, "double.fnt")
		end
		
		for index,twinkle in pairs(menu.introTimers.twinkles) do
			if twinkle.render and twinkle.sprite then
				daisy.renderSpriteStateFixed(twinkle.sprite, twinkle.x, twinkle.y)
			end
		end
		
		if progress then
			if progress > 255 then progress = 255 end
			daisy.renderRectangle(0, 0, w, h, progress, 0, 0, 0)
		end
	elseif menu.menuState == 1 then
	
		for index,star in pairs(menu.stars) do
			local x = math.floor(star.x / 2) * 2
			local y = math.floor(star.y / 2) * 2
			
			local color = 64 + math.ceil((star.velocity - 5) / 95 * -191)
			
			daisy.renderRectangle(x, y, 2, 2, 255, color, color, color)
		end
	
		daisy.renderSpriteStateFixed(menu.sprites.main, 0, 0)
		
		if menu.highlightedMenuItem then
		
			if menu.highlightedMenuItem.highlight then
				daisy.renderSpriteStateFixed(menu.highlightedMenuItem.highlight, menu.highlightedMenuItem.hx, menu.highlightedMenuItem.hy)
			end
		
			daisy.renderText(menu.highlightedMenuItem.name, 320+2, 400, 1, "double.fnt", 255, 0, 0, 0)
			daisy.renderText(menu.highlightedMenuItem.name, 320-2, 400, 1, "double.fnt", 255, 0, 0, 0)
			daisy.renderText(menu.highlightedMenuItem.name, 320, 400+2, 1, "double.fnt", 255, 0, 0, 0)
			daisy.renderText(menu.highlightedMenuItem.name, 320, 400-2, 1, "double.fnt", 255, 0, 0, 0)
			daisy.renderText(menu.highlightedMenuItem.name, 320, 400, 1, "double.fnt")
		end

		if menu.menuTimers.fadeTime > 0 or menu.menuTimers.fadeAction then
			local progress = math.ceil(16 * menu.menuTimers.fadeTime / menu.fadeTime) * 16
			if progress > 255 then progress = 255
			elseif progress < 0 then progress = 0 end
			if menu.menuTimers.fadeAction then
				progress = 255 - progress
			end
			daisy.renderRectangle(0, 0, w, h, progress, 0, 0, 0)
		end
		
	elseif menu.menuState == 2 then
	
		daisy.renderSpriteStateFixed(menu.sprites.console, 0, 0)
		
		local textCount = #menu.consoleText
		local y = 340
		for i=textCount,(textCount-13),-1 do
		
			if i <= 0 then
				break
			end
		
			daisy.renderText(menu.consoleText[i], 200, y, 0, "double.fnt", 160, 255, 255, 255)
			y = y - 20
		
		end
		local inputText = "> " .. menu.consoleInput
		if math.cos(menu.consoleTimer * math.pi * 4) > 0 then
			inputText = inputText .. "_"
		end
		daisy.renderText(inputText, 200, 360, 0, "double.fnt", 160, 255, 255, 255)
	
	elseif menu.menuState == 3 then
	
		daisy.renderSpriteStateFixed(menu.sprites.closeup, 0, 0)
	
	end
	
	--do
		--local x,y = daisy.getMousePosition()
		--daisy.renderText("x " .. x .. ", y " .. y, 10, 10)
	--end

end

local function parseInput()

	local text = string.lower(menu.consoleInput)
	if not menu.consoleOptions.role then
		
		if string.sub(text, 1, 1) == "h" then
			menu.consoleOptions.role = 1
			
			addConsoleText("You will act as host. Please enter your name, or leave blank for default (".. _settings.playerName ..").")
			
		elseif string.sub(text, 1, 1) == "c" then
			menu.consoleOptions.role = 2
			
			addConsoleText("You will act as client. Please enter your name, or leave blank for default (".. _settings.playerName ..").")
			
		elseif string.sub(text, 1, 1) == "r" then
			menu.consoleOptions.role = 3
			
			addConsoleText("You have chosen to watch a replay. Please enter the file name, excluding replay extension (" .. _replayExtension .. ").")
		end
		if menu.consoleOptions.role then
			return true
		end
	elseif menu.consoleOptions.role == 1 then
		
		if not menu.consoleOptions.playerName then
		
			menu.consoleOptions.playerName = text
			if string.len(text) == 0 then
				menu.consoleOptions.playerName = _settings.playerName
			end
			
			addConsoleText("You will be known as '" .. menu.consoleOptions.playerName .. "'. Please enter the port number to listen to, or leave blank for default (".. _settings.hostPort ..").")
			return true
			
		elseif not menu.consoleOptions.hostPort then
		
			local port = math.floor(tonumber(text, 10) or 0)
			
			if port <= 0 and string.len(text) > 0 then
				addConsoleText("Errornous port number.")
				port = nil
			elseif port == 0 then
				port = _settings.hostPort
			end
			
			if port then
				menu.consoleOptions.hostPort = port
				addConsoleText("You will use port " .. port .. ". Please enter a map seed, or leave blank for current timestamp.")
				return true
			end
			
		elseif not menu.consoleOptions.mapSeed then
			local seed = math.floor(tonumber(text, 10) or 0)
			
			if seed <= 0 and string.len(text) > 0 then
				addConsoleText("Errornous map seed number.")
				seed = nil
			elseif seed == 0 then
				seed = os.time() % 10000
			end
			
			if seed then
				menu.consoleOptions.mapSeed = seed
				addConsoleText("You will use seed " .. seed .. ". Please enter a map size, legal values are 1 (small) through 5 (gigantic), default is 2.")
				return true
			end
		elseif not menu.consoleOptions.mapSize then
			local size = math.floor(tonumber(text, 10) or 0)
			
			if (size <= 0 and string.len(text) > 0) or size > 5 then
				addConsoleText("Errornous map size number.")
				size = nil
			elseif size == 0 then
				size = 2
			end
			
			if size then
				menu.consoleOptions.mapSize = size
				addConsoleText("You will use map size " .. size .. ". Everything is ready, press return to launch host.")
				return true
			end
		else
			addConsoleText("Waiting for connection...")
			menu.consoleOptions.activateTimer = .5
		end
	elseif menu.consoleOptions.role == 2 then
	
		if not menu.consoleOptions.playerName then
		
			menu.consoleOptions.playerName = text
			if string.len(text) == 0 then
				menu.consoleOptions.playerName = _settings.playerName
			end
			
			addConsoleText("You will be known as '" .. menu.consoleOptions.playerName .. "'. Please enter the ip number to connect to, or leave blank for default (".. _settings.hostIp ..").")
			return true
			
		elseif not menu.consoleOptions.hostIp then
		
			menu.consoleOptions.hostIp = text
			if string.len(text) == 0 then
				menu.consoleOptions.hostIp = _settings.hostIp
			end
			
			addConsoleText("You will connect to '" .. menu.consoleOptions.hostIp .. "'. Please enter the host's port number, or leave blank for default (" .. _settings.hostPort .. ").")
			return true
			
		elseif not menu.consoleOptions.hostPort then
		
			local port = math.floor(tonumber(text, 10) or 0)
			
			if port <= 0 and string.len(text) > 0 then
				addConsoleText("Errornous port number.")
				port = nil
			elseif port == 0 then
				port = _settings.hostPort
			end
			
			if port then
				menu.consoleOptions.hostPort = port
				addConsoleText("You will use port " .. port .. ". Press return again when you are ready to connect.")
				return true
			end
			
		else
			addConsoleText("Connecting...")
			menu.consoleOptions.activateTimer = .5
		end
	
	elseif menu.consoleOptions.role == 3 then
		if not menu.consoleOptions.replayName then
		
			menu.consoleOptions.replayName = text .. _replayExtension
			
			addConsoleText("You will load '" .. menu.consoleOptions.replayName .. "'. Press return to start.")
			return true
			
		else
			addConsoleText("Loading replay...")
			menu.consoleOptions.activateTimer = .5
		end

	end

	return false
end

local function skipIntro()
	if menu.introTimers.timeState == 0 then
		menu.introTimers.timeState = 2
		menu.introTimers.timer = menu.fadeTime - menu.introTimers.timer
	elseif menu.introTimers.timeState == 1 then
		menu.introTimers.timeState = 2
		menu.introTimers.timer = menu.fadeTime
	end
end

local function mouseClick(x, y, button, clickCount)

	if menu.menuState == 0 then
		skipIntro()
	elseif menu.menuState == 1 then
	
		if menu.highlightedMenuItem and not menu.menuTimers.fadeAction then
			menu.menuTimers.fadeAction = menu.highlightedMenuItem.action
			menu.menuTimers.fadeTime = menu.fadeTime
		end
	elseif menu.menuState == 3 then
		menu.menuState = 1
		menu.highlightedMenuItem = nil
		menu.menuTimers.fadeTime = menu.fadeTime
		menu.menuTimers.fadeAction = nil
	end
end

local function keyPressed(key)
	--print("Key: " .. key)
	
	if menu.menuState == 0 then
		skipIntro()
		return
	end
	
	if menu.menuState == 2 and not menu.consoleOptions.activateTimer then
	
		if key == 8 then
			menu.consoleInput = string.sub(menu.consoleInput, 1, -2)
		elseif key == 27 then
			menu.consoleInput = ""
			menu.menuState = 1
			menu.highlightedMenuItem = nil
			menu.menuTimers.fadeTime = menu.fadeTime
			menu.menuTimers.fadeAction = nil
			menu.consoleOptions = {}
		elseif key == 13 then
			addConsoleText("> " .. menu.consoleInput)
			if parseInput() then
				menu.consoleInput = ""
			end
		end
	elseif menu.menuState == 3 then
		menu.menuState = 1
		menu.highlightedMenuItem = nil
		menu.menuTimers.fadeTime = menu.fadeTime
		menu.menuTimers.fadeAction = nil
	end
end

local function charEntered(key)
	--print("Char: " .. key)
	
	if menu.menuState == 2 and not menu.consoleOptions.activateTimer then
	
		if key >= 32 then
			menu.consoleInput = menu.consoleInput .. string.char(key)
		end
	
	end
end

function registerMenuState()
	hook.add("frameUpdate", menuRun)
	hook.add("frameRender", menuRender)
	hook.add("mouseButton", mouseClick)
	hook.add("keyPress", keyPressed)
	hook.add("keyCharacter", charEntered)
	
	menu.sprites.tigsource = daisy.createSpriteState("tigsource", "IngameGfx.dat")
	menu.sprites.artifact = daisy.createSpriteState("artifact", "IngameGfx.dat")
	menu.sprites.logo = daisy.createSpriteState("logo", "IngameGfx.dat")
	menu.sprites.main = daisy.createSpriteState("main", "IngameGfx.dat")
	menu.sprites.console = daisy.createSpriteState("mpconsol", "IngameGfx.dat")
	menu.sprites.mpHighlight = daisy.createSpriteState("Hmultiplayer", "IngameGfx.dat")
	menu.sprites.spHighlight = daisy.createSpriteState("Hsingleplayer", "IngameGfx.dat")
	menu.sprites.exitHighlight = daisy.createSpriteState("Hexit", "IngameGfx.dat")
	menu.sprites.closeup = daisy.createSpriteState("closeup", "IngameGfx.dat")
	
	menu.menuItems.single.highlight = menu.sprites.spHighlight
	menu.menuItems.multi.highlight = menu.sprites.mpHighlight
	menu.menuItems.exit.highlight = menu.sprites.exitHighlight
	
	menu.introTimers.logo = menu.sprites.tigsource
	for index,twinkle in pairs(menu.introTimers.twinkles) do
		twinkle.sprite = daisy.createSpriteState("twinkle", "IngameGfx.dat")
	end
	
	for i=1,100 do
		local x, y = math.random(640), math.random(480)
		table.insert(menu.stars, {x = x, y = y, velocity = math.random(5,100)})
	end
	
	daisy.stopAllMusic()
	
end

function unregisterMenuState()
	hook.remove("frameUpdate", menuRun)
	hook.remove("frameRender", menuRender)
	hook.remove("mouseButton", mouseClick)
	hook.remove("keyPress", keyPressed)
	hook.remove("keyCharacter", charEntered)
	
	for index,sprite in pairs(menu.sprites) do
		daisy.removeSpriteState(sprite)
	end
	
	menu = nil
end
