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