-module(ephraim_conv_handler). -include_lib("exmpp/include/exmpp_client.hrl"). -behaviour(gen_event). -export([start/4]). -export([init/1, handle_event/2, handle_call/2, handle_info/2, terminate/2, code_change/3]). -record(conv_handler_state, { supervisor :: pid(), event_manager :: pid(), connection :: pid(), roster :: pid(), convs = dict:new() :: dict() }). start(Supervisor, EventManager, Conn, Roster) -> gen_event:add_handler(EventManager, ?MODULE, #conv_handler_state{supervisor=Supervisor,event_manager=EventManager,connection=Conn,roster=Roster}). init(State) -> {ok, State}. -spec get_conv(#conv_handler_state{},exmpp_jid:jid()) -> {#conv_handler_state{},pid()|undefined}. get_conv(State, JID) -> {Node, Domain, Resource} = exmpp_jid:to_lower(exmpp_jid:parse(JID)), case Resource of undefined -> {State, undefined}; _ -> Key = list_to_binary([Node, <<"@">>, Domain, <<"/">>, Resource]), case dict:find(Key, State#conv_handler_state.convs) of {ok, Conv} -> {State, Conv}; error -> {ok, Conv} = supervisor:start_child(State#conv_handler_state.supervisor, {Key, {ephraim_conv, start_link, [State#conv_handler_state.event_manager, State#conv_handler_state.connection, State#conv_handler_state.roster, JID]}, transient, 1000, worker, [ephraim_conv]}), Dict = dict:store(Key, Conv, State#conv_handler_state.convs), {State#conv_handler_state{convs=Dict}, Conv} end end. handle_event({view_request, {conversation,JID,new}}, State) -> {NewState, _} = get_conv(State, JID), {ok, NewState}; handle_event({view_request, {conversation,JID,{send_message,Type,Body}}}, State) -> {NewState, Conv} = get_conv(State, JID), ephraim_conv:send_message(Conv, Type, Body), {ok, NewState}; handle_event({received_packet, #received_packet{packet_type=message, raw_packet=Packet}}, State) -> From = exmpp_xml:get_attribute(Packet, from, <<"unknown">>), Type = exmpp_message:get_type(Packet), Body = exmpp_message:get_body(Packet), NewState = if Body =/= undefined -> {State2, Conv} = get_conv(State, From), if Conv =/= undefined -> ephraim_conv:received_message(Conv, From, Type, Body); true -> ok end, State2; true -> io:format("Received strange message from ~p:~n~p~n", [From, Packet]), State end, {ok, NewState}; handle_event(_Event, State) -> {ok, State}. handle_call(_Msg, State) -> {noreply, State}. handle_info(_Msg, State) -> {ok, State}. terminate(_Reason, _State) -> ok. code_change(_OldVersion, State, _Extra) -> {ok, State}.