<!--
// 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" />

<sky-element>
<template>
  <style>
  :host {
    overflow: hidden;
    position: relative;
    will-change: transform;
  }
  #scrollable {
    will-change: transform;
  }
  #vbar {
    position: absolute;
    right: 0;
    background-color: lightgray;
    pointer-events: none;
    top: 0;
    height: 0;
    will-change: opacity;
    opacity: 0;
    transition-property: opacity;
    transition-function: ease-in-out;
  }
  </style>
  <div id="scrollable">
    <content />
  </div>
  <div id="vbar" />
</template>
<script>
import "dart:math" as math;
import "dart:sky";
import "animation/fling-curve.dart";
import "theme/view-configuration.dart" as config;

@Tagname('sky-scrollable')
class SkyScrollable extends SkyElement {
  Element _scrollable;
  Element _vbar;
  double _scrollOffset = 0.0;
  FlingCurve _flingCurve;
  int _flingAnimationId;

  SkyScrollable() {
    addEventListener('gesturescrollstart', _handleScrollStart);
    addEventListener('gesturescrollend', _handleScrollEnd);
    addEventListener('gesturescrollupdate', _handleScrollUpdate);
    addEventListener('gestureflingstart', _handleFlingStart);
    addEventListener('gestureflingcancel', _handleFlingCancel);
    addEventListener('wheel', _handleWheel);
  }

  void shadowRootReady() {
    _scrollable = shadowRoot.getElementById('scrollable');
    _vbar = shadowRoot.getElementById('vbar');
    // This is not documented anywhere, but the scrollbar appears to only paint
    // 3px even though it's official width is 10px?
    // Chrome appears 3px wide with a 3px outer spacing.
    // Contacts appears 3px wide with a 5px runner and 5px outer spacing.
    // Settings appears 4px wide with no outer spacing.
    const double paintPercent = 0.3;
    const double outerGapPercent = 0.3;
    const double innerGapPercent = 0.4;
    const double paintWidth = paintPercent * config.kScrollbarSize;
    _vbar.style['width'] = "${paintWidth}px";
    _vbar.style['margin-right'] = "${outerGapPercent * config.kScrollbarSize}px";
    _vbar.style['margin-left'] ="${innerGapPercent * config.kScrollbarSize}px";
    // The scroll thumb never quite makes it to the top or bottom in gmail
    // or chrome (in chrome more from the bottom than the top).
    _vbar.style['margin-top'] = "${config.kScrollbarSize}px";
    _vbar.style['margin-bottom'] = "${config.kScrollbarSize}px";

    // Some android apps round their scrollbars, some don't, not rounding for now.

    const double msToSeconds = 1.0 / 1000.0;
    _vbar.style['transition-duration'] = "${msToSeconds * config.kScrollbarFadeDuration}s";
    _vbar.style['transition-delay'] = "${msToSeconds * config.kScrollbarFadeDelay}s";
  }

  double get scrollOffset => _scrollOffset;

  set scrollOffset(double value) {
    // TODO(abarth): Can we get these values without forcing a synchronous layout?
    double outerHeight = clientHeight.toDouble();
    double innerHeight = _scrollable.clientHeight.toDouble();
    double scrollRange = innerHeight - outerHeight;
    double newScrollOffset = math.max(0.0, math.min(scrollRange, value));
    if (newScrollOffset == _scrollOffset)
      return;
    // TODO(eseidel): We should scroll in device pixels instead of logical
    // pixels, but to do that correctly we need to use a device pixel unit.
    _scrollOffset = newScrollOffset;
    String transform = 'translateY(${(-_scrollOffset).toInt()}px)';
    _scrollable.style['transform'] = transform;

    double topPercent = newScrollOffset / innerHeight * 100.0;
    double heightPercent = outerHeight / innerHeight * 100.0;
    _vbar.style['top'] = '${topPercent}%';
    _vbar.style['height'] = '${heightPercent}%';
  }

  bool scrollBy(double scrollDelta) {
    double oldScrollOffset = _scrollOffset;
    scrollOffset += scrollDelta;
    return _scrollOffset != oldScrollOffset;
  }

  void _scheduleFlingUpdate() {
    _flingAnimationId = window.requestAnimationFrame(_updateFling);
  }

  void _stopFling() {
    window.cancelAnimationFrame(_flingAnimationId);
    _flingCurve = null;
    _flingAnimationId = null;
    _vbar.style['opacity'] = '0';
  }

  void _updateFling(double timeStamp) {
    double scrollDelta = _flingCurve.update(timeStamp);
    if (scrollDelta == 0.0 || !scrollBy(scrollDelta))
      _stopFling();
    else
      _scheduleFlingUpdate();
  }

  void _handleScrollStart(_) {
    _vbar.style['opacity'] = '1';
  }

  void _handleScrollEnd(_) {
    _vbar.style['opacity'] = '0';
  }

  void _handleScrollUpdate(GestureEvent event) {
    scrollBy(-event.dy);
  }

  void _handleFlingStart(GestureEvent event) {
    _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
    _scheduleFlingUpdate();
  }

  void _handleFlingCancel(_) {
    _stopFling();
  }

  void _handleWheel(WheelEvent event) {
    scrollBy(-event.offsetY);
  }
}

_init(script) => register(script, SkyScrollable);
</script>
</sky-element>
