%% The Computer Language Shootout
%% http://shootout.alioth.debian.org/
%%
%% contributed by Paulo Sergio Almeida

-module(revcomp).
-export([main/1]).

main([_Args]) ->
  P = open_port({fd, 0, 1}, [{line,80}, eof]),
  loop(P, []),
  port_close(P),
  halt().

loop(P, L) ->
  receive
   {P, eof} ->
     write(P, list_to_binary(L), []);
   {P, {data, {eol, Line = ">"++_}}} ->
     write(P, list_to_binary(L), []),
     port_command(P, [Line, "\n"]),
     loop(P, []);
   {P, {data, {eol, Line}}} ->
     loop(P, [line(Line, []) | L])
  end.

line([], L) ->
  list_to_binary(L);
line([C|T], L) ->
  line(T,
    [element(C-64, 
      %$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K,$L,$M,
      {$T,$V,$G,$H,$E,$F,$C,$D,$I,$J,$M,$L,$K,
      %$N,$O,$P,$Q,$R,$S,$T,$U,$V,$W,$X,$Y,$Z
       $N,$O,$P,$Q,$Y,$S,$A,$A,$B,$W,$X,$R,$Z,
       0,0,0,0,0,0,
       $T,$V,$G,$H,$E,$F,$C,$D,$I,$J,$M,$L,$K,
       $N,$O,$P,$Q,$Y,$S,$A,$A,$B,$W,$X,$R,$Z})
     | L]).

write(P, <<Line:60/binary, R/binary>>, L) ->
  write(P, R, [[Line, "\n"] | L]);
write(P, <<>>, L) ->
  port_command(P, lists:reverse(L));
write(P, Line, L) ->
  write(P, <<>>, [[Line, "\n"] | L]).

