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

import android.annotation.UnsupportedAppUsage;

/** @hide */
public class Broadcaster
{
    @UnsupportedAppUsage
    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.
     */
    @UnsupportedAppUsage
    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.
     */
    @UnsupportedAppUsage
    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.
     */
    @UnsupportedAppUsage
    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;
}
