anchor.diff:  -author('theo@jivatechnology.com').
   -author('nicolas.alpi@gmail.com').
   
  +-behaviour(gen_server).
   -behaviour(gen_mod).
   
  +-define(PROCNAME, ?MODULE).
  +
  +%% event handlers
  +-export([
  +    set_presence_log/4,
  +    unset_presence_log/4
  +    ]).
  +
  +%% gen_server callbacks
  +-export([
  +    init/1,
  +    handle_call/3,
  +    handle_cast/2,
  +    handle_info/2,
  +    terminate/2,
  +    code_change/3
  +    ]).
  +
  +%% gen_mod callbacks.
   -export([
       start/2,
       stop/1,
  -    set_presence_log/4,
  -    unset_presence_log/4
  -    ]).
  +    start_link/2]).
   
   -include("ejabberd.hrl").
   -include("jlib.hrl").
   
  -%%%----------------------------------------------------------------------
  -%%% EVENT HANDLERS
  -%%%----------------------------------------------------------------------
  +-record(state, {host, urls, auth_user, auth_password}).
  +
  +%%====================================================================
  +%% Event handlers
  +%%====================================================================
   
   set_presence_log(User, Server, Resource, Presence) ->
       post_results(set_presence_hook, User, Server, Resource, lists:flatten(xml:element_to_string(Presence))),
  
positive.code:     end,
      ok.
      
  %%%----------------------------------------------------------------------
  %%% HELPER FUNCTIONS
  %%%----------------------------------------------------------------------
  
  post_results(Event, User, Server, Resource, Message) ->
      Url          = url_for(Event),
      AuthUser     = gen_mod:get_module_opt(global, ?MODULE, user,     undefined),
      AuthPassword = gen_mod:get_module_opt(global, ?MODULE, password, undefined),
      case is_list(AuthUser) andalso is_list(AuthPassword) of
          true  -> 
              UserPassword = base64:encode_to_string(AuthUser ++ ":" ++ AuthPassword),
  
negative.code:                     "application/x-www-form-urlencoded", Data
                  },
                  [],
                  [{sync, false},{stream, self}]
              );
          false ->
              false
      end,
      {reply, ok, State};
  handle_call(stop, _From, State) ->
      {stop, normal, ok, State}.
      
  %%--------------------------------------------------------------------
  %% Function: handle_cast(Msg, State) -> {noreply, State} |
  %%                                      {noreply, State, Timeout} |
  %%                                      {stop, Reason, State}
  %% Description: Handling cast messages
  %%--------------------------------------------------------------------
  handle_cast(_Msg, State) ->
      {noreply, State}.
  
  %%--------------------------------------------------------------------
  %% Function: handle_info(Info, State) -> {noreply, State} |
  %%                                       {noreply, State, Timeout} |
  %%                                       {stop, Reason, State}
  %% Description: Handling all non call/cast messages
  %%--------------------------------------------------------------------
  handle_info({http, {RequestId, stream_start, Headers}}, State) ->
      ?DEBUG("http stream_start RequestId: ~p, Headers: ~p",[RequestId, Headers]),
      {noreply, State};
  handle_info({http, {RequestId, stream, BinBodyPart}}, State) ->
      ?DEBUG("http stream RequestId: ~p, BinBodyPart: ~p",[RequestId, BinBodyPart]),
      {noreply, State};
  handle_info({http, {RequestId, stream_end, Headers}}, State) ->
      ?DEBUG("http stream_end RequestId: ~p, Headers: ~p",[RequestId, Headers]),
      {noreply, State};
  handle_info(_Info, State) ->
      {noreply, State}.
  
  %%--------------------------------------------------------------------
  %% Function: terminate(Reason, State) -> void()
  %% Description: This function is called by a gen_server when it is about to
  %% terminate. It should be the opposite of Module:init/1 and do any necessary
  %% cleaning up. When it returns, the gen_server terminates with Reason.
  %% The return value is ignored.
  %%--------------------------------------------------------------------
  terminate(_Reason, State) ->
      Host = State#state.host,
      ejabberd_hooks:delete(set_presence_hook,   Host, ?MODULE, set_presence_log,   50),
      ejabberd_hooks:delete(unset_presence_hook, Host, ?MODULE, unset_presence_log, 50),
      ok.
      
  %%--------------------------------------------------------------------
  %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
  %% Description: Convert process state when code is changed
  %%--------------------------------------------------------------------
  code_change(_OldVsn, State, _Extra) ->
      {ok, State}.
  
  %%====================================================================
  %% API
  %%====================================================================
  %%--------------------------------------------------------------------
  %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
  %% Description: Starts the server
  %%--------------------------------------------------------------------
  start_link(Host, Opts) ->
      Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
      gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []).
  
  %%====================================================================
  %% gen_mod callbacks
  %%====================================================================
  
  start(Host, Opts) ->
      Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
      ChildSpec =	{
          Proc,
  	    {?MODULE, start_link, [Host, Opts]},
  	    transient,
  	    1000,
  	    worker,
  	    [?MODULE]},
      supervisor:start_child(ejabberd_sup, ChildSpec).
      
  stop(Host) ->
      Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
      gen_server:call(Proc, stop),
      supervisor:delete_child(ejabberd_sup, Proc).
  