/*
 * Copyright (C) 2007 Esmertec AG. Copyright (C) 2007 The Android Open Source
 * Project
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package info.guardianproject.otr.app.im.engine;

import info.guardianproject.otr.OtrChatManager;
import info.guardianproject.otr.app.im.service.ChatSessionManagerAdapter;

import java.util.Hashtable;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * The ChatSessionManager keeps track of all current chat sessions and is also
 * responsible to dispatch the new incoming message to the right session.
 */
public abstract class ChatSessionManager {

    private CopyOnWriteArrayList<ChatSessionListener> mListeners;
    private ChatSessionManagerAdapter mAdapter;
    
    /** Map session to the participant communicate with. */
    protected Hashtable<String,ChatSession> mSessions;

    protected ChatSessionManager() {
        mListeners = new CopyOnWriteArrayList<ChatSessionListener>();
        mSessions = new Hashtable<String,ChatSession>();
    }
    
    public void setChatSessionManagerAdapter (ChatSessionManagerAdapter adapter)
    {
        mAdapter = adapter;
    }

    /**
     * Registers a ChatSessionListener with the ChatSessionManager to receive
     * events related to ChatSession.
     * 
     * @param listener the listener
     */
    public synchronized void addChatSessionListener(ChatSessionListener listener) {
        if ((listener != null) && !mListeners.contains(listener)) {
            mListeners.add(listener);
        }
    }

    /**
     * Removes a ChatSessionListener so that it will no longer be notified.
     * 
     * @param listener the listener to remove.
     */
    public synchronized void removeChatSessionListener(ChatSessionListener listener) {
        mListeners.remove(listener);
    }

    /**
     * Creates a new ChatSession with specified participant.
     * 
     * @param participant the participant.
     * @return the created ChatSession.
     */
    public synchronized ChatSession createChatSession(ImEntity participant) {
        
        String sessionKey = participant.getAddress().getAddress();
        ChatSession session = mSessions.get(sessionKey);

        if (session == null)
        {
            session = new ChatSession(participant, this);                        
            mAdapter.getChatSessionAdapter(session);
            mSessions.put(sessionKey,session);
    
            for (ChatSessionListener listener : mListeners) {
                listener.onChatSessionCreated(session);
            }

        }
        
        return session;
    }

    /**
     * Closes a ChatSession. This only removes the session from the list; the
     * protocol implementation should override this if it has special work to
     * do.
     * 
     * @param session the ChatSession to close.
     */
    public void closeChatSession(ChatSession session) {
        mSessions.remove(session.getParticipant().getAddress().getAddress());
    }

    /**
     * Sends a message to specified participant(s) asynchronously. TODO: more
     * docs on async callbacks.
     * 
     * @param message the message to send.
     */
    public abstract void sendMessageAsync(ChatSession session, Message message);
}

@@ -1818,37 +1818,24 @@
 %0A    public 
-synchronized 
 void addChat
@@ -1874,32 +1874,32 @@
 ner listener) %7B%0A
+
         if ((lis
@@ -2163,29 +2163,16 @@
  public 
-synchronized 
 void rem
@@ -2453,21 +2453,8 @@
 lic 
-synchronized 
 Chat
@@ -2499,16 +2499,38 @@
 ticipant
+, boolean isNewSession
 ) %7B%0A    
@@ -2772,32 +2772,32 @@
                %0A
-
             mAda
@@ -2822,32 +2822,46 @@
 nAdapter(session
+, isNewSession
 );%0A            m

remove unnecessary synchronization