// 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.
(function() {
  'use strict';

  var DiffSides = {
    LEFT: 'left',
    RIGHT: 'right',
  };

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

  var LEFT_SIDE_CLASS = 'target-side-left';
  var RIGHT_SIDE_CLASS = 'target-side-right';

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

    properties: {
      /**
       * Either DiffSides.LEFT or DiffSides.RIGHT.
       */
      side: {
        type: String,
        value: DiffSides.RIGHT,
      },
      diffRow: {
        type: Object,
        notify: true,
        observer: '_rowChanged',
      },

      /**
       * The diff views to cursor through and listen to.
       */
      diffs: {
        type: Array,
        value: function() {
          return [];
        },
      },

      foldOffsetTop: {
        type: Number,
        value: 0,
      },

      /**
       * If set, the cursor will attempt to move to the line number (instead of
       * the first chunk) the next time the diff renders. It is set back to null
       * when used.
       */
      initialLineNumber: {
        type: Number,
        value: null,
      },
    },

    observers: [
      '_updateSideClass(side)',
      '_diffsChanged(diffs.splices)',
    ],

    moveLeft: function() {
      this.side = DiffSides.LEFT;
      if (this._isTargetBlank()) {
        this.moveUp();
      }
    },

    moveRight: function() {
      this.side = DiffSides.RIGHT;
      if (this._isTargetBlank()) {
        this.moveUp();
      }
    },

    moveDown: function() {
      if (this._getViewMode() === DiffViewMode.SIDE_BY_SIDE) {
        this.$.cursorManager.next(this._rowHasSide.bind(this));
      } else {
        this.$.cursorManager.next();
      }
    },

    moveUp: function() {
      if (this._getViewMode() === DiffViewMode.SIDE_BY_SIDE) {
        this.$.cursorManager.previous(this._rowHasSide.bind(this));
      } else {
        this.$.cursorManager.previous();
      }
    },

    moveToNextChunk: function() {
      this.$.cursorManager.next(this._isFirstRowOfChunk.bind(this));
      this._fixSide();
    },

    moveToPreviousChunk: function() {
      this.$.cursorManager.previous(this._isFirstRowOfChunk.bind(this));
      this._fixSide();
    },

    moveToNextCommentThread: function() {
      this.$.cursorManager.next(this._rowHasThread.bind(this));
      this._fixSide();
    },

    moveToPreviousCommentThread: function() {
      this.$.cursorManager.previous(this._rowHasThread.bind(this));
      this._fixSide();
    },

    moveToLineNumber: function(number, side) {
      var row = this._findRowByNumber(number, side);
      if (row) {
        this.side = side;
        this.$.cursorManager.setCursor(row);
      }
    },

    /**
     * Get the line number element targeted by the cursor row and side.
     * @return {DOMElement}
     */
    getTargetLineElement: function() {
      var lineElSelector = '.lineNum';

      if (!this.diffRow) {
        return;
      }

      if (this._getViewMode() === DiffViewMode.SIDE_BY_SIDE) {
        lineElSelector += this.side === DiffSides.LEFT ? '.left' : '.right';
      }

      return this.diffRow.querySelector(lineElSelector);
    },

    getTargetDiffElement: function() {
      // Find the parent diff element of the cursor row.
      for (var diff = this.diffRow; diff; diff = diff.parentElement) {
        if (diff.tagName === 'GR-DIFF') { return diff; }
      }
      return null;
    },

    moveToFirstChunk: function() {
      this.$.cursorManager.moveToStart();
      this.moveToNextChunk();
    },

    reInitCursor: function() {
      this._updateStops();
      if (this.initialLineNumber) {
        this.moveToLineNumber(this.initialLineNumber, this.side);
        this.initialLineNumber = null;
      } else {
        this.moveToFirstChunk();
      }
    },

    handleDiffUpdate: function() {
      this._updateStops();

      if (!this.diffRow) {
        this.reInitCursor();
      }
    },

    /**
     * Get a short address for the location of the cursor. Such as '123' for
     * line 123 of the revision, or 'b321' for line 321 of the base patch.
     * Returns an empty string if an address is not available.
     * @return {String}
     */
    getAddress: function() {
      if (!this.diffRow) { return ''; }

      // Get the line-number cell targeted by the cursor. If the mode is unified
      // then prefer the revision cell if available.
      var cell;
      if (this._getViewMode() === DiffViewMode.UNIFIED) {
        cell = this.diffRow.querySelector('.lineNum.right');
        if (!cell) {
          cell = this.diffRow.querySelector('.lineNum.left');
        }
      } else {
        cell = this.diffRow.querySelector('.lineNum.' + this.side);
      }
      if (!cell) { return ''; }

      var number = cell.getAttribute('data-value');
      if (!number || number === 'FILE') { return ''; }

      return (cell.matches('.left') ? 'b' : '') + number;
    },

    _getViewMode: function() {
      if (!this.diffRow) {
        return null;
      }

      if (this.diffRow.classList.contains('side-by-side')) {
        return DiffViewMode.SIDE_BY_SIDE;
      } else {
        return DiffViewMode.UNIFIED;
      }
    },

    _rowHasSide: function(row) {
      var selector = (this.side === DiffSides.LEFT ? '.left' : '.right') +
          ' + .content';
      return !!row.querySelector(selector);
    },

    _isFirstRowOfChunk: function(row) {
      var parentClassList = row.parentNode.classList;
      return parentClassList.contains('section') &&
          parentClassList.contains('delta') &&
          !row.previousSibling;
    },

    _rowHasThread: function(row) {
      return row.querySelector('gr-diff-comment-thread');
    },

    /**
     * If we jumped to a row where there is no content on the current side then
     * switch to the alternate side.
     */
    _fixSide: function() {
      if (this._getViewMode() === DiffViewMode.SIDE_BY_SIDE &&
          this._isTargetBlank()) {
        this.side = this.side === DiffSides.LEFT ?
            DiffSides.RIGHT : DiffSides.LEFT;
      }
    },

    _isTargetBlank: function() {
      if (!this.diffRow) {
        return false;
      }

      var actions = this._getActionsForRow();
      return (this.side === DiffSides.LEFT && !actions.left) ||
          (this.side === DiffSides.RIGHT && !actions.right);
    },

    _rowChanged: function(newRow, oldRow) {
      if (oldRow) {
        oldRow.classList.remove(LEFT_SIDE_CLASS, RIGHT_SIDE_CLASS);
      }
      this._updateSideClass();
    },

    _updateSideClass: function() {
      if (!this.diffRow) {
        return;
      }
      this.toggleClass(LEFT_SIDE_CLASS, this.side === DiffSides.LEFT,
          this.diffRow);
      this.toggleClass(RIGHT_SIDE_CLASS, this.side === DiffSides.RIGHT,
          this.diffRow);
    },

    _isActionType: function(type) {
      return type !== 'blank' && type !== 'contextControl';
    },

    _getActionsForRow: function() {
      var actions = {left: false, right: false};
      if (this.diffRow) {
        actions.left = this._isActionType(
            this.diffRow.getAttribute('left-type'));
        actions.right = this._isActionType(
            this.diffRow.getAttribute('right-type'));
      }
      return actions;
    },

    _getStops: function() {
      return this.diffs.reduce(
          function(stops, diff) {
            return stops.concat(diff.getCursorStops());
          }, []);
    },

    _updateStops: function() {
      this.$.cursorManager.stops = this._getStops();
    },

    /**
     * Setup and tear down on-render listeners for any diffs that are added or
     * removed from the cursor.
     * @private
     */
    _diffsChanged: function(changeRecord) {
      if (!changeRecord) { return; }

      this._updateStops();

      var splice;
      var i;
      for (var spliceIdx = 0;
        changeRecord.indexSplices &&
            spliceIdx < changeRecord.indexSplices.length;
        spliceIdx++) {
        splice = changeRecord.indexSplices[spliceIdx];

        for (i = splice.index;
            i < splice.index + splice.addedCount;
            i++) {
          this.listen(this.diffs[i], 'render', 'handleDiffUpdate');
        }

        for (i = 0;
            i < splice.removed && splice.removed.length;
            i++) {
          this.unlisten(splice.removed[i], 'render', 'handleDiffUpdate');
        }
      }
    },

    _findRowByNumber: function(targetNumber, side) {
      var stops = this.$.cursorManager.stops;
      var selector;
      for (var i = 0; i < stops.length; i++) {
        selector = '.lineNum.' + side + '[data-value="' + targetNumber + '"]';
        if (stops[i].querySelector(selector)) {
          return stops[i];
        }
      }
    },
  });
})();
