<!DOCTYPE html>
<!--
Copyright (c) 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.
-->
<link rel="import" href="/base/events.html">
<link rel="import" href="/base/utils.html">
<link rel="import" href="/base/ui.html">
<link rel="import" href="/base/ui/container_that_decorates_its_children.html">
<link rel="stylesheet" href="/base/ui/list_view.css">
<script>
'use strict';

/**
 * @fileoverview Simple list view.
 */
tr.exportTo('tr.b.ui', function() {
  /**
   * @constructor
   */
  var ListView = tr.b.ui.define(
      'x-list-view', tr.b.ui.ContainerThatDecoratesItsChildren);

  ListView.prototype = {
    __proto__: tr.b.ui.ContainerThatDecoratesItsChildren.prototype,

    decorate: function() {
      tr.b.ui.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);

      this.classList.add('x-list-view');
      this.onItemClicked_ = this.onItemClicked_.bind(this);
      this.onKeyDown_ = this.onKeyDown_.bind(this);
      this.tabIndex = 0;
      this.addEventListener('keydown', this.onKeyDown_);

      this.selectionChanged_ = false;
    },

    decorateChild_: function(item) {
      item.classList.add('list-item');
      item.addEventListener('click', this.onItemClicked_, true);

      var listView = this;
      Object.defineProperty(
          item,
          'selected', {
            configurable: true,
            set: function(value) {
              var oldSelection = listView.selectedElement;
              if (oldSelection && oldSelection != this && value)
                listView.selectedElement.removeAttribute('selected');
              if (value)
                this.setAttribute('selected', 'selected');
              else
                this.removeAttribute('selected');
              var newSelection = listView.selectedElement;
              if (newSelection != oldSelection)
                tr.b.dispatchSimpleEvent(listView, 'selection-changed', false);
            },
            get: function() {
              return this.hasAttribute('selected');
            }
          });
    },

    undecorateChild_: function(item) {
      this.selectionChanged_ |= item.selected;

      item.classList.remove('list-item');
      item.removeEventListener('click', this.onItemClicked_);
      delete item.selected;
    },

    beginDecorating_: function() {
      this.selectionChanged_ = false;
    },

    doneDecoratingForNow_: function() {
      if (this.selectionChanged_)
        tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
    },

    get selectedElement() {
      var el = this.querySelector('.list-item[selected]');
      if (!el)
        return undefined;
      return el;
    },

    set selectedElement(el) {
      if (!el) {
        if (this.selectedElement)
          this.selectedElement.selected = false;
        return;
      }

      if (el.parentElement != this)
        throw new Error(
            'Can only select elements that are children of this list view');
      el.selected = true;
    },

    getElementByIndex: function(index) {
      return this.querySelector('.list-item:nth-child(' + index + ')');
    },

    clear: function() {
      var changed = this.selectedElement !== undefined;
      tr.b.ui.ContainerThatDecoratesItsChildren.prototype.clear.call(this);
      if (changed)
        tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
    },

    onItemClicked_: function(e) {
      var currentSelectedElement = this.selectedElement;
      if (currentSelectedElement)
        currentSelectedElement.removeAttribute('selected');
      var element = e.target;
      while (element.parentElement != this)
        element = element.parentElement;
      if (element !== currentSelectedElement)
        element.setAttribute('selected', 'selected');
      tr.b.dispatchSimpleEvent(this, 'selection-changed', false);
    },

    onKeyDown_: function(e) {
      if (this.selectedElement === undefined)
        return;

      if (e.keyCode == 38) { // Up arrow.
        var prev = this.selectedElement.previousSibling;
        if (prev) {
          prev.selected = true;
          tr.b.scrollIntoViewIfNeeded(prev);
          e.preventDefault();
          return true;
        }
      } else if (e.keyCode == 40) { // Down arrow.
        var next = this.selectedElement.nextSibling;
        if (next) {
          next.selected = true;
          tr.b.scrollIntoViewIfNeeded(next);
          e.preventDefault();
          return true;
        }
      }
    },

    addItem: function(textContent) {
      var item = document.createElement('div');
      item.textContent = textContent;
      this.appendChild(item);
      return item;
    }

  };

  return {
    ListView: ListView
  };

});
</script>
