<!--
  This in an HTML Import-able file that contains the definition
  of the following elements:

    <commits-table-d3-sk>

  This uses d3 to draw the commit table.  Unlike previous versions which used a table and basically
  drew the table row by row, this implementation draws it column by column.  Because filtering
  happens on a task spec (column) basis, drawing it column by column results in simpler code.

  D3 is much much faster than Polymer for this type of data visualization, although this element
  still offers a Polymer interface.  If any of the inputs change, the table will be redrawn.

  To use this file import it:

    <link href="/res/imp/commits-table-d3-sk" rel="import" />

  Usage:

    <commits-table-d3-sk></commits-table-d3-sk>

  Properties:
    // inputs
    task_details: Object, a map of commit hash to an object that has the task results by task spec.
    task_specs: Object, a map of the task spec names to an object that has, among other things, category,
        subcategory, and comments.
    tasks: Object, a map of the task spec names to an object that maps task IDs to task results.
    categories: Object, a map of the task spec categories to an object that has the subcategories and
        the colspan (total number of included task specs).
    category_list: Array<String>, an array of the task spec category names.
    commits: Array<Object>, the commit objects, in chronological detail.
    commits_map: Object, a map of commit hash to commit objects.
    logged_in: Boolean, if the links should be for internal or external pages.
    relanded_map: Object, a map of a commit hash that was relanded to the commit object that relands it.
    repo: String, the current repo.  Used to direct comments to the right place.
    repo_base: The base URL for commits. Commit hashes will be appended to this.
    reverted_map: Object, a map of a commit hash that was reverted to the commit object that reverts it.
    swarming_url: String, the URL of the Swarming server.
    task_scheduler_url: String, the URL of the Task Scheduler.

  Methods:
    None.

  Events:
    None.
-->
<script src="/res/imp/bower_components/d3/d3.min.js"></script>

<link rel="import" href="/res/imp/bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/iron-icons.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/communication-icons.html">
<link rel="import" href="/res/imp/bower_components/iron-icons/image-icons.html">
<link rel="import" href="/res/imp/bower_components/paper-dialog/paper-dialog.html">

<link rel="import" href="/res/common/imp/styles-sk.html">

<link rel="import" href="task-popup-sk.html">
<link rel="import" href="taskspec-popup-sk.html">
<link rel="import" href="commit-popup-sk.html">

<link rel="stylesheet" href="commits-table-d3.css">
<dom-module id="commits-table-d3-sk">
  <template>
    <style include="iron-flex styles-sk">
      #commits {
        min-height: 780px;
        min-width: 50px;
      }
      #tasks {
        border: 1px solid blue;
        min-height: 400px;
      }
      #legend {
        border-right: 1px solid black;
        font-size: 10px;
        height: 68px;
      }
      #table {
        /* 80 pixels of header and 35 * 20px of commits.
        It is important to preallocate this size, otherwise the flexbox layout
        behaves strangely (i.e. wrong) when the data is first added. */
        min-height: 780px;
      }
      iframe {
        border: 0;
      }
    </style>

    <div id="container" class="horizontal layout">
      <div id="commits">
        <div id="legend">
          <iron-icon class="tiny" icon="communication:chat"></iron-icon> comment<br/>
          <iron-icon class="tiny" icon="image:texture"></iron-icon> flaky<br/>
          <iron-icon class="tiny" icon="icons:block"></iron-icon> ignore failure<br/>
          <iron-icon class="tiny fg-failure" icon="icons:undo"></iron-icon> reverted<br/>
          <iron-icon class="tiny fg-success" icon="icons:redo"></iron-icon> relanded<br/>
        </div>
      </div>
      <div id="table" class="flex horizontal layout"></div>
    </div>

    <div id="infoDialog"></div>

  </template>
  <script>
  (function(){
    var TASK_HEIGHT = 20;
    Polymer({
      is: 'commits-table-d3-sk',
      properties: {
        // inputs from data source to render.
        task_specs: {
          type: Object,
        },
        task_details: {
          type: Object,
        },
        tasks: {
          type: Object,
        },
        categories: {
          type: Object,
        },
        category_list: {
          type: Array,
        },
        commit_label: {
          type: String,
        },
        commits: {
          type: Array,
        },
        commits_map: {
          type: Object,
        },
        logged_in: {
          type: Boolean,
        },
        relanded_map: {
          type: Object,
        },
        repo: {
          type: String,
        },
        repo_base: {
          type: String,
        },
        reverted_map: {
          type: Object,
        },
        swarming_url: {
          type: String,
        },
        time_points: {
          type: Object,
        },
        task_scheduler_url: {
          type: String,
        },

        // outputs
        drawing: {
          type: Boolean,
          notify: true,
          value: false,
        }
      },
      observers: [
        "redraw(task_specs, task_details, categories, category_list, commit_label, commits, commits_map, relanded_map, repo, reverted_map, time_points)",
      ],

      ready: function() {
        // We redraw, so as to try to better fit the screen size.
        d3.select(window).on('resize', this.redraw.bind(this));
        this.scopeSubtree(this.$.container, true);
      },

      redraw:function() {
        // This gets called any time one of the values changes.  Since the values are
        // updated simultaneously, we don't want to try to draw the table many times at the
        // same time, so we debounce it.  No timeout on the debounce because all the this.set
        // calls will happen before a paint call, so this just basically collates all the requests.
        this.debounce("redraw-commits-table", function(){
          this._redraw();
        }.bind(this));
      },

      _redraw:function() {
        this.set("drawing", true);
        console.time("d3 rendering");

        // Display pictures instead of tasks if there aren't any to display.
        var iframe = null;
        for (var i = 0; i < this.$.table.childNodes.length; i++) {
          var child = this.$.table.childNodes[i];
          if (child.tagName == "IFRAME") {
            iframe = child;
            break;
          }
        }
        if (this.category_list.length === 0) {
          if (!iframe) {
            iframe = document.createElement("iframe");
            iframe.src = "https://clients3.google.com/cast/chromecast/home?slideshow-period=300";
            this.$.table.appendChild(iframe);
          }
          // Images are 1920x1080. Scale to fit the size of the div.
          srcWidth = 1920;
          srcHeight = 1080;
          var scale = Math.min(this.$.table.clientWidth / srcWidth, this.$.table.clientHeight / srcHeight);
          iframe.style.width = (srcWidth * scale) + "px";
          iframe.style.height = (srcHeight * scale) + "px";
        } else {
          if (iframe) {
            this.$.table.removeChild(iframe);
          }
        }

        this._drawCommitMessages(this.commits, this.relanded_map, this.reverted_map, this.time_points);
        this._drawCategories(this.category_list, this.categories);
        this._drawSubCategories(this.categories);
        this._drawTaskSpecColumns(this.categories, this.task_specs, this.commits.length);
        this._drawTasks(this.commits, this.task_details);
        console.timeEnd("d3 rendering");
        this.set("drawing", false);
      },

      // Draw all of the commit divs that are on the left.
      _drawCommitMessages: function(commits, relanded_map, reverted_map, time_points){
        var openCommitDialog = this._openCommitDialog.bind(this);
        var commitLabel = this.commit_label;
        // It's easiest to delete all .commits and redraw them.  Normally, we would only update
        // the ones we want, but since we have a composed element and there aren't very many
        // commits, starting from scratch is simplest.
        d3.select(this.$.commits).selectAll(".commit").remove();
        var data = d3.select(this.$.commits).selectAll(".commit")
          .data(commits, function(commit, i){
            commit.index = i;
            return commit.hash;
          });
        // Create a commit div for each commit with id "patch_storage + codereview_number".
        // Eg: "gerrit12345" for Gerrit.
        // For posterity: Element selectors choke if an id starts with a number, thus the
        // patch_storage prefix helps with that.
        var newCommits = data
          .enter()
          .append("div")
          .classed("commit",true)
          .attr("id", function(commit){
            return commit.patchStorage + commit.issue;
          })
          .on("tap", function(commit) {
            // Stop the propogation so we don't immediately hide the popup we show.
            d3.event.stopPropagation();
            openCommitDialog(commit);
          });
        // Sort the commits to be in the order we are presented with them.
        data.order();
        // Set the mouseover to be the opposite of what the label says.
        newCommits
          .attr("title", function(commit) {
            if (commitLabel == "author") {
              return commit.shortSubject;
            }
            return commit.author;
          });

        // Add a spacer to every commit where the time bubble could be.  This allows all
        // the bubbles and non-bubble commits to line up vertically.
        var spacers = newCommits
          .insert("div")
          .classed("time-spacer",true);

        spacers.each(function(commit) {
          var point = time_points[commit.hash];
          if (point) {
          d3.select(this)
            .append("span")
            .classed("time-underline", true);
          d3.select(this)
            .insert("span")
            .classed("time", true)
            .attr("title", point.label)
            .text(point.label);
          }
        });

        // Insert a span with the commit label.
        newCommits
          .insert("span")
          .classed("author", function(){
            return commitLabel == "author";
          })
          .classed("subject", function(){
            return commitLabel == "subject";
          })
          .text(function(commit) {
            if (commitLabel == "author") {
              return commit.shortAuthor || "[no author]";
            }
            return commit.shortSubject || "[no subject]";
        });

        newCommits
          .insert("div")
          .classed("flex", true);
        newCommits
          .insert("span")
          .classed("commit-comment", true);
        newCommits
          .insert("span")
          .classed("commit-ignore", true);
        newCommits
          .insert("span")
          .classed("commit-revert", true);
        newCommits
          .insert("span")
          .classed("commit-reland", true);

        // On the other side, conditionally draw iron icons for comments, relands, reverts.
        this._addIronIcon(newCommits.select(".commit-comment"), "communication:chat", "tiny", function(commit){
          return commit.comments && commit.comments.length > 0;
        });
        this._addIronIcon(newCommits.select(".commit-ignore"), "icons:block", "tiny", function(commit){
            return commit.ignoreFailure;
        });
        var reverts = this._addIronIcon(newCommits.select(".commit-revert"), "icons:undo", "tiny fg-failure", function(commit){
          var reverterCommit = reverted_map[commit.hash];
          return (reverterCommit !== undefined && reverterCommit.timestamp > commit.timestamp);
        });
        reverts.on("mouseover", function(commit){
          var reverterIssue = reverted_map[commit.hash].issue;
          d3.select("#"+commit.patchStorage+reverterIssue).classed("bg-failure", true);
        })
        reverts.on("mouseleave", function(commit){
          d3.selectAll(".commit.bg-failure").classed("bg-failure", false);
        })
        var relands = this._addIronIcon(newCommits.select(".commit-reland"), "icons:redo", "tiny fg-success", function(commit){
          var relanderCommit = relanded_map[commit.hash];
          return (relanderCommit !== undefined && relanderCommit.timestamp > commit.timestamp);
        });
        relands.on("mouseover", function(commit){
          var relanderIssue = relanded_map[commit.hash].issue;
          d3.select("#"+commit.patchStorage+relanderIssue).classed("bg-success", true);
        });
        relands.on("mouseleave", function(commit){
          d3.selectAll(".commit.bg-success").classed("bg-success", false);
        });
      },

      // Adds iron icons to everything in the selection if shouldAddIcon returns truthy.  It
      // returns all icons that were added.
      _addIronIcon: function(selection, icon, classes, shouldAddIcon) {
        return selection
          .html(function(commit){
            // The Polymer templates will pick this up and make it a real iron-icon element.
            // However, if you try to do .insert("iron-icon")... that does not work.
            if (shouldAddIcon === undefined || shouldAddIcon(commit)) {
              return "<iron-icon class=\""+classes+"\" icon=\"" + icon + "\"></iron-icon>";
            }
          });
      },

      // Draw all of the divs for the categories, including the header.
      _drawCategories: function(category_list, categories){
        var data = d3.select(this.$.table).selectAll(".category")
          .data(category_list, function(category){
            return category;
          });
        data.exit().remove();
        var newCategories = data
          .enter()
          .append("div")
          .classed("category",true);
        data.order();
        data
          .style("flex-grow", function(category){
            // This keeps the rows about as evenly sized as possible.
            // colspan is the total number of task specs in this category.
            return categories[category].colspan;
          });

        newCategories
          .insert("div")
          .classed("category-title", true)
          .text(function(category){
            return category;
          })
        // .subcategories will hold all of the .subcategory elements.
        newCategories
          .insert("div")
          .classed("subcategories", true);
      },

      // Draw all of the divs for the subcategories, including the header
      _drawSubCategories: function(categories) {
        d3.select(this.$.table).selectAll(".subcategories").each(function(category){
          if (!categories[category]) {
            return;
          }
          var list = categories[category].subcategoryList.map(function(subcat){
            return {
              "category": category,
              "subcategory": subcat,
            };
          });

          var data = d3.select(this)
            .selectAll(".subcategory")
            .data(list, function(d) {
              return d.category + d.subcategory;
            });
          data.exit().remove();
          var subcategories = data
            .enter()
            .insert("div")
            .classed("subcategory", true);
          data.order();
          data
            .style("flex-grow", function(d){
              // This keeps the rows about as evenly sized as possible.
              return categories[d.category].subcategories[d.subcategory].task_specs.length;
            });
          subcategories
            .insert("div")
            .classed("subcategory-title", true)
            .text(function(d){
              return d.subcategory;
            });
          // .task-specs will hold all of the .task-spec elements.
          subcategories
            .insert("div")
            .classed("task-specs", true);
        });
      },

      // draw all of the task spec columns, including the header box with the flaky, ignore_failure,
      // and comment icons
      _drawTaskSpecColumns: function(categories, taskSpecs, num_commits) {
        var addIronIcon = this._addIronIcon.bind(this);
        var openTaskSpecDialog = this._openTaskSpecDialog.bind(this);
        d3.select(this.$.table).selectAll(".task-specs").each(function(d){
          if (!categories[d.category].subcategories[d.subcategory]) {
            return;
          }
          var list = categories[d.category].subcategories[d.subcategory].task_specs.map(function(taskSpec){
            return {
              "category": d.category,
              "subcategory": d.subcategory,
              "taskSpec": taskSpec,
            };
          });

          var data = d3.select(this)
            .selectAll(".task-spec")
            .data(list, function(d) {
              return d.category + d.subcategory + d.taskSpec;
            });
          data.exit().remove();
          var newTaskSpecs = data
            .enter()
            .insert("div")
            .classed("task-spec", true);
          data.order();
          var titles = newTaskSpecs
            .insert("div")
            .classed("task-spec-title", true)
            .attr("title", function(d){
              return d.taskSpec;
            })
            .on("tap", function(d){
              // Stop the propogation so we don't immediately hide the popup we show.
              d3.event.stopPropagation();
              openTaskSpecDialog(d.taskSpec);
            });
          titles
            .insert("span")
            .classed("taskspec-comment", true);
          titles
            .insert("span")
            .classed("taskspec-ignore", true);
          titles
            .insert("span")
            .classed("taskspec-flaky", true);

          addIronIcon(data.selectAll(".taskspec-ignore"), "icons:block", "tiny", function(d){
            return taskSpecs[d.taskSpec].ignoreFailure;
          });
          addIronIcon(data.selectAll(".taskspec-flaky"), "image:texture", "tiny", function(d){
            return taskSpecs[d.taskSpec].flaky;
          });
          addIronIcon(data.selectAll(".taskspec-comment"), "communication:chat", "tiny", function(d){
            return taskSpecs[d.taskSpec].comments && taskSpecs[d.taskSpec].comments.length > 0;
          });

          newTaskSpecs
            .insert("div")
            .classed("task-spec-spacer", true);

          // Set the height so that flexing doesn't throw off the multi column alignment.
          newTaskSpecs
            .insert("div")
            .classed("tasks", true)
            .style("max-height", function(){
              return (TASK_HEIGHT * num_commits) + "px";
            });
            // .style("min-height", function(){
            //   return (TASK_HEIGHT * num_commits) + "px";
            // });
        });
      },

      // Draws the task divs.  We forego flexbox helping us align these.  First, we create a task
      // div (which is a fixed height) in side of it create a div with the various task classes to
      // set the heights/widths/margins etc.  This is easier to line up with the adjacent columns
      // and allows for more consistent zooming behavior.
      _drawTasks: function(commits, task_details) {
        var openTaskDialog = this._openTaskDialog.bind(this);
        var addIronIcon = this._addIronIcon.bind(this);

        d3.select(this.$.table).selectAll(".tasks").each(function(d){
          var list = commits.map(function(commit) {
            return {
              "category": d.category,
              "subcategory": d.subcategory,
              "taskSpec": d.taskSpec,
              "commit": commit,
              "displayClass": commit.displayClass[d.taskSpec] || [],
            };
          });
          var data = d3.select(this)
            .selectAll(".task")
            .data(list, function(d) {
              return d.category + d.subcategory + d.taskSpec + d.commit.hash;
            });
          data.exit().remove();
          var newTasks = data
            .enter()
            .insert("div")
            .classed("task",true)
            .insert("div")
            .on("tap", function(d){
              // Stop the propogation so we don't immediately hide the popup we show.
              d3.event.stopPropagation();
              openTaskDialog(d);
            });
          newTasks
            .insert("span")
            .classed("task-comment", true);
          data.order();
          // Style the inside div.
          data.each(function(d){
            var task = this.children[0];
            // Remove any previously-set classes.
            var removeClasses = [];
            for (var i = 0; i < task.classList.length; i++) {
              var c = task.classList.item(i);
              if (c.indexOf("bg-") === 0 || c.indexOf("task_") === 0) {
                removeClasses.push(c);
              }
            }
            removeClasses.forEach(function(c) {
              task.classList.remove(c);
            });

            // Add task display class.
            for (var i = 0; i < d.displayClass.length; i++) {
              task.classList.add(d.displayClass[i]);
            }

            task.title = d.taskSpec + " @ " + d.commit.shortHash;

            var details = task_details[d.commit.hash] && task_details[d.commit.hash][d.taskSpec];
            if (details) {
              // Add the new class.
              task.classList.add(task_details[d.commit.hash][d.taskSpec].colorClass);
              addIronIcon(d3.select(task).select(".task-comment"), "communication:chat", "tiny", function(){
                return details.comments && details.comments.length > 0 &&
                    (task.classList.contains(CLASS_TASK_SINGLE)
                  || task.classList.contains(CLASS_TASK_TOP));
              });
            } else {
              task.style["background-color"] = "";
              task.title = "";
            }
          });
        });
      },

      _openTaskDialog: function(task) {
        if (this._infoPopupOpen()) {
          return;
        }
        var details = this.task_details[task.commit.hash][task.taskSpec];
        if (details) {
          var taskInfo = document.createElement("task-popup-sk");
          taskInfo.task = details;
          taskInfo.repo = this.repo;
          taskInfo.repo_base = this.repo_base;
          taskInfo.commit_details = this.commits_map;
          taskInfo.parent = this;
          taskInfo.swarming_url = this.swarming_url;
          taskInfo.task_scheduler_url = this.task_scheduler_url;
          this._openDialog(taskInfo);
        }
      },

      _openTaskSpecDialog: function(taskSpec) {
        if (this._infoPopupOpen()) {
          return;
        }
        if (taskSpec) {
          var taskSpecInfo = document.createElement("taskspec-popup-sk");
          taskSpecInfo.task_spec = this.task_specs[taskSpec];
          taskSpecInfo.repo = this.repo;
          taskSpecInfo.swarming_url = this.swarming_url;
          this._openDialog(taskSpecInfo);
        }
      },

      _openCommitDialog: function(commit) {
        if (this._infoPopupOpen()) {
          return;
        }
        var commitInfo = document.createElement("commit-popup-sk");
        commitInfo.commit = commit;
        commitInfo.repo = this.repo;
        commitInfo.repo_base = this.repo_base;
        this._openDialog(commitInfo);
      },

      // Is the info popup open?
      _infoPopupOpen: function() {
        return this.$.infoDialog.opened;
      },

      // Set the dialog content and open the dialog.
      _openDialog: function(child) {
        this.$.infoDialog.innerHTML = '';
        this.$.infoDialog.appendChild(child);
        child.show();
      },
    });
  })()
  </script>
</dom-module>
