<!--
Copyright (C) 2016 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../gr-diff-processor/gr-diff-processor.html">
<link rel="import" href="../gr-ranged-comment-layer/gr-ranged-comment-layer.html">

<dom-module id="gr-diff-builder">
  <template>
    <div class="contentWrapper">
      <content></content>
    </div>
    <gr-ranged-comment-layer
        id="rangeLayer"
        comments="[[comments]]"></gr-ranged-comment-layer>
    <gr-diff-processor
        id="processor"
        groups="{{_groups}}"></gr-diff-processor>
  </template>
  <script src="../gr-diff/gr-diff-line.js"></script>
  <script src="../gr-diff/gr-diff-group.js"></script>
  <script src="../gr-diff-highlight/gr-annotation.js"></script>
  <script src="gr-diff-builder.js"></script>
  <script src="gr-diff-builder-side-by-side.js"></script>
  <script src="gr-diff-builder-unified.js"></script>
  <script src="gr-diff-builder-image.js"></script>
  <script>
    (function() {
      'use strict';

      var DiffViewMode = {
        SIDE_BY_SIDE: 'SIDE_BY_SIDE',
        UNIFIED: 'UNIFIED_DIFF',
      };

      Polymer({
        is: 'gr-diff-builder',

        /**
         * Fired when the diff is rendered.
         *
         * @event render
         */

        properties: {
          viewMode: String,
          comments: Object,
          isImageDiff: Boolean,
          baseImage: Object,
          revisionImage: Object,
          _builder: Object,
          _groups: Array,
          _layers: Array,
        },

        get diffElement() {
          return this.queryEffectiveChildren('#diffTable');
        },

        observers: [
          '_groupsChanged(_groups.splices)',
        ],

        attached: function() {
          // Setup annotation layers.
          this._layers = [
            this._createIntralineLayer(),
            this.$.rangeLayer,
          ];
        },

        render: function(diff, comments, prefs) {
          // Stop the processor (if it's running).
          this.$.processor.cancel();

          this._builder = this._getDiffBuilder(diff, comments, prefs);

          this.$.processor.context = prefs.context;
          this.$.processor.keyLocations = this._getCommentLocations(comments);

          this._clearDiffContent();

          console.time('diff render');
          this.$.processor.process(diff.content).then(function() {
            if (this.isImageDiff) {
              this._builder.renderDiffImages();
            }
            console.timeEnd('diff render');
            this.fire('render');
          }.bind(this));
        },

        getLineElByChild: function(node) {
          while (node) {
            if (node instanceof Element) {
              if (node.classList.contains('lineNum')) {
                return node;
              }
              if (node.classList.contains('section')) {
                return null;
              }
            }
            node = node.previousSibling || node.parentElement;
          }
          return null;
        },

        getLineNumberByChild: function(node) {
          var lineEl = this.getLineElByChild(node);
          return lineEl ?
              parseInt(lineEl.getAttribute('data-value'), 10) : null;
        },

        renderLineRange: function(startLine, endLine, opt_side) {
          var groups =
              this._builder.getGroupsByLineRange(startLine, endLine, opt_side);
          groups.forEach(function(group) {
            var newElement = this._builder.buildSectionElement(group);
            var oldElement = group.element;

            // Transfer comment threads from existing section to new one.
            var threads = Polymer.dom(newElement).querySelectorAll(
                'gr-diff-comment-thread');
            threads.forEach(function(threadEl) {
              var lineEl = this.getLineElByChild(threadEl, oldElement);
              if (!lineEl) { // New comment thread.
                return;
              }
              var side = this.getSideByLineEl(lineEl);
              var line = lineEl.getAttribute('data-value');
              var oldThreadEl =
                  this.getCommentThreadByLine(line, side, oldElement);
              threadEl.parentNode.replaceChild(oldThreadEl, threadEl);
            }, this);

            // Replace old group elements with new ones.
            group.element.parentNode.replaceChild(newElement, group.element);
            group.element = newElement;
          }, this);

          this.async(function() {
            this.fire('render');
          }, 1);
        },

        getContentByLine: function(lineNumber, opt_side, opt_root) {
          return this._builder.getContentByLine(lineNumber, opt_side, opt_root);
        },

        getContentByLineEl: function(lineEl) {
          var root = Polymer.dom(lineEl.parentElement);
          var side = this.getSideByLineEl(lineEl);
          var line = lineEl.getAttribute('data-value');
          return this.getContentByLine(line, side, root);
        },

        getLineElByNumber: function(lineNumber, opt_side) {
          var sideSelector = !!opt_side ? ('.' + opt_side) : '';
          return this.diffElement.querySelector(
              '.lineNum[data-value="' + lineNumber + '"]' + sideSelector);
        },

        getContentsByLineRange: function(startLine, endLine, opt_side) {
          var result = [];
          this._builder.findLinesByRange(startLine, endLine, opt_side, null,
              result);
          return result;
        },

        getCommentThreadByLine: function(lineNumber, opt_side, opt_root) {
          var content = this.getContentByLine(lineNumber, opt_side, opt_root);
          return this.getCommentThreadByContentEl(content);
        },

        getCommentThreadByContentEl: function(contentEl) {
          if (contentEl.classList.contains('contentText')) {
            contentEl = contentEl.parentElement;
          }
          return contentEl.querySelector('gr-diff-comment-thread');
        },

        getSideByLineEl: function(lineEl) {
          return lineEl.classList.contains(GrDiffBuilder.Side.RIGHT) ?
              GrDiffBuilder.Side.RIGHT : GrDiffBuilder.Side.LEFT;
        },

        createCommentThread: function(changeNum, patchNum, path, side,
            projectConfig) {
          return this._builder.createCommentThread(changeNum, patchNum, path,
              side, projectConfig);
        },

        emitGroup: function(group, sectionEl) {
          this._builder.emitGroup(group, sectionEl);
        },

        showContext: function(newGroups, sectionEl) {
          var groups = this._builder.groups;
          // TODO(viktard): Polyfill findIndex for IE10.
          var contextIndex = groups.findIndex(function(group) {
            return group.element == sectionEl;
          });
          groups.splice.apply(groups, [contextIndex, 1].concat(newGroups));

          newGroups.forEach(function(newGroup) {
            this._builder.emitGroup(newGroup, sectionEl);
          }, this);
          sectionEl.parentNode.removeChild(sectionEl);

          this.async(function() {
            this.fire('render');
          }, 1);
        },

        _getDiffBuilder: function(diff, comments, prefs) {
          if (this.isImageDiff) {
            return new GrDiffBuilderImage(diff, comments, prefs,
                this.diffElement, this.baseImage, this.revisionImage);
          } else if (this.viewMode === DiffViewMode.SIDE_BY_SIDE) {
            return new GrDiffBuilderSideBySide(
                diff, comments, prefs, this.diffElement, this._layers);
          } else if (this.viewMode === DiffViewMode.UNIFIED) {
            return new GrDiffBuilderUnified(
                diff, comments, prefs, this.diffElement, this._layers);
          }
          throw Error('Unsupported diff view mode: ' + this.viewMode);
        },

        _clearDiffContent: function() {
          this.diffElement.innerHTML = null;
        },

        _getCommentLocations: function(comments) {
          var result = {
            left: {},
            right: {},
          };
          for (var side in comments) {
            if (side !== GrDiffBuilder.Side.LEFT &&
                side !== GrDiffBuilder.Side.RIGHT) {
              continue;
            }
            comments[side].forEach(function(c) {
              result[side][c.line || GrDiffLine.FILE] = true;
            });
          }
          return result;
        },

        _groupsChanged: function(changeRecord) {
          if (!changeRecord) { return; }
          changeRecord.indexSplices.forEach(function(splice) {
            var group;
            for (var i = 0; i < splice.addedCount; i++) {
              group = splice.object[splice.index + i];
              this._builder.groups.push(group);
              this._builder.emitGroup(group);
            }
          }, this);
        },

        _createIntralineLayer: function() {
          return {
            addListener: function() {},

            // Take a DIV.contentText element and a line object with intraline
            // differences to highlight and apply them to the element as
            // annotations.
            annotate: function(el, line, GrAnnotation) {
              var HL_CLASS = 'style-scope gr-diff';
              line.highlights.forEach(function(highlight) {
                // The start and end indices could be the same if a highlight is
                // meant to start at the end of a line and continue onto the
                // next one. Ignore it.
                if (highlight.startIndex === highlight.endIndex) { return; }

                // If endIndex isn't present, continue to the end of the line.
                var endIndex = highlight.endIndex === undefined ?
                    line.text.length : highlight.endIndex;

                GrAnnotation.annotateElement(
                    el,
                    highlight.startIndex,
                    endIndex - highlight.startIndex,
                    HL_CLASS);
              });
            },
          };
        },
      });
    })();
  </script>
</dom-module>
