local S = minetest.get_translator(minetest.get_current_modname())

local function path_to_sunlight_exists(position, light_level)
	local neighbours = {
		{ x = 0, y = 0, z =-1 },
		{ x = 0, y = 0, z = 1 },
		{ x = 0, y =-1, z = 0 },
		{ x = 0, y = 1, z = 0 },
		{ x =-1, y = 0, z = 0 },
		{ x = 1, y = 0, z = 0 },
	}
	for i=1, #neighbours do
		local offset = neighbours[i]
		local position_new = vector.add(
			position,
			offset
		)
		local light_level_new = minetest.get_node_light(
			position_new,
			nil
		)
		if 15 == light_level_new then
			-- found the sunlight
			return true
		elseif light_level_new > light_level then
			-- search where light is brighter
			if path_to_sunlight_exists(
				position_new,
				light_level_new
			) then
				return true
			end
		end
	end
end

local function sunlight_visible(position)
	local light_level
	-- Minetest 5.4.0+ can measure the daylight level at a position
	if nil ~= minetest.get_natural_light then
		light_level = minetest.get_natural_light(
			position,
			nil
		)
		if light_level >= 12 then
			return true
		end
	else -- Minetest 5.3.0 or less can only measure the light level
		local time = minetest.get_timeofday() * 24000
		-- only check light level during day
		if time > 6000 and time < 18000 then
			light_level = minetest.get_node_light(
				position,
				nil
			)
			if light_level >= 12 then
				return path_to_sunlight_exists(
					position,
					12
				)
			end
		end
	end
	return false
end

local boxes = { -8/16, -8/16, -8/16,  8/16, -2/16, 8/16 }

-- Daylight Sensor
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
	drawtype = "nodebox",
	tiles = { "jeija_solar_panel.png","jeija_solar_panel.png","jeija_solar_panel_side.png",
	"jeija_solar_panel_side.png","jeija_solar_panel_side.png","jeija_solar_panel_side.png", },
	wield_image = "jeija_solar_panel.png",
	wield_scale = { x=1, y=1, z=3 },
	paramtype = "light",
	is_ground_content = false,
	selection_box = {
		type = "fixed",
		fixed = boxes
	},
	node_box = {
		type = "fixed",
		fixed = boxes
	},
	drop = "mesecons_solarpanel:solar_panel_off",
	_doc_items_create_entry = false,
	groups = {handy=1,axey=1, not_in_creative_inventory = 1, material_wood=1, flammable=-1},
	sounds = mcl_sounds.node_sound_glass_defaults(),
	mesecons = {receptor = {
		state = mesecon.state.on,
		rules = mesecon.rules.pplate,
	}},
	on_rightclick = function(pos, node, clicker, pointed_thing)
		local protname = clicker:get_player_name()
		if minetest.is_protected(pos, protname) then
			minetest.record_protection_violation(pos, protname)
			return
		end
		minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_inverted_off"})
		mesecon.receptor_off(pos, mesecon.rules.pplate)
	end,
	_mcl_blast_resistance = 0.2,
	_mcl_hardness = 0.2,
})

minetest.register_node("mesecons_solarpanel:solar_panel_off", {
	drawtype = "nodebox",
	tiles = { "jeija_solar_panel.png","jeija_solar_panel.png","jeija_solar_panel_side.png",
	"jeija_solar_panel_side.png","jeija_solar_panel_side.png","jeija_solar_panel_side.png", },
	wield_image = "jeija_solar_panel.png",
	wield_scale = { x=1, y=1, z=3 },
	paramtype = "light",
	is_ground_content = false,
	selection_box = {
		type = "fixed",
		fixed = boxes
	},
	node_box = {
		type = "fixed",
		fixed = boxes
	},
	groups = {handy=1,axey=1, material_wood=1},
	description=S("Daylight Sensor"),
	_tt_help = S("Provides redstone power when in sunlight") .. "\n" ..S("Can be inverted"),
	_doc_items_longdesc = S("Daylight sensors are redstone components which provide redstone power when they are in sunlight and no power otherwise. They can also be inverted.").."\n"..
		S("In inverted state, they provide redstone power when they are not in sunlight and no power otherwise."),
	_doc_items_usagehelp = S("Use the daylight sensor to toggle its state."),
	sounds = mcl_sounds.node_sound_glass_defaults(),
	mesecons = {receptor = {
		state = mesecon.state.off,
		rules = mesecon.rules.pplate,
	}},
	on_rightclick = function(pos, node, clicker, pointed_thing)
		local protname = clicker:get_player_name()
		if minetest.is_protected(pos, protname) then
			minetest.record_protection_violation(pos, protname)
			return
		end
		minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_inverted_on"})
		mesecon.receptor_on(pos, mesecon.rules.pplate)
	end,
	_mcl_blast_resistance = 0.2,
	_mcl_hardness = 0.2,
})

minetest.register_craft({
	output = "mesecons_solarpanel:solar_panel_off",
	recipe = {
		{"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"},
		{"mcl_nether:quartz", "mcl_nether:quartz", "mcl_nether:quartz"},
		{"group:wood_slab", "group:wood_slab", "group:wood_slab"},
	}
})

minetest.register_abm({
	label = "Daylight turns on solar panels",
	nodenames = {"mesecons_solarpanel:solar_panel_off"},
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider)
		if sunlight_visible(pos) then
			minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
			mesecon.receptor_on(pos, mesecon.rules.pplate)
		end
	end,
})

minetest.register_abm({
	label = "Darkness turns off solar panels",
	nodenames = {"mesecons_solarpanel:solar_panel_on"},
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider)
		if not sunlight_visible(pos) then
			minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
			mesecon.receptor_off(pos, mesecon.rules.pplate)
		end
	end,
})

--- Inverted Daylight Sensor

minetest.register_node("mesecons_solarpanel:solar_panel_inverted_on", {
	drawtype = "nodebox",
	tiles = { "jeija_solar_panel_inverted.png","jeija_solar_panel_inverted.png","jeija_solar_panel_side.png",
	"jeija_solar_panel_side.png","jeija_solar_panel_side.png","jeija_solar_panel_side.png", },
	wield_image = "jeija_solar_panel_inverted.png",
	wield_scale = { x=1, y=1, z=3 },
	paramtype = "light",
	is_ground_content = false,
	selection_box = {
		type = "fixed",
		fixed = boxes
	},
	node_box = {
		type = "fixed",
		fixed = boxes
	},
	drop = "mesecons_solarpanel:solar_panel_off",
	groups = {handy=1,axey=1, not_in_creative_inventory = 1, material_wood=1},
	_doc_items_create_entry = false,
	sounds = mcl_sounds.node_sound_glass_defaults(),
	mesecons = {receptor = {
		state = mesecon.state.on,
		rules = mesecon.rules.pplate,
	}},
	on_rightclick = function(pos, node, clicker, pointed_thing)
		local protname = clicker:get_player_name()
		if minetest.is_protected(pos, protname) then
			minetest.record_protection_violation(pos, protname)
			return
		end
		minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_off"})
		mesecon.receptor_off(pos, mesecon.rules.pplate)
	end,
	_mcl_blast_resistance = 0.2,
	_mcl_hardness = 0.2,
})

minetest.register_node("mesecons_solarpanel:solar_panel_inverted_off", {
	drawtype = "nodebox",
	tiles = { "jeija_solar_panel_inverted.png","jeija_solar_panel_inverted.png","jeija_solar_panel_side.png",
	"jeija_solar_panel_side.png","jeija_solar_panel_side.png","jeija_solar_panel_side.png", },
	wield_image = "jeija_solar_panel_inverted.png",
	wield_scale = { x=1, y=1, z=3 },
	paramtype = "light",
	is_ground_content = false,
	selection_box = {
		type = "fixed",
		fixed = boxes
	},
	node_box = {
		type = "fixed",
		fixed = boxes
	},
	drop = "mesecons_solarpanel:solar_panel_off",
	groups = {handy=1,axey=1, not_in_creative_inventory=1, material_wood=1},
	description=S("Inverted Daylight Sensor"),
	_doc_items_create_entry = false,
	sounds = mcl_sounds.node_sound_glass_defaults(),
	mesecons = {receptor = {
		state = mesecon.state.off,
		rules = mesecon.rules.pplate,
	}},
	on_rightclick = function(pos, node, clicker, pointed_thing)
		local protname = clicker:get_player_name()
		if minetest.is_protected(pos, protname) then
			minetest.record_protection_violation(pos, protname)
			return
		end
		minetest.swap_node(pos, {name = "mesecons_solarpanel:solar_panel_on"})
		mesecon.receptor_on(pos, mesecon.rules.pplate)
	end,
	_mcl_blast_resistance = 0.2,
	_mcl_hardness = 0.2,
})

minetest.register_abm({
	label = "Darkness turns on inverted solar panels",
	nodenames = {"mesecons_solarpanel:solar_panel_inverted_off"},
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider)
		if not sunlight_visible(pos) then
			minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2})
			mesecon.receptor_on(pos, mesecon.rules.pplate)
		end
	end,
})

minetest.register_abm({
	label = "Daylight turns off inverted solar panels",
	nodenames = {"mesecons_solarpanel:solar_panel_inverted_on"},
	interval = 1,
	chance = 1,
	action = function(pos, node, active_object_count, active_object_count_wider)
		if sunlight_visible(pos) then
			minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2})
			mesecon.receptor_off(pos, mesecon.rules.pplate)
		end
	end,
})

minetest.register_craft({
	type = "fuel",
	recipe = "mesecons_solarpanel:solar_panel_off",
	burntime = 15
})

if minetest.get_modpath("doc") then
	doc.add_entry_alias("nodes", "mesecons_solarpanel:solar_panel_off", "nodes", "mesecons_solarpanel:solar_panel_on")
	doc.add_entry_alias("nodes", "mesecons_solarpanel:solar_panel_off", "nodes", "mesecons_solarpanel:solar_panel_inverted_off")
	doc.add_entry_alias("nodes", "mesecons_solarpanel:solar_panel_off", "nodes", "mesecons_solarpanel:solar_panel_inverted_off")
	doc.add_entry_alias("nodes", "mesecons_solarpanel:solar_panel_off", "nodes", "mesecons_solarpanel:solar_panel_inverted_on")
end