/* BEGIN_HEADER                                              Java TreeView
 *
 * $Author: alokito $
 * $RCSfile: ThreadListener.java,v $
 * $Revision: 1.4 $
 * $Date: 2010-05-02 13:34:53 $
 * $Name:  $
 *
 * This file is part of Java TreeView
 * Copyright (C) 2001-2014 Alok Saldanha, All Rights Reserved. Modifications Copyright (C) Lawrence Berkeley Lab.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * END_HEADER 
 */
package edu.stanford.genetics.treeview;



/* Call static "List all threads" to list all running threads. Stolen
   from O'Reilly's Java in a nutshell first edition. alok@genome. */

/* I added a constuctor which will pop up a window which monitors
   running threads */

import java.io.*;
import java.awt.*;
import java.awt.event.*;

public class ThreadListener extends Thread {
    boolean runin = true; // instance variable to tell if we are done...
    Frame top; // frame to hold thread monitor
    TextArea textarea;
    // Display info about a thread
    private static void print_thread_info(PrintStream out, Thread t, String indent) {
	if (t == null) return;
	out.println(indent + "Thread: " + t.getName() + " Priority: " +
		    t.getPriority() + (t.isDaemon()?"Daemon":"Not Daemon") +
		    (t.isAlive()?" Alive":" Not Alive"));
    }

    //Display info about a thread group and its threads and groups
    private static void list_group(PrintStream out, ThreadGroup g, String indent) {
	if (g == null) return;
	int num_threads = g.activeCount();
	int num_groups = g.activeGroupCount();
	Thread threads[] = new Thread[num_threads];
	ThreadGroup groups[] = new ThreadGroup[num_groups];
	g.enumerate(threads, false);
	g.enumerate(groups, false);
	
	out.println(indent + "Thread Group: " + g.getName() + " Max Priority " + g.getMaxPriority() + (g.isDaemon()?" Daemon":" Not Daemon"));
	
	for(int i = 0; i < num_threads; i++)
	    print_thread_info(out, threads[i], indent + " ");
	for(int i = 0; i < num_groups; i++)
	    list_group(out, groups[i], indent + " ");	
    }

    //find root thread and list recursively
    public static void listAllThreads(PrintStream out) {
	ThreadGroup current_thread_group;
	ThreadGroup root_thread_group;
	ThreadGroup parent;
	
	// Get the current thread group
	current_thread_group = Thread.currentThread().getThreadGroup();
	//now, go find root thread group
	root_thread_group = current_thread_group;
	parent = root_thread_group.getParent();
	while (parent != null) {
	    root_thread_group = parent;
	    parent = parent.getParent();
	}
	// list recursively
	list_group(out, root_thread_group,"");
    }
    
    public synchronized void run() {
	while (runin == true) {
	    ByteArrayOutputStream os = new ByteArrayOutputStream();
	    PrintStream ps = new PrintStream(os);
	    listAllThreads(ps);
	    textarea.setText(os.toString());
	    textarea.validate();
	    textarea.repaint();
	    try {
		this.wait(1000);
	    } catch (InterruptedException e) {
		// catches InterruptedException
		System.out.println("Somebody set us up the bomb!");
	    }
	}
    }

    public void finish() { runin = false;}

    public ThreadListener() {
	top = new Frame();
	textarea = new TextArea(20, 100);
	top.add(textarea);
	top.addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
		    runin = false;
		    top.dispose();		    
		}
	});
	
	top.pack();
	top.setVisible(true);
    }
}

