private void renderRow(
      XhtmlNode table, Row r, int indent, List<Boolean> indents, String imagePath)
      throws IOException {
    XhtmlNode tr = table.addTag("tr");
    String color = "white";
    if (r.getColor() != null) color = r.getColor();
    tr.setAttribute(
        "style", "border: 0px; padding:0px; vertical-align: top; background-color: " + color + ";");
    boolean first = true;
    for (Cell t : r.getCells()) {
      renderCell(
          tr,
          t,
          "td",
          first ? r.getIcon() : null,
          first ? r.getHint() : null,
          first ? indents : null,
          !r.getSubRows().isEmpty(),
          first ? r.getAnchor() : null,
          color,
          imagePath);
      first = false;
    }
    table.addText("\r\n");

    for (int i = 0; i < r.getSubRows().size(); i++) {
      Row c = r.getSubRows().get(i);
      List<Boolean> ind = new ArrayList<Boolean>();
      ind.addAll(indents);
      if (i == r.getSubRows().size() - 1) ind.add(true);
      else ind.add(false);
      renderRow(table, c, indent + 1, ind, imagePath);
    }
  }
 private XhtmlNode addStyle(XhtmlNode node, Piece p) {
   if (p.getStyle() != null) node.setAttribute("style", p.getStyle());
   return node;
 }
 private XhtmlNode renderCell(
     XhtmlNode tr,
     Cell c,
     String name,
     String icon,
     String hint,
     List<Boolean> indents,
     boolean hasChildren,
     String anchor,
     String color,
     String imagePath)
     throws IOException {
   XhtmlNode tc = tr.addTag(name);
   tc.setAttribute("class", "hierarchy");
   if (indents != null) {
     tc.addTag("img")
         .setAttribute("src", srcFor(imagePath, "tbl_spacer.png"))
         .setAttribute("style", "background-color: inherit")
         .setAttribute("class", "hierarchy")
         .setAttribute("alt", ".");
     tc.setAttribute(
         "style",
         "vertical-align: top; text-align : left; background-color: "
             + color
             + "; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url("
             + imagePath
             + checkExists(indents, hasChildren)
             + ")");
     for (int i = 0; i < indents.size() - 1; i++) {
       if (indents.get(i))
         tc.addTag("img")
             .setAttribute("src", srcFor(imagePath, "tbl_blank.png"))
             .setAttribute("style", "background-color: inherit")
             .setAttribute("class", "hierarchy")
             .setAttribute("alt", ".");
       else
         tc.addTag("img")
             .setAttribute("src", srcFor(imagePath, "tbl_vline.png"))
             .setAttribute("style", "background-color: inherit")
             .setAttribute("class", "hierarchy")
             .setAttribute("alt", ".");
     }
     if (!indents.isEmpty())
       if (indents.get(indents.size() - 1))
         tc.addTag("img")
             .setAttribute("src", srcFor(imagePath, "tbl_vjoin_end.png"))
             .setAttribute("style", "background-color: inherit")
             .setAttribute("class", "hierarchy")
             .setAttribute("alt", ".");
       else
         tc.addTag("img")
             .setAttribute("src", srcFor(imagePath, "tbl_vjoin.png"))
             .setAttribute("style", "background-color: inherit")
             .setAttribute("class", "hierarchy")
             .setAttribute("alt", ".");
   } else
     tc.setAttribute(
         "style",
         "vertical-align: top; text-align : left; background-color: "
             + color
             + "; padding:0px 4px 0px 4px");
   if (!Utilities.noString(icon)) {
     XhtmlNode img =
         tc.addTag("img")
             .setAttribute("src", srcFor(imagePath, icon))
             .setAttribute("class", "hierarchy")
             .setAttribute("style", "background-color: " + color + "; background-color: inherit")
             .setAttribute("alt", ".");
     if (hint != null) img.setAttribute("title", hint);
     tc.addText(" ");
   }
   for (Piece p : c.pieces) {
     if (!Utilities.noString(p.getTag())) {
       XhtmlNode tag = tc.addTag(p.getTag());
       if (p.attributes != null)
         for (String n : p.attributes.keySet()) tag.setAttribute(n, p.attributes.get(n));
       if (p.getHint() != null) tag.setAttribute("title", p.getHint());
       addStyle(tag, p);
     } else if (!Utilities.noString(p.getReference())) {
       XhtmlNode a = addStyle(tc.addTag("a"), p);
       a.setAttribute("href", p.getReference());
       if (!Utilities.noString(p.getHint())) a.setAttribute("title", p.getHint());
       a.addText(p.getText());
     } else {
       if (!Utilities.noString(p.getHint())) {
         XhtmlNode s = addStyle(tc.addTag("span"), p);
         s.setAttribute("title", p.getHint());
         s.addText(p.getText());
       } else if (p.getStyle() != null) {
         XhtmlNode s = addStyle(tc.addTag("span"), p);
         s.addText(p.getText());
       } else tc.addText(p.getText());
     }
   }
   if (!Utilities.noString(anchor))
     tc.addTag("a").setAttribute("name", nmTokenize(anchor)).addText(" ");
   return tc;
 }
  public XhtmlNode generate(TableModel model, String imagePath) throws IOException, FHIRException {
    checkModel(model);
    XhtmlNode table =
        new XhtmlNode(NodeType.Element, "table")
            .setAttribute("border", "0")
            .setAttribute("cellspacing", "0")
            .setAttribute("cellpadding", "0");
    table.setAttribute(
        "style", "border: 0px; font-size: 11px; font-family: verdana; vertical-align: top;");
    XhtmlNode tr = table.addTag("tr");
    tr.setAttribute(
        "style",
        "border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;");
    XhtmlNode tc = null;
    for (Title t : model.getTitles()) {
      tc = renderCell(tr, t, "th", null, null, null, false, null, "white", imagePath);
      if (t.width != 0) tc.setAttribute("style", "width: " + Integer.toString(t.width) + "px");
    }
    if (tc != null && model.getDocoRef() != null)
      tc.addTag("span")
          .setAttribute("style", "float: right")
          .addTag("a")
          .setAttribute("title", "Legend for this format")
          .setAttribute("href", model.getDocoRef())
          .addTag("img")
          .setAttribute("alt", "doco")
          .setAttribute("style", "background-color: inherit")
          .setAttribute("src", model.getDocoImg());

    for (Row r : model.getRows()) {
      renderRow(table, r, 0, new ArrayList<Boolean>(), imagePath);
    }
    if (model.getDocoRef() != null) {
      tr = table.addTag("tr");
      tc = tr.addTag("td");
      tc.setAttribute("class", "hierarchy");
      tc.setAttribute("colspan", Integer.toString(model.getTitles().size()));
      tc.addTag("br");
      XhtmlNode a =
          tc.addTag("a")
              .setAttribute("title", "Legend for this format")
              .setAttribute("href", model.getDocoRef());
      if (model.getDocoImg() != null)
        a.addTag("img")
            .setAttribute("alt", "doco")
            .setAttribute("style", "background-color: inherit")
            .setAttribute("src", model.getDocoImg());
      a.addText(" Documentation for this format");
    }
    return table;
  }