//   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.ui.swt;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.MessageBox;

import de.ugoe.cs.util.StringTools;
import de.ugoe.cs.util.console.Console;
import de.ugoe.cs.util.console.listener.ICommandListener;
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;

public class SWTConsole implements IOutputListener, IErrorListener, ITraceListener,
    ICommandListener, IExceptionListener
{

    private StyledText output;
    
    private Level traceLevel;

    public SWTConsole(StyledText styledText, Level traceLevel) {
        Console.getInstance().registerOutputListener(this);
        Console.getInstance().registerErrorListener(this);
        Console.getInstance().registerTraceListener(this);
        Console.getInstance().registerCommandListener(this);
        Console.getInstance().registerExceptionListener(this);
        this.output = styledText;
        this.traceLevel = traceLevel;
    }

    @Override
    public void outputMsg(String newMessage) {
        output.append(newMessage);
    }

    @Override
    public void errorMsg(String errMessage) {
        appendColored("[ERROR] " + errMessage, SWT.COLOR_RED);
    }

    @Override
    public void traceMsg(String traceMessage, Level level) {
        if( level.intValue()>=traceLevel.intValue()) {
            int color = SWT.COLOR_BLUE;
            if( level==Level.SEVERE ) {
                color = SWT.COLOR_RED;
            }
            appendColored("[" + level.toString() + "] " + traceMessage, color);
        }
    }

    @Override
    public void commandNotification(String command) {
        output.append("> " + command + StringTools.ENDLINE);
    }

    private void appendColored(String str, int id) {
        StyleRange styleRange = new StyleRange();
        styleRange.start = output.getText().length();
        styleRange.length = str.length();
        styleRange.foreground = output.getDisplay().getSystemColor(id);
        output.append(str);
        output.setStyleRange(styleRange);
    }

    @Override
    public void logException(Exception e) {
        MessageBox messageBox = new MessageBox(output.getShell(), SWT.ERROR);
        messageBox.setText("Error");
        
        if (e.getMessage() != null) {
            messageBox.setMessage(e.getMessage());
        }
        else {
            messageBox.setMessage("Unexpected exception occurred: " + e);
        }
        messageBox.open();
        
        String stackTrace = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            PrintStream ps = new PrintStream(baos, false, "UTF-8");
            e.printStackTrace(ps);        
            stackTrace = baos.toString("UTF-8");
        }
        catch (UnsupportedEncodingException e1) {
        }
        if( stackTrace!=null ) {
            appendColored(stackTrace, SWT.COLOR_RED);
        } else {
            appendColored(e.getMessage(), SWT.COLOR_RED);
        }
        
    }
}
