// ============================================================================
// File:               $File$
//
// Project:
//
// Purpose:
//
// Author:             Rammi
//
// Copyright Notice:   (c) 1999-2006  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date: 2006-02-01 13:48:49 +0100 (Mi, 01 Feb 2006) $
//
// History:	       $Log$
//=============================================================================

package de.caff.util.debug;

import java.lang.reflect.Field;

/**
 *  Interface for in-deep inspection of an object using reflection.
 *  Is not working well at the moment.
 *
 *  @author Rammi
 */
public class ObjectInspector
{
  /**
   *  Return a detailed description of an object.
   *  @param  obj  object to inspect
   *  @return detailed description
   */
  static String getInfo(Object obj) {
    try {
      Class  c = obj.getClass();
      String ret;
      ret = "Object: " + c.getName() + '@' + Integer.toHexString(obj.hashCode()) + '\n';
      ret += getFields(c, obj);
      return ret;
    } catch (Exception x) {
      // SecurityException?
      return "";
    }
  }

  private static String getFields(Class c, Object obj) {
    StringBuffer ret = new StringBuffer("{\n");
    Field[] fields = c.getDeclaredFields();
    for (int f = 0;   f < fields.length;   ++f) {
      ret.append('\t').append(fields[f].toString()).append(" = ").append(getValue(fields[f], obj)).append(";\n");
      /*
      ret.append(getModifiers(fields[f]));
      ret.append(fields[f].getName()).append(" = ").append();
      ret.append(getValue(fields[f])).append(";\n");
      */
    }
    ret.append("}");
    return ret.toString();
  }
  
  private static String getValue(Field f, Object obj) {
    try {
      //      ReflectPermission perm = new ReflectPermission("suppressAccessChecks");
      f.setAccessible(true);

      StringBuffer ret = new StringBuffer();
      Class type = f.getType();
      if (type.isPrimitive()) {
	if (type == Integer.TYPE) {
	  // int
	  ret.append(f.getInt(obj));
	}
	else if (type == Boolean.TYPE) {
	  // boolean
	  ret.append(f.getBoolean(obj));
	}
	else if (type == Byte.TYPE) {
	  // byte
	  ret.append(f.getByte(obj));
	}
	else if (type == Short.TYPE) {
	  // short
	  ret.append(f.getShort(obj));
	}
	else if (type == Long.TYPE) {
	  // long
	  ret.append(f.getLong(obj));
	}
	else if (type == Float.TYPE) {
	  // float
	  ret.append(f.getFloat(obj));
	}
	else if (type == Double.TYPE) {
	  // double
	  ret.append(f.getDouble(obj));
	}
      }
      else {
	ret.append(f.get(obj));
      }
      
      return ret.toString();
    } catch (IllegalAccessException x) {
      return "?";
    } catch (SecurityException x) {
      return "?";
    }
  }
}
