package testprocs;

import simulator.*;
import modules.color.*;
import modules.consensus.*;
import modules.neighborset.*;
import modules.node.*;
import modules.gradient.*;
import modules.region.*;
import utils.*;
import java.awt.*;
import java.util.*;

// Persistent Node testing

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

  PortedProcessor pp; ColorModule cm; RamboNode rn; Consensus cs;
  ActiveGradient ag;

  static final Symbol uiPort = Symbol.GetSymbol("UI");

  public void init() {
  }

  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("init")) {
          String nid = "X"; int size=3;
          if(tok.hasMoreTokens()) nid = tok.nextToken();
          if(tok.hasMoreTokens()) 
            size = (new Integer(tok.nextToken())).intValue();
          rn.initiateNode(Symbol.GetSymbol(nid),size);
        } else if(cmd.equals("kill")) {
          if(tok.hasMoreTokens()) {
            rn.killNode(Symbol.GetSymbol(tok.nextToken()));
          } else {
            Iterator i = rn.getNodes().iterator();
            while(i.hasNext()) { rn.killNode(i.next()); }
          }
        } else if(cmd.equals("center")) {
          Set s = rn.getNodes();
          if(!s.isEmpty()) rn.center(s.iterator().next());
        } else if(cmd.equals("get")) {
          Symbol nid = Symbol.GetSymbol("X");
          if(tok.hasMoreTokens()) nid=Symbol.GetSymbol(tok.nextToken());
          DelayedReturn dr = new DelayedReturn.Object();
          dr.addObserver(this); pendingIsWrite=false;
          System.out.println("Getting data from "+nid+" at "+pp.getUID());
          rn.getData(nid,dr);
        } else if(cmd.equals("set")) {
          Symbol nid = Symbol.GetSymbol("X");
          Object value = Symbol.GetSymbol("V");
          if(tok.hasMoreTokens()) nid=Symbol.GetSymbol(tok.nextToken());
          if(tok.hasMoreTokens()) value=Symbol.GetSymbol(tok.nextToken());
          DelayedReturn dr = new DelayedReturn.Object();
          dr.addObserver(this); pendingIsWrite=true;
          System.out.println("Setting "+nid+" to "+value+" at "+pp.getUID());
          rn.setData(nid,value,dr);
        }
      }
    } else if(name==PortedProcessor.kClock) {
      int t = ((Integer)data).intValue();


      Set nodes = rn.getNodes();
      Set consensus = cs.getConsensusProcesses();
      Set gradients = ag.getType(Consensus.type);

      boolean live=false;
      Iterator i=gradients.iterator();
      while(i.hasNext()) if(!ag.get(i.next()).isDead()) live=true;

      // coloring: none=blue; config=yellow, live=magenta; dead=cyan;

      if(false) {
        if(nodes.size()>0) cm.setColor(Color.yellow);
        else if(consensus.size()>0) cm.setColor(Color.magenta);
        else if(gradients.size()>0 && live) cm.setColor(Color.green);
        else if(gradients.size()>0) cm.setColor(Color.cyan);
        else cm.setColor(Color.blue);
      } else {
        if(nodes.size()>0) cm.setColor(cm.numberToColor(rn.debugit(nodes.iterator().next())));
        else if(consensus.size()>0) cm.setColor(Color.magenta);
        else cm.setColor(Color.blue);
      }
    }
    return dirty;
  }

  boolean pendingIsWrite=false;
  public void update(Observable o, Object arg) {
    if(pendingIsWrite)
      System.out.println("Write completed for "+pp.getUID()+": "+arg);
    else
      System.out.println("Read completed for "+pp.getUID()+": "+arg);
  }

  public String toString() {
    Set x = rn.getNodes();
    return "RNTestProc sez we're in "+x.toString();
  }
}


