package org.eclipse.mddi.modelbus.adapter.test.plugin.ui;


import java.io.*;


import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;


/**
 * This class is used for display messages in Eclipse platform.
 * It provides the static method displayMessage(Object output)
 * 
 * @author Prawee Sriplakich (LIP6)
 *
 *
 */
public class ConsoleView extends ViewPart {

    public static final String ID = "org.eclipse.mddi.modelbus.adapter.test.plugin.ui.ConsoleView";
    
	private TextViewer viewer; 
	private Action clearAction = new Action() {
		public void run() {
		  doc.set("");
		}
	};
	

	public ConsoleView() {
	}
	
	
	/**
	 * Displays an output message to the console.
	 * 
	 * @param output output to to displayed. If it is an exception, the StackTrace will be displayed.
	 */
	public static void displayMessage(Object output) {
		
	    Display d = Display.getDefault();
		// syncExec is used for solving thread problem. 
	    // In Eclipse, only GUI-created thread can invoke GUI methods
	    // if the current thread is not a GUI-created thread, then syncExec() is required.
	    d.syncExec(new PrintThread(output));
	}	
	

    IDocument doc = new Document();

    public void print(Object obj) {
		try {
			String _text = doc.get() +obj;
			doc.set( _text );	
		} catch(Exception e) {
		  e.printStackTrace();
		}    	    	
    }
    
    
    
    public void printException(Exception e) {
	  try {
	    e.printStackTrace();
	    ByteArrayOutputStream	out = new ByteArrayOutputStream();
	    PrintWriter w = new PrintWriter(out);
        w.print(doc.get());
        e.printStackTrace(w);	
		w.close();	
		String _text = out.toString();
		doc.set( _text + "\n\n");
	
	  } catch(Exception e2) {
	  	e2.printStackTrace();
	  }
    }
    
    

	public void createPartControl(Composite parent) {
      try {
		viewer = new TextViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);		
		viewer.setEditable(false);	

		
		viewer.setDocument(doc);
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
      } catch(RuntimeException e) {
			e.printStackTrace();
			throw e;
  	   }
	}

	private void fillLocalPullDown(IMenuManager manager) {
		
	    clearAction.setText("clear");		
		manager.add(clearAction);	
		
		manager.add(new Separator());
	}
	
	
	public void setFocus() {
		viewer.getControl().setFocus();
	}
	

    public static IViewPart getView(String id) {
        
        try {
            
            IViewPart view = PlatformUI
            	.getWorkbench()
            	.getActiveWorkbenchWindow()
            	.getActivePage()
            	.showView(id);
            
            return view;
            
        } catch (Exception e) {
            //System.out.println("Workbench View can not be initialized");
        	e.printStackTrace();
            return null;
        }
    }
    
    
    
    public static class PrintThread implements Runnable {

    	Object o;
    	PrintThread(Object o) {
    		this.o = o;
    	}
    	
		public void run() {
			ConsoleView instance = (ConsoleView) getView(ID);
		    if(instance!=null) {
		       if(o instanceof Exception) {
		       	 instance.printException((Exception)o);   
		       } else {
		       	 instance.print(o);
		       }
		    } else {
		       System.out.print("Console> " + o);    
		    }		
		}
    }
    
    
    
}