package org.dynmap;

import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Listener class for dynmap API lifecycle - addresses issues with startup order, restarts, etc
 * Listeners should subclass, provide needed methods, and register listener using 
 * DynmapCommonAPIListener.register() method and unregister using 
 * DynmapCommonAPIListener.unregister()
 */
public abstract class DynmapCommonAPIListener {
    /**
     * Called when API becomes enabled, or during call to register listener if API is already enabled
     * 
     * @param api - API interface (note: may be platform specific subclass, such as bukkit-specific API)
     */
    public abstract void apiEnabled(DynmapCommonAPI api);
    /**
     * Called when API becomes disabled/obsolete
     * 
     * @param api - API interface being disabled (not usable immediately after call completes)
     */
    public void apiDisabled(DynmapCommonAPI api) {
    }
    /**
     * Called when API listener added before API ready (internal use)
     */
    public void apiListenerAdded() {
    }
    
    private static DynmapCommonAPI dynmapapi = null;
    
    private static CopyOnWriteArrayList<DynmapCommonAPIListener> listeners = new CopyOnWriteArrayList<DynmapCommonAPIListener>();
    /**
     * Register listener instance
     * 
     * @param listener - listener to register
     */
    public static void register(DynmapCommonAPIListener listener) {
        listeners.add(listener);
        if(dynmapapi != null) {
            listener.apiEnabled(dynmapapi);
        }
        else {
            for (DynmapCommonAPIListener l : listeners) {
                l.apiListenerAdded();
            }
        }
    }
    /**
     * Unregister listener instance
     * 
     * @param listener - listener to unregister
     */
    public static void unregister(DynmapCommonAPIListener listener) {
        listeners.remove(listener);
    }
    // Internal call - MODS/PLUGINS MUST NOT USE
    public static void apiInitialized(DynmapCommonAPI api) {
        if(dynmapapi != null) {
            apiTerminated();
        }
        dynmapapi = api;
        if(dynmapapi != null) {
            for (DynmapCommonAPIListener l : listeners) {
                l.apiEnabled(api);
            }
        }
    }
    public static void apiTerminated() {
        if(dynmapapi != null) {
            for (DynmapCommonAPIListener l : listeners) {
                l.apiDisabled(dynmapapi);
            }
            dynmapapi = null;
        }
    }
}

@@ -1046,24 +1046,318 @@
 d() %7B%0A    %7D%0A
+    /**%0A     * Callback when web chat event is being processed:%0A     * @param source%0A     * @param name%0A     * @param message%0A     * @return true if not cancelled and not processed%0A     */%0A    public boolean webChatEvent(String source, String name, String message) %7B%0A        return true;%0A    %7D%0A
     %0A    pri
@@ -2546,24 +2546,73 @@
     %7D%0A    %7D%0A
+    // Internal call - MODS/PLUGINS MUST NOT USE%0A
     public s
@@ -2832,10 +2832,439 @@
 %7D%0A    %7D%0A
+    // Internal call - MODS/PLUGINS MUST NOT USE%0A    public static boolean fireWebChatEvent(String source, String name, String message) %7B%0A        boolean noCancel = true;%0A        if(dynmapapi != null) %7B%0A            for (DynmapCommonAPIListener l : listeners) %7B%0A                noCancel = l.webChatEvent(source, name, message) && noCancel;%0A            %7D%0A            dynmapapi = null;%0A        %7D%0A        return noCancel;%0A    %7D%0A    %0A
 %7D%0A

Add WebChatEvent handling