extends Reference

static func build_house2(main_xform: Transform):
	var rnd = streaming.get_place_rnd(main_xform)
	print(main_xform.origin, " seed = ", rnd.state)
	var l = 5 + 2 * (rnd.randi() % 5) - 1
	var h = l - 1
	var d = 3 + rnd.randi() % (l - 4 + 1)
	var range_used = false
	var objects = []
	for k in range(l + 1):
		var pos = Vector3(0, 0, k * 2)
		var xform = Transform(Basis(), pos)
		if k > 0:
			var what
			if k != d && rnd.randf() > 0.5 && !range_used:
				what = "roof_floor_range"
				range_used = true
			else:
				what = "roof_floor"
			objects.push_back({"xform": xform, "data": [what]})
			var xt = [Transform(Basis(), pos), Transform(Basis().rotated(Vector3.UP, PI), pos - Vector3(0, 0, 2))]
			for x in range(xt.size()):
				if x == 0 && k == d:
					continue
				if rnd.randf() > 0.5:
					what = "wall_solid"
				elif rnd.randf() > 0.5:
					what = "window_narrow"
				else:
					what = "window_wide"
				objects.push_back({"xform": xt[x], "data": [what]})
		var obj_data = []
		if k > 1 && k < l && rnd.randf() > 0.6:
			objects.push_back({"xform": xform, "data": ["wall_internal"]})

		match k:
			0:
				obj_data = ["side_wall", "bottom_side"]
			1:
				obj_data = ["bottom"]
			2:
				obj_data = ["bottom_wheels"]
			d:
				obj_data = ["entry", "bottom"]
			h:
				obj_data = ["bottom_wheels"]
			l:
				obj_data = ["side_wall_rotated", "bottom_side_rotated", "bottom"]
			_:
				obj_data = ["bottom"]
		objects.push_back({"xform": xform, "data": obj_data})
	return objects

static func build_walls(pos: Vector3, rnd: RandomNumberGenerator):
	var objects = []
	var xt = [Transform(Basis(), pos), Transform(Basis().rotated(Vector3.UP, PI), pos - Vector3(0, 0, 2))]
	for x in range(xt.size()):
		var obj_data = []
		if rnd.randf() > 0.5:
			obj_data.push_back("wall_solid")
		elif rnd.randf() > 0.5:
			obj_data.push_back("window_narrow")
		else:
			obj_data.push_back("window_wide")
		objects.push_back({"xform": xt[x], "data": obj_data})
	return objects

static func build_house(main_xform: Transform):
	var rnd = streaming.get_place_rnd(main_xform)
	var terminals = [
		"side_wall",
		"side_wall_rotated",
		"room",
		"entry",
		"room_range",
		"wheels_room"
	]
	var grammar = {
		"start": ["side_wall", "room", "wheels_room", "rooms_entry", "wheels_room", "side_wall_rotated"],
		"rooms_entry": ["rooms", "entry!", "rooms"],
		"rooms": ["rooms#", ["room", "range!"]],
		"entry!": ["entry"],
		"range!": ["room_range"],
		"rooms#": ["rooms"]
	}
	var seen = {}
	var queue = ["start"]
	var complete = false
	while !complete:
		complete = true
		var data = []
		for k in range(queue.size()):
			var item = queue[k]
			print("item=", item)
			if !item in terminals:
				complete = false
				for de in grammar[item]:
					var e
					if typeof(de) == TYPE_ARRAY:
						while true:
							e = de[rnd.randi() % de.size()]
							if !e.ends_with("!") || !seen.has(e):
								break
					else:
						e = de
					print("e=", e)
					if e.ends_with("!"):
						if seen.has(e):
							continue
						else:
							seen[e] = 1
					if e.ends_with("#"):
						if queue.size() < 12:
							if rnd.randf() >= 0.3:
								data.push_back(e)
					else:
						data.push_back(e)
			else:
				data.push_back(item)
		queue = data
		if complete:
			if !seen.has("entry!") || !seen.has("range!"):
				complete = false
				seen.clear()
				queue = ["start"]
	print("queue: ", queue)
	var objects = []
	for k in range(queue.size()):
		var pos = Vector3(0, 0, k * 2)
		var xform = Transform(Basis(), pos)
		var xt = [Transform(Basis(), pos), Transform(Basis().rotated(Vector3.UP, PI), pos - Vector3(0, 0, 2))]
		match queue[k]:
			"side_wall":
				objects.push_back({"xform": xform, "data": ["side_wall", "bottom_side"]})
			"room":
				objects.push_back({"xform": xform, "data": ["roof_floor", "bottom"]})
				objects.append_array(build_walls(pos, rnd))
				if rnd.randf() > 0.6:
					objects.push_back({"xform": xform, "data": ["wall_internal"]})
			"wheels_room":
				objects.push_back({"xform": xform, "data": ["roof_floor", "bottom_wheels"]})
				objects.append_array(build_walls(pos, rnd))
				if rnd.randf() > 0.6:
					objects.push_back({"xform": xform, "data": ["wall_internal"]})
			"room_range":
				objects.push_back({"xform": xform, "data": ["roof_floor_range", "bottom"]})
				objects.append_array(build_walls(pos, rnd))
				if rnd.randf() > 0.6:
					objects.push_back({"xform": xform, "data": ["wall_internal"]})
			"entry":
				for x in range(xt.size()):
					var obj_data = []
					if x == 0:
						continue
					if rnd.randf() > 0.5:
						obj_data.push_back("wall_solid")
					elif rnd.randf() > 0.5:
						obj_data.push_back("window_narrow")
					else:
						obj_data.push_back("window_wide")
					objects.push_back({"xform": xt[x], "data": obj_data})
				objects.push_back({"xform": xform, "data": ["roof_floor", "entry", "bottom"]})
			"side_wall_rotated":
				objects.append_array(build_walls(pos, rnd))
				objects.push_back({"xform": xform, "data": ["roof_floor", "side_wall_rotated", "bottom_side_rotated", "bottom"]})
	return objects
