package modules.gradient;

import utils.*;
import simulator.*;
import java.util.*;

public class VersionedGradient extends Gradient {
  double quality = 0;
  int version = 0;

  public String toString() {
    return "("+super.toString()+", "+quality+", "+version+")";
  }
  public double getQuality() { return quality; }
  public void setQuality(double q) { quality=q; }
  public int getVersion() { return version; }
  public void setVersion(int v) { version=v; }
  public void incrementVersion() { version++; }

  public VersionedGradient(Object gid, Symbol type, Object data, 
         PropagationTest limit) {
    super(gid,type,data,limit); 
    this.quality = 0;
    this.version = 1;
  }
  public VersionedGradient(Object gid, Symbol type, Object data, 
         PropagationTest limit, double quality, int version) {
    super(gid,type,data,limit); 
    this.quality = quality;
    this.version = version;
  }
  public VersionedGradient(Object gid, Symbol type, Object data, 
         PropagationTest limit, int hop, double quality, int version) {
    super(gid,type,data,limit,hop); 
    this.quality = quality;
    this.version = version;
  }

  public Object clone() {
    VersionedGradient c = 
      new VersionedGradient(gid,type,data,limit,hopcount,quality,version);
    c.dead=dead; c.finaldead=finaldead; c.delete=delete; c.age=age; 
    return c;
  }

  // Integrate data from a neighbor.
  // differs from super in that it'll take newer versions, whatever
  // their quality or hopcount, and higher quality specimens of the
  // same version.
  void integrate(Gradient n) {
    flagreset=false;
    if(!(n instanceof VersionedGradient)) return;
    VersionedGradient nbr = (VersionedGradient)n;
    if(!nbr.dead) {
      if(version<nbr.version ||
         (version==nbr.version && (quality<nbr.quality ||
                                   (quality==nbr.quality && 
                                    hopcount > nbr.hopcount)))) {
        hopcount = nbr.hopcount+1;
        data = nbr.data;
        version=nbr.version;
        quality=nbr.quality;
        limit=nbr.limit;
        flagreset=true;
      }
    } else if(nbr.dead && dead && !nbr.finaldead && 
              (version==nbr.version && quality==nbr.quality && 
               hopcount < nbr.hopcount)) {
      finaldead = false;
      age = 0;
    }
  }
}
