package lukazitnik.jshint;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.editor.Utilities;
import org.netbeans.modules.editor.NbEditorDocument;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.openide.modules.ModuleInstall;
import org.openide.text.Line;

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        PropertyChangeListener pcl = new PropertyChangeListener() {

            class MyDocumentListener implements DocumentListener {

                private final LinkedList<JSHintAnnotation> attachedAnnotations = new LinkedList<>();

                @Override
                public void insertUpdate(DocumentEvent de) {
                    handleUpdate(de);
                }

                @Override
                public void removeUpdate(DocumentEvent de) {
                    handleUpdate(de);
                }

                @Override
                public void changedUpdate(DocumentEvent de) {
                    handleUpdate(de);
                }

                private void handleUpdate(DocumentEvent de) {
                    NbEditorDocument d = (NbEditorDocument) de.getDocument();
                    detachAnnotations(d);
                    attachAnnotations(d);
                }

                private void detachAnnotations(NbEditorDocument d) {
                    for (JSHintAnnotation annotation : attachedAnnotations) {
                        annotation.detach();
                    }
                }

                private void attachAnnotations(NbEditorDocument d) {
                    JSHint jshint = JSHint.instance;

                    for (JSHintError error : jshint.lint(d)) {

                        // Line indexes start from 0, while line numbers start from 1
                        Integer offset = Utilities.getRowStartFromLineOffset(d, error.getLine() - 1);

                        Line line = NbEditorUtilities.getLine(d, offset, false);
                        JSHintAnnotation annotation = new JSHintAnnotation(error);

                        annotation.attach(line);
                        attachedAnnotations.add(annotation);
                    }
                }
            }

            HashMap<NbEditorDocument, MyDocumentListener> history = new HashMap<>();

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

                if (jtc == null) {
                    return;
                }

                NbEditorDocument focusedDocument = (NbEditorDocument) jtc.getDocument();
                MyDocumentListener dl;

                switch (evt.getPropertyName()) {
                    case EditorRegistry.FOCUS_GAINED_PROPERTY:
                        dl = new MyDocumentListener();
                        if (!history.containsKey(focusedDocument)) {
                            history.put(focusedDocument, dl);
                            dl.attachAnnotations(focusedDocument);
                        }
                        focusedDocument.addDocumentListener(dl);
                        break;
                    case EditorRegistry.FOCUS_LOST_PROPERTY:
                        dl = history.get(focusedDocument);
                        focusedDocument.removeDocumentListener(dl);
                        break;
                    case EditorRegistry.COMPONENT_REMOVED_PROPERTY:
                        List<NbEditorDocument> openedDocuments = new ArrayList<>();
                        for (JTextComponent component : EditorRegistry.componentList()) {
                            openedDocuments.add((NbEditorDocument) component.getDocument());
                        }
                        for (NbEditorDocument historicalDocuments : history.keySet()) {
                            if (!openedDocuments.contains(historicalDocuments)) {
                                dl = history.remove(historicalDocuments);
                                dl.detachAnnotations(historicalDocuments);
                                historicalDocuments.removeDocumentListener(dl);
                            }
                        }
                        break;
                }
            }
        };

        EditorRegistry.addPropertyChangeListener(pcl);
    }

}

@@ -774,33 +774,30 @@
   class 
-MyDocumentListene
+JSHintAnnotato
 r implem
@@ -2576,33 +2576,30 @@
 cument, 
-MyDocumentListene
+JSHintAnnotato
 r%3E histo
@@ -2949,32 +2949,33 @@
 .getDocument();%0A
+%0A
                 
@@ -2978,29 +2978,193 @@
     
-MyDocumentListener dl
+if (!NbEditorUtilities.getFileObject(focusedDocument).getMIMEType().equals(%22text/javascript%22)) %7B%0A                    return;%0A                %7D%0A%0A                JSHintAnnotator annotator
 ;%0A%0A 
@@ -3302,34 +3302,38 @@
     
-dl = new MyDocumentListene
+annotator = new JSHintAnnotato
 r();
@@ -3459,18 +3459,25 @@
 cument, 
-dl
+annotator
 );%0A     
@@ -3499,18 +3499,25 @@
         
-dl
+annotator
 .attachA
@@ -3623,34 +3623,41 @@
 ocumentListener(
-dl
+annotator
 );%0A             
@@ -3751,34 +3751,41 @@
                 
-dl
+annotator
  = history.get(f
@@ -3856,34 +3856,41 @@
 ocumentListener(
-dl
+annotator
 );%0A             
@@ -4470,18 +4470,25 @@
         
-dl
+annotator
  = histo
@@ -4551,18 +4551,25 @@
         
-dl
+annotator
 .detachA
@@ -4676,18 +4676,25 @@
 istener(
-dl
+annotator
 );%0A     

check mime type