-module(mycaptcha).
-compile(export_all).

-record(captcha, 	{key, value}).

new() ->
	CryptKey = crypto:rand_bytes(16),

	ok = try mnesia:dirty_write({captcha, 0, CryptKey})
	catch
		_:_ ->
			{atomic, ok} = mnesia:create_table(captcha, [{ram_copies, [node()]}, {attributes, record_info(fields, captcha)}]),
			mnesia:dirty_write({captcha, 0, CryptKey})
	end,

	FileName = lists:flatmap(fun(Item) -> integer_to_list(Item) end, tuple_to_list(now())),

	Code = generate_rand(5),

	File = io_lib:format("/tmp/~s.png",[FileName]),

	Cmd = io_lib:format("convert -background 'none' -fill '#222222' -size 175 -gravity Center -wave 5x100 -swirl 50 -font DejaVu-Serif-Book -pointsize 28 label:~s -draw 'Bezier 10,40 50,35 100,35 150,35 200,50 250,35 300,35' ~s", [Code, File]),
	os:cmd(Cmd),

	{ok, BinPng} = file:read_file(File),
	file:delete(File),

	Sha = crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code),
	CodeHex = mochihex:to_hex(Sha),

	{CodeHex, BinPng}.

check(CodeHex, Code) ->
	Sha = mochihex:to_bin(CodeHex),
	[Rec] = mnesia:dirty_read({captcha, 0}),
	CryptKey = Rec#captcha.value,

	case crypto:sha_mac(CryptKey, integer_to_list(lists:sum(Code)) ++ Code) of
		Sha ->
			true;

		_ ->
			false
	end.

generate_rand(Length) ->
	Now = now(),
	random:seed(element(1, Now), element(2, Now), element(3, Now)),
	lists:foldl(fun(_I, Acc) -> [do_rand(0) | Acc] end, [], lists:seq(1, Length)).

do_rand(R) when R > 46, R < 58; R > 64, R < 91; R > 96 ->  
R;

do_rand(_R) ->
	%do_rand(48 + random:uniform(74)). %% exluding zero
	do_rand(47 + random:uniform(75)).
