// Path: src/main/java/com/fatico/winthing/Application.java
// public class Application {
//     private static final Application app = new Application();
// 
//     private boolean debug = false;
//     private WindowGui gui;
//     private Logger logger;
// 
//     private void parseArgs(String[] args) {
//         for (String arg : args) {
//             if (arg.equals("-debug")) {
//                 debug = true;
//             }
//         }
//     }
// 
//     public static boolean debug() {
//         return app.debug;
//     }
// 
//     public static WindowGui getApp() {
//         return app.gui;
//     }
// 
//     @SuppressFBWarnings("DM_EXIT")
//     public static void quit() {
//         app.logger.info("Application terminated.");
//         System.exit(0);
//     }
// 
//     public static void main(final String[] args) {
//         try {
//             app.parseArgs(args);
// 
//             app.logger = LoggerFactory.getLogger(Application.class);
// 
//             app.gui = new WindowGui();
//             app.gui.initialize();
// 
//             final Injector injector = Guice.createInjector(new ApplicationModule());
//             final Engine engine = injector.getInstance(Engine.class);
//             engine.run();
// 
//         } catch (final Throwable throwable) {
//             app.logger.error("Critical error.", throwable);
//             System.exit(1);
//         }
//     }
// }
// 
// Path: src/main/java/com/fatico/winthing/logging/ConsoleLogger.java
// public class ConsoleLogger extends ConsoleAppender<ILoggingEvent> {
//     private static final int LOG_SIZE = 50;
//     private static final ConcurrentLinkedQueue<String> events = new ConcurrentLinkedQueue<String>();
// 
//     public static String getEvents() {
//         if (events.size() == 0) {
//             return "";
//         }
// 
//         StringJoiner joiner = new StringJoiner("");
//         Iterator<String> iterator = events.iterator();
//         while (iterator.hasNext()) {
//             joiner.add(iterator.next());
//         }
// 
//         String result = joiner.toString();
// 
//         return result;
//     }
// 
//     protected void append(ILoggingEvent event) {
//         super.append(event);
// 
//         if (events.size() > LOG_SIZE) {
//             events.remove();
//         }
// 
//         byte[] data = encoder.encode(event);
//         events.add(new String(data, Charset.forName("UTF-8")));
// 
//         Application.getApp().reload();
//     }
// }


import com.fatico.winthing.Application;
import com.fatico.winthing.logging.ConsoleLogger;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

    public void initialize() throws AWTException {
        setTitle(appName + " " + appVersion);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
        setVisible(false);
        setLayout(new BorderLayout());
        setResizable(false);
        setPreferredSize(new Dimension(800, 530));
        setSize(getPreferredSize());

        JTextArea logs = new JTextArea();
        logs.setEditable(false);
        logs.setRows(25);
        components.put(Gui.TEXTAREA.key, logs);

        JScrollPane scrolls = new JScrollPane(logs);
        scrolls.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        getContentPane().add(scrolls, BorderLayout.NORTH);
        components.put(Gui.SCROLLBAR.key, scrolls);

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(panel, BorderLayout.SOUTH);

        JButton btnClose = new JButton("Close");
        btnClose.setToolTipText("Close this window");
        btnClose.addMouseListener(new MouseEventListener(this, Actions.CLOSE));
        panel.add(btnClose);

        JButton btnQuit = new JButton("Quit");
        btnQuit.setToolTipText("Stop and terminate application");
// Path: src/main/java/com/fatico/winthing/Application.java
// public class Application {
//     private static final Application app = new Application();
// 
//     private boolean debug = false;
//     private WindowGui gui;
//     private Logger logger;
// 
//     private void parseArgs(String[] args) {
//         for (String arg : args) {
//             if (arg.equals("-debug")) {
//                 debug = true;
//             }
//         }
//     }
// 
//     public static boolean debug() {
//         return app.debug;
//     }
// 
//     public static WindowGui getApp() {
//         return app.gui;
//     }
// 
//     @SuppressFBWarnings("DM_EXIT")
//     public static void quit() {
//         app.logger.info("Application terminated.");
//         System.exit(0);
//     }
// 
//     public static void main(final String[] args) {
//         try {
//             app.parseArgs(args);
// 
//             app.logger = LoggerFactory.getLogger(Application.class);
// 
//             app.gui = new WindowGui();
//             app.gui.initialize();
// 
//             final Injector injector = Guice.createInjector(new ApplicationModule());
//             final Engine engine = injector.getInstance(Engine.class);
//             engine.run();
// 
//         } catch (final Throwable throwable) {
//             app.logger.error("Critical error.", throwable);
//             System.exit(1);
//         }
//     }
// }
// 
// Path: src/main/java/com/fatico/winthing/logging/ConsoleLogger.java
// public class ConsoleLogger extends ConsoleAppender<ILoggingEvent> {
//     private static final int LOG_SIZE = 50;
//     private static final ConcurrentLinkedQueue<String> events = new ConcurrentLinkedQueue<String>();
// 
//     public static String getEvents() {
//         if (events.size() == 0) {
//             return "";
//         }
// 
//         StringJoiner joiner = new StringJoiner("");
//         Iterator<String> iterator = events.iterator();
//         while (iterator.hasNext()) {
//             joiner.add(iterator.next());
//         }
// 
//         String result = joiner.toString();
// 
//         return result;
//     }
// 
//     protected void append(ILoggingEvent event) {
//         super.append(event);
// 
//         if (events.size() > LOG_SIZE) {
//             events.remove();
//         }
// 
//         byte[] data = encoder.encode(event);
//         events.add(new String(data, Charset.forName("UTF-8")));
// 
//         Application.getApp().reload();
//     }
// }


// Path: src/main/java/com/fatico/winthing/gui/WindowGui.java
import com.fatico.winthing.Application;
import com.fatico.winthing.logging.ConsoleLogger;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;


    public void initialize() throws AWTException {
        setTitle(appName + " " + appVersion);
        setDefaultCloseOperation(HIDE_ON_CLOSE);
        setVisible(false);
        setLayout(new BorderLayout());
        setResizable(false);
        setPreferredSize(new Dimension(800, 530));
        setSize(getPreferredSize());

        JTextArea logs = new JTextArea();
        logs.setEditable(false);
        logs.setRows(25);
        components.put(Gui.TEXTAREA.key, logs);

        JScrollPane scrolls = new JScrollPane(logs);
        scrolls.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        getContentPane().add(scrolls, BorderLayout.NORTH);
        components.put(Gui.SCROLLBAR.key, scrolls);

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(panel, BorderLayout.SOUTH);

        JButton btnClose = new JButton("Close");
        btnClose.setToolTipText("Close this window");
        btnClose.addMouseListener(new MouseEventListener(this, Actions.CLOSE));
        panel.add(btnClose);

        JButton btnQuit = new JButton("Quit");
        btnQuit.setToolTipText("Stop and terminate application");
        btnQuit.addMouseListener(new MouseEventListener(this, Actions.QUIT));