//   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.util.console;

import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;

import de.ugoe.cs.util.console.listener.IErrorListener;
import de.ugoe.cs.util.console.listener.IExceptionListener;
import de.ugoe.cs.util.console.listener.IOutputListener;
import de.ugoe.cs.util.console.listener.ITraceListener;

/**
 * <p>
 * A listener that gets a PrintWriter and outputs all information to that PrintWriter. 
 * </p>
 * 
 * @author Steffen Herbold
 */
public class PrintWriterListener implements IOutputListener, IErrorListener, ITraceListener,
    IExceptionListener
{

    /**
     * <p>
     * Defines the trace level used by this console.
     * </p>
     */
    private Level traceLevel;

    private final SimpleDateFormat ft = new SimpleDateFormat("HH:mm:ss");

    private final PrintWriter out;

    /**
     * <p>
     * Creates a new PrintWriterListener. The trace level is {@link Level#WARNING}.
     * </p>
     */
    public PrintWriterListener(PrintWriter out) {
        this(out, Level.WARNING);
    }

    /**
     * <p>
     * Creates a new PrintWriterListener.
     * </p>
     * 
     * @param traceLevel
     *            trace level used by this text console
     */
    public PrintWriterListener(PrintWriter out, Level traceLevel) {
        this.out = out;
        this.traceLevel = traceLevel;
    }

    /**
     * <p>
     * Prints messages to out.
     * </p>
     * 
     * @see ConsoleObserver#outputMsg(java.lang.String)
     */
    public void outputMsg(String newMessage) {
        out.print(newMessage);
    }

    /**
     * <p>
     * Prints messages to out.
     * </p>
     * 
     * @see ConsoleObserver#errorMsg(String)
     */
    @Override
    public void errorMsg(String errMessage) {
        out.print(errMessage);
    }

    /**
     * <p>
     * Prints the stacktrace of an exception to out if the log level is more or equally detailed to
     * <code>Level.FINE</code>. Otherwise, it just prints a line naming the exception or only the
     * message, if any.
     * </p>
     * 
     * @see ConsoleObserver#logException(Exception)
     */
    @Override
    public void logException(Exception e) {
        if (traceLevel.intValue() > Level.FINE.intValue()) {
            if (e.getMessage() != null) {
                out.println(e.getMessage());
            }
            else {
                out.println(e);
            }
        }
        else {
            e.printStackTrace(out);
        }
    }

    /**
     * <p>
     * Prints messages to out. These message are only printed if the trace level is higher than the
     * defined minimum.
     * </p>
     */
    @Override
    public void traceMsg(String traceMessage, Level level) {
        if (level.intValue() >= traceLevel.intValue()) {
            out.print("[" + level.toString() + "] [" + ft.format(new Date()) + "] " + traceMessage);
        }
    }
}
