/*
 * Copyright (C) 2006 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 android.os;

/** @hide */
public class Broadcaster
{
    public Broadcaster()
    {
    }

    /**
     *  Sign up for notifications about something.
     *
     *  When this broadcaster pushes a message with senderWhat in the what field,
     *  target will be sent a copy of that message with targetWhat in the what field.
     */
    public void request(int senderWhat, Handler target, int targetWhat)
    {
        synchronized (this) {
            Registration r = null;
            if (mReg == null) {
                r = new Registration();
                r.senderWhat = senderWhat;
                r.targets = new Handler[1];
                r.targetWhats = new int[1];
                r.targets[0] = target;
                r.targetWhats[0] = targetWhat;
                mReg = r;
                r.next = r;
                r.prev = r;
            } else {
                // find its place in the map
                Registration start = mReg;
                r = start;
                do {
                    if (r.senderWhat >= senderWhat) {
                        break;
                    }
                    r = r.next;
                } while (r != start);
                int n;
                if (r.senderWhat != senderWhat) {
                    // we didn't find a senderWhat match, but r is right
                    // after where it goes
                    Registration reg = new Registration();
                    reg.senderWhat = senderWhat;
                    reg.targets = new Handler[1];
                    reg.targetWhats = new int[1];
                    reg.next = r;
                    reg.prev = r.prev;
                    r.prev.next = reg;
                    r.prev = reg;

                    if (r == mReg && r.senderWhat > reg.senderWhat) {
                        mReg = reg;
                    }
                    
                    r = reg;
                    n = 0;
                } else {
                    n = r.targets.length;
                    Handler[] oldTargets = r.targets;
                    int[] oldWhats = r.targetWhats;
                    // check for duplicates, and don't do it if we are dup.
                    for (int i=0; i<n; i++) {
                        if (oldTargets[i] == target && oldWhats[i] == targetWhat) {
                            return;
                        }
                    }
                    r.targets = new Handler[n+1];
                    System.arraycopy(oldTargets, 0, r.targets, 0, n);
                    r.targetWhats = new int[n+1];
                    System.arraycopy(oldWhats, 0, r.targetWhats, 0, n);
                }
                r.targets[n] = target;
                r.targetWhats[n] = targetWhat;
            }
        }
    }
    
    /**
     * Unregister for notifications for this senderWhat/target/targetWhat tuple.
     */
    public void cancelRequest(int senderWhat, Handler target, int targetWhat)
    {
        synchronized (this) {
            Registration start = mReg;
            Registration r = start;
            
            if (r == null) {
                return;
            }
            
            do {
                if (r.senderWhat >= senderWhat) {
                    break;
                }
                r = r.next;
            } while (r != start);
            
            if (r.senderWhat == senderWhat) {
                Handler[] targets = r.targets;
                int[] whats = r.targetWhats;
                int oldLen = targets.length;
                for (int i=0; i<oldLen; i++) {
                    if (targets[i] == target && whats[i] == targetWhat) {
                        r.targets = new Handler[oldLen-1];
                        r.targetWhats = new int[oldLen-1];
                        if (i > 0) {
                            System.arraycopy(targets, 0, r.targets, 0, i);
                            System.arraycopy(whats, 0, r.targetWhats, 0, i);
                        }

                        int remainingLen = oldLen-i-1;
                        if (remainingLen != 0) {
                            System.arraycopy(targets, i+1, r.targets, i,
                                    remainingLen);
                            System.arraycopy(whats, i+1, r.targetWhats, i,
                                    remainingLen);
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * For debugging purposes, print the registrations to System.out
     */
    public void dumpRegistrations()
    {
        synchronized (this) {
            Registration start = mReg;
            System.out.println("Broadcaster " + this + " {");
            if (start != null) {
                Registration r = start;
                do {
                    System.out.println("    senderWhat=" + r.senderWhat);
                    int n = r.targets.length;
                    for (int i=0; i<n; i++) {
                        System.out.println("        [" + r.targetWhats[i]
                                        + "] " + r.targets[i]);
                    }
                    r = r.next;
                } while (r != start);
            }
            System.out.println("}");
        }
    }

    /**
     * Send out msg.  Anyone who has registered via the request() method will be
     * sent the message.
     */
    public void broadcast(Message msg)
    {
        synchronized (this) {
            if (mReg == null) {
                return;
            }
            
            int senderWhat = msg.what;
            Registration start = mReg;
            Registration r = start;
            do {
                if (r.senderWhat >= senderWhat) {
                    break;
                }
                r = r.next;
            } while (r != start);
            if (r.senderWhat == senderWhat) {
                Handler[] targets = r.targets;
                int[] whats = r.targetWhats;
                int n = targets.length;
                for (int i=0; i<n; i++) {
                    Handler target = targets[i];
                    Message m = Message.obtain();
                    m.copyFrom(msg);
                    m.what = whats[i];
                    target.sendMessage(m);
                }
            }
        }
    }

    private class Registration
    {
        Registration next;
        Registration prev;

        int senderWhat;
        Handler[] targets;
        int[] targetWhats;
    }
    private Registration mReg;
}
