package org.opengroupware.jope.foundation;

import java.util.Map;

/*
 * NSObject
 * 
 * An NSObject is basically an Object which directly implements
 * NSKeyValueCoding to avoid code in framework internal classes.
 * 
 * For own classes you are not required to use NSObject, its just a convenience
 * class.
 */
public class NSObject extends Object
  implements NSKeyValueCoding, NSKeyValueCodingAdditions, NSValidation,
             NSNull.NSNullDetection
{

  /* KVC */
  
  public void takeValueForKey(Object _value, String _key) {
    NSKeyValueCoding.DefaultImplementation.takeValueForKey(this, _value, _key);
  }
  public Object valueForKey(String _key) {
    return NSKeyValueCoding.DefaultImplementation.valueForKey(this, _key);
  }
  
  public void takeValueForKeyPath(Object _value, String _keyPath) {
    NSKeyValueCodingAdditions.DefaultImplementation.
      takeValueForKeyPath(this, _value, _keyPath);
  }
  public Object valueForKeyPath(String _keyPath) {
    return NSKeyValueCodingAdditions.DefaultImplementation.
             valueForKeyPath(this, _keyPath);    
  }

  public Object handleQueryWithUnboundKey(String _key) {
    return null;
  }
  public void handleTakeValueForUnboundKey(Object _value, String _key) {
  }

  public void takeValuesFromDictionary(Map<String, Object> _map) {
    NSKeyValueCodingAdditions.DefaultImplementation
      .takeValuesFromDictionary(this, _map);
    
  }
  public Map<String, Object> valuesForKeys(String[] _keys) {
    return NSKeyValueCodingAdditions.DefaultImplementation.
      valuesForKeys(this, _keys);
  }
  
  /* NSValidation */

  public Object validateValueForKey(Object _value, String _key)
    throws ValidationException
  {
    return NSValidation.DefaultImplementation
      .validateValueForKey(_key, _value, _key);
  }
  
  /* NSNull detection */
   
  public boolean isNull() {
    return false;
  }
  public boolean isNotNull() {
    return true;
  }
  public boolean isEmpty() {
    return false;
  }
  public boolean isNotEmpty() {
    return !this.isEmpty();
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    /* this is what should be overridden by subclasses */
  }
  
  public String toString() {
    StringBuffer sb = new StringBuffer(256);
    
    sb.append("<");
    sb.append(this.getClass().getName());
    // TODO: add some reference-id
    sb.append(":");
    
    this.appendAttributesToDescription(sb);
    sb.append(">");
    return sb.toString();
  }
}
