<!--
// Copyright 2014 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="../../framework/sky-element/sky-element.sky" as="SkyElement" />
<import src="city-data-service.sky" as="CityDataService" />
<import src="city-sequence.sky" as="CitySequence" />

<script>
// TODO(esprehn): exports should start as the empty object.
module.exports = {};
</script>

<sky-element name="state-header">
<template>
  <style>
    div {
      font-size: 16px;
      color: #FFF;
      background-color: #333;
      padding: 4px 4px 4px 12px;
      display: paragraph;
    }
  </style>
  <div>{{ state }}</div>
</template>
<script>
module.exports.StateHeaderElement = class extends SkyElement {
  set datum(datum) {
    this.state = datum.state;
  }
}.register();
</script>
</sky-element>

<sky-element name="letter-header">
<template>
  <style>
    div {
      font-size: 12px;
      font-weight: bold;
      padding: 2px 4px 4px 12px;
      background-color: #DDD;
      display: paragraph;
    }
  </style>
  <div>{{ letter }}</div>
</template>
<script>
module.exports.LetterHeaderElement = class extends SkyElement {
  set datum(datum) {
    this.letter = datum.letter;
  }
}.register();
</script>
</sky-element>

<sky-element name="city-item">
<template>
  <style>
    :host {
      display: flex;
      font-size: 13px;
      padding: 8px 4px 4px 12px;
      border-bottom: 1px solid #EEE;
      line-height: 15px;
      overflow: hidden;
    }

    div {
      display: paragraph;
    }

    span {
      display: inline;
    }

    #name {
      font-weight: bold
    }

    #population {
      color: #AAA;
    }

  </style>
  <div>
    <span id="name">{{ name }}</span>,
    <span id="population">population {{ population }}</span>
  </div>
</template>
<script>
module.exports.CityItemElement = class extends SkyElement {
  set datum(datum) {
    this.name = datum.name;
    this.population = datum.population;
  }
}.register();
</script>
</sky-element>

<sky-element name="city-list">
<template>
  <style>

  :host {
      overflow: hidden;
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      display: block;
      background-color: #fff;
  }

  #scroller {
    overflow-x: hidden;
    overflow-y: auto;
    perspective: 5px;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
  }

  #scroller::-webkit-scrollbar {
    display:none;
  }

  #scrollarea {
    will-change: transform;
    transform-style: preserve-3d;
  }

  #contentarea {
    position: absolute;
    will-change: contents;
    width: 100%;
  }

  .void {
    display: none;
  }

  .position {
    position: absolute;
    left: 0;
    right: 0;
  }

  </style>
  <div id="scroller" fit>
    <div id="scrollarea">
      <div id="contentarea">
      </div>
    </div>
  </div>
</template>
<script>

(function(global) {
    "use strict";

    var LOAD_LENGTH = 20;
    var LOAD_BUFFER_PRE = LOAD_LENGTH * 4;
    var LOAD_BUFFER_POST = LOAD_LENGTH * 4;

    function Loader(cityList) {
      this.cityList = cityList;
      this.loadingData = false;
      this.data = null;
      this.zeroIndex = 0;
      this.loadIndex = 0;
    }

    Loader.prototype.localIndex = function(externalIndex) {
      return externalIndex + this.zeroIndex;
    }

    Loader.prototype.externalIndex = function(localIndex) {
      return localIndex - this.zeroIndex;
    }

    Loader.prototype.getItems = function() {
      return this.data ? this.data.items : [];
    }

    Loader.prototype.maybeLoadMoreData =
        function(dataloadedCallback, firstVisible) {
      if (this.loadingData)
        return;

      if (firstVisible) {
        this.loadIndex = this.externalIndex(
            this.data.items.indexOf(firstVisible));
      }

      var localIndex = this.localIndex(this.loadIndex);
      var loadedPre = 0;
      var loadedPost = 0;

      if (this.data) {
        loadedPre = localIndex;
        loadedPost = this.data.items.length - loadedPre;
      }

      var loadTime;
      if (loadedPre >= LOAD_BUFFER_PRE &&
          loadedPost >= LOAD_BUFFER_POST) {

        var cityList = this.cityList;
        setTimeout(function() {
           cityList.dispatchEvent(new Event('load'));
        });

        if (window.startLoad) {
          loadTime = new Date().getTime() - window.startLoad;
          console.log('Load: ' + loadTime + 'ms');
          window.startLoad = undefined;
        }
        return;
      }

      this.loadingData = true;

      var loadIndex;

      if (!this.data) {
        // Initial batch
        loadIndex = 0;
      } else if (loadedPost < LOAD_BUFFER_POST) {
        // Load forward first
        loadIndex = this.data.items.length;
      } else {
        // Then load backward
        loadIndex = -LOAD_LENGTH;
      }

      var self = this;
      var externalIndex = this.externalIndex(loadIndex);

      try {
        CityDataService.service.then(function(cityService) {
          return cityService.get(externalIndex, LOAD_LENGTH)
              .then(function(cities) {
            var indexOffset = 0;
            var newData = new CitySequence(cities);
            if (!self.data) {
              self.data = newData;
            } else if (loadIndex > 0) {
              self.data.append(newData);
            } else {
              self.zeroIndex += LOAD_LENGTH;
              indexOffset = LOAD_LENGTH;
              newData.append(self.data);
              self.data = newData;
            }

            self.loadingData = false;
            dataloadedCallback(self.data, indexOffset);
          });
        }).catch(function(ex) {
          console.log(ex.stack);
        });
      } catch (ex) {
        console.log(ex.stack);
      }
    }

    function Scroller() {
      this.contentarea = null;
      this.scroller = null;
      this.contentTop = 0; // #contentarea's current top
      this.scrollTop = 0; // #scrollarea's current top
      this.scrollHeight = -1; // height of #scroller (the viewport)
      this.lastScrollTop = 0; // last known scrollTop to compute deltas
    }

    Scroller.prototype.setup = function(scroller, scrollarea, contentarea) {
      this.contentarea = contentarea;
      this.scroller = scroller;

      this.scrollHeight = scroller.offsetHeight;
      scrollarea.style.height = (this.scrollHeight) * 4 + 'px';

      this.reset();
    }

    Scroller.prototype.captureNewFrame = function(event) {
        var scrollTop = event.target.scrollTop;

        // Protect from re-entry.
        if (this.lastScrollTop == scrollTop)
          return false;

        var scrollDown = scrollTop > this.lastScrollTop;
        if (scrollDown) {
          while (scrollTop > this.scrollHeight * 1.5) {
            scrollTop -= this.scrollHeight;
            this.contentTop -= this.scrollHeight;
          }
        } else {
          while(scrollTop < this.scrollHeight * 1.5) {
            scrollTop += this.scrollHeight;
            this.contentTop += this.scrollHeight;
          }
        }

        this.lastScrollTop = scrollTop;
        event.target.scrollTop = scrollTop;
        this.contentarea.style.top = this.contentTop + 'px';

        this.scrollTop = scrollTop - this.contentTop;

        return true;
    }

    Scroller.prototype.reset = function() {
      if (!this.contentarea)
        return;

      this.scroller.scrollTop = this.scrollHeight;
      this.lastScrollTop = this.scrollHeight;

      this.contentarea.style.top = this.scrollHeight + 'px';
      this.contentTop = this.scrollHeight;
      this.scrollTop = 0;
    }

    // Current position and height of the scroller, that could
    // be used (by Tiler, for example) to reason about where to
    // place visible things.
    Scroller.prototype.getCurrentFrame = function() {
      return { top: this.scrollTop, height: this.scrollHeight };
    }

    Scroller.prototype.hasFrame = function() {
      return this.scrollHeight != -1;
    }

    function Tile(datum, element, viewType, index) {
      this.datum = datum;
      this.element = element;
      this.viewType = viewType;
      this.index = index;
    }

    function Tiler(contentArea, views, viewHeights) {
      this.contentArea = contentArea;
      this.drawTop = 0;
      this.drawBottom = 0;
      this.firstItem = -1;
      this.tiles = [];
      this.viewHeights = viewHeights;
      this.views = views;
    }

    Tiler.prototype.setupViews = function(scrollFrame) {
      for (var type in this.viewHeights) {
        this.initializeViewType(scrollFrame, type, this.viewHeights[type]);
      }
    }

    Tiler.prototype.initializeViewType = function(scrollFrame, viewType,
                                                  height) {
      var count = Math.ceil(scrollFrame.height / height) * 2;
      var viewCache = this.views[viewType] = {
        indices: [],
        elements: []
      };

      var protoElement;
      switch (viewType) {
        case 'stateHeader':
          protoElement = document.createElement('state-header');
          break;
        case 'letterHeader':
          protoElement = document.createElement('letter-header');
          break;
        case 'cityItem':
          protoElement = document.createElement('city-item');
          break;
        default:
          console.warn('Unknown viewType: ' + viewType);
      }
      protoElement.style.display = 'none';
      protoElement.style.height = height;
      protoElement.classList.add('position');

      for (var i = 0; i < count; i++) {
        var clone = protoElement.cloneNode(false);
        this.contentArea.appendChild(clone);
        viewCache.elements.push(clone);
        viewCache.indices.push(i);
      }
    }

    Tiler.prototype.checkoutTile = function(viewType, datum, top) {
      var viewCache = this.views[viewType];
      var index = viewCache.indices.pop();
      var element = viewCache.elements[index];
      element.datum = datum;
      element.style.display = '';
      element.style.top = top + 'px';

      return new Tile(datum, element, viewType, index);
    }

    Tiler.prototype.checkinTile = function(tile) {
      if (!tile.element)
        return;

      tile.element.style.display = 'none';
      this.views[tile.viewType].indices.push(tile.index);
    }

    Tiler.prototype.getFirstVisibleDatum = function(scrollFrame) {
      var tiles = this.tiles;
      var viewHeights = this.viewHeights;

      var itemTop = this.drawTop - scrollFrame.top;
      if (itemTop >= 0 && tiles.length)
        return tiles[0].datum;

      var tile;
      for (var i = 0; i < tiles.length && itemTop < 0; i++) {
        tile = tiles[i];
        var height = viewHeights[tile.viewType];
        itemTop += height;
      }

      return tile ? tile.datum : null;
    }

    Tiler.prototype.viewType = function(datum) {
      switch (datum.headerOrder) {
        case 1: return 'stateHeader';
        case 2: return 'letterHeader';
        default: return 'cityItem';
      }
    }

    Tiler.prototype.drawTiles = function(scrollFrame, data) {
      var tiles = this.tiles;
      var viewHeights = this.viewHeights;

      var buffer = Math.round(scrollFrame.height / 2);
      var targetTop = scrollFrame.top - buffer;
      var targetBottom = scrollFrame.top + scrollFrame.height + buffer;

      // Collect down to targetTop
      var first = tiles[0];
      while (tiles.length &&
             targetTop > this.drawTop + viewHeights[first.viewType]) {

        var height = viewHeights[first.viewType];
        this.drawTop += height;

        this.firstItem++;
        this.checkinTile(tiles.shift());

        first = tiles[0];
      }

      // Collect up to targetBottom
      var last = tiles[tiles.length - 1];
      while(tiles.length &&
            targetBottom < this.drawBottom - viewHeights[last.viewType]) {

        var height = viewHeights[last.viewType];
        this.drawBottom -= height;

        this.checkinTile(tiles.pop());

        last = tiles[tiles.length - 1];
      }

      // Layout up to targetTop
      while (this.firstItem > 0 &&
             targetTop < this.drawTop) {

        var datum = data[this.firstItem - 1];
        var type = this.viewType(datum);
        var height = viewHeights[type];

        this.drawTop -= height;

        var tile = targetBottom < this.drawTop ?
            new Tile(datum, null, datum.viewType, -1) : // off-screen
            this.checkoutTile(type, datum, this.drawTop);

        this.firstItem--;
        tiles.unshift(tile);
      }

      // Layout down to targetBottom
      while (this.firstItem + tiles.length < data.length - 1 &&
             targetBottom > this.drawBottom) {

        var datum = data[this.firstItem + tiles.length];
        var type = this.viewType(datum);
        var height = viewHeights[type];

        this.drawBottom += height;

        var tile = targetTop > this.drawBottom ?
            new Tile(datum, null, datum.viewType, -1) : // off-screen
            this.checkoutTile(type, datum, this.drawBottom - height);

        tiles.push(tile);
      }

      // Debug validate:
      // for (var i = 0; i < tiles.length; i++) {
      //   if (tiles[i].datum !== data[this.firstItem + i])
      //     throw Error('Invalid')
      // }
    }

    // FIXME: Needs better name.
    Tiler.prototype.updateFirstItem = function(offset) {
      var tiles = this.tiles;

      if (!tiles.length) {
        this.firstItem = 0;
      } else {
        this.firstItem += offset;
      }
    }

    Tiler.prototype.checkinAllTiles = function() {
      var tiles = this.tiles;
      while (tiles.length) {
        this.checkinTile(tiles.pop());
      }
    }

    Tiler.prototype.reset = function() {
      this.checkinAllTiles();
      this.drawTop = 0;
      this.drawBottom = 0;
    }

    module.exports.CityListElement = class extends SkyElement {

      created() {
        this.loader = null;
        this.scroller = null;
        this.tiler = null;
        this.date = null;
        this.month = null;
        this.views = null;
      }

      attached() {
        this.views = {};
        this.loader = new Loader(this);
        this.scroller = new Scroller();
        this.tiler = new Tiler(
            this.shadowRoot.getElementById('contentarea'), this.views, {
          stateHeader: 27,
          letterHeader: 18,
          cityItem: 30
        });

        this.dataLoaded = this.dataLoaded.bind(this);
        this.scrollerElement = this.shadowRoot.getElementById('scroller');
        this.scrollerElement.addEventListener('scroll',
            this.handleScroll.bind(this));

        var self = this;
        setTimeout(function() {
          self.domReady();
          self.loader.maybeLoadMoreData(self.dataLoaded);
        });
      }

      domReady() {
        this.scroller.setup(this.shadowRoot.getElementById('scroller'),
            this.shadowRoot.getElementById('scrollarea'),
            this.shadowRoot.getElementById('contentarea'));
        var scrollFrame = this.scroller.getCurrentFrame();
        this.tiler.setupViews(scrollFrame);
      }

      updateView(data, scrollChanged) {
        var scrollFrame = this.scroller.getCurrentFrame();
        this.tiler.drawTiles(scrollFrame, data);
        var datum = scrollChanged ?
            this.tiler.getFirstVisibleDatum(scrollFrame) : null;
        this.loader.maybeLoadMoreData(this.dataLoaded, datum);
      }

      dataLoaded(data, indexOffset) {
        var scrollFrame = this.scroller.getCurrentFrame();
        this.tiler.updateFirstItem(indexOffset);
        this.updateView(data.items, false);
      }

      handleScroll(event) {
        if (!this.scroller.captureNewFrame(event))
          return;

        this.updateView(this.loader.getItems(), true);
      }

      scrollBy(amount) {
        this.scrollerElement.scrollTop += amount;
        this.handleScroll({ target: this.scrollerElement });
      }
    }.register();

})(this);
</script>
</sky-element>
