package lukazitnik.jshint.annotations;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import lukazitnik.jshint.JSHintError;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.modules.editor.NbEditorDocument;

public class EditorRegistryListener implements PropertyChangeListener {

    Map<NbEditorDocument, JSHintDocumentListener> history = new HashMap<>();

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        JTextComponent jtc = EditorRegistry.lastFocusedComponent();

        if (jtc == null) {
            return;
        }

        final NbEditorDocument focusedDocument = (NbEditorDocument) jtc.getDocument();
        String mimeType = (String) focusedDocument.getProperty(NbEditorDocument.MIME_TYPE_PROP);

        if (!mimeType.equals("text/javascript")) {
            return;
        }

        switch (evt.getPropertyName()) {
            case EditorRegistry.FOCUS_GAINED_PROPERTY:
                if (!history.keySet().contains(focusedDocument)) {

                    // The file has just been opened, so ...
                    addDocumentListenerAndAnnotations(focusedDocument);
                }
                break;
            case EditorRegistry.COMPONENT_REMOVED_PROPERTY:

                // Clean up history
                List<NbEditorDocument> openDocuments = getOpenDocuments();
                Iterator<NbEditorDocument> it = history.keySet().iterator();
                while (it.hasNext()) {
                    NbEditorDocument historicalDocument = it.next();
                    if (!openDocuments.contains(historicalDocument)) {

                        // Don't bother calling removeDocumentListenerAndAnnotations()
                        it.remove();
                    }
                }
                break;
        }
    }

    public void updateOpenDocuments() {
        List<NbEditorDocument> openDocuments = getOpenDocuments();
        for (NbEditorDocument d : openDocuments) {
            addDocumentListenerAndAnnotations(d);
        }
    }

    public void updateHistoryDocuments() {
        Iterator<NbEditorDocument> it = history.keySet().iterator();
        while (it.hasNext()) {
            NbEditorDocument d = it.next();
            removeDocumentListenerAndAnnotations(d);
            it.remove();
        }
    }

    private List<NbEditorDocument> getOpenDocuments() {
        List<NbEditorDocument> openDocuments = new ArrayList<>();
        for (JTextComponent component : EditorRegistry.componentList()) {
            openDocuments.add((NbEditorDocument) component.getDocument());
        }
        return openDocuments;
    }

    private void addDocumentListenerAndAnnotations(NbEditorDocument d) {
        JSHintDocumentListener dl = new JSHintDocumentListener();
        dl.updateAnnotations(d);
        d.addDocumentListener(dl);
        history.put(d, dl);
    }

    private void removeDocumentListenerAndAnnotations(NbEditorDocument d) {
        SwingUtilities.invokeLater(new Annotator(d, new LinkedList<JSHintError>()));
        d.removeDocumentListener(history.get(d));
    }

}

@@ -1589,32 +1589,34 @@
 uments = getOpen
+JS
 Documents();%0A   
@@ -1604,32 +1604,32 @@
 nJSDocuments();%0A
-
                 
@@ -2159,32 +2159,34 @@
 uments = getOpen
+JS
 Documents();%0A   
@@ -2620,24 +2620,26 @@
 ent%3E getOpen
+JS
 Documents() 
@@ -2792,28 +2792,32 @@
         
-open
+NbEditor
 Document
 s.add((N
@@ -2812,14 +2812,13 @@
 ment
-s.add(
+ d = 
 (NbE
@@ -2855,18 +2855,210 @@
 cument()
-)
 ;
+%0A            String mimeType = (String) d.getProperty(NbEditorDocument.MIME_TYPE_PROP);%0A            if (mimeType.equals(%22text/javascript%22)) %7B%0A                openDocuments.add(d);%0A            %7D
 %0A       

fix issue #1