package co.forsaken.projectindigo.gui;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import co.forsaken.api.json.AsyncJsonWebCall;
import co.forsaken.projectindigo.IndigoLauncher;
import co.forsaken.projectindigo.data.Mod;
import co.forsaken.projectindigo.data.Mod.ModType;
import co.forsaken.projectindigo.data.Server;
import co.forsaken.projectindigo.data.tokens.ActiveServersToken;
import co.forsaken.projectindigo.data.tokens.ServerToken;
import co.forsaken.projectindigo.gui.components.Button;
import co.forsaken.projectindigo.gui.components.CachedImage;
import co.forsaken.projectindigo.gui.components.Label;
import co.forsaken.projectindigo.gui.components.RoundedBox;
import co.forsaken.projectindigo.gui.components.ScrollBarUI;
import co.forsaken.projectindigo.log.LogManager;
import co.forsaken.projectindigo.utils.Callback;
import co.forsaken.projectindigo.utils.Utils;
@SuppressWarnings("serial") public class ServerBasePanel extends BasePanel implements ActionListener {
private Map<String, Server> servers = new HashMap<String, Server>();
private static final int PADDING = 20;
private RoundedBox actionsBox;
private RoundedBox descriptionBox;
private RoundedBox modListBox;
private RoundedBox headerBox;
private RoundedBox otherServersBox;
private Map<String, Button> otherServersButtons = new HashMap<String, Button>();
private Button joinButton;
private Button startButton;
private Button editButton;
private Button settingsButton;
private Button forceUpdateButton;
private CachedImage forsakenLogo;
private JScrollPane descriptionScrollPane;
private JTextPane serverDescriptionPane;
private Label serverIPLabel;
private Label serverNameLabel;
private Label serverOnlineUsersLabel;
private JScrollPane modScrollPane;
private JTextPane modPane;
public CachedImage serverImage;
private Server activeServer;
private boolean launched = false;
public ServerBasePanel(MainPanel mainPanel) {
super(mainPanel, 1);
loadServers();
}
public void loadServers() {
activeServer = null;
servers.clear();
for (Button b : otherServersButtons.values()) {
b.setVisible(false);
remove(b);
}
otherServersButtons.clear();
if (serverNameLabel != null) {
serverNameLabel.setText("Loading modpacks....");
serverDescriptionPane.setText("");
serverIPLabel.setText("");
serverOnlineUsersLabel.setText("");
modPane.setText("");
}
new AsyncJsonWebCall("http://info.forsaken.co/server/getActive").execute(ActiveServersToken.class, new Callback<ActiveServersToken>() {
public void run(final ActiveServersToken result) {
for (final ServerToken t : result.servers) {
new Thread() {
public void run() {
Server s = new Server(t);
if (s != null && s.online) {
s.finishedLoading();
if (activeServer == null && (9 - Integer.parseInt(s.getToken().order)) == 0) {
setServer(s);
}
addServer(s);
servers.put(t.name, s);
} else {
LogManager.error(t.friendlyName + " repository seems to be offline, this is " + t.modpackType + "'s fault");
}
}
}.start();
}
}
});
}
public void initComponents() {
headerBox = new RoundedBox(MainPanel.BORDER_COLOUR);
headerBox.setBounds((getWidth() - (getWidth() - (PADDING * 2))) / 2, PADDING, getWidth() - (PADDING * 2), 60);
serverNameLabel = new Label(this, "Loading modpacks....");
serverNameLabel.setFont(IndigoLauncher.getMinecraftFont(24));
serverNameLabel.setBounds(headerBox.getX() + PADDING, headerBox.getY() + ((headerBox.getHeight() - 26) / 2), (int) (headerBox.getWidth() * 0.75), 26);
serverOnlineUsersLabel = new Label(this, "");
serverOnlineUsersLabel.setFont(IndigoLauncher.getMinecraftFont(14));
serverOnlineUsersLabel.setForeground(new Color(127, 204, 156));
serverOnlineUsersLabel.setBounds(serverNameLabel.getX() + (Utils.getLabelWidth(serverNameLabel) + PADDING), serverNameLabel.getY(), (int) (serverNameLabel.getWidth() * 0.75), 26);
serverIPLabel = new Label(this, "");
serverIPLabel.setFont(IndigoLauncher.getMinecraftFont(18));
serverIPLabel.setForeground(new Color(255, 255, 255, 100));
serverIPLabel.setBounds((headerBox.getX() + headerBox.getWidth() + PADDING) - (Utils.getLabelWidth(serverIPLabel) + PADDING), headerBox.getY() + ((headerBox.getHeight() - 18) / 2), (int) (headerBox.getWidth() * 0.75), 18);
otherServersBox = new RoundedBox(MainPanel.BORDER_COLOUR);
otherServersBox.setBounds(headerBox.getX(), getHeight() - (getHeight() - (headerBox.getHeight() + PADDING) - (PADDING * 2)) - PADDING, 200, getHeight() - (headerBox.getHeight() + PADDING) - (PADDING * 2));
actionsBox = new RoundedBox(MainPanel.BORDER_COLOUR);
actionsBox.setBounds(getWidth() - 200 - PADDING, getHeight() - (getHeight() - (headerBox.getHeight() + PADDING) - (PADDING * 2)) - PADDING, 200, getHeight() - (headerBox.getHeight() + PADDING) - (PADDING * 2));
serverImage = new CachedImage("", "", 150, 150);
serverImage.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 150) / 2), actionsBox.getY() + PADDING, 150, 150);
forsakenLogo = new CachedImage("forsaken_logo", "http://i.imgur.com/E1DmV87.png", 150, 150);
forsakenLogo.setBounds(otherServersBox.getX() + ((otherServersBox.getWidth() - 150) / 2), (otherServersBox.getY() + otherServersBox.getHeight() - ((otherServersBox.getWidth() - 150) / 2)) - 150, 150, 150);
forsakenLogo.addMouseListener(new MouseListener() {
@Override public void mouseClicked(MouseEvent e) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(new URL("http://www.forsaken.co").toURI());
} catch (IOException e1) {
e1.printStackTrace();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
}
}
@Override public void mousePressed(MouseEvent e) {}
@Override public void mouseReleased(MouseEvent e) {}
@Override public void mouseEntered(MouseEvent e) {}
@Override public void mouseExited(MouseEvent e) {}
});
joinButton = new Button(this, "Join Server");
joinButton.setBackground(new Color(0x73FF73));
joinButton.setHoverColour(new Color(0x40FF40));
joinButton.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 180) / 2), (serverImage.getY() + serverImage.getHeight()) + PADDING, 180, 25);
joinButton.addActionListener(this);
joinButton.setActionCommand("CONNECT");
startButton = new Button(this, "Launch Pack");
startButton.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 180) / 2), (joinButton.getY() + joinButton.getHeight()) + (PADDING / 2), 180, 25);
startButton.addActionListener(this);
startButton.setActionCommand("START");
editButton = new Button(this, "Edit Modpack");
editButton.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 180) / 2), (startButton.getY() + startButton.getHeight()) + (PADDING / 2), 180, 25);
editButton.addActionListener(this);
editButton.setActionCommand("EDIT");
settingsButton = new Button(this, "Settings");
settingsButton.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 180) / 2), (actionsBox.getY() + actionsBox.getHeight() - 25) - (PADDING / 2), 180, 25);
settingsButton.addActionListener(this);
settingsButton.setActionCommand("SETTINGS");
forceUpdateButton = new Button(this, "Force Update");
forceUpdateButton.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 180) / 2), (editButton.getY() + editButton.getHeight()) + (PADDING / 2), 180, 25);
forceUpdateButton.addActionListener(this);
forceUpdateButton.setActionCommand("UPDATE");
descriptionBox = new RoundedBox(MainPanel.BORDER_COLOUR);
descriptionBox.setBounds(otherServersBox.getX() + otherServersBox.getWidth() + PADDING, actionsBox.getY(), getWidth() - 400 - (PADDING * 4), actionsBox.getHeight() - 175 - PADDING);
serverDescriptionPane = new JTextPane();
serverDescriptionPane.setForeground(Color.WHITE);
serverDescriptionPane.setOpaque(false);
serverDescriptionPane.setEditable(false);
serverDescriptionPane.setFont(IndigoLauncher.getMinecraftFont(14));
serverDescriptionPane.setContentType("text/html");
serverDescriptionPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
serverDescriptionPane.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(e.getURL().toURI());
} catch (IOException e1) {
e1.printStackTrace();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
}
}
}
});
descriptionScrollPane = new JScrollPane(serverDescriptionPane);
descriptionScrollPane.setBounds(descriptionBox.getX() + (PADDING / 2), descriptionBox.getY() + (PADDING / 2), descriptionBox.getWidth() - PADDING, descriptionBox.getHeight() - PADDING);
descriptionScrollPane.setBorder(null);
descriptionScrollPane.setOpaque(false);
descriptionScrollPane.getViewport().setOpaque(false);
descriptionScrollPane.getVerticalScrollBar().setOpaque(false);
descriptionScrollPane.getVerticalScrollBar().setUI(new ScrollBarUI());
modListBox = new RoundedBox(MainPanel.BORDER_COLOUR);
modListBox.setBounds(descriptionBox.getX(), descriptionBox.getY() + descriptionBox.getHeight() + PADDING, descriptionBox.getWidth(), actionsBox.getHeight() - descriptionBox.getHeight() - PADDING);
modPane = new JTextPane();
modPane.setForeground(Color.WHITE);
modPane.setOpaque(false);
modPane.setEditable(false);
modPane.setContentType("text/html");
modPane.setFont(IndigoLauncher.getMinecraftFont(14));
modPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
modPane.addHyperlinkListener(new HyperlinkListener() {
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(e.getURL().toURI());
} catch (IOException e1) {
e1.printStackTrace();
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
}
}
}
});
modScrollPane = new JScrollPane(modPane);
modScrollPane.setBounds(modListBox.getX() + (PADDING / 2), modListBox.getY() + (PADDING / 2), modListBox.getWidth() - PADDING, modListBox.getHeight() - PADDING);
modScrollPane.setBorder(null);
modScrollPane.setOpaque(false);
modScrollPane.getViewport().setOpaque(false);
modScrollPane.getVerticalScrollBar().setOpaque(false);
modScrollPane.getVerticalScrollBar().setUI(new ScrollBarUI());
Dimension size = new Dimension((int) modScrollPane.getVerticalScrollBar().getSize().getWidth(), 200);
modScrollPane.getVerticalScrollBar().setMinimumSize(size);
modScrollPane.getVerticalScrollBar().setMaximumSize(size);
modScrollPane.getVerticalScrollBar().setSize(size);
add(descriptionScrollPane, 0);
add(modScrollPane, 0);
add(serverImage, 0);
add(forsakenLogo, 0);
add(descriptionBox);
add(modListBox);
add(headerBox);
add(actionsBox);
add(otherServersBox);
}
public void addServer(Server server) {
Button btn = new Button(this, server.getToken().friendlyName);
btn.setBounds(otherServersBox.getX() + ((otherServersBox.getWidth() - 180) / 2), (otherServersBox.getY()) + (PADDING / 2) + ((25 + (PADDING / 2)) * (9 - Integer.parseInt(server.getToken().order))), 180, 25);
btn.addActionListener(this);
btn.setActionCommand(server.getToken().name);
otherServersButtons.put(server.getToken().name, btn);
}
public void setServer(Server _server) {
if (!_server.online) {
LogManager.error(_server.getToken().friendlyName + " could not be activated.. It had some residual errors");
return;
}
activeServer = _server;
serverNameLabel.setText(activeServer.getToken().friendlyName + " v" + activeServer.getToken().version);
serverOnlineUsersLabel.setText(activeServer.getToken().playerCount + " online members");
serverOnlineUsersLabel.setBounds(serverNameLabel.getX() + (Utils.getLabelWidth(serverNameLabel) + (PADDING / 2)), headerBox.getY() + ((headerBox.getHeight() - 12) / 2), (int) (serverNameLabel.getWidth() * 0.75), 12);
serverIPLabel.setText(activeServer.getToken().friendlyIp);
serverIPLabel.setBounds((headerBox.getX() + headerBox.getWidth() + PADDING) - (Utils.getLabelWidth(serverIPLabel) + (PADDING * 2)), headerBox.getY() + ((headerBox.getHeight() - 18) / 2), (int) (headerBox.getWidth() * 0.75), 18);
serverDescriptionPane.setText(activeServer.getDesc().replace("\n", "<br />"));
serverDescriptionPane.setCaretPosition(0);
String modsInfo = "";
SortedSet<String> keys = new TreeSet<String>(activeServer.getModList().keySet());
for (String key : keys) {
Mod m = activeServer.getModList().get(key);
if (m.getType() != ModType.mod) continue;
if (!modsInfo.isEmpty()) modsInfo += "<br />";
modsInfo += "<tr><td><a href=" + m.getInfoUrl() + ">" + m.getName() + " </a>" + (m.getAuthorsAsString() != null && !m.getAuthorsAsString().isEmpty() ? "<p>- by " + m.getAuthorsAsString() + "</p>" : "") + "</td></tr>";
}
modsInfo += "</table>";
modPane.setText("<style type=\"text/css\">a {color:white;text-decoration: none} p {color: gray;}</style><table>" + modsInfo);
modPane.setCaretPosition(0);
}
public void updateServersDir() {
for (Server s : servers.values()) {
s.updateDirLinks();
}
}
public void updateUser(String username) {
serverImage.update(((LoginPanel) getMainPanel().getPanel(0)).getLoginResponse().getName(), "http://avatar.forsaken.co/" + ((LoginPanel) getMainPanel().getPanel(0)).getLoginResponse().getName());
serverImage.setBounds(actionsBox.getX() + ((actionsBox.getWidth() - 150) / 2), actionsBox.getY() + PADDING, 150, 150);
}
@Override public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("CONNECT") || e.getActionCommand().equals("UPDATE") || e.getActionCommand().equals("START")) {
if (e.getActionCommand().equals("UPDATE")) {
forceUpdateButton.setText("Forcing update");
launched = false;
} else {
launched = true;
}
if (activeServer.needsDownload() || e.getActionCommand().equals("UPDATE")) {
try {
getMainPanel().switchPage(-1);
((ProgressPanel) getMainPanel().getPanel(-1)).stateChanged("Checking closest download server", "[0/0]", 0);
activeServer.cleanup();
activeServer.download((ProgressPanel) getMainPanel().getPanel(-1), e.getActionCommand().equals("CONNECT"));
} catch (IOException e1) {
e1.printStackTrace();
}
} else {
activeServer.launch(getMainPanel(), e.getActionCommand().equals("CONNECT"));
}
} else if (e.getActionCommand().equals("EDIT")) {
if (!activeServer.getMinecraftDir().exists()) {
JOptionPane.showMessageDialog(_mainPanel, "The server needs to be launched before you can edit it", "Not downloaded", JOptionPane.WARNING_MESSAGE);
} else {
try {
Desktop.getDesktop().open(activeServer.getMinecraftDir());
} catch (IOException ex) {
ex.printStackTrace();
}
}
} else if (e.getActionCommand().equals("SETTINGS")) {
switchPage(3);
} else {
for (String s : servers.keySet()) {
if (e.getActionCommand().equalsIgnoreCase(s)) {
setServer(servers.get(s));
}
}
}
}
}