// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/**
 *******************************************************************************
 * 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);
}
