package floobits.utilities;

import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.JBColor;

import javax.swing.*;

/**
 * Do not add a Log.error statement to this class. Error statements are user visible exceptions. Use
 * Utitls.errorMessage to notify the user of a problem and Flog.warn to log an exception in a way that doesn't
 * disturb the user.
 */
public class Flog {
    public static Logger Log = Logger.getInstance(Flog.class);
    private static String maybeFormat(String s, Object... args) {
        if (args.length == 0) {
            return s;
        } else {
            return String.format(s, args);
        }
    }
    public static void log (String s, Object... args) {
        Log.info(maybeFormat(s, args));
    }
    public static void debug (String s, Object... args) {
        Log.debug(maybeFormat(s, args));
    }
    public static void warn (Throwable e) {
        Log.warn(e);
    }
    public static void warn (String s, Object... args) {
        Log.warn(maybeFormat(s, args));
    }
    public static void info (String s, Object... args) {
        Log.info(maybeFormat(s, args));
    }

    public static void statusMessage(final String message, final NotificationType notificationType, final Project project) {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
            @Override
            public void run() {
                ApplicationManager.getApplication().runWriteAction(new Runnable() {
                    public void run() {
                        try {
                            Notifications.Bus.notify(new Notification("Floobits", "Floobits", message, notificationType), project);
                        } catch (Throwable e) {
                            Flog.warn(e);
                            Flog.log(message);
                        }
                    }
                });
            }
        });
    }

    public static void statusMessage(String message, Project project) {
        statusMessage(message, NotificationType.INFORMATION, project);
    }

    public static void errorMessage(String message, Project project) {
        statusMessage(message, NotificationType.ERROR, project);
    }

    public static void flashMessage(final String message, final Project project) {
        ApplicationManager.getApplication().invokeLater(new Runnable() {
            @Override
            public void run() {
                ApplicationManager.getApplication().runWriteAction(new Runnable() {
                    public void run() {
                        StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
                        if (statusBar == null) {
                            return;
                        }
                        JLabel jLabel = new JLabel(message);
                        statusBar.fireNotificationPopup(jLabel, JBColor.WHITE);
                    }
                });
            }
        });
    }
}

@@ -55,28 +55,17 @@
 ication.
-Notification
+*
 ;%0Aimport
@@ -95,47 +95,14 @@
 ion.
-NotificationType;%0Aimport com.intellij.n
+impl.N
 otif
@@ -112,22 +112,26 @@
 tion
-.Notific
+sConfigur
 ation
-s
+Impl
 ;%0Aim
@@ -280,16 +280,168 @@
 roject;%0A
+import com.intellij.openapi.ui.popup.Balloon;%0Aimport com.intellij.openapi.ui.popup.BalloonBuilder;%0Aimport com.intellij.openapi.ui.popup.JBPopupFactory;%0A
 import c
@@ -556,29 +556,93 @@
 or;%0A
-%0Aimport javax.swing.*
+import com.intellij.ui.LightColors;%0A%0Aimport javax.swing.*;%0Aimport java.util.TimerTask
 ;%0A%0A/
@@ -901,16 +901,72 @@
  Flog %7B%0A
+    public static String ID = %22Floobits notifications%22;%0A
     publ
@@ -1692,32 +1692,319 @@
 , args));%0A    %7D%0A
+    private static void ensureRegistered() %7B%0A        if (!(NotificationsConfigurationImpl.getNotificationsConfigurationImpl().isRegistered(ID))) %7B%0A            NotificationsConfiguration.getNotificationsConfiguration().register(ID, NotificationDisplayType.BALLOON, false);%0A        %7D%0A    %7D
 %0A    public stat
@@ -2426,111 +2426,862 @@
     
-Notifications.Bus.notify(new Notification(%22Floobits%22, %22Floobits%22, message, notificationType), project);
+ensureRegistered();%0A                            final Notification statusMessage = new Notification(%22Floobits%22, %22Floobits%22, message, notificationType);%0A                            Notifications.Bus.notify(statusMessage, project);%0A                            boolean sticky = NotificationsConfigurationImpl.getSettings(ID).getDisplayType() == NotificationDisplayType.STICKY_BALLOON;%0A                            if (!sticky) %7B%0A                                java.util.Timer timer = new java.util.Timer();%0A                                timer.schedule(new java.util.TimerTask() %7B%0A                                    @Override%0A                                    public void run() %7B%0A                                        statusMessage.expire();%0A                                    %7D%0A                                %7D, 3000);%0A                            %7D
 %0A   

Fix status messages not disappearing.