//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   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 de.ugoe.cs.autoquest.jfcmonitor;

import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.FocusEvent;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
 * <p>
 * Start-up class of the application.
 * </p>
 * <p>
 * Launches the application under test in the same JVM.
 * </p>
 * 
 * @author Steffen Herbold
 * @author Fabian Glaser
 * @version 1.0
 */
public class Runner {

    /**
     * <p>
     * Debugging variable. If set to true, the logging is also written to the console.
     * </p>
     */
    private final static boolean stdOutputWrite = true;

    /**
     * <p>
     * Main method of the application.
     * </p>
     * 
     * @param args
     *            the first parameter defines the Jar file that contains the start-up information of
     *            the application under test. The remaining parameters are passed on the toe
     *            application under test.
     */
    public static void main(String[] args) {
        String logfileName = "jfcmonitor_" + System.currentTimeMillis() + ".log";

        FileOutputStream fis;
        OutputStreamWriter writer;
        try {
            // the writer is not closed explicitly!
            fis = new FileOutputStream(logfileName, true);
            writer = new OutputStreamWriter(fis, "UTF-8");
        }
        catch (IOException e) {
            System.err.println("JFCMONITOR -- failure opening logfile: " + e.getMessage());
            return;
        }

        JFCMonitorOutputWriter jfcWriter = new JFCMonitorOutputWriter(writer);
        AWTEventListener listenerFile = new JFCListener(jfcWriter);
        Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile, AWTEvent.KEY_EVENT_MASK);
        Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile, AWTEvent.MOUSE_EVENT_MASK);
        Toolkit.getDefaultToolkit().addAWTEventListener(listenerFile, FocusEvent.FOCUS_EVENT_MASK);
        Toolkit.getDefaultToolkit().addAWTEventListener(new JFCWindowMonitor(jfcWriter),
                                                        AWTEvent.WINDOW_EVENT_MASK);
        JFCComponent.addPropertyChangeListener(new JFCTitleChangeListener(jfcWriter));
        JFCComponent.addContainerListener(new JFCContainerListener(jfcWriter));

        if (stdOutputWrite) {
            AWTEventListener listenerStdOut;
            try {
            	OutputStreamWriter stdOutputWriter = new OutputStreamWriter(System.out, "UTF-8");
            	JFCMonitorOutputWriter stdJfcWriter = new JFCMonitorOutputWriter(stdOutputWriter);
                listenerStdOut = new JFCListener(stdJfcWriter);
                Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
                                                                AWTEvent.KEY_EVENT_MASK);
                Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
                                                                AWTEvent.MOUSE_EVENT_MASK);
                Toolkit.getDefaultToolkit().addAWTEventListener(listenerStdOut,
                                                                FocusEvent.FOCUS_EVENT_MASK);
                Toolkit.getDefaultToolkit().addAWTEventListener(new JFCWindowMonitor(stdJfcWriter),
                        AWTEvent.WINDOW_EVENT_MASK);
                JFCComponent.addPropertyChangeListener(new JFCTitleChangeListener(stdJfcWriter));
                JFCComponent.addContainerListener(new JFCContainerListener(stdJfcWriter));
            }
            catch (UnsupportedEncodingException e) {
                System.err
                    .println("JFCMONITOR -- failure to create OutputStreamWriter with UTF-8 encoding to System.out");
            }
        }

        JarLauncher launcher = new JarLauncher(args[0], Arrays.copyOfRange(args, 1, args.length));
        launcher.exec();
    }
}
