/**
 * @license
 * Copyright 2013 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package foam.core;

public abstract class AbstractFObject
    implements FCloneable
{

  public Model MODEL();

  public int compare(boolean o1, boolean o2) {
    return o1 == o2 ? 0 : o1 ? 1 : 0;
  }

  public int compare(String o1, String o2) {
    return o1 == o2 ? 0 : o1 == null ? -1 : o2 == null ? 1 : o1.compareTo(o2);
  }
  
  public int compare(short  o1, short  o2) { return Short.compare(o1, o2);   }
  public int compare(int    o1, int    o2) { return Integer.compare(o1, o2); }
  public int compare(long   o1, long   o2) { return Long.compare(o1, o2);    }
  public int compare(float  o1, float  o2) { return Float.compare(o1, o2);   }
  public int compare(double o1, double o2) { return Double.compare(o1, o2);  }
  
  
  public int hash(Boolean b) { return b ? 1 ? 0; }
  public int hash(String s)  { return s == null ? 0 : s.hashCode(); }
  public int hash(short s)   { return s; }
  public int hash(int i)     { return i; }
  public int hash(long l)    { return (int)(l^(l>>>32)); }
  public int hash(float f)   { return hash(Float.floatToIntBits(f)); }
  public int hash(double d)  { return hash(Double.doubleToLongBits(d)); }


  public equals(Object o) {
    return this.compareTo(o) == 0;
  }

  public String toString() {
    StringBuilder sb = new StringBuilder();
    append(sb);
    return sb;
  }

  public appendToJSON(StringBuilder b) {
    b.append("{");
    b.append("model_:");
    b.append(toJSON(MODEL().getName()));
    for ( Property p : MODEL().getProperties() ) {
      // TODO: do not output default values
      b.append(",");
      b.append(p.getName());
      b.append(":");
      b.append(p.get(this)); // TODO: escape propertly, maybe p.toJSON()
    }
    b.append("}");
    return b;
  }

  public String toJSON() {
    StringBuilder sb = new StringBuilder();
    appendToJSON(sb);
    return sb;
  }

  public AbstractFObject set(Property p, Object value) {
    p.set(this, value);
    return this;
  }
}
@@ -719,16 +719,25 @@
  public 
+abstract 
 Model MO
@@ -1384,17 +1384,17 @@
 nt hash(
-B
+b
 oolean b
@@ -1410,17 +1410,17 @@
 n b ? 1 
-?
+:
  0; %7D%0A  
@@ -1788,16 +1788,72 @@
  public 
+abstract int compareTo(Object other);%0A%0A  public boolean 
 equals(O
@@ -1878,13 +1878,8 @@
 urn 
-this.
 comp
@@ -1890,32 +1890,91 @@
 o(o) == 0;%0A  %7D%0A%0A
+  public abstract StringBuilder append(StringBuilder sb);%0A%0A
   public String 
@@ -2051,32 +2051,43 @@
 );%0A    return sb
+.toString()
 ;%0A  %7D%0A%0A  public 
@@ -2086,16 +2086,30 @@
  public 
+StringBuilder 
 appendTo
@@ -2606,16 +2606,27 @@
 eturn sb
+.toString()
 ;%0A  %7D%0A%0A 

Fix (some) java compile errors.