package usda.weru.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.log4j.Logger;
import usda.weru.weps.Weps;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class WepsExceptionHandler implements Thread.UncaughtExceptionHandler {

    Weps source;
    
    public WepsExceptionHandler(Weps w)
    {
        source = w;
    }
    
    /**
     *
     * @param t
     * @param e
     */
    @Override
    public void uncaughtException(Thread t, final Throwable e) {

        //Log the exception
        Logger logger;
        StackTraceElement[] trace = e.getStackTrace();
        if (trace.length > 0) {
            StackTraceElement topOfTheStack = trace[0];
            logger = Logger.getLogger(topOfTheStack.getClassName());
        } else {
            logger = Logger.getLogger(WepsExceptionHandler.class);
        }

        if (e instanceof OutOfMemoryError) {
            Util.logMemoryUsage();
            logger.warn("Out of memory.  Running garbage collector and attempting to recover.");
            Runtime.getRuntime().gc();
            Thread.yield();
            return;
        } else {
            logger.error("Unexpected Error", e);
        }

        Runnable task = new Runnable() {

            @Override
            public void run() {
                int report = JOptionPane.showConfirmDialog(null,
                        "An unexpected error was detected.\nWould you like to submit a bug report?",
                        "Unexpected Error", JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE);
                if (JOptionPane.YES_OPTION == report) {
                    //fill in the message with the stacktrace
                    StringWriter buffer = new StringWriter();
                    e.printStackTrace(new PrintWriter(buffer));
                    Mantis.message("Unexpected " + e.getClass().getSimpleName(), e.getMessage()
                            + "\n" + buffer.toString(), source.getExceptionPackage());
                }
            }
        };

        //Dispatch to the swing thread for handling the error reporting.
        if (!SwingUtilities.isEventDispatchThread()) {
            SwingUtilities.invokeLater(task);
        } else {
            task.run();
        }
    }
}
