package net.kagani;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import net.kagani.utils.Utils;

public class Launcher implements Runnable {

	/**
	 * @author: Pax M
	 */

	private JFrame frame;
	private JPanel panel;

	private JCheckBox chckbxAutoUpdate;

	private JProgressBar progressBar;

	private JButton btnPlay;

	private JTextPane status, information, informationHeader,
			serverInformation, headerServerInformation;

	private JLabel background, logo;
	private JLabel forumsButton, storeButton, hiscoresButton, voteButton,
			cpanelButton, exitButton, minimizeButton, preferencesButton;

	private GraphicsEnvironment graphicsEnviroment;
	private GraphicsDevice[] graphicsDevice;

	private int pX, pY;
	private JLabel announcementIcon;
	private JTextPane textPane;
	private JTextPane txtpnPreferences;
	private JLabel editPreferences;
	private JTextPane changelog;
	private JTextPane changeLog;

	public static void main(String[] args) {
		/*
		 * try { UpdateLog.readUpdates(); } catch (Exception e) {
		 * e.printStackTrace(); }
		 */
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Launcher window = new Launcher();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public Launcher() throws IOException {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		frame = new JFrame();
		graphicsEnviroment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		graphicsDevice = graphicsEnviroment.getScreenDevices();
		InputStream imageStream = Launcher.class
				.getResourceAsStream("resources/images/64.png");
		BufferedImage bufferedImage = ImageIO.read(imageStream);

		frame.setTitle("Kagani");
		frame.setBounds(100, 100, 1113, 653);
		frame.setUndecorated(true);
		frame.getContentPane().setLayout(null);
		frame.setIconImage(bufferedImage);

		background = new JLabel("");
		background.setForeground(new Color(211, 211, 211, 211));
		background.setIcon(new ImageIcon(Launcher.class
				.getResource("resources/images/background.jpg")));
		background.setBounds(0, -133, 1113, 786);

		forumsButton = new JLabel("Community  |");
		forumsButton.setBounds(119, 21, 97, 38);
		forumsButton.setOpaque(true);
		forumsButton.setFont(new Font("Arial", Font.PLAIN, 17));
		forumsButton.setForeground(new Color(211, 211, 211, 211));
		forumsButton.setBackground(new Color(0, 0, 0, 0));

		storeButton = new JLabel("Store  |");
		storeButton.setBounds(226, 21, 58, 38);
		storeButton.setOpaque(true);
		storeButton.setFont(new Font("Arial", Font.PLAIN, 17));
		storeButton.setForeground(new Color(211, 211, 211, 211));
		storeButton.setBackground(new Color(0, 0, 0, 0));

		hiscoresButton = new JLabel("Hiscores  |");
		hiscoresButton.setBounds(294, 21, 79, 38);
		hiscoresButton.setOpaque(true);
		hiscoresButton.setFont(new Font("Arial", Font.PLAIN, 17));
		hiscoresButton.setForeground(new Color(211, 211, 211, 211));
		hiscoresButton.setBackground(new Color(0, 0, 0, 0));

		voteButton = new JLabel("Vote  |");
		voteButton.setBounds(383, 21, 58, 38);
		voteButton.setOpaque(true);
		voteButton.setFont(new Font("Arial", Font.PLAIN, 17));
		voteButton.setForeground(new Color(211, 211, 211, 211));
		voteButton.setBackground(new Color(0, 0, 0, 0));

		cpanelButton = new JLabel("Account Management");
		cpanelButton.setBounds(440, 21, 168, 38);
		cpanelButton.setOpaque(true);
		cpanelButton.setFont(new Font("Arial", Font.PLAIN, 17));
		cpanelButton.setForeground(new Color(211, 211, 211, 211));
		cpanelButton.setBackground(new Color(0, 0, 0, 0));

		chckbxAutoUpdate = new JCheckBox("Auto update");
		chckbxAutoUpdate.setBounds(855, 620, 86, 22);
		chckbxAutoUpdate.setOpaque(false);
		chckbxAutoUpdate.setForeground(new Color(211, 211, 211, 211));
		chckbxAutoUpdate.setFocusable(false);
		chckbxAutoUpdate.setSelected(true);
		chckbxAutoUpdate.setCursor(new Cursor(Cursor.HAND_CURSOR));

		serverInformation = new JTextPane();
		serverInformation.setFont(new Font("Gadugi", Font.PLAIN, 16));
		serverInformation.setText("Server Status: Online" + "\nCurrent Time: "
				+ Utils.getTime() + "\nLauncher Version: " + Settings.VERSION
				+ "\nServer Version: " + Settings.REVISION + "");
		serverInformation.setOpaque(true);
		serverInformation.setEditable(false);
		serverInformation.setHighlighter(null);
		serverInformation.setForeground(new Color(211, 211, 211, 211));
		serverInformation.setBackground(new Color(0, 0, 0, 125));
		serverInformation.setBounds(566, 146, 262, 343);
		serverInformation.setBorder(BorderFactory.createStrokeBorder(
				new BasicStroke(1.0f), new Color(255, 255, 255, 55)));
		frame.getContentPane().add(serverInformation);

		logo = new JLabel("");
		logo.setIcon(new ImageIcon(Launcher.class
				.getResource("resources/images/64.png")));
		logo.setBounds(5, 5, 64, 54);
		frame.getContentPane().add(logo);

		frame.getContentPane().add(forumsButton);
		frame.getContentPane().add(storeButton);
		frame.getContentPane().add(hiscoresButton);

		frame.getContentPane().add(voteButton);
		frame.getContentPane().add(cpanelButton);
		frame.getContentPane().add(chckbxAutoUpdate);
		SimpleAttributeSet attribs = new SimpleAttributeSet();
		StyleConstants.setAlignment(attribs, StyleConstants.ALIGN_CENTER);
		StyleConstants.setFontFamily(attribs, "calibri");
		StyleConstants.setFontSize(attribs, 14);
		headerServerInformation = new JTextPane();
		headerServerInformation.setText("Information");
		headerServerInformation.setOpaque(true);
		headerServerInformation.setEditable(false);
		headerServerInformation.setBorder(null);
		headerServerInformation.setBackground(new Color(96, 176, 48, 185));
		headerServerInformation.setBounds(566, 122, 262, 23);
		headerServerInformation.setParagraphAttributes(attribs, true);

		editPreferences = new JLabel("Edit Preferences");
		editPreferences.setOpaque(true);
		editPreferences.setForeground(new Color(211, 211, 211, 211));
		editPreferences.setFont(new Font("Arial", Font.PLAIN, 17));
		editPreferences.setBackground(new Color(0, 0, 0, 0));
		editPreferences.setBounds(909, 451, 168, 38);
		frame.getContentPane().add(editPreferences);

		txtpnPreferences = new JTextPane();
		txtpnPreferences.setText("Preferences");
		txtpnPreferences.setOpaque(true);
		txtpnPreferences.setEditable(false);
		txtpnPreferences.setBorder(null);
		txtpnPreferences.setBackground(new Color(96, 176, 48, 185));
		txtpnPreferences.setBounds(841, 122, 262, 23);
		txtpnPreferences.setParagraphAttributes(attribs, true);
		frame.getContentPane().add(txtpnPreferences);
		frame.getContentPane().add(headerServerInformation);

		information = new JTextPane();
		information.setFont(new Font("Gadugi", Font.PLAIN, 16));
		information.setText("loading");
		information.setBounds(5, 146, 262, 343);
		information.setEditable(false);
		information.setOpaque(true);
		information.setHighlighter(null);
		information.setBackground(new Color(0, 0, 0, 185));
		information.setForeground(new Color(211, 211, 211));
		information.setBorder(BorderFactory.createStrokeBorder(new BasicStroke(
				1.0f), new Color(255, 255, 255, 55)));

		btnPlay = new JButton("Play".toUpperCase());
		btnPlay.setBounds(947, 578, 156, 64);
		btnPlay.setFocusable(false);
		btnPlay.setCursor(new Cursor(Cursor.HAND_CURSOR));
		frame.getContentPane().add(btnPlay);

		changeLog = new JTextPane();
		changeLog.setText("Changelog");
		changeLog.setOpaque(true);
		changeLog.setEditable(false);
		changeLog.setBorder(null);
		changeLog.setBackground(new Color(96, 176, 48, 185));
		changeLog.setBounds(288, 122, 262, 23);
		changeLog.setParagraphAttributes(attribs, true);
		frame.getContentPane().add(changeLog);

		changelog = new JTextPane();
		changelog.setText("loading");
		changelog.setOpaque(true);
		changelog.setForeground(new Color(211, 211, 211, 211));
		changelog.setFont(new Font("Gadugi", Font.PLAIN, 16));
		changelog.setEditable(false);
		changelog.setBorder(BorderFactory.createStrokeBorder(

		new BasicStroke(1.0f), new Color(255, 255, 255, 55)));
		changelog.setBackground(new Color(0, 0, 0, 125));
		changelog.setBounds(288, 146, 262, 343);
		frame.getContentPane().add(changelog);

		progressBar = new JProgressBar();
		progressBar.setForeground(new Color(96, 176, 48, 185));
		progressBar.setStringPainted(true);
		progressBar.setBounds(5, 619, 844, 23);
		progressBar.setBorderPainted(false);
		progressBar.setBorder(BorderFactory.createStrokeBorder(new BasicStroke(
				3.0f), new Color(0, 0, 0, 55)));
		progressBar.setBackground(new Color(96, 176, 48, 185));

		frame.getContentPane().add(progressBar);

		exitButton = new JLabel("");
		exitButton.setIcon(new ImageIcon(Launcher.class
				.getResource("/net/kagani/resources/images/exit.png")));
		exitButton.setBounds(1081, 5, 22, 23);
		exitButton.setFocusable(false);

		minimizeButton = new JLabel("");
		minimizeButton.setIcon(new ImageIcon(Launcher.class
				.getResource("/net/kagani/resources/images/minimize.png")));
		minimizeButton.setBounds(1055, 5, 22, 23);
		minimizeButton.setFocusable(false);

		preferencesButton = new JLabel("");
		preferencesButton.setIcon(new ImageIcon(Launcher.class
				.getResource("/net/kagani/resources/images/preferences.png")));
		preferencesButton.setBounds(1029, 5, 22, 23);
		preferencesButton.setFocusable(false);

		informationHeader = new JTextPane();
		informationHeader.setText("Announcement");
		informationHeader.setBounds(5, 122, 262, 23);
		informationHeader.setHighlighter(null);
		informationHeader.setOpaque(true);
		informationHeader.setBackground(new Color(96, 176, 48, 185));
		informationHeader.setBorder(null);
		informationHeader.setEditable(false);
		informationHeader.setBorder(BorderFactory.createStrokeBorder(
				new BasicStroke(1.0f), new Color(255, 255, 255, 55)));
		informationHeader.setParagraphAttributes(attribs, true);

		status = new JTextPane();
		status.setText("Ready to play....");
		status.setBounds(5, 592, 844, 23);
		status.setEditable(false);
		status.setOpaque(false);
		status.setForeground(new Color(96, 176, 48, 185));

		frame.getContentPane().add(status);

		textPane = new JTextPane();
		textPane.setText("Background: Default\nExit on client: No\nAuto-update: Yes");
		textPane.setOpaque(true);
		textPane.setForeground(new Color(211, 211, 211, 211));
		textPane.setFont(new Font("Gadugi", Font.PLAIN, 16));
		textPane.setEditable(false);
		textPane.setBorder(BorderFactory.createStrokeBorder(new BasicStroke(
				1.0f), new Color(255, 255, 255, 55)));
		textPane.setBackground(new Color(0, 0, 0, 125));
		textPane.setBounds(841, 146, 262, 343);
		frame.getContentPane().add(textPane);
		frame.getContentPane().add(informationHeader);
		frame.getContentPane().add(information);
		frame.getContentPane().add(exitButton);
		frame.getContentPane().add(minimizeButton);
		frame.getContentPane().add(preferencesButton);
		panel = new JPanel();

		panel.setBounds(0, 0, 1113, 64);
		panel.setOpaque(true);
		panel.setBackground(new Color(0, 0, 0, 55));
		frame.getContentPane().add(panel);
		frame.getContentPane().add(background);

		announcementIcon = new JLabel("");
		announcementIcon.setIcon(new ImageIcon(Launcher.class
				.getResource("/net/kagani/resources/images/announcement.png")));
		announcementIcon.setBounds(5, 115, 30, 30);
		frame.getContentPane().add(announcementIcon);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);

		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

		frame.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				int options = JOptionPane.showConfirmDialog(null,
						"Are you sure you wish to exit?", Settings.NAME,
						JOptionPane.YES_NO_OPTION,
						JOptionPane.INFORMATION_MESSAGE);
				if (options == JOptionPane.YES_OPTION)
					e.getWindow().dispose();
			}
		});

		requestUpdates();
		getAnnouncementText();
		getChangelogText();
		addActions();
		addMouseListeners();
	}

	private void getAnnouncementText() throws IOException {
		URL yahoo = new URL("http://" + Settings.IP + "/play/announcement.txt");
		URLConnection yc = yahoo.openConnection();
		BufferedReader in = new BufferedReader(new InputStreamReader(
				yc.getInputStream(), "UTF-8"));
		String inputLine;
		StringBuilder a = new StringBuilder();
		while ((inputLine = in.readLine()) != null)
			a.append(inputLine);
		in.close();
		information.setText(a.toString().replaceAll("-l", "\n"));
	}

	private void getChangelogText() throws IOException {
		URL yahoo = new URL("http://" + Settings.IP + "/play/updates.txt");
		URLConnection yc = yahoo.openConnection();
		BufferedReader in = new BufferedReader(new InputStreamReader(
				yc.getInputStream(), "UTF-8"));
		String inputLine;
		StringBuilder a = new StringBuilder();
		while ((inputLine = in.readLine()) != null)
			a.append(inputLine);
		in.close();
		changelog.setText(a.toString().replaceAll("-l", "\n"));
	}

	public void readVersion() {
		try (Scanner scanner = new Scanner(new URL("http://" + Settings.IP
				+ "/play/version.txt").openStream())) {
			int output = scanner.nextInt();
			Settings.REVISION = output;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void addActions() {
		btnPlay.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent evt) {
				if (Settings.VERSION != Settings.REQUEST_VERSION)
					checkLauncherVersion();
				else
					run();
			}
		});
	}

	private void addMouseListeners() {
		exitButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				exitButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/exit_hover.png")));
				exitButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseExited(MouseEvent e) {
				exitButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/exit.png")));
			}

			@Override
			public void mousePressed(MouseEvent e) {
				exitButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/exit.png")));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e)) {
					int options = JOptionPane.showConfirmDialog(null,
							"Are you sure you wish to exit?", Settings.NAME,
							JOptionPane.YES_NO_OPTION,
							JOptionPane.INFORMATION_MESSAGE);
					if (options == JOptionPane.YES_OPTION)
						System.exit(-1);
				}
			}

		});
		minimizeButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				minimizeButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/minimize_hover.png")));
				minimizeButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseExited(MouseEvent e) {
				minimizeButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/minimize.png")));
			}

			@Override
			public void mousePressed(MouseEvent e) {
				minimizeButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/minimize.png")));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					frame.setState(Frame.ICONIFIED);
			}
		});
		editPreferences.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				editPreferences.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					JOptionPane.showMessageDialog(null,
							"Currently under development", Settings.NAME,
							JOptionPane.INFORMATION_MESSAGE);
			}
		});
		preferencesButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				preferencesButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/preferences_hover.png")));
				preferencesButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseExited(MouseEvent e) {
				preferencesButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/preferences.png")));
			}

			@Override
			public void mousePressed(MouseEvent e) {
				preferencesButton.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/preferences.png")));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					JOptionPane.showMessageDialog(null,
							"Currently under development", Settings.NAME,
							JOptionPane.INFORMATION_MESSAGE);
			}
		});
		forumsButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				forumsButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net/forums");
			}
		});
		storeButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				storeButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net/store");
			}
		});
		hiscoresButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				hiscoresButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net/hiscores");
			}
		});
		voteButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				voteButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net/vote");
			}
		});
		cpanelButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				cpanelButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net/cpanel");
			}
		});

		panel.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				pX = e.getX();
				pY = e.getY();

				if (SwingUtilities.isLeftMouseButton(e)
						&& e.getClickCount() == 2 && !e.isConsumed()) {
					e.consume();
					fullScreen();
				}
			}
		});
		panel.addMouseMotionListener(new MouseAdapter() {
			public void mouseDragged(MouseEvent e) {
				if (graphicsEnviroment.getDefaultScreenDevice()
						.getFullScreenWindow() == frame)
					return;
				if (SwingUtilities.isLeftMouseButton(e))
					frame.setLocation(frame.getLocation().x + e.getX() - pX,
							frame.getLocation().y + e.getY() - pY);
			}
		});

		logo.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				logo.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/64_hover.png")));
				logo.setCursor(new Cursor(Cursor.HAND_CURSOR));
			}

			@Override
			public void mouseExited(MouseEvent e) {
				logo.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/64.png")));
			}

			@Override
			public void mousePressed(MouseEvent e) {
				logo.setIcon(new ImageIcon(Launcher.class
						.getResource("resources/images/64.png")));
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e))
					Utils.sendOpenURL("https://kagani.net");
				else if (SwingUtilities.isRightMouseButton(e)) {
					JOptionPane.showMessageDialog(null,
							"Currently under development", Settings.NAME,
							JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
	}

	protected void fullScreen() {
		graphicsDevice[0].setFullScreenWindow(graphicsDevice[0]
				.getFullScreenWindow() == frame ? null : frame);
	}

	private void checkLauncherVersion() {
		if (Settings.VERSION != Settings.REQUEST_VERSION) {
			Utils.sendOpenURL("https://kagani.net/play/"
					+ Settings.NAME.toLowerCase() + ".jar");
			status.setText("Please open the new launcher.");
			progressBar.setValue(100);
			progressBar.setString("100%");
		} else
			JOptionPane.showMessageDialog(frame,
					"Your launcher is up to date.", Settings.NAME, 2);
	}

	private void requestUpdates() {
		status.setText("Launcher is up to date.");
		progressBar.setString("Up to date");
		try {
			Settings.REQUEST_VERSION = Integer
					.parseInt(new Scanner(new URL("http://" + Settings.IP
							+ "/play/version.txt").openStream()).nextLine());
			if (Settings.VERSION != Settings.REQUEST_VERSION) {
				status.setText("Outdated launcher. Please update.");
				JOptionPane
						.showMessageDialog(
								frame,
								"<html>You have an outdated version of the launcher, please update.<br><br><center><a href='https://kagani.net/play/kagani.jar'>https://kagani.net/play/kagani.jar</a></center></html>",
								Settings.NAME, 2);
			}
		} catch (Exception e) {
			status.setText("error: " + e);
		}
	}

	@Override
	public void run() {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					double version = Double.parseDouble(System.getProperty(
							"java.version").substring(0, 3));
					if (version < 1.6) {
						status.setText("Error - outdated version of Java");
						JOptionPane
								.showMessageDialog(
										null,
										"You have an oudated version of java - please update your Java at www.java.com/download/",
										Settings.NAME,
										JOptionPane.ERROR_MESSAGE);
						return;
					}

					SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

						@Override
						protected Void doInBackground() throws Exception {

							File dir = new File(Settings.DIRECTORY);
							if (!dir.exists() && !dir.mkdir()) {
								throw new Exception(
										"Unable to create directory "
												+ Settings.DIRECTORY);
							}

							URL url = new URL("http://" + Settings.IP
									+ "/play/" + Settings.CLIENT + ".jar");
							URLConnection conn = url.openConnection();
							conn.setRequestProperty("User-Agent", "Kagani - "
									+ Settings.REVISION);

							int fileSize = conn.getContentLength();

							File file2 = new File(Settings.DIRECTORY
									+ Settings.OLD_CLIENT);
							if (file2.exists()) {
								file2.delete();
								status.setText("Deleting old client...");
								System.out.println("Deleting " + file2);
							}

							File existingClient = new File(Settings.DIRECTORY
									+ Settings.CLIENT + ".jar");
							if (existingClient.exists()
									&& existingClient.length() == fileSize) {
								return null;
							}

							InputStream in = null;
							OutputStream out = null;

							try {
								in = new BufferedInputStream(url.openStream());
								out = new FileOutputStream(Settings.DIRECTORY
										+ Settings.CLIENT + ".jar");

								byte data[] = new byte[1024];

								long total = 0;
								int count = 0;

								while ((count = in.read(data)) != -1) {
									out.write(data, 0, count);

									total += count;
									setProgress((int) ((total * 100) / fileSize));
								}

							} catch (IOException e) {
								status.setText("Error loading client...");
								JOptionPane.showMessageDialog(null,
										e.getMessage());
							} finally {
								if (in != null) {
									in.close();
								}
								if (out != null) {
									out.close();
								}
							}
							return null;
						}

						@Override
						protected void done() {
							status.setText("Attempting to launch client...");
							btnPlay.setEnabled(true);
							progressBar.setValue(100);
							progressBar.setString("100%");
							try {
								ProcessBuilder pb = new ProcessBuilder(
										new String[] { "java", "-Xmx768m",
												"-Xss2m",
												"-Dsun.java2d.noddraw=true",
												"-XX:CompileThreshold=1500",
												"-Xincgc",
												"-XX:+UseConcMarkSweepGC",
												"-XX:+UseParNewGC", "-jar",
												Settings.CLIENT + ".jar" });

								// osx fix
								if (System.getProperty("os.name")
										.equalsIgnoreCase("mac os x")) {
									pb = new ProcessBuilder(new String[] {
											"/usr/libexec/java_home", "-v",
											"1.6.*", "--exec", "java",
											"-Xmx768m", "-Xss2m",
											"-Dsun.java2d.noddraw=true",
											"-XX:CompileThreshold=1500",
											"-Xincgc",
											"-XX:+UseConcMarkSweepGC",
											"-XX:+UseParNewGC", "-jar",
											Settings.CLIENT + ".jar" });
								}

								pb.directory(new File(Settings.DIRECTORY));
								pb.start();

								// System.exit(0);

							} catch (Exception e) {
								status.setText("Error loading client...");
								JOptionPane.showMessageDialog(null,
										e.getMessage());
								e.printStackTrace();
							}
						}
					};

					worker.addPropertyChangeListener(new PropertyChangeListener() {
						@Override
						public void propertyChange(PropertyChangeEvent event) {
							if (event.getPropertyName().equalsIgnoreCase(
									"progress")) {
								int progress = (Integer) event.getNewValue();
								btnPlay.setEnabled(false);
								progressBar.setValue(progress);
								progressBar.setString(progress + "%");
								status.setText("Downloading client updates...");
							}
						}
					});

					worker.execute();

				} catch (Exception e) {
					JOptionPane.showMessageDialog(null, e.getMessage());
					e.printStackTrace();
				}
			}
		});
	}
}