package org.helioviewer.jhv.plugins.swek.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.helioviewer.jhv.plugins.swek.config.SWEKEventType;

/**
 * This model manages all the SWEKEventTypeTreeModels and delegate events. This
 * was primarily created to handle the selection in the distributed event trees.
 * 
 * The SWEKTreeModel is the central point of access.
 * 
 * @author Bram Bourgoignie (Bram.Bourgoignie@oma.be)
 * 
 */
public class SWEKTreeModel {
    /** The singleton instance of the SWEKTreeModel */
    private static SWEKTreeModel singletonInstance;

    /** Holder for the SWEK event type tree models */
    private final List<SWEKTreeModelListener> listeners;

    /**  */
    private final Set<SWEKEventType> loadingTypes;

    private SWEKTreeModel() {
        listeners = new ArrayList<SWEKTreeModelListener>();
        loadingTypes = new HashSet<SWEKEventType>();
    }

    public static SWEKTreeModel getSingletonInstance() {
        if (singletonInstance == null) {
            singletonInstance = new SWEKTreeModel();
        }
        return singletonInstance;
    }

    /**
     * Adds a new SWEK tree model listener.
     * 
     * @param swekTreeModelListener
     *            the listener to add
     */
    public void addSWEKTreeModelListener(SWEKTreeModelListener swekTreeModelListener) {
        listeners.add(swekTreeModelListener);
    }

    /**
     * removes a SWEK tree model listener.
     * 
     * @param swekTreeModelListener
     *            the listener to remove
     */
    public void removeSWEKTreeModelListener(SWEKTreeModelListener swekTreeModelListener) {
        listeners.remove(swekTreeModelListener);
    }

    /**
     * Inform the SWEK tree model about a subtree that was collapsed.
     */
    public void subTreeCollapsed() {
        fireTreeExpansionChanged();
    }

    /**
     * Inform the SWEK tree model about a subtree that was expanded.
     */
    public void subTreeExpanded() {
        fireTreeExpansionChanged();
    }

    /**
     * Sets the event type to start loading.
     * 
     * @param eventType
     *            the event type that started loading
     */
    public void setStartLoading(SWEKEventType eventType) {
        loadingTypes.add(eventType);
        fireEventTypeStartLoading(eventType);
    }

    /**
     * Sets the event type to stop loading.
     * 
     * @param eventType
     *            the event type that stopped loading
     */
    public void setStopLoading(SWEKEventType eventType) {
        loadingTypes.remove(eventType);
        fireEventTypeStopLoading(eventType);
    }

    /**
     * Inform the SWEK tree model listeners about a change of the tree.
     */
    private void fireTreeExpansionChanged() {
        for (SWEKTreeModelListener l : listeners) {
            l.expansionChanged();
        }
    }

    /**
     * Inform the tree model listeners an event type started loading.
     * 
     * @param eventType
     *            the event type that started loading
     */
    private void fireEventTypeStartLoading(SWEKEventType eventType) {
        for (SWEKTreeModelListener l : listeners) {
            l.startedDownloadingEventType(eventType);
        }
    }

    /**
     * Inform the tree model listeners an event type stopped loading.
     * 
     * @param eventType
     *            the event type that stopped loading
     */
    private void fireEventTypeStopLoading(SWEKEventType eventType) {
        for (SWEKTreeModelListener l : listeners) {
            l.stoppedDownloadingEventType(eventType);
        }

    }
}

@@ -91,19 +91,19 @@
 til.Hash
-Set
+Map
 ;%0Aimport
@@ -136,19 +136,19 @@
 va.util.
-Set
+Map
 ;%0A%0Aimpor
@@ -772,19 +772,19 @@
 e final 
-Set
+Map
 %3CSWEKEve
@@ -789,16 +789,25 @@
 ventType
+, Integer
 %3E loadin
@@ -936,19 +936,19 @@
 new Hash
-Set
+Map
 %3CSWEKEve
@@ -953,16 +953,25 @@
 ventType
+, Integer
 %3E();%0A   
@@ -2298,24 +2298,203 @@
     
-loadingTypes.add
+synchronized (loadingTypes) %7B%0A            if (loadingTypes.containsKey(eventType)) %7B%0A                Integer i = loadingTypes.get(eventType);%0A                i++;%0A                loadingTypes.put
 (eve
@@ -2491,35 +2491,115 @@
 es.put(eventType
+, i
 );%0A
+            %7D else %7B%0A                loadingTypes.put(eventType, 0);%0A        
         fireEven
@@ -2620,32 +2620,56 @@
 ing(eventType);%0A
+            %7D%0A        %7D%0A
     %7D%0A%0A    /**%0A 
@@ -2855,32 +2855,245 @@
 pe eventType) %7B%0A
+        synchronized (loadingTypes) %7B%0A            if (loadingTypes.containsKey(eventType)) %7B%0A                Integer i = loadingTypes.get(eventType);%0A                i--;%0A                if (i == 0) %7B%0A            
         loadingT
@@ -3108,32 +3108,44 @@
 ove(eventType);%0A
+            
         fireEven
@@ -3169,24 +3169,217 @@
 eventType);%0A
+                %7D else %7B%0A                    loadingTypes.put(eventType, i);%0A                %7D%0A            %7D else %7B%0A                fireEventTypeStopLoading(eventType);%0A            %7D%0A        %7D%0A
     %7D%0A%0A    /

Fix the loading indication