local module = {}

local function new(name,tab)
	local instance = Instance.new(name)
	for index,item in pairs(tab) do
		instance[index] = item
	end
	return instance
end

local function block(cframe,size)
	return new("Part",{
		Material = Enum.Material.WoodPlanks,
		Color = Color3.new(0.301961, 0.14902, 0.0588235),
		Anchored = true,
		CFrame = cframe + Vector3.new(0,size.Y/2,0),
		Size = size,
		Transparency = 0.5,
		Parent = workspace
	})
end

local function mark(position)
	return block(CFrame.new(position),Vector3.one * 128)
end

local function r(v)
	return math.noise(v.X*0.379,v.Y*0.379,v.Z*0.379) + 1
end

local px = Vector3.xAxis
local py = Vector3.xAxis
local pz = Vector3.xAxis

module.main = function(ox,oy,oz,noise)
	local n = function(v) return noise(v.X,v.Y,v.Z) end
	local o = Vector3.new(ox,oy,oz)

	--[[
		origin: where the wall starts
		direction: where the wall faces
		magnitude: the size of the wall
		depth: the current depth of the wall
	]]
	local walls = {}
	local function hit(origin,direction,magnitude,depth)
		
	end
	local function wall(origin,direction,magnitude)
		
	end
	local function project(origin,direction,magnitude)
		local depth = 0
		for i = 1,4 do
			depth += magnitude * 0.5
			local probe = origin + direction * depth
			if n(probe) > 0.05 then continue end
			if hit(origin,direction,magnitude,depth) then continue end
			mark(origin + direction * depth)
		end
		if depth == 0 then return nil
		else return depth end
	end
	
	local function extrude(origin,look,width,height)
		local depth = project(origin,look,width)
		if not depth then return end
		return block(CFrame.lookAlong(origin - look * depth * 0.5,look),Vector3.new(width,height,depth))
	end

	local no = n(o)
	local norm = Vector3.new(no - n(o + Vector3.xAxis),no - n(o + Vector3.yAxis),no - n(o + Vector3.zAxis)).Unit
	local flat = Vector3.new(norm.X,0,norm.Z).Unit;
	mark(o).CFrame = CFrame.lookAlong(o,norm)
	o = o + project(o,-norm,64) * -norm or o
	extrude(o,flat,r(o+px)*256,r(o+py)*256)
end

return module