package floobits.utilities;

import com.intellij.notification.*;
import com.intellij.notification.impl.NotificationsConfigurationImpl;
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 String ID = "Floobits notifications";
    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));
    }
    private static void ensureRegistered() {
        NotificationsConfiguration.getNotificationsConfiguration().register(ID, NotificationDisplayType.BALLOON, false);
    }
    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 {
                            ensureRegistered();
                            final Notification statusMessage = new Notification("Floobits", "Floobits", message, notificationType);
                            Notifications.Bus.notify(statusMessage, project);
                            boolean sticky = NotificationsConfigurationImpl.getSettings(ID).getDisplayType() == NotificationDisplayType.STICKY_BALLOON;
                            if (!sticky) {
                                java.util.Timer timer = new java.util.Timer();
                                timer.schedule(new java.util.TimerTask() {
                                    @Override
                                    public void run() {
                                        statusMessage.expire();
                                    }
                                }, 3000);
                            }
                        } 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);
                    }
                });
            }
        });
    }
}

@@ -128,16 +128,76 @@
 onImpl;%0A
+import com.intellij.notification.impl.ui.NotificationsUtil;%0A
 import c
@@ -240,32 +240,32 @@
 icationManager;%0A
-
 import com.intel
@@ -482,16 +482,205 @@
 swing.*;
+%0Aimport javax.swing.event.HyperlinkEvent;%0Aimport javax.swing.event.HyperlinkListener;%0Aimport java.awt.*;%0Aimport java.io.IOException;%0Aimport java.net.URI;%0Aimport java.net.URISyntaxException;
 %0A%0A/**%0A *
@@ -2391,108 +2391,1231 @@
     
-final Notification statusMessage = new Notification(%22Floobits%22, %22Floobits%22, message, notificationTyp
+NotificationListener listener = new NotificationListener() %7B%0A                                @Override%0A                                public void hyperlinkUpdate(Notification notification, HyperlinkEvent event) %7B%0A                                        if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) %7B%0A                                            try %7B%0A                                                URI uri = event.getURL().toURI();%0A                                                Desktop.getDesktop().browse(uri);%0A                                            %7D catch (IOException error) %7B%0A                                                Flog.warn(error);%0A                                            %7D catch (URISyntaxException error) %7B%0A                                                Flog.warn(error);%0A                                            %7D%0A                                        %7D%0A                                %7D%0A                            %7D;%0A                            final Notification statusMessage = new Notification(%22Floobits%22, %22Floobits%22, message,%0A                                    notificationType, listener);%0A                            NotificationsUtil.wrapListener(statusMessag
 e);%0A

Support links in status messages.