<!--
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-->
<import src="sky-element/sky-element.sky" as="SkyElement" />
<import src="fling-curve.sky" as="FlingCurve" />

<sky-element
  name="sky-scrollable"
  on-gesturescrollstart="handleScrollStart_"
  on-gesturescrollend="handleScrollEnd_"
  on-gesturescrollupdate="handleScrollUpdate_"
  on-gestureflingstart="handleFlingStart_"
  on-gestureflingcancel="handleFlingCancel_"
  on-wheel="handleWheel_">
<template>
  <style>
  :host {
    overflow: hidden;
    position: relative;
  }
  #scrollable {
    transform: translateY(0);
  }
  #vbar {
    position: absolute;
    right: 0;
    width: 3px;
    background-color: lightgray;
    pointer-events: none;
    top: 0;
    height: 0;
    will-change: opacity;
    opacity: 0;
    transition: opacity 0.2s ease-in-out;
  }
  </style>
  <div id="scrollable">
    <content />
  </div>
  <div id="vbar" />
</template>
<script>
module.exports = class extends SkyElement {
  created() {
    this.scrollable_ = null;
    this.vbar_ = null;
    this.scrollOffset_ = 0;
    this.flingCurve_ = null;
    this.flingAnimationId_ = null;
  }

  shadowRootReady() {
    this.scrollable_ = this.shadowRoot.getElementById('scrollable');
    this.vbar_ = this.shadowRoot.getElementById('vbar');
  }

  get scrollOffset() {
    return this.scrollOffset_;
  }

  set scrollOffset(value) {
    // TODO(abarth): Can we get these values without forcing a synchronous layout?
    var outerHeight = this.clientHeight;
    var innerHeight = this.scrollable_.clientHeight;
    var scrollRange = innerHeight - outerHeight;
    var newScrollOffset = Math.max(0, Math.min(scrollRange, value));
    if (newScrollOffset == this.scrollOffset_)
      return;
    this.scrollOffset_ = newScrollOffset;
    var transform = 'translateY(' + -this.scrollOffset_.toFixed(2) + 'px)';
    this.scrollable_.style.transform = transform;

    var topPercent = newScrollOffset / innerHeight * 100;
    var heightPercent = outerHeight / innerHeight * 100;
    this.vbar_.style.top = topPercent + '%';
    this.vbar_.style.height = heightPercent + '%';
  }

  scrollBy(scrollDelta) {
    var oldScrollOffset = this.scrollOffset_;
    this.scrollOffset += scrollDelta;
    return this.scrollOffset_ != oldScrollOffset;
  }

  scheduleFlingUpdate_() {
    this.flingAnimationId_ = requestAnimationFrame(this.updateFling_.bind(this));
  }

  stopFling_() {
    cancelAnimationFrame(this.flingAnimationId_);
    this.flingCurve_ = null;
    this.flingAnimationId_ = null;
    this.vbar_.style.opacity = 0;
  }

  updateFling_(timeStamp) {
    var scrollDelta = this.flingCurve_.update(timeStamp);
    if (!scrollDelta || !this.scrollBy(scrollDelta))
      return this.stopFling_();
    this.scheduleFlingUpdate_();
  }

  handleScrollStart_(event) {
    this.vbar_.style.opacity = 1;
  }

  handleScrollEnd_(event) {
    this.vbar_.style.opacity = 0;
  }

  handleScrollUpdate_(event) {
    this.scrollBy(-event.dy);
  }

  handleFlingStart_(event) {
    this.flingCurve_ = new FlingCurve(-event.velocityY, event.timeStamp);
    this.scheduleFlingUpdate_();
  }

  handleFlingCancel_(event) {
    this.stopFling_();
  }

  handleWheel_(event) {
    this.scrollBy(-event.offsetY);
  }
}.register();
</script>
</sky-element>
