// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.BusyObject;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class FrameStateManagerImpl extends FrameStateManager {
  private final List<FrameStateListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();

  private final BusyObject.Impl myActive;

  public FrameStateManagerImpl() {
    myActive = new BusyObject.Impl() {
      @Override
      public boolean isReady() {
        return ApplicationManager.getApplication().isActive();
      }
    };

    ApplicationManager.getApplication().getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, new ApplicationActivationListener() {
      @Override
      public void applicationActivated(@NotNull IdeFrame ideFrame) {
        System.setProperty("com.jetbrains.suppressWindowRaise", "false");
        myActive.onReady();
        fireActivationEvent();
      }

      @Override
      public void applicationDeactivated(@NotNull IdeFrame ideFrame) {
        System.setProperty("com.jetbrains.suppressWindowRaise", "true");
        if (!ApplicationManager.getApplication().isDisposed()) {
          fireDeactivationEvent();
        }
      }
    });
  }

  @Override
  public ActionCallback getApplicationActive() {
    return myActive.getReady(this);
  }

  private void fireDeactivationEvent() {
    for (FrameStateListener listener : myListeners) {
      listener.onFrameDeactivated();
    }
  }

  private void fireActivationEvent() {
    for (FrameStateListener listener : myListeners) {
      listener.onFrameActivated();
    }
  }

  @Override
  public void addListener(@NotNull FrameStateListener listener) {
    myListeners.add(listener);
  }

  @Override
  public void addListener(@NotNull final FrameStateListener listener, @Nullable Disposable disposable) {
    if (disposable != null) {
      ApplicationManager.getApplication().getMessageBus().connect(disposable).subscribe(FrameStateListener.TOPIC, listener);
    }
    else {
      myListeners.add(listener);
    }
  }

  @Override
  public void removeListener(@NotNull FrameStateListener listener) {
    myListeners.remove(listener);
  }
}

@@ -830,58 +830,8 @@
 mpl 
-myActive;%0A%0A  public FrameStateManagerImpl() %7B%0A    
 myAc
@@ -857,26 +857,24 @@
 ct.Impl() %7B%0A
-  
     @Overrid
@@ -875,26 +875,24 @@
 verride%0A    
-  
 public boole
@@ -902,26 +902,24 @@
 isReady() %7B%0A
-  
       return
@@ -975,19 +975,50 @@
     
+%7D%0A
   %7D
+;%0A
 %0A  
-  %7D;%0A
+public FrameStateManagerImpl() %7B
 %0A   
@@ -1079,16 +1079,23 @@
 onnect()
+%0A      
 .subscri
@@ -1168,24 +1168,175 @@
 istener() %7B%0A
+        private final FrameStateListener myPublisher = ApplicationManager.getApplication().getMessageBus().syncPublisher(FrameStateListener.TOPIC);%0A%0A  
       @Overr
@@ -1337,32 +1337,34 @@
 @Override%0A      
+ 
+ 
 public void appl
@@ -1402,32 +1402,34 @@
 ame ideFrame) %7B%0A
+  
         System.s
@@ -1494,16 +1494,18 @@
         
+  
 myActive
@@ -1524,35 +1524,147 @@
         
+ 
-fireActivationEvent
+ myPublisher.onFrameActivated();%0A          for (FrameStateListener listener : myListeners) %7B%0A            listener.onFrameActivated
 ();%0A    
@@ -1665,19 +1665,35 @@
 ;%0A      
+ 
-%7D%0A%0A
+   %7D%0A        %7D%0A%0A  
       @O
@@ -1696,24 +1696,26 @@
   @Override%0A
+  
       public
@@ -1773,32 +1773,34 @@
 rame) %7B%0A        
+  
 System.setProper
@@ -1860,13 +1860,14 @@
     
+  
 if (
-!
 Appl
@@ -1928,51 +1928,30 @@
     
+ 
-fireDeactivationEvent()
+ return
 ;%0A    
-    %7D%0A
       %7D%0A
     
@@ -1950,164 +1950,59 @@
   %7D%0A
+%0A
     
-%7D);%0A  %7D%0A%0A  @Override%0A  public ActionCallback getApplicationActive() %7B%0A    return myActive.getReady(this);%0A  %7D%0A%0A  private void fireDeactivationEvent() %7B%0A
+      myPublisher.onFrameDeactivated();%0A      
     
@@ -2043,32 +2043,38 @@
  myListeners) %7B%0A
+      
       listener.o
@@ -2090,32 +2090,38 @@
 ctivated();%0A
+      
     %7D%0A  
 %7D%0A%0A  private
@@ -2112,144 +2112,127 @@
 %7D%0A  
-%7D%0A%0A  private void fireActivationEvent() %7B%0A    for (FrameStateListener listener : myListeners) %7B%0A      listener.onFrameActivated();%0A    %7D
+      %7D%0A      %7D);%0A  %7D%0A%0A  @Override%0A  public ActionCallback getApplicationActive() %7B%0A    return myActive.getReady(this);
 %0A  %7D
@@ -2487,9 +2487,9 @@
 ble 
-!
+=
 = nu
@@ -2490,24 +2490,74 @@
  == null) %7B%0A
+      myListeners.add(listener);%0A    %7D%0A    else %7B%0A
       Applic
@@ -2679,58 +2679,8 @@
   %7D%0A
-    else %7B%0A      myListeners.add(listener);%0A    %7D%0A
   %7D%0A

add FrameStateListener message bus topic (part 2)