// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/**
 *******************************************************************************
 * Copyright (C) 2001-2009, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.util.ArrayList;
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;

/**
 * <p>Abstract implementation of a notification facility.  Clients add
 * EventListeners with addListener and remove them with removeListener.
 * Notifiers call notifyChanged when they wish to notify listeners.
 * This queues the listener list on the notification thread, which
 * eventually dequeues the list and calls notifyListener on each
 * listener in the list.</p>
 *
 * <p>Subclasses override acceptsListener and notifyListener
 * to add type-safe notification.  AcceptsListener should return
 * true if the listener is of the appropriate type; ICUNotifier
 * itself will ensure the listener is non-null and that the
 * identical listener is not already registered with the Notifier.
 * NotifyListener should cast the listener to the appropriate
 * type and call the appropriate method on the listener.
 */
public abstract class ICUNotifier {
    private final Object notifyLock = new Object();
    private NotifyThread notifyThread;
    private List<EventListener> listeners;

    /**
     * Add a listener to be notified when notifyChanged is called.
     * The listener must not be null. AcceptsListener must return
     * true for the listener.  Attempts to concurrently
     * register the identical listener more than once will be
     * silently ignored.
     */
    public void addListener(EventListener l) {
        if (l == null) {
            throw new NullPointerException();
        }

        if (acceptsListener(l)) {
            synchronized (notifyLock) {
                if (listeners == null) {
                    listeners = new ArrayList<EventListener>();
                } else {
                    // identity equality check
                    for (EventListener ll : listeners) {
                        if (ll == l) {
                            return;
                        }
                    }
                }

                listeners.add(l);
            }
        } else {
            throw new IllegalStateException("Listener invalid for this notifier.");
        }
    }

    /**
     * Stop notifying this listener.  The listener must
     * not be null.  Attempts to remove a listener that is
     * not registered will be silently ignored.
     */
    public void removeListener(EventListener l) {
        if (l == null) {
            throw new NullPointerException();
        }
        synchronized (notifyLock) {
            if (listeners != null) {
                // identity equality check
                Iterator<EventListener> iter = listeners.iterator();
                while (iter.hasNext()) {
                    if (iter.next() == l) {
                        iter.remove();
                        if (listeners.size() == 0) {
                            listeners = null;
                        }
                        return;
                    }
                }
            }
        }
    }

    /**
     * Queue a notification on the notification thread for the current
     * listeners.  When the thread unqueues the notification, notifyListener
     * is called on each listener from the notification thread.
     */
    public void notifyChanged() {
        synchronized (notifyLock) {
            if (listeners != null) {
                if (notifyThread == null) {
                    notifyThread = new NotifyThread(this);
                    notifyThread.setDaemon(true);
                    notifyThread.start();
                }
                notifyThread.queue(listeners.toArray(new EventListener[listeners.size()]));
            }
        }
    }

    /**
     * The notification thread.
     */
    private static class NotifyThread extends Thread {
        private final ICUNotifier notifier;
        private final List<EventListener[]> queue = new ArrayList<EventListener[]>();

        NotifyThread(ICUNotifier notifier) {
            this.notifier = notifier;
        }

        /**
         * Queue the notification on the thread.
         */
        public void queue(EventListener[] list) {
            synchronized (this) {
                queue.add(list);
                notify();
            }
        }

        /**
         * Wait for a notification to be queued, then notify all
         * listeners listed in the notification.
         */
        @Override
        public void run() {
            EventListener[] list;
            while (true) {
                try {
                    synchronized (this) {
                        while (queue.isEmpty()) {
                            wait();
                        }
                        list = queue.remove(0);
                    }

                    for (int i = 0; i < list.length; ++i) {
                        notifier.notifyListener(list[i]);
                    }
                }
                catch (InterruptedException e) {
                }
            }
        }
    }

    /**
     * Subclasses implement this to return true if the listener is
     * of the appropriate type.
     */
    protected abstract boolean acceptsListener(EventListener l);

    /**
     * Subclasses implement this to notify the listener.
     */
    protected abstract void notifyListener(EventListener l);
}
