assertion type person(id, firstName, lastName, address, age);
message type setSortColumn(number);

function newRow(id, firstName, lastName, address, age) {
  spawn named ('model' + id) {
    assert person(id, firstName, lastName, address, age);
  }
}

function spawnModel() {
  newRow(1, 'Keith', 'Example', '94 Main St.', 44);
  newRow(2, 'Karen', 'Fakeperson', '5504 Long Dr.', 34);
  newRow(3, 'Angus', 'McFictional', '2B Pioneer Heights', 39);
  newRow(4, 'Sue', 'Donnem', '1 Infinite Loop', 104);
  newRow(5, 'Boaty', 'McBoatface', 'Arctic Ocean', 1);
}

function spawnView() {
  spawn named 'view' {
    var ui = new Syndicate.UI.Anchor();
    field this.orderColumn = 2;

    function cell(text) {
      // Should escape text in a real application.
      return '<td>' + text + '</td>';
    }

    on message setSortColumn($c) { this.orderColumn = c; }

    during person($id, $firstName, $lastName, $address, $age) {
      assert ui.context(id)
        .html('table#the-table tbody',
              '<tr>' + [id, firstName, lastName, address, age].map(cell).join('') + '</tr>',
              [id, firstName, lastName, address, age][this.orderColumn]);
    }
  }
}

function spawnController() {
  spawn named 'controller' {
    on message Syndicate.UI.globalEvent('table#the-table th', 'click', $e) {
      :: setSortColumn(JSON.parse(e.target.dataset.column));
    }
  }
}

ground dataspace G {
  Syndicate.UI.spawnUIDriver();

  spawnModel();
  spawnView();
  spawnController();
}
