package utils;

import java.util.*;

// versioned-data holds an object with n dimensions of ordering
public class VersionedData implements Comparable {
  Object data;
  int version;
  double quality;
  public VersionedData() { init(null,0,0); }
  public VersionedData(Object d) { init(d,0,0); }
  public VersionedData(int v, double q) { init(null,v,q); }
  public VersionedData(Object d, int v, double q) { init(d,v,q); }

  private void init(Object d, int v, double q) 
  { data=d; version=v; quality=q; }
  
  public void set(Object d) { data=d; }
  public void reset() { init(null,0,0); }
  public Object get() { return data; }
  public void merge(VersionedData vd) {
    if(vd.version>version || (vd.version==version && vd.quality>quality)) 
      { data=vd.data; version=vd.version; quality=vd.quality; }
  }

  public void incrementVersion() { version++; }
  public void setVersion(int v) { version=v; }
  public int getVersion() { return version; }
  public void setQuality(double q) { quality=q; }
  public double getQuality() { return quality; }

  public boolean equals(Object o) {
    if(o==null||!(o instanceof VersionedData)) return false;
    VersionedData d = (VersionedData)o;
    boolean deq = ((data!=null && data.equals(d.data)) ||
                   (d.data==null && data==null));
    return (deq && version==d.version && quality==d.quality);
  }
  // returns -1 if less than o, +1 if greater, 0 if equal
  public int compareTo(Object o) {
    if(o==null||!(o instanceof VersionedData)) throw new ClassCastException();
    VersionedData d = (VersionedData)o;
    if(version<d.version) { return -1; }
    else if(version>d.version) { return 1; }
    else if(quality<d.quality) { return -1; }
    else if(quality>d.quality) { return 1; }
    else return 0; //version and quality are both equal
  }

  public String toString(boolean verbose) { 
    if(verbose) return "("+data+", "+version+", "+quality+")"; 
    else return  "([DATA], "+version+", "+quality+")"; 
  }
  public String toString() { return toString(true); }
  public Object clone() { return new VersionedData(data,version,quality); }
}
