<commit_before>package com.timepath.tf2.hudeditor;

import apple.OSXAdapter;
import com.timepath.Utils;
import com.timepath.hl2.io.VTF;
import com.timepath.hl2.io.test.VBFTest;
import com.timepath.hl2.io.test.VCCDTest;
import com.timepath.hl2.io.test.VTFTest;
import com.timepath.hl2.io.util.Element;
import com.timepath.hl2.io.util.Property;
import com.timepath.plaf.OS;
import com.timepath.plaf.linux.Ayatana;
import com.timepath.plaf.linux.GtkFixer;
import com.timepath.plaf.mac.Application;
import com.timepath.plaf.mac.Application.AboutEvent;
import com.timepath.plaf.mac.Application.AboutHandler;
import com.timepath.plaf.mac.Application.PreferencesEvent;
import com.timepath.plaf.mac.Application.PreferencesHandler;
import com.timepath.plaf.mac.Application.QuitEvent;
import com.timepath.plaf.mac.Application.QuitHandler;
import com.timepath.plaf.mac.Application.QuitResponse;
import com.timepath.plaf.x.filechooser.BaseFileChooser;
import com.timepath.plaf.x.filechooser.FileChooserTest;
import com.timepath.plaf.x.filechooser.NativeFileChooser;
import com.timepath.steam.SteamUtils;
import com.timepath.steam.io.GCF;
import com.timepath.steam.io.GCF.DirectoryEntry;
import com.timepath.steam.io.RES;
import com.timepath.steam.io.VDF;
import com.timepath.steam.io.test.ArchiveTest;
import com.timepath.steam.io.test.DataTest;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author timepath
 */
@SuppressWarnings("serial")
public class EditorFrame extends javax.swing.JFrame {

    private static final Logger LOG = Logger.getLogger(EditorFrame.class.getName());

    //<editor-fold defaultstate="collapsed" desc="Variables">
    private final EditorMenuBar jmb;

    private final DefaultMutableTreeNode fileSystemRoot;

    private final FileTree fileTree;

    private final PropertyTable propTable;

    private static Canvas canvas;

    private boolean updating;

    public boolean autoCheck = true;

    private File lastLoaded;

    private JSpinner spinnerWidth;

    private JSpinner spinnerHeight;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Dialogs">
    //<editor-fold defaultstate="collapsed" desc="Updates">
    private BufferedReader getPage(String s) throws IOException {
        URL u = new URL(s);
        URLConnection c = u.openConnection();
//        HttpURLConnection c = (HttpURLConnection) u.openConnection();
        LOG.log(Level.INFO, "{0} size: {1}", new Object[]{s, c.getContentLength()});
        InputStream is = c.getInputStream();
        return new BufferedReader(new InputStreamReader(is));
    }

    private String currentVersion() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.current");
        String l = r.readLine();
        r.close();
        return l;
    }

    private String checksum() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.MD5");
        String l = r.readLine();
        r.close();
        return l;
    }

    private String changelog() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.changes");
        String text = "";
        String grep = Main.myVer;
        String line;
        while((line = r.readLine()) != null) {
            if(grep != null && line.contains(grep)) {
                text += line.replace(grep, "<b><u>" + grep + "</u></b>");
            } else {
                text += line;
            }
        }
        r.close();
        return text;
    }

    private void checkForUpdates(final boolean force) {
        new Thread() {
            int retries = 3;

            private String calculateTime(long diffInSeconds) {
                StringBuilder sb = new StringBuilder();

                long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
                long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
                long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
                //<editor-fold defaultstate="collapsed" desc="approximate d/m/y">
                
                //                long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
                //                long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
                //                long years = (diffInSeconds = (diffInSeconds / 12));
                
                //                if(years > 0) {
                //                    if(years == 1) {
                //                        sb.append("a year");
                //                    } else {
                //                        sb.append(years + " years");
                //                    }
                //                    if(years <= 6 && months > 0) {
                //                        if(months == 1) {
                //                            sb.append(" and a month");
                //                        } else {
                //                            sb.append(" and " + months + " months");
                //                        }
                //                    }
                //                } else if(months > 0) {
                //                    if(months == 1) {
                //                        sb.append("a month");
                //                    } else {
                //                        sb.append(months + " months");
                //                    }
                //                    if(months <= 6 && days > 0) {
                //                        if(days == 1) {
                //                            sb.append(" and a day");
                //                        } else {
                //                            sb.append(" and " + days + " days");
                //                        }
                //                    }
                //                } else if(days > 0) {
                //                    if(days == 1) {
                //                        sb.append("a day");
                //                    } else {
                //                        sb.append(days + " days");
                //                    }
                //                    if(days <= 3 && hrs > 0) {
                //                        if(hrs == 1) {
                //                            sb.append(" and an hour");
                //                        } else {
                //                            sb.append(" and " + hrs + " hours");
                //                        }
                //                    }
                //                } else
                //</editor-fold>
                    if(hrs > 0) {
                    if(hrs == 1) {
                        sb.append("an hour");
                    } else {
                        sb.append(hrs + " hours");
                    }
                    if(min > 1) {
                        sb.append(" and " + min + " minutes");
                    }
                } else if(min > 0) {
                    if(min == 1) {
                        sb.append("a minute");
                    } else {
                        sb.append(min + " minutes");
                    }
                    if(sec > 1) {
                        sb.append(" and " + sec + " seconds");
                    }
                } else {
                    if(sec <= 1) {
                        sb.append("about a second");
                    } else {
                        sb.append("about " + sec + " seconds");
                    }
                }

                sb.append(" ago");

                return sb.toString();
            }

            private void doCheckForUpdates() {
                try {
                    String current = currentVersion();
                    final long lastUpdate = Long.parseLong(current);
                    boolean equal = current.equals(Main.myVer);
                    LOG.log(Level.INFO, "{0} ={1}= {2}", new Object[]{current, equal ? "" : "/", Main.myVer});

                    if(current.compareTo(Main.myVer) <= 0 && !force) {
                        return;
                    }
                    
                    String text = changelog();

                    final JEditorPane pane = new JEditorPane("text/html", text);
                    Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
                    pane.setPreferredSize(new Dimension(s.width / 4, s.height / 2));
                    pane.setEditable(false);
                    pane.setOpaque(false);
                    pane.setBackground(new Color(0, 0, 0, 0));
                    pane.addHyperlinkListener(linkListener);
                    JScrollPane window = new JScrollPane(pane);
                    window.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

                    final JLabel lastUpdated = new JLabel();

                    new Timer(1000, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            lastUpdated.setText(calculateTime((System.currentTimeMillis() - lastUpdate) / 1000));
                        }
                    }).start();

                    if((Main.myVer == null || current.compareTo(Main.myVer) > 0)) {
//                        updateButton.setEnabled(true);
                        int returnCode = JOptionPane.showConfirmDialog(EditorFrame.this, new JComponent[]{new JLabel("Would you like to update to the latest version?"), new JLabel(), window, lastUpdated}, "A new update is available", JOptionPane.YES_NO_OPTION);
                        if(returnCode == JOptionPane.YES_OPTION) {
                            String md5 = checksum();

                            final File downloaded = new File(Utils.workingDirectory(EditorFrame.class) + "update.tmp");
                            for(int attempt = 1;; attempt++) {
                                LOG.log(Level.INFO, "Checking for {0}", downloaded);
                                if(!downloaded.exists()) {
                                    long startTime = System.currentTimeMillis();

                                    LOG.info("Connecting to Dropbox...");
<commit_msg>Fixed timer<commit_after>package com.timepath.tf2.hudeditor;

import apple.OSXAdapter;
import com.timepath.Utils;
import com.timepath.hl2.io.VTF;
import com.timepath.hl2.io.test.VBFTest;
import com.timepath.hl2.io.test.VCCDTest;
import com.timepath.hl2.io.test.VTFTest;
import com.timepath.hl2.io.util.Element;
import com.timepath.hl2.io.util.Property;
import com.timepath.plaf.OS;
import com.timepath.plaf.linux.Ayatana;
import com.timepath.plaf.linux.GtkFixer;
import com.timepath.plaf.mac.Application;
import com.timepath.plaf.mac.Application.AboutEvent;
import com.timepath.plaf.mac.Application.AboutHandler;
import com.timepath.plaf.mac.Application.PreferencesEvent;
import com.timepath.plaf.mac.Application.PreferencesHandler;
import com.timepath.plaf.mac.Application.QuitEvent;
import com.timepath.plaf.mac.Application.QuitHandler;
import com.timepath.plaf.mac.Application.QuitResponse;
import com.timepath.plaf.x.filechooser.BaseFileChooser;
import com.timepath.plaf.x.filechooser.FileChooserTest;
import com.timepath.plaf.x.filechooser.NativeFileChooser;
import com.timepath.steam.SteamUtils;
import com.timepath.steam.io.GCF;
import com.timepath.steam.io.GCF.DirectoryEntry;
import com.timepath.steam.io.RES;
import com.timepath.steam.io.VDF;
import com.timepath.steam.io.test.ArchiveTest;
import com.timepath.steam.io.test.DataTest;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetContext;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author timepath
 */
@SuppressWarnings("serial")
public class EditorFrame extends javax.swing.JFrame {

    private static final Logger LOG = Logger.getLogger(EditorFrame.class.getName());

    //<editor-fold defaultstate="collapsed" desc="Variables">
    private final EditorMenuBar jmb;

    private final DefaultMutableTreeNode fileSystemRoot;

    private final FileTree fileTree;

    private final PropertyTable propTable;

    private static Canvas canvas;

    private boolean updating;

    public boolean autoCheck = true;

    private File lastLoaded;

    private JSpinner spinnerWidth;

    private JSpinner spinnerHeight;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Dialogs">
    //<editor-fold defaultstate="collapsed" desc="Updates">
    private BufferedReader getPage(String s) throws IOException {
        URL u = new URL(s);
        URLConnection c = u.openConnection();
//        HttpURLConnection c = (HttpURLConnection) u.openConnection();
        LOG.log(Level.INFO, "{0} size: {1}", new Object[]{s, c.getContentLength()});
        InputStream is = c.getInputStream();
        return new BufferedReader(new InputStreamReader(is));
    }

    private String currentVersion() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.current");
        String l = r.readLine();
        r.close();
        return l;
    }

    private String checksum() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.MD5");
        String l = r.readLine();
        r.close();
        return l;
    }

    private String changelog() throws IOException {
        BufferedReader r = getPage("https://dl.dropbox.com/u/42745598/tf/Hud%20Editor/TF2%20HUD%20Editor.jar.changes");
        String text = "";
        String grep = Main.myVer;
        String line;
        while((line = r.readLine()) != null) {
            if(grep != null && line.contains(grep)) {
                text += line.replace(grep, "<b><u>" + grep + "</u></b>");
            } else {
                text += line;
            }
        }
        r.close();
        return text;
    }

    private void checkForUpdates(final boolean force) {
        new Thread() {
            int retries = 3;

            private String calculateTime(long diffInSeconds) {
                StringBuilder sb = new StringBuilder();

                long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
                long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
                long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
                long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
                //<editor-fold defaultstate="collapsed" desc="approximate months/years">
                //                long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
                //                long years = (diffInSeconds = (diffInSeconds / 12));

                //                if(years > 0) {
                //                    if(years == 1) {
                //                        sb.append("a year");
                //                    } else {
                //                        sb.append(years + " years");
                //                    }
                //                    if(years <= 6 && months > 0) {
                //                        if(months == 1) {
                //                            sb.append(" and a month");
                //                        } else {
                //                            sb.append(" and " + months + " months");
                //                        }
                //                    }
                //                } else if(months > 0) {
                //                    if(months == 1) {
                //                        sb.append("a month");
                //                    } else {
                //                        sb.append(months + " months");
                //                    }
                //                    if(months <= 6 && days > 0) {
                //                        if(days == 1) {
                //                            sb.append(" and a day");
                //                        } else {
                //                            sb.append(" and " + days + " days");
                //                        }
                //                    }
                //                } else 
                //</editor-fold>
                if(days > 0) {
                    if(days == 1) {
                        sb.append("a day");
                    } else {
                        sb.append(days).append(" days");
                    }
                    if(days <= 3 && hrs > 0) {
                        if(hrs == 1) {
                            sb.append(" and an hour");
                        } else {
                            sb.append(" and ").append(hrs).append(" hours");
                        }
                    }
                } else if(hrs > 0) {
                    if(hrs == 1) {
                        sb.append("an hour");
                    } else {
                        sb.append(hrs).append(" hours");
                    }
                    if(min > 1) {
                        sb.append(" and ").append(min).append(" minutes");
                    }
                } else if(min > 0) {
                    if(min == 1) {
                        sb.append("a minute");
                    } else {
                        sb.append(min).append(" minutes");
                    }
                    if(sec > 1) {
                        sb.append(" and ").append(sec).append(" seconds");
                    }
                } else {
                    if(sec <= 1) {
                        sb.append("about a second");
                    } else {
                        sb.append("about ").append(sec).append(" seconds");
                    }
                }

                sb.append(" ago");

                return sb.toString();
            }

            private void doCheckForUpdates() {
                try {
                    String current = currentVersion();
                    final long lastUpdate = Long.parseLong(current);
                    boolean equal = current.equals(Main.myVer);
                    LOG.log(Level.INFO, "{0} ={1}= {2}", new Object[]{current, equal ? "" : "/", Main.myVer});

                    if(Main.myVer != null && current.compareTo(Main.myVer) <= 0 && !force) {
                        return;
                    }

                    String text = changelog();

                    final JEditorPane pane = new JEditorPane("text/html", text);
                    Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
                    pane.setPreferredSize(new Dimension(s.width / 4, s.height / 2));
                    pane.setEditable(false);
                    pane.setOpaque(false);
                    pane.setBackground(new Color(0, 0, 0, 0));
                    pane.addHyperlinkListener(linkListener);
                    JScrollPane window = new JScrollPane(pane);
                    window.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

                    final JLabel lastUpdated = new JLabel();

                    new Timer(1000, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            lastUpdated.setText(calculateTime((System.currentTimeMillis() / 1000) - lastUpdate));
                        }
                    }).start();

                    if((Main.myVer == null || current.compareTo(Main.myVer) > 0)) {
//                        updateButton.setEnabled(true);
                        int returnCode = JOptionPane.showConfirmDialog(EditorFrame.this, new JComponent[]{new JLabel("Would you like to update to the latest version?"), new JLabel(), window, lastUpdated}, "A new update is available", JOptionPane.YES_NO_OPTION);
                        if(returnCode == JOptionPane.YES_OPTION) {
                            String md5 = checksum();

                            final File downloaded = new File(Utils.workingDirectory(EditorFrame.class) + "update.tmp");
                            for(int attempt = 1;; attempt++) {
                                LOG.log(Level.INFO, "Checking for {0}", downloaded);
                                if(!downloaded.exists()) {
                                    long startTime = System.currentTimeMillis();

                                    LOG.info("Connecting to Dropbox...");

{'fraction_non_alphanumeric': 0.1123971290068017, 'fraction_numerical': 0.009770395701025891, 'mean_word_length': 1.6818502469011387, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 55, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 111, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6606175', 'n_tokens_mistral': 7548, 'n_tokens_neox': 6981, 'n_words': 1421}