package nxm.xbc.intr;

import nxm.sys.lib.Command;
import nxm.sys.lib.Intrinsic;
import nxm.sys.lib.Midas;
import nxm.sys.lib.Shell;
import nxm.sys.lib.Time;

/**
  Handles changing piped processing modes.

  @author Jeff Schoen
*/
public class Xpipe extends Intrinsic {

  String func, controls;

  /**b default constructor */
  public Xpipe () {}

  public int process() {

    func = MA.getU("MODE");

    if (func.equals("INIT") || func.equals("ON")) {
      setPipeMode(Midas.PINIT);
      String switches = "/XS=1";
      int setup = MA.getL("/SETUP");
      if (setup>0) switches += "/SETUP="+setup;
      int controls = MA.getL("/CONTROLS");
      if (controls>0) switches += "/CONTROLS="+controls;
      Shell.runCommand(M,"XPANEL"+switches);
    }
    else if (func.equals("RUN")) {
      setPipeMode(Midas.PRUN);
    }
    else if (func.equals("PAUSE")) {
      setPipeMode(Midas.PPAUSE);
      // handled in pipe io class
    }
    else if (func.equals("WAIT")) {
      setPipeMode(Midas.PWAIT);
    }
    else if (func.equals("WAITFOR")) {
      setPipeMode(Midas.PWAIT);
      String regname = MA.getU(2);
      if (M.macro==null) M.warning("No macro running");
      else if (M.registry.get(regname)==null)
	M.warning("WaitFor command "+regname+" not found in registry");
      else M.macro.waitFor = regname;
    }
    else if (func.equals("STOP")) {
      setPipeMode(Midas.PSTOP);
    }
    else if (func.equals("OFF")) {
      nxm.sys.lib.Table.Iterator ti;
      nxm.sys.lib.Table mreg = M.registry.table;
      if (M.macro==null) {
        setPipeMode(Midas.PWAIT);
        // wait for all registered commands to finish
        while (mreg.size()>1) Time.sleep(0.1);
      }
      else if (M.pipeMode==Midas.PINIT || M.pipeMode==Midas.PRUN) {
        setPipeMode(Midas.PWAIT);
        M.macro.nextIndex--;	// repeat command
        return FINISH;
      }
      setPipeMode(Midas.POFF);
      M.status = Command.EXIT;
      // remove any defunct commands
      if (M.macro!=null && M.macro.getRegistry()!=null) {
        mreg = M.macro.getRegistry();
        for (ti=mreg.iterator(); ti.getNext();) {
          if (ti.value instanceof Command && ((Command)ti.value).state!=0);
          else mreg.remove(ti.key);
        }
      }
      if (mreg!=null) {
        // wait for all registered commands to finish
        for (int i=0; i<20 && mreg.size()>1; i++) Time.sleep(0.1);
        // System.out.println("Table size  "+mreg.size()+" "+mreg.toString());
        if (mreg.size()>1) for (ti=mreg.iterator(); ti.getNext();) {
          if (!ti.key.equals("MAIN")) M.warning("Timeout closing "+ti.value);
        }
      }
      M.pipes.clear();
      M.status = 0;
    }
    else {
      M.error("Unsupported pipe function: "+func);
    }

    return FINISH;
  }

  private void setPipeMode (int mode) {
    if (M.macro != null) M.macro.setPipeMode(mode);
    M.pipeMode = mode;
  }

}
