local constants = {
	card_max_length = 140;
}

local kpbox = {
	type = 'fixed';
	fixed = {
		-0.5, -0.5, -0.4;
		 0.5,  0.2,  0.4;
	};
}
local keypunch_formspec = function(pos,msg)
	local meta = minetest.get_meta(pos)
	local inv = meta:get_inventory()

	local form = [[
		formspec_version[3] size[10.0,8]
		list[current_player;main;0.25,3;8,4;]
		item_image[0.25,1.50;1,1;sorcery:keypunch]
		list[context;cardstack;6.25,1.50;3,1;]
		listring[current_player;main] listring[context;card]
	]]
	local slot = function(name,ghost,x,y,w,h)
		w = w or 1  h = h or 1
		local s = string.format('list[context;%s;%f,%f;%f,%f;]', name, x, y,w,h)
		if ghost and inv:is_empty(name) then
			s = string.format('image[%f,%f;1,1;sorcery_ui_ghost_%s.png]',x,y,ghost) .. s
		end
		form = form .. s
	end
	slot('card','punchcard',0.25,0.25)
	if not inv:is_empty('card') then
		if msg and #msg > constants.card_max_length then
			form = form .. 'style[ctxt;border=false]' ..
				'box[1.5,0.25;4.50,2.25;#ff1010ff]'
		end
		form = form ..
			'button[6.25,0.25;3.50,1;punch;Punch]' ..
			string.format('textarea[1.5,0.25;4.50,2.25;ctxt;;%s]', minetest.formspec_escape(msg or ''))
	end

	meta:set_string('formspec',form)
end
minetest.register_node('sorcery:keypunch', {
	description = 'Keypunch';
	drawtype = 'mesh';
	mesh = 'sorcery-keypunch.obj';
	sunlight_propagates = true;
	paramtype = 'light';
	paramtype2 = 'facedir';
	after_dig_node = sorcery.lib.node.purge_container;
	groups = {
		oddly_breakable_by_hand = 2;
		sorcery_tech = 1;
	};
	selection_box = kpbox;
	collision_box = kpbox;
	tiles = {
		'default_wood.png';
		'default_cloud.png';
		'default_steel_block.png';
		'default_copper_block.png';
		'default_tin_block.png';
	};
	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()
		inv:set_size('card',1)
		inv:set_size('cardstack',3)
		meta:set_string('infotext','Keypunch')
		keypunch_formspec(pos)
	end;
	on_metadata_inventory_put = function(pos) keypunch_formspec(pos) end;
	on_metadata_inventory_take = function(pos) keypunch_formspec(pos) end;
	on_metadata_inventory_move = function(pos) keypunch_formspec(pos) end;
	allow_metadata_inventory_put = function(pos,list,idx,stack,user)
		local pcv = minetest.get_item_group(stack:get_name(), 'sorcery_punchcard')
		if pcv ~= 0 then
			if     list == 'card' and pcv == 1 then return 1
			elseif list == 'cardstack' then return stack:get_count() end
		end
		return 0
	end;
	allow_metadata_inventory_move = function(pos, fl, fi, tl, ti, ct, user)
		if fl == 'cardstack' and tl == 'card' then
			local meta = minetest.get_meta(pos)
			local inv = meta:get_inventory()
			local name = inv:get_stack(fl,fi):get_name()
			local pcv = minetest.get_item_group(name, 'sorcery_punchcard')
			if pcv == 1 then return 1 end
		elseif fl == 'card' and tl == 'cardstack' then return ct
		end
		return 0
	end;
	on_receive_fields = function(pos,form,fields,user)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()
		if minetest.get_item_group(inv:get_stack('card',1):get_name(), 'sorcery_punchcard') == 1 and fields.ctxt then
			if #fields.ctxt > constants.card_max_length then
				-- signal error to user
				keypunch_formspec(pos, fields.ctxt)
				return
			end
			local newcard = ItemStack('sorcery:punchcard')
			newcard:get_meta():set_string('data',fields.ctxt)
			inv:set_stack('card',1,newcard)
			keypunch_formspec(pos)
		end
	end;
})

minetest.register_node('sorcery:teletype', {
	description = 'Teletype';
	after_dig_node = sorcery.lib.node.purge_container;
	on_construct = function(pos)
		local meta = minetest.get_meta(pos)
		local inv = meta:get_inventory()

		inv:set_size('card',1)
		meta:set_string('infotext','Teletype')
	end;
})
minetest.register_node('sorcery:teletype_active', {
})
minetest.register_node('sorcery:teletype_done', {
})
minetest.register_node('sorcery:teleprinter', {

})

minetest.register_node('sorcery:punchcard_receiver', {
	description = 'Punchcard Sender';
})

for _,c in pairs {
	{'sorcery:punchcard_blank', 'Blank Punch Card', 'sorcery_punchcard.png', 1};
	{'sorcery:punchcard', 'Punch Card', 'sorcery_punchcard_punched.png', 2};
} do minetest.register_craftitem(c[1], {
		description = c[2];
		inventory_image = c[3];
		groups = {
			paper = 1, flammable = 1;
			punchcard = c[4], sorcery_punchcard = c[4];
		};
		_sorcery = {
			material = {
				powder = 'sorcery:pulp';
				grindvalue = 1; hardness = 1;
			};
		};
	})
end

