-module(badsequence).
-export([make_sequence/0, get_next/1, reset/1]).
-export([init/0, handle_call/2, handle_cast/2]).
-export([go/1]).

% API 
make_sequence() ->
    server:start(badsequence).
get_next(Sequence) -> 
    N = read(Sequence),
    write(Sequence, N+1),
    N.
reset(Sequence) ->
    write(Sequence,0).
read(Sequence) ->
     server:call(Sequence,read).
write(Sequence,N) ->
     server:cast(Sequence,{write,N}).

% Server callbacks 
init()                    -> 0. 
handle_call(read, N)      -> {N, N}. 
handle_cast({write, N},_) -> N. 

go(N) ->
    Pid = self(),
    S = make_sequence(),
    loop(1,N,fun(_) -> spawn(fun() -> loop(1,100,fun(_) -> get_next(S) end), Pid ! die end) end),
    loop(1,N,fun(_) -> wait() end),
    io:format("Done!~n"),
    F = N * 100,
    F = get_next(S),
    ok.

loop(N, N, F) ->
    F(N);
loop(I, N, F) -> 
    F(I),
    loop(I+1, N, F).

wait() ->
    receive
        die -> void
    end.
