extends Node

# Cache : ~/.cache/godot/


func GenerateMap(filemap:String, longitude:int, latitude:int):
	Config.msg_debug("GenerateMap => Start")
	Config.msg_debug(" [" + filemap + "] longitude:" + str(longitude) + " latitude:" + str(latitude))
	var image = Image.new()
	var arr = []
	var mesh = ArrayMesh.new()
	
	arr.resize(Mesh.ARRAY_MAX)
	# Set up the PoolVectorXArrays.
	var verts = PoolVector3Array()
	var uvs = PoolVector2Array()
	var normals = PoolVector3Array()
	var indices = PoolIntArray()

	# Vertex indices.
	var thisrow = 0
	var prevrow = 0
	var point = 0
	image.load(filemap)
	var width = image.get_width()
	var height = image.get_height()
	image.lock()
	Config.msg_debug("width:" + str(width) + " , height:" + str(height))
	var lvl = image.get_pixel(0,0).v
	Config.msg_debug("level:" + str(lvl))
	Config.msg_debug("a:" + str(image.get_pixel(0,0).a))
	Config.msg_debug("r:" + str(image.get_pixel(0,0).r))
	Config.msg_debug("v:" + str(image.get_pixel(0,0).v))
	Config.msg_debug("b:" + str(image.get_pixel(0,0).b))
	var txt
	# y => height, x => width
	for y in range(height):
		for x in range(width):
			var z = int(image.get_pixel(x,y).v * 100)
			var vert = Vector3(x*10.0, z, y*10.0)
			Config.msg_debug("x:" + str(x) + " , y:" + str(y) + " , z:" + str(z))
			verts.append(vert)
			normals.append(vert.normalized())
			uvs.append(Vector2(x, y))
			point += 1
			if x > 0 and y > 0:
				indices.append(prevrow + x - 1)
				indices.append(prevrow + x)
				indices.append(thisrow + x - 1)
				indices.append(prevrow + x)
				indices.append(thisrow + x)
				indices.append(thisrow + x - 1)
#		if y > 0:
#			indices.append(prevrow + width - 1)
#			indices.append(prevrow)
#			indices.append(thisrow + width - 1)
#			indices.append(prevrow)
#			indices.append(prevrow + width)
#			indices.append(thisrow + width - 1)
		prevrow = thisrow
		thisrow = point

	arr[Mesh.ARRAY_VERTEX] = verts
	arr[Mesh.ARRAY_TEX_UV] = uvs
	arr[Mesh.ARRAY_NORMAL] = normals
	arr[Mesh.ARRAY_INDEX] = indices
	image.unlock()
	# Create mesh surface from mesh array.
	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used.
	# Commit to the ArrayMesh.
	ResourceSaver.save("res://map" + str(longitude) + "-" + str(latitude) + ".tres", mesh, 32)
	Config.msg_debug("GenerateMap => End")


func GenerateSphere(rings:int = 50, radial_segments:int = 50, height:int = 1, radius:int = 1):
	Config.msg_debug("GenerateSphere => Start")
	var arr = []
	var mesh = ArrayMesh.new()

	arr.resize(Mesh.ARRAY_MAX)
	# Set up the PoolVectorXArrays.
	var verts = PoolVector3Array()
	var uvs = PoolVector2Array()
	var normals = PoolVector3Array()
	var indices = PoolIntArray()

	# Vertex indices.
	var thisrow = 0
	var prevrow = 0
	var point = 0

	# Loop over rings.
	for i in range(rings + 1):
		var v = float(i) / rings
		var w = sin(PI * v)
		var y = cos(PI * v)

		# Loop over segments in ring.
		for j in range(radial_segments):
			var u = float(j) / radial_segments
			var x = sin(u * PI * 0.2)
			var z = cos(u * PI * 0.2)
			var vert = Vector3(x * radius * w, y, z * radius * w)
			verts.append(vert)
			normals.append(vert.normalized())
			uvs.append(Vector2(u, v))
			point += 1

			# Create triangles in ring using indices.
			if i > 0 and j > 0:
				indices.append(prevrow + j - 1)
				indices.append(prevrow + j)
				indices.append(thisrow + j - 1)

				indices.append(prevrow + j)
				indices.append(thisrow + j)
				indices.append(thisrow + j - 1)

		if i > 0:
			indices.append(prevrow + radial_segments - 1)
			indices.append(prevrow)
			indices.append(thisrow + radial_segments - 1)

			indices.append(prevrow)
			indices.append(prevrow + radial_segments)
			indices.append(thisrow + radial_segments - 1)

		prevrow = thisrow
		thisrow = point

	# Assign arrays to mesh array.
	arr[Mesh.ARRAY_VERTEX] = verts
	arr[Mesh.ARRAY_TEX_UV] = uvs
	arr[Mesh.ARRAY_NORMAL] = normals
	arr[Mesh.ARRAY_INDEX] = indices

	# Create mesh surface from mesh array.
	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used.
	
	# Commit to the ArrayMesh.
	ResourceSaver.save("user://sphere.tres", mesh, 32)
	Config.msg_debug("GenerateSphere => End")


func generate_super_map(filemap:String, longitude:int, latitude:int):

	Config.msg_debug("GenerateMap => Start")
	Config.msg_debug(" [" + filemap + "] longitude:" + str(longitude) + " latitude:" + str(latitude))
	var image = Image.new()
	var arr = []
	var mesh = ArrayMesh.new()
	
	arr.resize(Mesh.ARRAY_MAX)
	# Set up the PoolVectorXArrays.
	var verts = PoolVector3Array()
	var uvs = PoolVector2Array()
	var normals = PoolVector3Array()
	var indices = PoolIntArray()

	# Vertex indices.
	var thisrow = 0
	var prevrow = 0
	var point = 0
	image.load(filemap)
	var width = image.get_width()
	var height = image.get_height()
	image.lock()
	Config.msg_debug("width:" + str(width) + " , height:" + str(height))
	var lvl = image.get_pixel(0,0).v
	Config.msg_debug("level:" + str(lvl))
	Config.msg_debug("a:" + str(image.get_pixel(0,0).a))
	Config.msg_debug("r:" + str(image.get_pixel(0,0).r))
	Config.msg_debug("v:" + str(image.get_pixel(0,0).v))
	Config.msg_debug("b:" + str(image.get_pixel(0,0).b))
	var txt
	# y => height, x => width
	for y in range(height):
		for x in range(width):
			var z = int(image.get_pixel(x,y).v * 100)
			var vert = Vector3(x*10.0, z, y*10.0)
			Config.msg_debug("x:" + str(x) + " , y:" + str(y) + " , z:" + str(z))
			verts.append(vert)
			normals.append(vert.normalized())
			uvs.append(Vector2(x, y))
			point += 1
			if x > 0 and y > 0:
				indices.append(prevrow + x - 1)
				indices.append(prevrow + x)
				indices.append(thisrow + x - 1)
				indices.append(prevrow + x)
				indices.append(thisrow + x)
				indices.append(thisrow + x - 1)
		prevrow = thisrow
		thisrow = point

	var rings:int = 50
	var radial_segments:int = 50
	var radius:int = 1
	arr[Mesh.ARRAY_VERTEX] = verts
	arr[Mesh.ARRAY_TEX_UV] = uvs
	arr[Mesh.ARRAY_NORMAL] = normals
	arr[Mesh.ARRAY_INDEX] = indices
	image.unlock()
	# Create mesh surface from mesh array.
	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used.
	
	# Add 2nd surface
	arr = []
	arr.resize(Mesh.ARRAY_MAX)
	# Set up the PoolVectorXArrays.
	verts = PoolVector3Array()
	uvs = PoolVector2Array()
	normals = PoolVector3Array()
	indices = PoolIntArray()

	# Vertex indices.
	thisrow = 0
	prevrow = 0
	point = 0

	# Loop over rings.
	for i in range(rings + 1):
		var v = float(i) / rings
		var w = sin(PI * v)
		var y = cos(PI * v)

		# Loop over segments in ring.
		for j in range(radial_segments):
			var u = float(j) / radial_segments
			var x = sin(u * PI * 0.2)
			var z = cos(u * PI * 0.2)
			var vert = Vector3(x * radius * w, y, z * radius * w)
			verts.append(vert)
			normals.append(vert.normalized())
			uvs.append(Vector2(u, v))
			point += 1

			# Create triangles in ring using indices.
			if i > 0 and j > 0:
				indices.append(prevrow + j - 1)
				indices.append(prevrow + j)
				indices.append(thisrow + j - 1)

				indices.append(prevrow + j)
				indices.append(thisrow + j)
				indices.append(thisrow + j - 1)

		if i > 0:
			indices.append(prevrow + radial_segments - 1)
			indices.append(prevrow)
			indices.append(thisrow + radial_segments - 1)

			indices.append(prevrow)
			indices.append(prevrow + radial_segments)
			indices.append(thisrow + radial_segments - 1)

		prevrow = thisrow
		thisrow = point

	# Assign arrays to mesh array.
	arr[Mesh.ARRAY_VERTEX] = verts
	arr[Mesh.ARRAY_TEX_UV] = uvs
	arr[Mesh.ARRAY_NORMAL] = normals
	arr[Mesh.ARRAY_INDEX] = indices

	# Create mesh surface from mesh array.
	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr) # No blendshapes or compression used.
	
	
	# Commit to the ArrayMesh.
	ResourceSaver.save("res://map" + str(longitude) + "-" + str(latitude) + ".tres", mesh, 32)
	Config.msg_debug("GenerateMap => End")