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

<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 {
  created() {
    this.state = "";
  }
  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 {
  created() {
    this.letter = "";
  }
  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>
    <t>, </t>
    <span id="population">population {{ population }}</span>
  </div>
</template>
<script>
module.exports.CityItemElement = class extends SkyElement {
  created() {
    this.name = "";
    this.population = "";
  }
  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;
  }

  #contentarea {
    will-change: transform;
  }

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

  </style>
    <div id="contentarea">
    </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.scrollTop = 0;
      this.scrollHeight = -1;
    }

    Scroller.prototype.setup = function(scrollHeight, contentarea) {
      this.scrollHeight = scrollHeight;
      this.contentarea = contentarea;
    }

    Scroller.prototype.scrollBy = function(amount) {
        this.scrollTop += amount;
        this.scrollTo();
    }

    Scroller.prototype.scrollTo = function() {
      var transform = 'translateY(' + -this.scrollTop.toFixed(2) + 'px)';
      this.contentarea.style.transform = transform;
    }

    // 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;
      }
    }

    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
        });

        var self = this;
        this.addEventListener('wheel', function(event) {
          self.scrollBy(-event.offsetY)
        });

        setTimeout(function() {
          self.domReady();
          self.loader.maybeLoadMoreData(self.dataLoaded.bind(self));
        });
      }

      domReady() {
        this.scroller.setup(this.clientHeight,
            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.bind(this), datum);
      }

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

      scrollBy(amount) {
        this.scroller.scrollBy(amount);
        this.updateView(this.loader.getItems(), true);
      }
    }.register();

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