/**
  * Load image with current class loader.
  *
  * @param fileName image resource file name
  * @return image
  */
 public static Image loadSwtImage(String fileName) {
   Image result = null;
   try {
     ClassLoader classloader = DavGatewayTray.class.getClassLoader();
     URL imageUrl = classloader.getResource(fileName);
     result = new Image(display, imageUrl.openStream());
   } catch (IOException e) {
     DavGatewayTray.warn(new BundleMessage("LOG_UNABLE_TO_LOAD_IMAGE"), e);
   }
   return result;
 }
  /** Create tray icon and register frame listeners. */
  public void init() {
    // register error handler to avoid application crash on concurrent X access from SWT and AWT
    try {
      OS.gdk_error_trap_push();
    } catch (NoClassDefFoundError e) {
      // ignore
    }
    final String systemLookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
    try {
      // workaround for bug when SWT and AWT both try to access Gtk
      if (systemLookAndFeelClassName.indexOf("gtk") >= 0) {
        System.setProperty("swing.defaultlaf", UIManager.getCrossPlatformLookAndFeelClassName());
      } else {
        System.setProperty("swing.defaultlaf", systemLookAndFeelClassName);
      }
    } catch (Exception e) {
      DavGatewayTray.warn(new BundleMessage("LOG_UNABLE_TO_SET_LOOK_AND_FEEL"));
    }

    new Thread("SWT") {
      @Override
      public void run() {
        try {
          display = new Display();
          shell = new Shell(display);

          final Tray tray = display.getSystemTray();
          if (tray != null) {

            trayItem = new TrayItem(tray, SWT.NONE);
            trayItem.setToolTipText(BundleMessage.format("UI_DAVMAIL_GATEWAY"));

            awtImage = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_PNG);
            image = loadSwtImage(AwtGatewayTray.TRAY_PNG);
            image2 = loadSwtImage(AwtGatewayTray.TRAY_ACTIVE_PNG);
            inactiveImage = loadSwtImage(AwtGatewayTray.TRAY_INACTIVE_PNG);

            trayItem.setImage(image);

            // create a popup menu
            final Menu popup = new Menu(shell, SWT.POP_UP);
            trayItem.addListener(
                SWT.MenuDetect,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            popup.setVisible(true);
                          }
                        });
                  }
                });

            MenuItem aboutItem = new MenuItem(popup, SWT.PUSH);
            aboutItem.setText(BundleMessage.format("UI_ABOUT"));
            aboutItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            if (aboutFrame == null) {
                              aboutFrame = new AboutFrame();
                            }
                            aboutFrame.update();
                            aboutFrame.setVisible(true);
                            aboutFrame.toFront();
                            aboutFrame.requestFocus();
                          }
                        });
                  }
                });

            trayItem.addListener(
                SWT.DefaultSelection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            // create frame on first call
                            if (settingsFrame == null) {
                              settingsFrame = new SettingsFrame();
                            }
                            settingsFrame.reload();
                            settingsFrame.setVisible(true);
                            settingsFrame.toFront();
                            settingsFrame.requestFocus();
                          }
                        });
                  }
                });

            // create menu item for the default action
            MenuItem defaultItem = new MenuItem(popup, SWT.PUSH);
            defaultItem.setText(BundleMessage.format("UI_SETTINGS"));
            defaultItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {
                            // create frame on first call
                            if (settingsFrame == null) {
                              settingsFrame = new SettingsFrame();
                            }
                            settingsFrame.reload();
                            settingsFrame.setVisible(true);
                            settingsFrame.toFront();
                            settingsFrame.requestFocus();
                          }
                        });
                  }
                });

            MenuItem logItem = new MenuItem(popup, SWT.PUSH);
            logItem.setText(BundleMessage.format("UI_SHOW_LOGS"));
            logItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    display.asyncExec(
                        new Runnable() {
                          public void run() {

                            Logger rootLogger = Logger.getRootLogger();
                            LF5Appender lf5Appender =
                                (LF5Appender) rootLogger.getAppender("LF5Appender");
                            if (lf5Appender == null) {
                              logBrokerMonitor =
                                  new LogBrokerMonitor(LogLevel.getLog4JLevels()) {
                                    @Override
                                    protected void closeAfterConfirm() {
                                      hide();
                                    }
                                  };
                              lf5Appender = new LF5Appender(logBrokerMonitor);
                              lf5Appender.setName("LF5Appender");
                              rootLogger.addAppender(lf5Appender);
                            }
                            lf5Appender.getLogBrokerMonitor().show();
                          }
                        });
                  }
                });

            MenuItem exitItem = new MenuItem(popup, SWT.PUSH);
            exitItem.setText(BundleMessage.format("UI_EXIT"));
            exitItem.addListener(
                SWT.Selection,
                new Listener() {
                  public void handleEvent(Event event) {
                    DavGateway.stop();
                  }
                });

            // display settings frame on first start
            if (Settings.isFirstStart()) {
              // create frame on first call
              if (settingsFrame == null) {
                settingsFrame = new SettingsFrame();
              }
              settingsFrame.setVisible(true);
              settingsFrame.toFront();
              settingsFrame.requestFocus();
            }

            synchronized (mainThread) {
              // ready
              isReady = true;
              mainThread.notifyAll();
            }

            while (!shell.isDisposed()) {
              if (!display.readAndDispatch()) {
                display.sleep();
              }
            }

            dispose();
          }
        } catch (Exception exc) {
          DavGatewayTray.error(exc);
        }
        // make sure we do exit
        System.exit(0);
      }
    }.start();
    while (true) {
      // wait for SWT init
      try {
        synchronized (mainThread) {
          if (isReady) {
            break;
          }
          mainThread.wait(1000);
        }
      } catch (InterruptedException e) {
        DavGatewayTray.error(new BundleMessage("LOG_ERROR_WAITING_FOR_SWT_INIT"), e);
      }
    }
  }
  protected void createAndShowGUI() {
    System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());

    image = DavGatewayTray.loadImage("tray.png");
    image2 = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_ACTIVE_PNG);
    inactiveImage = DavGatewayTray.loadImage(AwtGatewayTray.TRAY_INACTIVE_PNG);

    mainFrame = new JFrame();
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.setTitle(BundleMessage.format("UI_DAVMAIL_GATEWAY"));
    mainFrame.setIconImage(image);

    JPanel errorPanel = new JPanel();
    errorPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_MESSAGE")));
    errorPanel.setLayout(new BoxLayout(errorPanel, BoxLayout.X_AXIS));
    errorArea = new JTextPane();
    errorArea.setEditable(false);
    errorArea.setBackground(mainFrame.getBackground());
    errorLabel = new JLabel();
    errorPanel.add(errorLabel);
    errorPanel.add(errorArea);

    JPanel messagePanel = new JPanel();
    messagePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_LAST_LOG")));
    messagePanel.setLayout(new BoxLayout(messagePanel, BoxLayout.X_AXIS));

    messageArea = new JTextPane();
    messageArea.setText(BundleMessage.format("LOG_STARTING_DAVMAIL"));
    messageArea.setEditable(false);
    messageArea.setBackground(mainFrame.getBackground());
    messagePanel.add(messageArea);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
    mainPanel.add(errorPanel);
    mainPanel.add(messagePanel);
    mainFrame.add(mainPanel);

    aboutFrame = new AboutFrame();
    settingsFrame = new SettingsFrame();
    buildMenu();

    mainFrame.setMinimumSize(new Dimension(400, 180));
    mainFrame.pack();
    // workaround MacOSX
    if (mainFrame.getSize().width < 400 || mainFrame.getSize().height < 180) {
      mainFrame.setSize(
          Math.max(mainFrame.getSize().width, 400), Math.max(mainFrame.getSize().height, 180));
    }
    // center frame
    mainFrame.setLocation(
        mainFrame.getToolkit().getScreenSize().width / 2 - mainFrame.getSize().width / 2,
        mainFrame.getToolkit().getScreenSize().height / 2 - mainFrame.getSize().height / 2);
    mainFrame.setVisible(true);

    // display settings frame on first start
    if (Settings.isFirstStart()) {
      settingsFrame.setVisible(true);
      settingsFrame.toFront();
      settingsFrame.requestFocus();
    }
  }