package nloc;

import java.util.List;
import java.util.ArrayList;
import java.util.ListIterator;
import java.util.Arrays;

public class TestNloc {


  public static void main(String[] args) {

    //Nloc nlSX = new Nloc(getNlocS1());
    //Nloc nlSX = new Nloc(getNlocS2());
    //Nloc nlSX = new Nloc(getNlocS6());
    //Nloc nlSX = new Nloc(getNlocS7());
    //Nloc nlSX = new Nloc(getNlocS8());

    //try {
    //  List<Channel> chlist = nlSX.getModulesByName(Arrays.asList("ch1","ch3"));
    //  List<Channel> chlist = nlSX.getModulesByName(Arrays.asList("ch1"));
    //  System.out.println(nlSX.getHeaderPathlength(chlist));
    //} catch(Exception e) {
    //  System.out.println( e.getMessage());
    //}

    
    //String[] mtv = {"m4","d1","m1","m3","h0","m5"};
    //try {
    //  List<List<SequenceTuple>> sequences = nlSX.getPossibleSequences(mtv);
    //  printSequences(sequences);
    //} catch(Exception e) {
    //  System.out.println( e.getMessage());
    //}
    //


    //Droplet p = new Droplet(DropletType.PAYLOAD,"p");
    //Droplet h1 = new Droplet(DropletType.HEADER,"h1");
    //Droplet h2 = new Droplet(DropletType.HEADER,"h2");
    //Droplet h3 = new Droplet(DropletType.HEADER,"h3");
    //Droplet h4 = new Droplet(DropletType.HEADER,"h4");

    //Pump pump = new Pump();
    //Channel outlet = new Channel("ch1",1,1);
    //Sink sink = new Sink();

    //List<Channel> path = Arrays.asList(pump, outlet, sink);

    //Nloc nloc = new Nloc(path);

    //SequenceTuple st0 = new SequenceTuple(p,path,0,0);
    //SequenceTuple st1 = new SequenceTuple(h1,path,1,2);
    //SequenceTuple st2 = new SequenceTuple(h2,path,1,1);
    //SequenceTuple st3 = new SequenceTuple(h3,path,2,2);
    //
    //List<SequenceTuple> stl = new ArrayList<SequenceTuple>();
    //stl.add(st0);
    //stl.add(st1);
    //stl.add(st2);
    //stl.add(st3);

    //List<List<SequenceTuple>> stll = new ArrayList<List<SequenceTuple>>();
    //stll.add(stl);
    //
    //List<Droplet> dropletList = nloc.generateDropletListRecursive(new ArrayList<Droplet>(), stl, 1);

    //for (Droplet dr: dropletList) {
    //  System.out.println("dr: " + dr.getName() + " Pos: " + dr.getPosition().getSteps() );
    //}
  }

  public static void printSequence(List<SequenceTuple> seq) {
    for (SequenceTuple stup: seq) {
      if (seq.indexOf(stup) == (seq.size() - 1)) {
        System.out.print(stup.getDroplet().getName() + ": " + stup.getMinPos() +
            ":" + stup.getMaxPos());
      } else { 
        System.out.print(stup.getDroplet().getName() + ": " + stup.getMinPos() +
            ":" + stup.getMaxPos() + " -> ");
      }
    }
    System.out.println("\n");
  }

  public static void printSequences(List<List<SequenceTuple>> sequences) {
    System.out.println("##################");
    System.out.println("# " + sequences.size() + " Sequences Found");
    System.out.println("##################");
    System.out.println("");
    for (List<SequenceTuple> sl: sequences) {
      printSequence(sl);
    }
  } 

  public static void printPath(List<Channel> path) {
    System.out.println("Pathlength Payload: " + Nloc.getPayloadPathlength(path));
    System.out.println("Pathlength Header: " + Nloc.getHeaderPathlength(path));
    for (Channel ch : path) {
      if (path.indexOf(ch) == (path.size() - 1)) {
        System.out.print(ch.getName());
      } else {
        System.out.print(ch.getName() + " -> ");
      }
    }
    System.out.println("");
    System.out.println("");
  }

  public static void printPaths(List<List<Channel>> pathlist) {
    System.out.println("");
    System.out.println("#############################");
    System.out.println("# Number of paths found: " + pathlist.size());
    System.out.println("#############################");
    for (List<Channel> p : pathlist) {
      printPath(p);
    }
  }

  public static List<Channel> getNlocS1() {

    // channel(name, psteps, hsteps)
    Channel ch1 = new Channel("ch1",1,1);
    Channel ch2 = new Channel("ch2",1,1);
    Channel ch3 = new Channel("ch3",1,1);
    Channel ch4 = new Channel("ch4",1,1);
    Channel ch5 = new Channel("ch5",1,1);
    Channel ch6 = new Channel("ch6",1,1);
    Channel ch7 = new Channel("ch7",1,1);
    Channel ch8 = new Channel("ch8",1,1);
    Channel ch9 = new Channel("ch9",1,1);
    Channel ch10 = new Channel("ch10",1,1);
    Channel ch11 = new Channel("ch11",3,3);
    Channel ch12 = new Channel("ch12",1,1);
    Channel ch13 = new Channel("ch13",1,1);
    Channel ch14 = new Channel("ch14",1,1);
    Channel ch15 = new Channel("ch15",1,1);

    Module m0 = new Module("m0", 5,1);
    Module m1 = new Module("m1", 5,1);
    Module m2 = new Module("m2", 5,1);
    Module d1 = new Module("d1", 5,1);
    Module d2 = new Module("d2", 5,1);
    Module h1 = new Module("h1", 5,1);
    Module h2 = new Module("h2", 5,1);
    Module f2 = new Module("f2", 5,1);

    Pump p0 = new Pump();
    Sink s0 = new Sink();

    List<Channel> chlist = Arrays.asList(ch1, ch2, ch3, ch4, ch5, ch6, ch7, 
        ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, m0, m1, m2, d1, d2, h1, 
        h2, f2, p0, s0);

    p0.addChild(ch1);
    p0.addChild(ch2);
    p0.addChild(ch3);

    ch1.addChild(m2);
    m2.addChild(ch4);
    ch4.addChild(d2);
    d2.addChild(ch6);

    ch2.addChild(h2);
    h2.addChild(ch5);

    ch6.addChild(ch7);
    ch5.addChild(ch7);
    ch3.addChild(ch7);

    ch7.addChild(m1);
    m1.addChild(ch8);
    ch8.addChild(f2);
    f2.addChild(ch9);

    ch9.addChild(ch11);
    ch9.addChild(ch10);

    ch11.addChild(h1);
    h1.addChild(ch12);

    ch12.addChild(ch13);
    ch10.addChild(ch13);

    ch13.addChild(m0);
    m0.addChild(ch14);
    ch14.addChild(d1);
    d1.addChild(ch15);

    ch15.addChild(s0);
    return chlist;
  }

  public static List<Channel> getNlocS2() {

    // channel(name, psteps, hsteps)
    Channel ch1 = new Channel("ch1",1,1);
    Channel ch2 = new Channel("ch2",1,1);
    Channel ch3 = new Channel("ch3",1,1);
    Channel ch4 = new Channel("ch4",1,1);
    Channel ch5 = new Channel("ch5",1,1);
    Channel ch6 = new Channel("ch6",3,3);
    Channel ch7 = new Channel("ch7",1,1);
    Channel ch8 = new Channel("ch8",1,1);
    Channel ch9 = new Channel("ch9",1,1);
    Channel ch10 = new Channel("ch10",1,1);
    Channel ch11 = new Channel("ch11",1,1);
    Channel ch12 = new Channel("ch12",3,3);
    Channel ch13 = new Channel("ch13",1,1);
    Channel ch14 = new Channel("ch14",1,1);
    Channel ch15 = new Channel("ch15",1,1);
    Channel ch16 = new Channel("ch16",1,1);
    Channel ch17 = new Channel("ch17",3,3);
    Channel ch18 = new Channel("ch18",1,1);
    Channel ch19 = new Channel("ch19",1,1);
    Channel ch20 = new Channel("ch20",1,1);
    Channel ch21 = new Channel("ch21",3,3);
    Channel ch22 = new Channel("ch22",1,1);
    Channel ch23 = new Channel("ch23",1,1);
    Channel ch24 = new Channel("ch24",1,1);
    Channel ch25 = new Channel("ch25",3,3);
    Channel ch26 = new Channel("ch26",1,1);
    Channel ch27 = new Channel("ch27",1,1);
    Channel ch28 = new Channel("ch28",1,1);
    Channel ch29 = new Channel("ch29",1,1);
    Channel ch30 = new Channel("ch30",1,1);

    Module m0 = new Module("m0", 5,1);
    Module m1 = new Module("m1", 5,1);
    Module m2 = new Module("m2", 5,1);
    Module m3 = new Module("m3", 5,1);
    Module m4 = new Module("m4", 5,1);
    Module m5 = new Module("m5", 5,1);
    Module h0 = new Module("h0", 5,1);
    Module h3 = new Module("h3", 5,1);
    Module d1 = new Module("d1", 5,1);
    Module f2 = new Module("f2", 5,1);

    Pump p0 = new Pump();
    Sink s0 = new Sink();

    List<Channel> chlist = Arrays.asList(ch1, ch2, ch3, ch4, ch5, ch6, ch7, 
        ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, ch19,
        ch20, ch21, ch22, ch23, ch24, ch25, ch26, ch27, ch28, ch29, ch30, m0, 
        m1, m2, m3, m4, m5, h0, h3, d1, f2, p0, s0);

    p0.addChild(ch1);
    p0.addChild(ch2);
    p0.addChild(ch3);
    p0.addChild(ch4);

    ch1.addChild(m4);
    m4.addChild(ch8);
    ch8.addChild(ch11);
    ch8.addChild(ch12);

    ch12.addChild(d1);
    d1.addChild(ch15);

    ch2.addChild(ch9);

    ch3.addChild(m2);
    m2.addChild(ch5);
    ch5.addChild(ch6);
    ch5.addChild(ch7);

    ch6.addChild(ch9);
    ch9.addChild(h3);
    h3.addChild(ch13);

    ch4.addChild(ch10);
    ch7.addChild(ch10);
    ch10.addChild(f2);
    f2.addChild(ch14);
    ch14.addChild(ch16);
    ch14.addChild(ch17);

    ch11.addChild(ch18);
    ch15.addChild(ch18);
    ch13.addChild(ch18);
    ch16.addChild(ch18);

    ch18.addChild(m1);
    m1.addChild(ch19);
    ch19.addChild(ch20);
    ch19.addChild(ch21);

    ch21.addChild(ch22);
    ch17.addChild(ch22);
    ch22.addChild(m3);
    m3.addChild(ch23);
    ch23.addChild(ch24);
    ch23.addChild(ch25);

    ch20.addChild(ch26);
    ch24.addChild(ch26);

    ch26.addChild(m0);
    m0.addChild(ch28);

    ch25.addChild(h0);
    h0.addChild(ch27);

    ch28.addChild(ch29);
    ch27.addChild(ch29);

    ch29.addChild(m5);
    m5.addChild(ch30);

    ch30.addChild(s0);
    return chlist;
  }

  public static List<Channel> getNlocS6() {

    // channel(name, psteps, hsteps)
    Channel ch1 = new Channel("ch1",1,1);
    Channel ch2 = new Channel("ch2",1,1);
    Channel ch3 = new Channel("ch3",1,1);
    Channel ch4 = new Channel("ch4",1,1);
    Channel ch5 = new Channel("ch5",3,3);
    Channel ch6 = new Channel("ch6",1,1);
    Channel ch7 = new Channel("ch7",1,1);
    Channel ch8 = new Channel("ch8",1,1);
    Channel ch9 = new Channel("ch9",1,1);
    Channel ch10 = new Channel("ch10",3,3);
    Channel ch11 = new Channel("ch11",1,1);
    Channel ch12 = new Channel("ch12",1,1);
    Channel ch13 = new Channel("ch13",1,1);
    Channel ch14 = new Channel("ch14",3,3);
    Channel ch15 = new Channel("ch15",1,1);
    Channel ch16 = new Channel("ch16",1,1);
    Channel ch17 = new Channel("ch17",1,1);
    Channel ch18 = new Channel("ch18",1,1);
    Channel ch19 = new Channel("ch19",1,1);
    Channel ch20 = new Channel("ch20",1,1);

    Module m0 = new Module("m0", 5,1);
    Module m1 = new Module("m1", 5,1);
    Module m3 = new Module("m3", 5,1);
    Module m4 = new Module("m4", 5,1);
    Module m5 = new Module("m5", 5,1);
    Module h0 = new Module("h0", 5,1);
    Module h3 = new Module("h3", 5,1);
    Module d1 = new Module("d1", 5,1);

    Pump p0 = new Pump();
    Sink s0 = new Sink();

    List<Channel> chlist = Arrays.asList(ch1, ch2, ch3, ch4, ch5, ch6, ch7, 
        ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, ch19,
        ch20, m0, m1, m3, m4, m5, h0, h3, d1, p0, s0);

    p0.addChild(ch1);
    p0.addChild(ch2);

    ch2.addChild(h3);
    h3.addChild(ch4);

    ch1.addChild(m4);
    m4.addChild(ch3);

    ch3.addChild(ch5);
    ch3.addChild(ch6);

    ch5.addChild(d1);
    d1.addChild(ch7);

    ch7.addChild(ch8);
    ch6.addChild(ch8);
    ch4.addChild(ch8);

    ch8.addChild(m1);
    m1.addChild(ch9);
    ch9.addChild(ch10);
    ch9.addChild(ch11);

    ch10.addChild(ch12);
    ch12.addChild(m3);
    m3.addChild(ch13);

    ch13.addChild(ch14);
    ch13.addChild(ch15);

    ch14.addChild(h0);
    h0.addChild(ch16);

    ch15.addChild(ch17);
    ch11.addChild(ch17);

    ch17.addChild(m0);
    m0.addChild(ch18);

    ch16.addChild(ch19);
    ch18.addChild(ch19);

    ch19.addChild(m5);
    m5.addChild(ch20);

    ch20.addChild(s0);
    return chlist;
  }

  public static List<Channel> getNlocS7() {

    // channel(name, psteps, hsteps)
    Channel ch1 = new Channel("ch1",1,1);
    Channel ch2 = new Channel("ch2",1,1);
    Channel ch3 = new Channel("ch3",1,1);
    Channel ch4 = new Channel("ch4",1,1);
    Channel ch5 = new Channel("ch5",1,1);
    Channel ch6 = new Channel("ch6",1,1);
    Channel ch7 = new Channel("ch7",1,1);
    Channel ch8 = new Channel("ch8",3,3);
    Channel ch9 = new Channel("ch9",1,1);
    Channel ch10 = new Channel("ch10",1,1);
    Channel ch11 = new Channel("ch11",1,1);
    Channel ch12 = new Channel("ch12",3,3);
    Channel ch13 = new Channel("ch13",1,1);
    Channel ch14 = new Channel("ch14",1,1);
    Channel ch15 = new Channel("ch15",1,1);
    Channel ch16 = new Channel("ch16",1,1);
    Channel ch17 = new Channel("ch17",1,1);
    Channel ch18 = new Channel("ch18",1,1);

    Module m0 = new Module("m0", 5,1);
    Module m1 = new Module("m1", 5,1);
    Module m3 = new Module("m3", 5,1);
    Module m4 = new Module("m4", 5,1);
    Module m5 = new Module("m5", 5,1);
    Module h0 = new Module("h0", 5,1);
    Module h3 = new Module("h3", 5,1);
    Module d1 = new Module("d1", 5,1);

    Pump p0 = new Pump();
    Sink s0 = new Sink();

    List<Channel> chlist = Arrays.asList(ch1, ch2, ch3, ch4, ch5, ch6, ch7, 
        ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, 
        m0, m1, m3, m4, m5, h0, h3, d1, p0, s0);

    p0.addChild(ch1);
    p0.addChild(ch2);

    ch2.addChild(h3);
    h3.addChild(ch4);

    ch1.addChild(m4);
    m4.addChild(ch3);

    ch3.addChild(d1);
    d1.addChild(ch5);

    ch5.addChild(ch6);
    ch4.addChild(ch6);

    ch6.addChild(m1);
    m1.addChild(ch7);

    ch7.addChild(ch8);
    ch7.addChild(ch9);

    ch8.addChild(ch10);
    ch10.addChild(m3);
    m3.addChild(ch11);

    ch11.addChild(ch12);
    ch11.addChild(ch13);

    ch13.addChild(ch15);
    ch9.addChild(ch15);

    ch12.addChild(h0);
    h0.addChild(ch14);

    ch15.addChild(m0);
    m0.addChild(ch16);

    ch14.addChild(ch17);
    ch16.addChild(ch17);

    ch17.addChild(m5);
    m5.addChild(ch18);

    ch18.addChild(s0);

    return chlist;
  }
  public static List<Channel> getNlocS8() {

    // channel(name, psteps, hsteps)
    Channel ch1 = new Channel("ch1",1,1);
    Channel ch2 = new Channel("ch2",7,7);
    Channel ch3 = new Channel("ch3",4,4);
    Channel ch4 = new Channel("ch4",1,1);
    Channel ch5 = new Channel("ch5",1,1);
    Channel ch6 = new Channel("ch6",1,1);
    Channel ch7 = new Channel("ch7",1,1);
    Channel ch8 = new Channel("ch8",1,1);
    Channel ch9 = new Channel("ch9",3,3);
    Channel ch10 = new Channel("ch10",1,1);
    Channel ch11 = new Channel("ch11",1,1);
    Channel ch12 = new Channel("ch12",1,1);
    Channel ch13 = new Channel("ch13",3,3);
    Channel ch14 = new Channel("ch14",1,1);
    Channel ch15 = new Channel("ch15",1,1);
    Channel ch16 = new Channel("ch16",1,1);
    Channel ch17 = new Channel("ch17",1,1);
    Channel ch18 = new Channel("ch18",1,1);
    Channel ch19 = new Channel("ch19",1,1);

    Module m0 = new Module("m0", 5,1);
    Module m1 = new Module("m1", 5,1);
    Module m3 = new Module("m3", 5,1);
    Module m4 = new Module("m4", 5,1);
    Module m5 = new Module("m5", 5,1);
    Module h0 = new Module("h0", 5,1);
    Module h3 = new Module("h3", 5,1);
    Module d1 = new Module("d1", 5,1);

    Pump p0 = new Pump();
    Sink s0 = new Sink();

    List<Channel> chlist = Arrays.asList(ch1, ch2, ch3, ch4, ch5, ch6, ch7, 
        ch8, ch9, ch10, ch11, ch12, ch13, ch14, ch15, ch16, ch17, ch18, ch19,
        m0, m1, m3, m4, m5, h0, h3, d1, p0, s0);

    p0.addChild(ch1);

    ch1.addChild(ch2);
    ch1.addChild(ch3);

    ch2.addChild(m4);
    m4.addChild(ch4);
    ch4.addChild(d1);
    d1.addChild(ch6);

    ch3.addChild(h3);
    h3.addChild(ch5);

    ch6.addChild(ch7);
    ch5.addChild(ch7);

    ch7.addChild(m1);
    m1.addChild(ch8);
    ch8.addChild(ch9);
    ch8.addChild(ch10);

    ch9.addChild(ch11);
    ch11.addChild(m3);
    m3.addChild(ch12);

    ch12.addChild(ch13);
    ch12.addChild(ch14);

    ch13.addChild(h0);
    h0.addChild(ch15);

    ch10.addChild(ch16);
    ch14.addChild(ch16);
    ch16.addChild(m0);
    m0.addChild(ch17);

    ch15.addChild(ch18);
    ch17.addChild(ch18);

    ch18.addChild(m5);
    m5.addChild(ch19);

    ch19.addChild(s0);

    return chlist;
  }
}