/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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 org.apache.batik.dom.events;

import org.apache.batik.dom.util.IntTable;
import org.apache.batik.dom.util.HashTable;

import org.w3c.dom.events.EventListener;

/**
 * Class to manager event listeners for one event type.
 *
 * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
 * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
 * @version $Id$
 */
public class EventListenerList {

    /**
     * Total number of event listners.
     */
    protected int n;

    /**
     * Linked list of entries.
     */
    protected Entry head;

    /**
     * Counts of listener entries with a given namespace URI.
     */
    protected IntTable counts = new IntTable();

    /**
     * Cache of listeners with any namespace URI.
     */
    protected Entry[] listeners;

    /**
     * Caches of listeners with a given namespace URI.
     */
    protected HashTable listenersNS = new HashTable();

    /**
     * Adds a listener.
     */
    public void addListener(String namespaceURI,
                            Object group,
                            EventListener listener) {
        for (Entry e = head; e != null; e = e.next) {
            if ((namespaceURI != null && namespaceURI.equals(e.namespaceURI)
                        || namespaceURI == null && e.namespaceURI == null)
                    && e.listener == listener) {
                // Listener is already in the list, so do nothing.
                return;
            }
        }
        head = new Entry(listener, namespaceURI, group, head);
        counts.inc(namespaceURI);
        n++;
        listeners = null;
        listenersNS.remove(namespaceURI);
    }

    /**
     * Removes a listener.
     */
    public void removeListener(String namespaceURI,
                               EventListener listener) {
        if (head == null) {
            return;
        } else if (head != null
                && (namespaceURI != null && namespaceURI.equals(head.namespaceURI)
                    || namespaceURI == null && head.namespaceURI == null)
                && listener == head.listener) {
            head = head.next;
        } else {
            Entry e;
            Entry prev = head;
            for (e = head.next; e != null; e = e.next) {
                if ((namespaceURI != null && namespaceURI.equals(e.namespaceURI)
                            || namespaceURI == null && e.namespaceURI == null)
                        && e.listener == listener) {
                    prev.next = e.next;
                    break;
                }
                prev = e;
            }
            if (e == null) {
                // Listener not present.
                return;
            }
        }
        counts.dec(namespaceURI);
        n--;
        listeners = null;
        listenersNS.remove(namespaceURI);
    }

    /**
     * Returns an array containing all event listener entries.
     */
    public Entry[] getEventListeners() {
        if (listeners != null) {
            return listeners;
        }
        listeners = new Entry[n];
        int i = 0;
        for (Entry e = head; e != null; e = e.next) {
            listeners[i++] = e;
        }
        return listeners;
    }

    /**
     * Returns an array of EventListeners that match the given namespace URI.
     */
    public Entry[] getEventListeners(String namespaceURI) {
        if (namespaceURI == null) {
            return getEventListeners();
        }
        Entry[] ls = (Entry[]) listenersNS.get(namespaceURI);
        if (ls != null) {
            return ls;
        }
        int count = counts.get(namespaceURI);
        if (count == 0) {
            return null;
        }
        ls = new Entry[count];
        listenersNS.put(namespaceURI, ls);
        int i = 0;
        for (Entry e = head; i < count; e = e.next) {
            if (namespaceURI.equals(e.namespaceURI)) {
                ls[i++] = e;
            }
        }
        return ls;
    }

    /**
     * Returns whether there is an event listener for the given namespace URI.
     */
    public boolean hasEventListener(String namespaceURI) {
        if (namespaceURI == null) {
            return n != 0;
        }
        return counts.get(namespaceURI) != 0;
    }

    /**
     * Returns the number of event listeners stored in this object.
     */
    public int size() {
        return n;
    }

    /**
     * EventListenerTable entry class.
     */
    public class Entry {
        
        /**
         * The event listener.
         */
        protected EventListener listener;

        /**
         * The namespace URI of the event the listener is listening for.
         */
        protected String namespaceURI;

        /**
         * The event group.
         */
        protected Object group;

        /**
         * Flag used by getListeners.
         */
        protected boolean mark;

        /**
         * The next Entry in the list.
         */
        protected Entry next;

        /**
         * Creates a new Entry object.
         */
        public Entry(EventListener listener,
                     String namespaceURI,
                     Object group,
                     Entry next) {
            this.listener = listener;
            this.namespaceURI = namespaceURI;
            this.group = group;
            this.next = next;
        }

        /**
         * Returns the event listener.
         */
        public EventListener getListener() {
            return listener;
        }

        /**
         * Returns the event group.
         */
        public Object getGroup() {
            return group;
        }

        /**
         * Returns the event namespace URI.
         */
        public String getNamespaceURI() {
            return namespaceURI;
        }
    }
}
