/*
 * 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 java.util.Vector;
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;

    /** Map session to the participant communicate with. */
    protected Vector<ChatSession> mSessions;

    protected ChatSessionManager() {
        mListeners = new CopyOnWriteArrayList<ChatSessionListener>();
        mSessions = new Vector<ChatSession>();
    }

    /**
     * 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) {
        for (ChatSession session : mSessions) {
            
            if (session.getParticipant().equals(participant)) {
                return session;
            }
        }
        
        

        ChatSession session = new ChatSession(participant, this);
        for (ChatSessionListener listener : mListeners) {
            listener.onChatSessionCreated(session);
        }

        mSessions.add(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);
    }

    /**
     * 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);
}

@@ -696,16 +696,44 @@
 ngine;%0A%0A
+import java.util.Hashtable;%0A
 import j
@@ -1146,23 +1146,33 @@
 otected 
-Vector%3C
+Hashtable%3CString,
 ChatSess
@@ -1323,15 +1323,25 @@
 new 
-Vector%3C
+Hashtable%3CString,
 Chat
@@ -2266,37 +2266,41 @@
 pant) %7B%0A        
-for (
+%0A        
 ChatSession sess
@@ -2303,17 +2303,17 @@
 session 
-:
+=
  mSessio
@@ -2318,53 +2318,14 @@
 ions
-) %7B%0A            %0A            if (session
 .get
-P
+(p
 arti
@@ -2334,79 +2334,70 @@
 pant
-().equals(participant)) %7B%0A                return session;%0A            %7D
+.getAddress().getBareAddress());%0A%0A        if (session == null)
 %0A   
@@ -2397,25 +2397,25 @@
 ll)%0A        
-%7D
+%7B
 %0A        %0A  
@@ -2415,39 +2415,12 @@
     
-%0A
     
-    %0A%0A        ChatSession 
 sess
@@ -2461,16 +2461,103 @@
  this);%0A
+            mSessions.put(participant.getAddress().getBareAddress(),session);%0A    %0A    
         
@@ -2602,24 +2602,28 @@
 isteners) %7B%0A
+    
             
@@ -2666,24 +2666,28 @@
 n);%0A        
+    
 %7D%0A%0A        m
@@ -2689,32 +2689,18 @@
     
-mSessions.add(session);%0A
+%7D%0A        
 %0A   
@@ -3050,24 +3050,71 @@
 move(session
+.getParticipant().getAddress().getBareAddress()
 );%0A    %7D%0A%0A  

use a hashtable to find sessions - a lot better than iterating!