package net.minecraft.server.gui;

import org.apache.logging.log4j.LogManager;
import java.awt.event.ActionEvent;
import javax.swing.JScrollBar;
import javax.swing.text.Document;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import net.minecraft.DefaultUncaughtExceptionHandler;
import com.mojang.util.QueueLogAppender;
import java.awt.event.FocusListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusAdapter;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import net.minecraft.server.MinecraftServer;
import javax.swing.JPanel;
import java.awt.LayoutManager;
import java.awt.BorderLayout;
import java.awt.Dimension;
import com.google.common.collect.Lists;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.Component;
import javax.swing.JFrame;
import javax.swing.UIManager;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Collection;
import net.minecraft.server.dedicated.DedicatedServer;
import org.apache.logging.log4j.Logger;
import java.awt.Font;
import javax.swing.JComponent;

public class MinecraftServerGui extends JComponent {
    private static final Font MONOSPACED;
    private static final Logger LOGGER;
    private final DedicatedServer server;
    private Thread logAppenderThread;
    private final Collection<Runnable> finalizers;
    private final AtomicBoolean isClosing;
    
    public static MinecraftServerGui showFrameFor(final DedicatedServer wd) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception ex) {}
        final JFrame jFrame2 = new JFrame("Minecraft server");
        final MinecraftServerGui wj3 = new MinecraftServerGui(wd);
        jFrame2.setDefaultCloseOperation(2);
        jFrame2.add(wj3);
        jFrame2.pack();
        jFrame2.setLocationRelativeTo(null);
        jFrame2.setVisible(true);
        jFrame2.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(final WindowEvent windowEvent) {
                if (!wj3.isClosing.getAndSet(true)) {
                    jFrame2.setTitle("Minecraft server - shutting down!");
                    wd.halt(true);
                    MinecraftServerGui.this.runFinalizers();
                }
            }
        });
        wj3.addFinalizer(jFrame2::dispose);
        wj3.start();
        return wj3;
    }
    
    private MinecraftServerGui(final DedicatedServer wd) {
        this.finalizers = Lists.newArrayList();
        this.isClosing = new AtomicBoolean();
        this.server = wd;
        this.setPreferredSize(new Dimension(854, 480));
        this.setLayout(new BorderLayout());
        try {
            this.add(this.buildChatPanel(), "Center");
            this.add(this.buildInfoPanel(), "West");
        }
        catch (Exception exception3) {
            MinecraftServerGui.LOGGER.error("Couldn't build server GUI", (Throwable)exception3);
        }
    }
    
    public void addFinalizer(final Runnable runnable) {
        this.finalizers.add(runnable);
    }
    
    private JComponent buildInfoPanel() {
        final JPanel jPanel2 = new JPanel(new BorderLayout());
        final StatsComponent wl3 = new StatsComponent(this.server);
        this.finalizers.add(wl3::close);
        jPanel2.add(wl3, "North");
        jPanel2.add(this.buildPlayerPanel(), "Center");
        jPanel2.setBorder(new TitledBorder(new EtchedBorder(), "Stats"));
        return jPanel2;
    }
    
    private JComponent buildPlayerPanel() {
        final JList<?> jList2 = new PlayerListComponent(this.server);
        final JScrollPane jScrollPane3 = new JScrollPane(jList2, 22, 30);
        jScrollPane3.setBorder(new TitledBorder(new EtchedBorder(), "Players"));
        return jScrollPane3;
    }
    
    private JComponent buildChatPanel() {
        final JPanel jPanel2 = new JPanel(new BorderLayout());
        final JTextArea jTextArea3 = new JTextArea();
        final JScrollPane jScrollPane4 = new JScrollPane(jTextArea3, 22, 30);
        jTextArea3.setEditable(false);
        jTextArea3.setFont(MinecraftServerGui.MONOSPACED);
        final JTextField jTextField5 = new JTextField();
        final JTextComponent textComponent;
        final String string4;
        jTextField5.addActionListener(actionEvent -> {
            string4 = textComponent.getText().trim();
            if (!string4.isEmpty()) {
                this.server.handleConsoleInput(string4, this.server.createCommandSourceStack());
            }
            textComponent.setText("");
            return;
        });
        jTextArea3.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(final FocusEvent focusEvent) {
            }
        });
        jPanel2.add(jScrollPane4, "Center");
        jPanel2.add(jTextField5, "South");
        jPanel2.setBorder(new TitledBorder(new EtchedBorder(), "Log and chat"));
        String string5;
        final Object o;
        final JTextArea jTextArea4;
        final JScrollPane jScrollPane5;
        (this.logAppenderThread = new Thread(() -> {
            while (true) {
                string5 = QueueLogAppender.getNextLogEvent("ServerGuiConsole");
                if (o != null) {
                    this.print(jTextArea4, jScrollPane5, string5);
                }
                else {
                    break;
                }
            }
            return;
        })).setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(MinecraftServerGui.LOGGER));
        this.logAppenderThread.setDaemon(true);
        return jPanel2;
    }
    
    public void start() {
        this.logAppenderThread.start();
    }
    
    public void close() {
        if (!this.isClosing.getAndSet(true)) {
            this.runFinalizers();
        }
    }
    
    private void runFinalizers() {
        this.finalizers.forEach(Runnable::run);
    }
    
    public void print(final JTextArea jTextArea, final JScrollPane jScrollPane, final String string) {
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(() -> this.print(jTextArea, jScrollPane, string));
            return;
        }
        final Document document5 = jTextArea.getDocument();
        final JScrollBar jScrollBar6 = jScrollPane.getVerticalScrollBar();
        boolean boolean7 = false;
        if (jScrollPane.getViewport().getView() == jTextArea) {
            boolean7 = (jScrollBar6.getValue() + jScrollBar6.getSize().getHeight() + MinecraftServerGui.MONOSPACED.getSize() * 4 > jScrollBar6.getMaximum());
        }
        try {
            document5.insertString(document5.getLength(), string, null);
        }
        catch (BadLocationException ex) {}
        if (boolean7) {
            jScrollBar6.setValue(Integer.MAX_VALUE);
        }
    }
    
    static {
        MONOSPACED = new Font("Monospaced", 0, 12);
        LOGGER = LogManager.getLogger();
    }
}
