/**
 * 
 */
package com.beem.project.beem.service;

import java.util.HashMap;
import java.util.Map;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;

import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

import com.beem.project.beem.service.aidl.IChat;
import com.beem.project.beem.service.aidl.IChatManager;
import com.beem.project.beem.service.aidl.IChatManagerListener;
import com.beem.project.beem.service.aidl.IMessageListener;

/**
 * An adapter for smack's ChatManager. This class provides functionnality to handle chats.
 * @author darisk
 */
public class BeemChatManager extends IChatManager.Stub {

    /**
     * Tag to use with log methods.
     */
    public static final String TAG = "BeemChatManager";
    private ChatManager mAdaptee;
    private Map<String, Chat> mChats = new HashMap<String, Chat>();
    private ChatListener mChatListener = new ChatListener();
    private RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners =
	new RemoteCallbackList<IChatManagerListener>();

    /**
     * Constructor.
     * @param chatManager the smack ChatManager to adapt
     */
    public BeemChatManager(final ChatManager chatManager) {
	// TODO Auto-generated constructor stub
	mAdaptee = chatManager;
	mAdaptee.addChatListener(mChatListener);
    }

    /**
     * Create a chat session.
     * @param jid the jid of the contact you want to chat with
     * @param listener listener to use for chat events on this chat session
     * @return the chat session
     */
    public Chat createChat(String jid, MessageListener listener) {
	return mAdaptee.createChat(jid, listener);
    }

    /**
     * Create a chat session.
     * @param contact the contact you want to chat with
     * @param listener listener to use for chat events on this chat session
     * @return the chat session
     */
    public Chat createChat(Contact contact, MessageListener listener) {
	String jid = contact.getJID();
	return createChat(jid, listener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
	// TODO Auto-generated method stub
	mRemoteChatCreationListeners.register(listener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IChat createChat(Contact contact, IMessageListener listener) throws RemoteException {
	// TODO Auto-generated method stub
	return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
	// TODO Auto-generated method stub
	mRemoteChatCreationListeners.unregister(listener);
    }

    /**
     * A listener for all the chat creation event that happens on the connection.
     * @author darisk
     */
    private class ChatListener implements ChatManagerListener {

	/**
	 * Constructor.
	 */
	public ChatListener() {
	    // TODO Auto-generated constructor stub
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void chatCreated(Chat chat, boolean locally) {
	    if (!locally) {
		mChats.put(chat.getParticipant(), chat);
	    }
	    final int n = mRemoteChatCreationListeners.beginBroadcast();

	    for (int i = 0; i < n; i++) {
		IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
		try {
		    IChat newchat = new ChatAdapter(chat);
		    listener.chatCreated(newchat, locally);
		} catch (RemoteException e) {
		    // The RemoteCallbackList will take care of removing the
		    // dead listeners.
		    Log.w(TAG, "Error while triggering remote connection listeners", e);
		}
	    }
	    mRemoteChatCreationListeners.finishBroadcast();
	}
    }

}
