/**
 * @license
 * 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';

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

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

  const ScrollBehavior = {
    KEEP_VISIBLE: 'keep-visible',
    NEVER: 'never',
  };

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

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

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

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

      /**
       * 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.
       *
       * @type {?number}
       */
      initialLineNumber: {
        type: Number,
        value: null,
      },

      /**
       * The scroll behavior for the cursor. Values are 'never' and
       * 'keep-visible'. 'keep-visible' will only scroll if the cursor is beyond
       * the viewport.
       */
      _scrollBehavior: {
        type: String,
        value: ScrollBehavior.KEEP_VISIBLE,
      },

      _focusOnMove: {
        type: Boolean,
        value: true,
      },

      _listeningForScroll: Boolean,
    },

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

    attached() {
      // Catch when users are scrolling as the view loads.
      this.listen(window, 'scroll', '_handleWindowScroll');
    },

    detached() {
      this.unlisten(window, 'scroll', '_handleWindowScroll');
    },

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

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

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

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

    moveToNextChunk() {
      this.$.cursorManager.next(this._isFirstRowOfChunk.bind(this),
          target => {
            return target.parentNode.scrollHeight;
          });
      this._fixSide();
    },

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

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

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

    /**
     * @param {number} number
     * @param {string} side
     * @param {string=} opt_path
     */
    moveToLineNumber(number, side, opt_path) {
      const row = this._findRowByNumberAndFile(number, side, opt_path);
      if (row) {
        this.side = side;
        this.$.cursorManager.setCursor(row);
      }
    },

    /**
     * Get the line number element targeted by the cursor row and side.
     *
     * @return {?Element|undefined}
     */
    getTargetLineElement() {
      let 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() {
      // Find the parent diff element of the cursor row.
      for (let diff = this.diffRow; diff; diff = diff.parentElement) {
        if (diff.tagName === 'GR-DIFF') { return diff; }
      }
      return null;
    },

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

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

    _handleWindowScroll() {
      if (this._listeningForScroll) {
        this._scrollBehavior = ScrollBehavior.NEVER;
        this._focusOnMove = false;
        this._listeningForScroll = false;
      }
    },

    handleDiffUpdate() {
      this._updateStops();

      if (!this.diffRow) {
        this.reInitCursor();
      }
      this._scrollBehavior = ScrollBehavior.KEEP_VISIBLE;
      this._focusOnMove = true;
      this._listeningForScroll = false;
    },

    _handleDiffRenderStart() {
      this._listeningForScroll = true;
    },

    /**
     * Get an object describing the location of the cursor. Such as
     * {leftSide: false, number: 123} for line 123 of the revision, or
     * {leftSide: true, number: 321} for line 321 of the base patch.
     * Returns null if an address is not available.
     *
     * @return {?Object}
     */
    getAddress() {
      if (!this.diffRow) { return null; }

      // Get the line-number cell targeted by the cursor. If the mode is unified
      // then prefer the revision cell if available.
      let 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 null; }

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

      return {
        leftSide: cell.matches('.left'),
        number: parseInt(number, 10),
      };
    },

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

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

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

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

    _rowHasThread(row) {
      return row.querySelector('.comment-thread');
    },

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

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

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

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

    _updateSideClass() {
      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(type) {
      return type !== 'blank' && type !== 'contextControl';
    },

    _getActionsForRow() {
      const 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() {
      return this.diffs.reduce(
          (stops, diff) => {
            return stops.concat(diff.getCursorStops());
          }, []);
    },

    _updateStops() {
      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(changeRecord) {
      if (!changeRecord) { return; }

      this._updateStops();

      let splice;
      let i;
      for (let 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-start', '_handleDiffRenderStart');
          this.listen(this.diffs[i], 'render-content', 'handleDiffUpdate');
        }

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

    _findRowByNumberAndFile(targetNumber, side, opt_path) {
      let stops;
      if (opt_path) {
        const diff = this.diffs.filter(diff => diff.path === opt_path)[0];
        stops = diff.getCursorStops();
      } else {
        stops = this.$.cursorManager.stops;
      }
      let selector;
      for (let i = 0; i < stops.length; i++) {
        selector = '.lineNum.' + side + '[data-value="' + targetNumber + '"]';
        if (stops[i].querySelector(selector)) {
          return stops[i];
        }
      }
    },
  });
})();
