package com.reason.ide;

import com.intellij.AppTopics;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.util.messages.MessageBusConnection;
import com.reason.hints.InsightManagerImpl;
import com.reason.ide.format.ReformatOnSave;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;

import static com.reason.Platform.getOsPrefix;

public class ORProjectTracker implements ProjectComponent {

    private final Logger m_log = Logger.getInstance("ReasonML");

    private final Project m_project;
    @Nullable
    private MessageBusConnection m_messageBusConnection;
    @Nullable
    private ORVirtualFileListener m_vfListener;
    @Nullable
    private ORFileEditorListener m_fileEditorListener;

    protected ORProjectTracker(Project project) {
        m_project = project;
    }

    @Override
    public void projectOpened() {
        if (SystemInfo.is64Bit) {
            // Try to locate Rincewind
            if (!getOsPrefix().isEmpty()) {
                InsightManagerImpl insightManager = (InsightManagerImpl) InsightManagerImpl.getInstance(m_project);
                File rincewindFile = insightManager.getRincewindFile();
                if (rincewindFile.exists()) {
                    m_log.info("Found " + rincewindFile);
                    insightManager.isDownloaded.set(true);
                } else {
                    insightManager.downloadRincewindIfNeeded();
                }
            }
        } else {
            m_log.info("32Bit system detected, can't use rincewind");
        }

        //EditorFactory.getInstance().getEventMulticaster().addDocumentListener(m_documentListener);

        m_messageBusConnection = m_project.getMessageBus().connect();
        m_fileEditorListener = new ORFileEditorListener(m_project);
        m_messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, m_fileEditorListener);
        m_messageBusConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new ReformatOnSave(m_project));

        m_vfListener = new ORVirtualFileListener(m_project);
        VirtualFileManager.getInstance().addVirtualFileListener(m_vfListener);
    }

    @Override
    public void projectClosed() {
        if (m_vfListener != null) {
            VirtualFileManager.getInstance().removeVirtualFileListener(m_vfListener);
            m_vfListener = null;
        }
        if (m_messageBusConnection != null) {
            m_messageBusConnection.disconnect();
            m_messageBusConnection = null;
        }
    }

    public boolean isOpen(@NotNull VirtualFile file) {
        return m_fileEditorListener != null && m_fileEditorListener.isOpen(file);
    }
}

@@ -49,16 +49,76 @@
 Topics;%0A
+import com.intellij.openapi.application.ApplicationManager;%0A
 import c
@@ -324,16 +324,327 @@
 roject;%0A
+import com.intellij.openapi.projectRoots.Sdk;%0Aimport com.intellij.openapi.projectRoots.SdkModificator;%0Aimport com.intellij.openapi.roots.ModuleRootEvent;%0Aimport com.intellij.openapi.roots.ModuleRootListener;%0Aimport com.intellij.openapi.roots.OrderRootType;%0Aimport com.intellij.openapi.roots.ProjectRootManager;%0A
 import c
@@ -769,32 +769,68 @@
 ualFileManager;%0A
+import com.intellij.util.ArrayUtil;%0A
 import com.intel
@@ -869,16 +869,61 @@
 ection;%0A
+import com.reason.OCamlSourcesOrderRootType;%0A
 import c
@@ -1003,16 +1003,43 @@
 OnSave;%0A
+import gnu.trove.Equality;%0A
 import o
@@ -1134,24 +1134,80 @@
 a.io.File;%0A%0A
+import static com.intellij.ProjectTopics.PROJECT_ROOTS;%0A
 import stati
@@ -2442,171 +2442,1753 @@
     
-//EditorFactory.getInstance().getEventMulticaster().addDocumentListener(m_documentListener);%0A%0A        m_messageBusConnection
+m_messageBusConnection = m_project.getMessageBus().connect();%0A%0A        m_messageBusConnection.subscribe(PROJECT_ROOTS,%0A                new ModuleRootListener() %7B%0A                    @Override%0A                    public void rootsChanged(ModuleRootEvent event) %7B%0A                        ApplicationManager.getApplication().invokeLater(() -%3E %7B%0A                            Sdk projectSdk = ProjectRootManager.getInstance((Project) event.getSource()).getProjectSdk();%0A                            if (projectSdk != null) %7B%0A                                // Hack to get ocaml sources indexed like java sources%0A                                // Find a better way to do it !!%0A%0A                                VirtualFile%5B%5D ocamlSources = projectSdk.getRootProvider().getFiles(OCamlSourcesOrderRootType.getInstance());%0A                                VirtualFile%5B%5D javaSources = projectSdk.getRootProvider().getFiles(OrderRootType.SOURCES);%0A                                boolean equals = ArrayUtil.equals(ocamlSources, javaSources, (Equality%3CVirtualFile%3E) (v1, v2) -%3E v1.getPath().equals(v2.getPath()));%0A%0A                                if (!equals) %7B%0A                                    SdkModificator sdkModificator
  = 
-m_
 project
+Sdk
 .get
-MessageBus().connect();
+SdkModificator();%0A%0A                                    sdkModificator.removeRoots(OrderRootType.SOURCES);%0A                                    for (VirtualFile root : ocamlSources) %7B%0A                                        sdkModificator.addRoot(root, OrderRootType.SOURCES);%0A                                    %7D%0A%0A                                    sdkModificator.commitChanges();%0A                                %7D%0A                            %7D%0A                        %7D);%0A                    %7D%0A                %7D);%0A
 %0A   

index ocaml sources !!!!!!!!!!