/*
 *This library is free software; you can redistribute it and/or
 *modify it under the terms of the GNU Lesser General Public
 *License as published by the Free Software Foundation; either
 *version 2.1 of the License, or (at your option) any later version.
 *
 *This library is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *Lesser General Public License for more details.
 *
 *You should have received a copy of the GNU Lesser General Public
 *License along with this library; if not, write to the Free Software
 *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/* 
 * This software was written by Phillip Lord (p.lord@hgmp.mrc.ac.uk)
 * whilst at the University of Manchester as a Pfizer post-doctoral 
 * Research Fellow. 
 *
 * The initial code base is copyright by Pfizer, or the University
 * of Manchester. Modifications to the initial code base are copyright
 * of their respective authors, or their employers as appropriate. 
 * Authorship of the modifications may be determined from the ChangeLog
 * placed at the end of this file
 */

package uk.ac.man.bioinf.debug; // Package name inserted by JPack


/**
 * Debug.java
 * 
 * This forms the basis of the Debugging architecture. All debugging
 * statements go through static methods of this class, but what is to
 * be done with these statements is delegated to an instance of
 * DebugInterface. 
 * 
 * This instance can be set by naming the class on the command line
 * as the debug.debug property, or programmatically with the
 * setInstance() methods. If this represents a change (rather than the
 * first time the instance is set) both the old and the new instances
 * are informed what is going on, and about each other so that Debug
 * logs can be traced. 
 *
 * If there is a problem with the initiation of the debug class the
 * default is used, and information is dumped to System.out. What else
 * can you do under such circumstances?
 *
 * Created: Wed Mar  1 21:59:20 2000
 *
 * @author Phillip Lord
 * @version $Id: Debug.java,v 1.7 2001/05/08 15:50:47 lord Exp $
 */

public class Debug
{
  /**
   * This is the main switch variable. It if is set to true before the
   * compile then any assertions or debug statements within the code
   * will be left in place, and will impose a runtime penalty. If it
   * is set to false, before the compile then those assertions will be
   * optimised away.    
   */
  public static final boolean debug = false;
  private static DebugInterface inst;
  
  static 
  {
    if( System.getProperty( "debug.debug" ) == null ){
      // this is a weird way of doing things, but its type safe!!!!
      setInstance( DefaultDebug.class.getName() );
    }
    else{
      setInstance( "uk.ac.man.bioinf.debug.Debug" + System.getProperty( "debug.debug" ) );
    }
  }

  public static void setInstance( DebugInterface deb )
  {
    try{
      DebugInterface old = inst;
      if( inst != null && debug ){
	inst.message( null, "DEBUG: Replacing debug instance with instance of " + 
                      deb.getClass().getName() );
      }
      
      inst = deb;
      if( old != null && debug ){
	inst.message( null, "DEBUG: Old Debug instance of class " + 
                      old.getClass().getName() + " replaced" );
      }
      if( debug ){
        inst.message( null, "DEBUG: Debug instance of class " + 
                      deb.getClass().getName() + " installed" );
      }
    }
    catch( Exception exp ){
      System.out.println( "ERROR: There is a difficulty loading the debug class " 
                          + deb.getClass().getName() );
      exp.printStackTrace();
      System.out.println( "ERROR: Using the default debug class instead" );
      setInstance( DefaultDebug.class.getName() );
    }
  }
  
  public static void setInstance( String debugClass )
  {
    try{
      Class debug = Class.forName( debugClass );
      setInstance
	( (DebugInterface)debug.newInstance() );
    }
    catch( ClassNotFoundException cnf ){
      System.out.println( "ERROR: Debug Class Not Found. Refer to documentation for possible values" );
      System.out.println( "ERROR: Using the default debug class instead" );
      setInstance( DefaultDebug.class.getName() );
    }
    catch( Exception exp ){
      System.out.println( "ERROR: There is a difficulty loading the debug class " + debugClass );
      System.out.println( "ERROR: Using the default debug class instead" );
      setInstance( DefaultDebug.class.getName() );
    }
  }
  
  public static DebugInterface getInstance()
  {
    return inst;
  }
  
  public static void message( Object obj, String message )
  {
    inst.message( obj, message );
  }

  public static void message( Object obj, Object message )
  {
    inst.message( obj, message );
  }
  
  public static void message( Class cla, String message )
  {
    inst.message( cla, message );
  }

  public static void message( Class cla, Object message )
  {
    inst.message( cla, message );
  }
  
  public static void throwable( Object obj, Throwable th )
  {
    inst.throwable( obj, th );
  }

  public static void throwable( Class cla, Throwable th )
  {
    inst.throwable( cla, th );
  }

  public static void both( Object obj, String message, Throwable th )
  {
    inst.both( obj, message, th );
  }

  public static void both( Class cla, String message, Throwable th )
  {
    inst.both( cla, message, th );
  }
  
  public static void both( Object obj, Object message, Throwable th )
  {
    inst.both( obj, message, th );
  }

  public static void both( Class cla, Object message, Throwable th )
  {
    inst.both( cla, message, th );
  }
}// Debug


/*
 * ChangeLog
 * $Log: Debug.java,v $
 * Revision 1.7  2001/05/08 15:50:47  lord
 * Spam suppression
 *
 * Revision 1.6  2001/04/11 17:04:42  lord
 * Added License agreements to all code
 *
 * Revision 1.5  2000/11/09 16:42:13  lord
 * Package update
 *
 * Revision 1.4  2000/05/08 16:26:11  lord
 * More informative when Debug instance is changed.
 * Added getInstance method.
 * Added horror of horrors, documentation
 *
 * Revision 1.3  2000/04/19 17:17:13  lord
 * Changed main switch field to "debug" rather than "Debug"
 *
 * Revision 1.2  2000/03/09 18:02:47  lord
 * Implemented default class
 *
 * Revision 1.1  2000/03/02 15:25:59  lord
 * Initial checkin
 *
 */
