anchor.diff:          ]).
   -export([ ping/1
           , games/1
  +        , single_game/1
           ]).
   
   -define(UCHAR,  8/unsigned-integer).
  
positive.code: 
    {comment, ""}.
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %% Message parsing/handling
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  hdp_recv(Config) ->
    {socket, UdpSocket} = lists:keyfind(socket, 1, Config),
    Port = application:get_env(serpents, udp_port, 8584),
    {ok, {{127, 0, 0, 1}, Port, Packet}} =
  
negative.code:       132 -> game_update;
        Other when Other band 128 == 0 -> throw(error)
      end,
    {Type, MsgId, Time, hdp_parse(Type, Parser, Message)}.
  
  hdp_parse(ping_response, _, <<>>) -> pong;
  hdp_parse(info_response, default, <<GameCount:?UCHAR, Games/binary>>) ->
    { GameCount
    , [ {GameId, TickRate, Players, MaxP}
      || <<GameId:?USHORT, TickRate:?UCHAR, Players:?UCHAR, MaxP:?UCHAR>> <= Games
      ]
    };
  hdp_parse(info_response, detail, GameDesc) ->
    << GameId:?USHORT
     , TickRate:?UCHAR
     , Cols:?UCHAR
     , Rows:?UCHAR
     , CurrP:?UCHAR
     , MaxP:?UCHAR
     , Players/binary>> = GameDesc,
    {GameId, TickRate, Cols, Rows, MaxP, hdp_parse_players(CurrP, Players)}.
  
  hdp_parse_players(CurrP, Players) when length(Players) == CurrP ->
    [ {Id, Name}
    || <<Id:?UINT, NameSize:?UCHAR, Name:NameSize/binary>> <= Players
    ].
  
  hdp_send(Message, Config) ->
    {socket, UdpSocket} = lists:keyfind(socket, 1, Config),
    Port = application:get_env(serpents, udp_port, 8584),
    gen_udp:send(UdpSocket, localhost, Port, Message).
  
  
  hdp_game(MsgId, GameId) ->
    H = hdp_head(2, MsgId),
    <<H/binary, GameId:?USHORT>>.
  
  hdp_games(MsgId) -> hdp_head(2, MsgId).
  
  