/**
   * Returns a html representation of the construction protocol.
   *
   * @param imgBase64 : image file to be included
   */
  public String getHTML(String imgBase64) {
    StringBuilder sb = new StringBuilder();

    boolean icon_column;

    // Let's be W3C compliant:
    sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n");
    sb.append("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
    sb.append("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">");
    sb.append("<head>\n");
    sb.append("<title>");
    sb.append(StringUtil.toHTMLString(GeoGebraConstants.APPLICATION_NAME));
    sb.append(" - ");
    sb.append(app.getPlain("ConstructionProtocol"));
    sb.append("</title>\n");
    sb.append("<meta keywords = \"");
    sb.append(StringUtil.toHTMLString(GeoGebraConstants.APPLICATION_NAME));
    sb.append(" export\">");

    sb.append(
        "<style type=\"text/css\"><!--body { font-family:Arial,Helvetica,sans-serif; margin-left:40px }--></style>");

    sb.append("<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">");
    sb.append("</head>\n");

    sb.append("<body>\n");

    // header with title
    Construction cons = kernel.getConstruction();
    String title = cons.getTitle();
    if (!title.equals("")) {
      sb.append("<h1>");
      sb.append(StringUtil.toHTMLString(title));
      sb.append("</h1>\n");
    }

    // header with author and date
    String author = cons.getAuthor();
    String date = cons.getDate();
    String line = null;
    if (!author.equals("")) {
      line = author;
    }
    if (!date.equals("")) {
      if (line == null) line = date;
      else line = line + " - " + date;
    }
    if (line != null) {
      sb.append("<h3>");
      sb.append(StringUtil.toHTMLString(line));
      sb.append("</h3>\n");
    }

    // include image file
    if (imgBase64 != null) {
      sb.append("<p>\n");
      sb.append("<img src=\"data:image/png;base64,");
      sb.append(imgBase64);
      sb.append("\" alt=\"");
      sb.append(StringUtil.toHTMLString(GeoGebraConstants.APPLICATION_NAME));
      sb.append(' ');
      sb.append(StringUtil.toHTMLString(app.getPlain("DrawingPad")));
      sb.append("\" border=\"1\">\n");
      sb.append("</p>\n");
    }

    // table
    sb.append("<table border=\"1\">\n");

    // table headers
    sb.append("<tr>\n");
    TableColumnModel colModel = table.getColumnModel();
    int nColumns = colModel.getColumnCount();

    for (int nCol = 0; nCol < nColumns; nCol++) {
      // toolbar icon will only be inserted on request

      icon_column = table.getColumnName(nCol).equals("ToolbarIcon");
      if ((icon_column && addIcons) || !icon_column) {
        TableColumn tk = colModel.getColumn(nCol);
        title = (String) tk.getIdentifier();
        sb.append("<th>");
        sb.append(StringUtil.toHTMLString(title));
        sb.append("</th>\n");
      }
    }
    sb.append("</tr>\n");

    // table rows
    int endRow = table.getRowCount();
    for (int nRow = 0; nRow < endRow; nRow++) {
      sb.append("<tr  valign=\"baseline\">\n");
      for (int nCol = 0; nCol < nColumns; nCol++) {

        // toolbar icon will only be inserted on request
        icon_column = table.getColumnName(nCol).equals("ToolbarIcon");
        if ((icon_column && addIcons) || !icon_column) {
          int col = table.getColumnModel().getColumn(nCol).getModelIndex();
          String str =
              StringUtil.toHTMLString(
                  ((ConstructionTableData) data).getPlainHTMLAt(nRow, col), false);
          sb.append("<td>");
          if (str.equals("")) sb.append("&nbsp;"); // space
          else {
            Color color = ((ConstructionTableData) data).getColorAt(nRow, col);
            if (color != Color.black) {
              sb.append("<span style=\"color:#");
              sb.append(StringUtil.toHexString(new org.geogebra.desktop.awt.GColorD(color)));
              sb.append("\">");
              sb.append(str);
              sb.append("</span>");
            } else sb.append(str);
          }
          sb.append("</td>\n");
        }
      }
      sb.append("</tr>\n");
    }

    sb.append("</table>\n");

    // footer
    sb.append(((GuiManagerD) app.getGuiManager()).getCreatedWithHTML(false));

    // append base64 string so that file can be reloaded with File -> Open
    sb.append(
        "\n<!-- Base64 string so that this file can be opened in GeoGebra with File -> Open -->");
    sb.append("\n<applet style=\"display:none\">");
    sb.append("\n<param name=\"ggbBase64\" value=\"");
    appendBase64((AppD) app, sb);
    sb.append("\">\n<applet>");

    sb.append("\n</body>");
    sb.append("\n</html>");

    return sb.toString();
  }