Task.define();
function print (id, m) {
    var r = 200, g = 30, b = 30;
    var i = 0, step = 30;

    var li = $("<li>").append(m)
        .css("color", "rgb(" + [r, g, b].join(",") + ")");
    $("#t" + id).append(li);
    setTimeout(function() {
                   i++;
                   function n(c) { return c - ((c / step) * i);}
                   li.css("color", "rgb(" + [n(r), n(g), n(b)].join(",") + ")");
                   if (i < step) setTimeout(arguments.callee, 50);
               }, 0);
}

$(function() {
    var t1 = new Task(
          function(v) {
              print(1, "start.");
              print(1, "got an argument, '" + v + "'.");
          }, function() {
              print(1, "try to pass a variable to next statemtnt, "
                    + "set 'Ada' to this.x1 .");
              this.x1 = "Ada";
          }, function() {
              print(1, "got a variable from the previous statemtnt, '"
                    + this.x1 + "'.");
          }, function(v) {
              print(1, "the argument is still alive, '" + v + "'.");
          }, function() {
              print(1, "wating for entry1 called.");
          },
          accept(
              "entry1", function(msg) {
                  print(0, msg);
              }
          ), function() {
              print(1, "randezvous at entry 1 completed.");
          }, function() {
              print(1, "waiting for entry2 which takes 2,000ms to complete.");
          },
          accept(
              "entry2", function(msg) {
                  print(0, msg);
              },
              delay(2000)
          ), function() {
              print(1, "wating for entry3 called, using a syntax sugar.");
          }, function entry3(msg) {
              print(0, msg);
          }, function() {
              print(1, "randezvous at entry3 complated.");
          },
          function() {
              print(1, "wait 4,000ms not to accept t2's call.");
          },
          delay(4000),
          function() {
              print(1, "waiting entry4 for 0ms.");
          },
          select(
              function entry4(msg) {
                  print(0, msg);
              },
              delay(0, function() {
                        print(1, "randezvous at t1.entry4 timed out.");
                    })
          ),
          function() {
              print(1, "wating for entry5 or entry6 called for 10,000ms.");
          },
          select(
              function entry5() {
                  print(0, "randezvousing at t1.entry5 .");
                  return true;
              },
              accept(
                  "entry6",
                  function(msg) {
                      print(0, msg);
                      print(0, "takes 3,000ms.");
                      return true;
                  },
                  delay(3000)),
              delay(10000, function() {
                        print(1, "randezvous at entry5/entry6 timed out.");
                        return false;
                    })
          ),
          function() {
              if(this.__prev)
                  print(1, "randezvous at entry5/entry6 completed.");
          }, function() {
              print(1, "completed.");
          }
      );

      var t2 = new Task(
          function() {
              print(2, "start in 3 secs.");
          },
          delay(3000),
          function() {
              print(2, "start.");
          }, function() {
              print(2, "calling t1.entry1 .");
          },
          call(
              t1.entry1,
              ["randezvousing at t1.entry1 ."]
          ), function() {
              print(2, "randezvousing at t1.entry1 completed.");
          }, function() {
              print(2, "call t1.entry2 in 4 secs.");
              this.i = 4;
          },
          loop(
              function() {return this.i > 0;},
              function() {
                  print(2, "left: "  + this.i-- + " sec(s).");
              },
              delay(1000)
          ),
          call(
              t1.entry2,
              ["randezvousing at t1.entry2 ."]
          ),
          function() {
              print(2, "randezvouse at t1.entry2 completed.");
          }, function() {
              print(2, "calling t1.entry3 .");
          },
          call(
              t1.entry3,
              ["randezvousing at t1.entry3 ."],
              function() {
                  print(2, "randezvousing at t1.entry3 completed.");
              }
          ),
          function() {
              print(2, "calling t1.entry4 for 2,000ms");
          },
          select(
              call(
                  t1.entry4,
                  ["randezvousing at t1.entry4 (this message never shown)"]),
              delay(2000, function() {
                        print(2, "aborted to call t1.entry4.");
                    })
          ),
          function() {
              print(2, "completed.");
          }
      );


      $("#start").click(function() {
          t1.activate("Lovelace");
          t2.activate();
      });

      $("#call_entry5").click(t1.entry5);
      $("#call_entry6").click(
          function() {
              var input = $(this);
              input.attr("value", "Wating for randezvous at t1.entry6");
              t1.entry6(
                  ["randezvousing at t1.entry6 ."],
                  function() {
                      input.attr("value", "Randezvous at t1.entry6 completed");
                  },
                  function() {
                      input.attr("value", "Randezvousing at t1.entry6");
                  }
              );
          }
      );
  });