/**
 * @license
 * Copyright (C) 2017 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.
 */
import '../../../scripts/bundled-polymer.js';

import '../../../styles/shared-styles.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-fixed-panel_html.js';

/** @extends Polymer.Element */
class GrFixedPanel extends GestureEventListeners(
    LegacyElementMixin(
        PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-fixed-panel'; }

  static get properties() {
    return {
      floatingDisabled: {
        type: Boolean,
        value: false,
      },
      readyForMeasure: {
        type: Boolean,
        observer: '_readyForMeasureObserver',
      },
      keepOnScroll: {
        type: Boolean,
        value: false,
      },
      _isMeasured: {
        type: Boolean,
        value: false,
      },

      /**
       * Initial offset from the top of the document, in pixels.
       */
      _topInitial: Number,

      /**
       * Current offset from the top of the window, in pixels.
       */
      _topLast: Number,

      _headerHeight: Number,
      _headerFloating: {
        type: Boolean,
        value: false,
      },
      _observer: {
        type: Object,
        value: null,
      },
      /**
       * If place before any other content defines how much
       * of the content below it is covered by this panel
       */
      floatingHeight: {
        type: Number,
        value: 0,
        notify: true,
      },

      _webComponentsReady: Boolean,
    };
  }

  static get observers() {
    return [
      '_updateFloatingHeight(floatingDisabled, _isMeasured, _headerHeight)',
    ];
  }

  _updateFloatingHeight(floatingDisabled, isMeasured, headerHeight) {
    if ([
      floatingDisabled,
      isMeasured,
      headerHeight,
    ].some(arg => arg === undefined)) {
      return;
    }
    this.floatingHeight =
        (!floatingDisabled && isMeasured) ? headerHeight : 0;
  }

  /** @override */
  attached() {
    super.attached();
    if (this.floatingDisabled) {
      return;
    }
    // Enable content measure unless blocked by param.
    if (this.readyForMeasure !== false) {
      this.readyForMeasure = true;
    }
    this.listen(window, 'resize', 'update');
    this.listen(window, 'scroll', '_updateOnScroll');
    this._observer = new MutationObserver(this.update.bind(this));
    this._observer.observe(this.$.header, {childList: true, subtree: true});
  }

  /** @override */
  detached() {
    super.detached();
    this.unlisten(window, 'scroll', '_updateOnScroll');
    this.unlisten(window, 'resize', 'update');
    if (this._observer) {
      this._observer.disconnect();
    }
  }

  _readyForMeasureObserver(readyForMeasure) {
    if (readyForMeasure) {
      this.update();
    }
  }

  _computeHeaderClass(headerFloating, topLast) {
    const fixedAtTop = this.keepOnScroll && topLast === 0;
    return [
      headerFloating ? 'floating' : '',
      fixedAtTop ? 'fixedAtTop' : '',
    ].join(' ');
  }

  unfloat() {
    if (this.floatingDisabled) {
      return;
    }
    this.$.header.style.top = '';
    this._headerFloating = false;
    this.updateStyles({'--header-height': ''});
  }

  update() {
    this.debounce('update', () => {
      this._updateDebounced();
    }, 100);
  }

  _updateOnScroll() {
    this.debounce('update', () => {
      this._updateDebounced();
    });
  }

  _updateDebounced() {
    if (this.floatingDisabled) {
      return;
    }
    this._isMeasured = false;
    this._maybeFloatHeader();
    this._reposition();
  }

  _getElementTop() {
    return this.getBoundingClientRect().top;
  }

  _reposition() {
    if (!this._headerFloating) {
      return;
    }
    const header = this.$.header;
    // Since the outer element is relative positioned, can  use its top
    // to determine how to position the inner header element.
    const elemTop = this._getElementTop();
    let newTop;
    if (this.keepOnScroll && elemTop < 0) {
      // Should stick to the top.
      newTop = 0;
    } else {
      // Keep in line with the outer element.
      newTop = elemTop;
    }
    // Initialize top style if it doesn't exist yet.
    if (!header.style.top && this._topLast === newTop) {
      header.style.top = newTop;
    }
    if (this._topLast !== newTop) {
      if (newTop === undefined) {
        header.style.top = '';
      } else {
        header.style.top = newTop + 'px';
      }
      this._topLast = newTop;
    }
  }

  _measure() {
    if (this._isMeasured) {
      return; // Already measured.
    }
    const rect = this.$.header.getBoundingClientRect();
    if (rect.height === 0 && rect.width === 0) {
      return; // Not ready for measurement yet.
    }
    const top = document.body.scrollTop + rect.top;
    this._topLast = top;
    this._headerHeight = rect.height;
    this._topInitial =
      this.getBoundingClientRect().top + document.body.scrollTop;
    this._isMeasured = true;
  }

  _isFloatingNeeded() {
    return this.keepOnScroll ||
      document.body.scrollWidth > document.body.clientWidth;
  }

  _maybeFloatHeader() {
    if (!this._isFloatingNeeded()) {
      return;
    }
    this._measure();
    if (this._isMeasured) {
      this._floatHeader();
    }
  }

  _floatHeader() {
    this.updateStyles({'--header-height': this._headerHeight + 'px'});
    this._headerFloating = true;
  }
}

customElements.define(GrFixedPanel.is, GrFixedPanel);
