package testprocs;

import simulator.*;
import modules.color.*;
import modules.gradient.*;
import utils.*;
import java.awt.*;
import java.util.*;

public class LatchGradient implements ProcessorModule {
  public Symbol getName() { return Symbol.GetSymbol("LatchGradient"); }
  public void link(PortedProcessor p) {
    pp = p;
    pp.addClockListener(this);
    pp.openNetworkPort(this,uiPort);
    ag = (ActiveGradient)p.getModule("ActiveGradient");
    cm = (ColorModule)p.getModule("Color");
  }

  PortedProcessor pp;
  ColorModule cm; ActiveGradient ag;
  static final Symbol uiPort = Symbol.GetSymbol("UI");

  public void init() {}

  static final int r=4;
  public boolean signalEvent(Symbol name, Object data) {
    boolean dirty=false;
    if(name==uiPort) {
      StringTokenizer tok = new StringTokenizer(data.toString());
      if(tok.hasMoreTokens()) { 
        String cmd=tok.nextToken();
        if(cmd.equals("l")) {
          Symbol gid = Symbol.GetSymbol("node");
          if(tok.hasMoreTokens()) gid=Symbol.GetSymbol(tok.nextToken());
          Gradient g = new Gradient(gid,gid,null,new DistancePropagation(r));
          ag.sendGradient(g);
          ag.latchGradient(gid);
        } else if(cmd.equals("lv")) {
          Symbol gid = Symbol.GetSymbol("node");
          int version = 1;
          if(tok.hasMoreTokens()) gid=Symbol.GetSymbol(tok.nextToken());
          if(tok.hasMoreTokens()) 
            version=(new Integer(tok.nextToken())).intValue();
          Gradient g = new VersionedGradient(gid,gid,null,new DistancePropagation(r),0,version);
          ag.sendGradient(g);
          ag.latchGradient(gid);
        } else if(cmd.equals("u")) {
          Symbol gid = Symbol.GetSymbol("node");
          if(tok.hasMoreTokens()) gid=Symbol.GetSymbol(tok.nextToken());
          ag.unlatchGradient(gid);
        }
      }
    } else if(name==PortedProcessor.kClock) {
      Collection gset = ag.getAll();

      boolean hasLive = false, hasDead=false;
      Iterator i = gset.iterator();
      while(i.hasNext()) {
        Gradient g = (Gradient)i.next();
        if(g.isDead()) hasDead=true; else hasLive=true;
      }
      // blue if empty, cyan if dead, magenta if live, yellow if mixed
      if(hasDead && hasLive) cm.setColor(Color.yellow);
      else if(!hasDead && hasLive) cm.setColor(Color.magenta);
      else if(hasDead && !hasLive) cm.setColor(Color.cyan);
      else cm.setColor(Color.blue);
    }
    return dirty;
  }
}

