local perlin = require("pnoise")
local dict = require("dictionary")
local function gen(w,h,mode)
	if not mode then mode = "default" end
	local count = {}
	local t = math.random(1,100000)
	local map = {}
	local oTime = os.epoch("utc")
	for x=1,w do
		map[x] = {}
		for y=1,h do
			if os.epoch("utc") > oTime+5000 then
				os.sleep(0)
				oTime = os.epoch("utc")
			end
			local p
			local mapval
			if mode == "default" then
				local p1 = (perlin:noise(x/20,(y/20)*1.3,t)+0.8)*5
				p1 = p1/
				(
					(
						(w/2)
						/
						((w/2)-math.abs((w/2)-x))
					)
					+
					(
						(h/2)
						/
						((h/2)-math.abs((h/2)-y))
					)
				+1)
				local p2 = (perlin:noise(x/30,(y/30)*1.3,t))
				local p = p1+p2

				mapval = math.floor(p*5+0.5)
			elseif mode == "islands" then
				local p1 = (perlin:noise(x/100,(y/100)*1.3,t)+0.2)*2
				local p2 = (perlin:noise(x/30,(y/30)*1.3,t))
				local bdist = 50
				local val = 0
				if x <= bdist then
					p1 = p1/(((bdist/(bdist-math.abs(bdist-x)))-1)*1.5+1)
				elseif x >= w-(bdist-1) then
					p1 = p1/(bdist/(bdist-math.abs(x-(w-(bdist-1)))))
				end
				if y <= bdist then
					p1 = p1/(bdist/(bdist-math.abs(bdist-y)))
				elseif y >= h-(bdist-1) then
					p1 = p1/(bdist/(bdist-math.abs(y-(h-(bdist-1)))))
				end
				--[[if y <= bdist or y >= h-(bdist-1) then
					val ]]
				if val ~= 0 then
					p1 = p1/val
				end
				--[[p1 = p1/
				(
					(
						(w/2)
						/
						((w/2)-math.abs((w/2)-x))
					)
					+
					(
						(h/2)
						/
						((h/2)-math.abs((h/2)-y))
					)
				+1)]]
				--[[local p2 = (perlin:noise(x/60,(y/60)*1.3,t)+0.8)*3]]
				--[[p = (p1+p2)/2]]
				p = p1+p2
				mapval = math.floor(p*5+0.5)
				-- this is wrong cuz border doesnt work properly now
			elseif mode == "continents" then
				local p1 = (perlin:noise(x/80,(y/80)*1.3,t)+0.4)*1.5 -- 0.25)*2 is perfect for islands
				local p2 = (perlin:noise(x/30,(y/30)*1.3,t))
				local bdist = 50
				local val = 0
				if x <= bdist then
					p1 = p1/(bdist/(bdist-math.abs(bdist-x)))
				elseif x >= w-(bdist-1) then
					p1 = p1/(bdist/(bdist-math.abs(x-(w-(bdist-1)))))
				end
				if y <= bdist then
					p1 = p1/(bdist/(bdist-math.abs(bdist-y)))
				elseif y >= h-(bdist-1) then
					p1 = p1/(bdist/(bdist-math.abs(y-(h-(bdist-1)))))
				end
				--[[if y <= bdist or y >= h-(bdist-1) then
					val ]]
				if val ~= 0 then
					p1 = p1/val
				end
				p = p1+p2
				mapval = math.floor(p*5+0.5)
			end
			map[x][y] = mapval
			if map[x][y] == math.inf then map[x][y] = 50 end
			if not count[map[x][y]] then
				count[map[x][y]] = 0
			end
			count[map[x][y]] = count[map[x][y]]+1
		end
	end
	_G.lOS.mapcount = count
	return map
end
return gen