/*
 * Copyright 2013 MovingBlocks
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.terasology.engine;

import com.google.common.collect.Lists;

import org.terasology.engine.modes.StateMainMenu;
import org.terasology.engine.paths.PathManager;
import org.terasology.engine.subsystem.EngineSubsystem;
import org.terasology.engine.subsystem.headless.HeadlessAudio;
import org.terasology.engine.subsystem.headless.HeadlessGraphics;
import org.terasology.engine.subsystem.headless.HeadlessInput;
import org.terasology.engine.subsystem.headless.HeadlessTimer;
import org.terasology.engine.subsystem.headless.mode.StateHeadlessSetup;
import org.terasology.engine.subsystem.lwjgl.LwjglAudio;
import org.terasology.engine.subsystem.lwjgl.LwjglGraphics;
import org.terasology.engine.subsystem.lwjgl.LwjglInput;
import org.terasology.engine.subsystem.lwjgl.LwjglTimer;

import javax.swing.*;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;

/**
 * Main method for launching Terasology
 *
 * @author Benjamin Glatzel <benjamin.glatzel@me.com>
 * @author Kireev   Anton   <adeon.k87@gmail.com>
 */
public final class Terasology {
    
    private static final String HOME_ARG = "-homedir=";
    private static final String LOCAL_ARG = "-homedir";
    private static final String HEADLESS_ARG = "-headless";

    private Terasology() {
    }

    public static void main(String[] args) {
        try {
            boolean isHeadless = false;
            Path homePath = null;
            for (String arg : args) {
                if (arg.startsWith(HOME_ARG)) {
                    homePath = Paths.get(arg.substring(HOME_ARG.length()));
                } else if (arg.equals(LOCAL_ARG)) {
                    homePath = Paths.get("");
                } else if (arg.equals(HEADLESS_ARG)) {
                    isHeadless = true;
                }
            }
            if (homePath != null) {
                PathManager.getInstance().useOverrideHomePath(homePath);
            } else {
                PathManager.getInstance().useDefaultHomePath();
            }

            Collection<EngineSubsystem> subsystemList;
            if (isHeadless) {
                subsystemList = Lists.newArrayList(new HeadlessGraphics(), new HeadlessTimer(), new HeadlessAudio(), new HeadlessInput());
            } else {
                subsystemList = Lists.<EngineSubsystem>newArrayList(new LwjglGraphics(), new LwjglTimer(), new LwjglAudio(), new LwjglInput());
            }

            TerasologyEngine engine = new TerasologyEngine(subsystemList);
            engine.init();
            if (isHeadless) {
                engine.run(new StateHeadlessSetup());
            } else {
                engine.run(new StateMainMenu());
            }
            engine.dispose();
        } catch (Throwable t) {
            String text = getNestedMessageText(t);
            JOptionPane.showMessageDialog(null, text, "Fatal Error", JOptionPane.ERROR_MESSAGE);
        }
        System.exit(0);
    }

    private static String getNestedMessageText(Throwable t) {
        String nl = System.getProperty("line.separator");
        StringBuilder sb = new StringBuilder();

        Throwable cause = t;
        while (cause != null && cause != cause.getCause()) {
            if (cause.getMessage() != null) {
                sb.append(cause.getClass().getSimpleName());
                sb.append(": ");
                sb.append(cause.getLocalizedMessage());
                sb.append(nl);
            }

            cause = cause.getCause();
        }

        return sb.toString();
    }
}

@@ -1400,16 +1400,105 @@
 ing.*;%0A%0A
+import java.awt.GraphicsEnvironment;%0Aimport java.lang.reflect.InvocationTargetException;%0A
 import j
@@ -3096,32 +3096,44 @@
 ;%0A            %7D%0A
+            
 %0A            Ter
@@ -3465,47 +3465,499 @@
     
-String text = getNestedMessageText(t);%0A
+%0A            if (!GraphicsEnvironment.isHeadless()) %7B%0A                String text = getNestedMessageText(t);%0A                showModalDialog(text);%0A            %7D%0A        %7D%0A        System.exit(0);%0A    %7D%0A%0A    private static void showModalDialog(final String text) %7B%0A        // Swing element methods must be called in the swing thread%0A        try %7B%0A            SwingUtilities.invokeAndWait(new Runnable() %7B%0A                %0A                @Override%0A                public void run() %7B%0A        
     
@@ -4049,16 +4049,24 @@
 SSAGE);%0A
+        
         
@@ -4071,39 +4071,155 @@
   %7D%0A        
-System.exit(0);
+    %7D);%0A        %7D catch (InvocationTargetException %7C InterruptedException e) %7B%0A            e.printStackTrace(System.err);%0A        %7D
 %0A    %7D%0A%0A    

Use swing thread for error message dialog display