
missions.check_owner = function(pos, player)
	-- check override priv
	local has_override = minetest.check_player_privs(player, "protection_bypass")
	if has_override then
		return true
	end

	-- check owner
	local meta = minetest.get_meta(pos)
	return player and player:is_player() and player:get_player_name() == meta:get_string("owner")
end

local SECONDS_IN_DAY = 3600*24
local SECONDS_IN_HOUR = 3600
local SECONDS_IN_MINUTE = 60



missions.get_owner_from_pos = function(pos)
	local meta = minetest.get_meta(pos)
	return meta:get_string("owner")
end


local playermissions = {}
local playerabort = {}

--persistence stuff

minetest.register_on_joinplayer(function(player)
	local missionStr = player:get_meta():get_string(missions.MISSION_ATTRIBUTE_NAME)

	local mission = nil
	if missionStr then
		mission = minetest.deserialize(missionStr)
	end

	if mission and mission.version == missions.CURRENT_MISSION_SPEC_VERSION then
		-- only load if compatible with current spec
		local step = mission.steps[mission.currentstep]
		if step == nil then
			return
		end

		-- reset init flag
		step.initialized = false

		-- store in variable
		playermissions[player:get_player_name()] = mission
	end
end)

minetest.register_on_leaveplayer(function(player)
	playermissions[player:get_player_name()] = nil
end)

missions.persist_mission = function(player, mission)
	player:get_meta():set_string(missions.MISSION_ATTRIBUTE_NAME, minetest.serialize(mission))
end

minetest.register_on_respawnplayer(function(player)
	missions.abort(player:get_player_name())
end)


missions.set_current_mission = function(player, mission)
	playerabort[player:get_player_name()] = false
	playermissions[player:get_player_name()] = mission
end



missions.get_current_mission = function(player)
	return playermissions[player:get_player_name()]
end

missions.abort = function(playername)
	playerabort[playername] = true
end

missions.has_aborted = function(playername)
	return playerabort[playername]
end


missions.format_time = function(seconds)
	local str = ""


	if seconds >= SECONDS_IN_DAY then
		local days = math.floor(seconds / SECONDS_IN_DAY)
		str = str .. days .. " d "
		seconds = seconds - (days * SECONDS_IN_DAY)
	end

	if seconds >= SECONDS_IN_HOUR then
		local hours = math.floor(seconds / SECONDS_IN_HOUR)
		str = str .. hours .. " h "
		seconds = seconds - (hours * SECONDS_IN_HOUR)
	end

	if seconds >= SECONDS_IN_MINUTE then
		local minutes = math.floor(seconds / SECONDS_IN_MINUTE)
		str = str .. minutes .. " min "
		seconds = seconds - (minutes * SECONDS_IN_MINUTE)
	end

	str = str .. seconds .. " s"

	return str
end

-- mission steps setter/getter
missions.get_steps = function(pos)
	local meta = minetest.get_meta(pos)
	local steps = minetest.deserialize(meta:get_string("steps"))

	return steps
end

missions.set_steps = function(pos, steps)
	local meta = minetest.get_meta(pos)
	meta:set_string("steps", minetest.serialize(steps))
end

-- user selected step

local SELECTED_LIST_ITEM_ATTR_NAME = "missions_selected_list_item"

missions.get_selected_list_item = function(player)
	local s = player:get_meta():get_string(SELECTED_LIST_ITEM_ATTR_NAME)
	if 0 == #s then return 1 end
	return tonumber(s)
end

missions.set_selected_list_item = function(player, num)
	player:get_meta():set_string(SELECTED_LIST_ITEM_ATTR_NAME, tostring(num))
end



-- node register helper
missions.only_owner_can_dig = function(pos, player)
	if not player then
		return false
	end

	local has_override = minetest.check_player_privs(player, "protection_bypass")

	local meta = minetest.get_meta(pos)
	local playername = player:get_player_name() or ""
	return meta:get_string("owner") == playername or has_override
end


-- returns the image (item, node, tool) or ""
missions.get_image = function(name)
	-- stolen from drawers code
	local texture = "blank.png"
	local def = minetest.registered_items[name]
	if not def then
		return texture
	end

	if def.inventory_image and #def.inventory_image > 0 then
		texture = def.inventory_image
	else
		if not def.tiles then return texture end
		local tiles = table.copy(def.tiles)

		for k,v in pairs(tiles) do
		        if type(v) == "table" then
		                tiles[k] = v.name
		        end
		end

		-- tiles: up, down, right, left, back, front
		-- inventorycube: up, front, right
		if #tiles <= 2 then
		        texture = minetest.inventorycube(tiles[1], tiles[1], tiles[1])
		elseif #tiles <= 5 then
		        texture = minetest.inventorycube(tiles[1], tiles[3], tiles[3])
		else -- full tileset
		        texture = minetest.inventorycube(tiles[1], tiles[6], tiles[3])
		end
	end

	return texture

end



missions.show_banner = function(player, title, msg)
	minetest.sound_play({name="missions_generic", gain=0.25}, {to_player=player:get_player_name()})


	local one = player:hud_add({
		hud_elem_type = "image",
		name = "award_bg",
		scale = {x = 2, y = 1},
		text = "missions_bg_default.png",
		position = {x = 0.5, y = 0},
		offset = {x = 0, y = 138},
		alignment = {x = 0, y = -1}
	})

	local two = player:hud_add({
		hud_elem_type = "text",
		name = "award_au",
		number = 0xFFFFFF,
		scale = {x = 100, y = 20},
		text = title,
		position = {x = 0.5, y = 0},
		offset = {x = 0, y = 40},
		alignment = {x = 0, y = -1}
	})

	local three = player:hud_add({
		hud_elem_type = "text",
		name = "rank_title",
		number = 0xFFFFFF,
		scale = {x = 100, y = 20},
		text = msg,
		position = {x = 0.5, y = 0},
		offset = {x = 30, y = 100},
		alignment = {x = 0, y = -1}
	})

	local rank_offset = {x = -1.5, y = 126}

	local four = player:hud_add({
		hud_elem_type = "image",
		name = "award_icon",
		scale = {x = 2, y = 2},
		text = "missions_block_preview.png",
		position = {x = 0.4, y = 0},
		offset = rank_offset,
		alignment = {x = 0, y = -1}
	})

	minetest.after(4, function()
		player:hud_remove(one)
		player:hud_remove(two)
		player:hud_remove(three)
		player:hud_remove(four)
	end)
end
