package modules.gradient;

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

// NOTE: fringes do not work correctly when they are asked to
// propagate an area of size 1. [the propagate function doesn't
// get invoked]
public class FringedPropagation implements PropagationTest {
  protected final int fringeSize;
  protected final PropagationTest test;
  protected final DistancePropagation ftest;
  protected static final Symbol type = Symbol.GetSymbol("fringe");

  public FringedPropagation(int f, PropagationTest t) {
    fringeSize = f; test=t;
    ftest = new DistancePropagation(f);
  }
  // kludge to use to start when it's unable to start itself
  public void startFringe(Gradient g, PortedProcessor pp) {
    propagate(g,pp);
  }
  public PropagationTest getTest() { return test; }

  // send an extra gradient that fringes out beyond our normal
  // limits by the defined radius. Propagation takes place in
  // the normal area or the extended gradient.
  public boolean propagate(Gradient g, PortedProcessor pp) {
    Object gid = new Pair(g.gid,type);
    ActiveGradient ag = (ActiveGradient)pp.getModule("ActiveGradient");
    Gradient fg = ag.get(gid);
    if(test.propagate(g,pp)) {
      if(fg==null) ag.sendGradient(gid,type,null,ftest);
      else ag.renewGradient(fg);
      return true;
    } else {
      if(fg!=null) return true;
    }
    return false;
  }
}
