// DebuggingPanel.java
//
// Created: October 2005
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

package org.biomoby.service.dashboard;

import org.tulsoft.tools.gui.SwingUtils;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.Timer;
import javax.swing.SwingUtilities;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


/**
 * A debugging panel. <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: DebuggingPanel.java,v 1.5 2006/02/12 18:47:39 senger Exp $
 */

public class DebuggingPanel
    extends AbstractPanel
    implements PropertyChangeListener {

    JProgressBar memory;
    CommonConsole console;

    /*********************************************************************
     * Default constructor.
     ********************************************************************/
    public DebuggingPanel() {
	super();
	panelIconFileName = "images/console.gif";
    }

    /**************************************************************************
     *
     **************************************************************************/
    public JComponent getComponent (PropertyChannel newPropertyChannel) {
 	setPropertyChannel (newPropertyChannel);
 	propertyChannel.addPropertyChangeListener (this);

	memory = new JProgressBar (0, (int)Runtime.getRuntime().maxMemory());
	memory.setValue (calculateMemory());
	memory.setStringPainted (true);

	JButton gcButton =
	    createButton (" Perform GC ",
			  "Call the garbage collector",
			  -1,
			  new ActionListener() {
			      public void actionPerformed (ActionEvent e) {
				  SwingUtilities.invokeLater (new Runnable() {
					  public void run() {
					      Runtime.getRuntime().gc();
					  }
				      });
			      }
			  });

	console = new CommonConsole();
	console.setAppendMode (true);
	console.setVerboseMode (false);

        Timer timer = new Timer (1000, new ActionListener() {
		public void actionPerformed (ActionEvent evt) {
		    memory.setValue (calculateMemory());
// 		    System.out.println ("Current: " + Runtime.getRuntime().totalMemory() +
// 					"\tMaximum: " + Runtime.getRuntime().maxMemory() +
// 					"\tFree: " + Runtime.getRuntime().freeMemory());
                }
            });

	JLabel memLabel = new JLabel ("Memory: ");

	// put it together
	JPanel p = new JPanel (new GridBagLayout(), true);
  	SwingUtils.addComponent (p, memLabel, 0, 0, 1, 1, NONE, NWEST, 0.0, 0.0);
  	SwingUtils.addComponent (p, memory,   1, 0, 1, 1, HORI, WEST,  1.0, 0.0);
  	SwingUtils.addComponent (p, gcButton, 2, 0, 1, 1, NONE, NEAST, 0.0, 0.0);
  	SwingUtils.addComponent (p, console,  0, 1, 3, 1, BOTH, NWEST, 1.0, 1.0);

	timer.start();
	return p;
    }

    //
    private int calculateMemory() {
	Runtime runtime = Runtime.getRuntime();
	return (int)(runtime.totalMemory() - runtime.freeMemory());
    }


    /**************************************************************************
     * I print to a console whatever is propagated througt the
     * property channel (Hey, I am a debugging panel, am I not?)
     **************************************************************************/
    public void propertyChange (PropertyChangeEvent event) {
	if (console == null)
	    return;   // no place (yet) to report
        String prop = event.getPropertyName();
        if (prop == null) return;     // no interest in non-specific changes
	Object obj = event.getNewValue();
	if (obj == null) return;

	StringBuffer buf = new StringBuffer();
	buf.append ("---[ ");
	buf.append (prop);
	buf.append (" ]------------------------------------------------------------------------\n");
	buf.append (obj.toString());
	buf.append ("\n");

	console.setText (new String (buf));
    }

    /**************************************************************************
     *
     **************************************************************************/
    public String getName() {
	return "Debugging Panel";
    }

    /**************************************************************************
     *
     **************************************************************************/
    public String getDescription() {
	return
	    "A panel with a loosely defined purpose. " +
	    "It serves for debugging and for finding loose ends.";
    }

    /**************************************************************************
     *
     **************************************************************************/
    public boolean loadOnlyOnDemand() {
	return true;
    }

}
