<!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.
-->

<polymer-element name="tr-ui-a-tab-view"
    constructor="TracingAnalysisTabView">
  <template>
    <style>
      :host {
        display: flex;
        flex-flow: column nowrap;
        overflow: hidden;
        box-sizing: border-box;
      }

      tab-strip[tabs-hidden] {
        display: none;
      }

      tab-strip {
        background-color: rgb(236, 236, 236);
        border-bottom: 1px solid #8e8e8e;
        display: flex;
        flex: 0 0 auto;
        flex-flow: row;
        overflow-x: auto;
        padding: 0 10px 0 10px;
        font-size: 12px;
      }

      tab-button {
        display: block;
        flex: 0 0 auto;
        padding: 4px 15px 1px 15px;
        margin-top: 2px;
      }

      tab-button[selected=true] {
        background-color: white;
        border: 1px solid rgb(163, 163, 163);
        border-bottom: none;
        padding: 3px 14px 1px 14px;
      }

      tabs-content-container {
        display: flex;
        flex: 1 1 auto;
        overflow: auto;
        width: 100%;
      }

      ::content > * {
        flex: 1 1 auto;
      }

      ::content > *:not([selected]) {
        display: none;
      }

      button-label {
        display: inline;
      }

      tab-strip-heading {
        display: block;
        flex: 0 0 auto;
        padding: 4px 15px 1px 15px;
        margin-top: 2px;
        margin-before: 20px;
        margin-after: 10px;
      }
      #tsh {
        display: inline;
        font-weight: bold;
      }
    </style>

    <tab-strip>
      <tab-strip-heading id="tshh">
        <span id="tsh"></span>
      </tab-strip-heading>
      <template repeat="{{tab in tabs_}}">
        <tab-button
            button-id="{{ tab.id }}"
            on-click="{{ tabButtonSelectHandler_ }}"
            selected="{{ selectedTab_.id === tab.id }}">
          <button-label>{{ tab.label ? tab.label : 'No Label'}}</button-label>
        </tab-button>
      </template>
    </tab-strip>

    <tabs-content-container id='content-container'>
        <content></content>
    </tabs-content-container>

  </template>

  <script>
  'use strict';
  Polymer({
    ready: function() {
      this.$.tshh.style.display = 'none';

      // A tab is represented by the following tuple:
      // (id, label, content, observer, savedScrollTop, savedScrollLeft).
      // The properties are used in the following way:
      // id: Uniquely identifies a tab. It is the same number as the index
      //     in the tabs array. Used primarily by the on-click event attached
      //     to buttons.
      // label: A string, representing the label printed on the tab button.
      // content: The light-dom child representing the contents of the tab.
      //     The content is appended to this tab-view by the user.
      // observers: The observers attached to the content node to watch for
      //     attribute changes. The attributes of interest are: 'selected',
      //     and 'tab-label'.
      // savedScrollTop/Left: Used to return the scroll position upon switching
      //     tabs. The values are generally saved when a tab switch occurs.
      //
      // The order of the tabs is relevant for the tab ordering.
      this.tabs_ = [];
      this.selectedTab_ = undefined;

      // Register any already existing children.
      for (var i = 0; i < this.children.length; i++)
        this.processAddedChild_(this.children[i]);

      // In case the user decides to add more tabs, make sure we watch for
      // any child mutations.
      this.childrenObserver_ = new MutationObserver(
          this.childrenUpdated_.bind(this));
      this.childrenObserver_.observe(this, { childList: 'true' });
    },

    get tabStripHeadingText() {
      return this.$.tsh.textContent;
    },

    set tabStripHeadingText(tabStripHeadingText) {
      this.$.tsh.textContent = tabStripHeadingText;
      if (!!tabStripHeadingText)
        this.$.tshh.style.display = '';
      else
        this.$.tshh.style.display = 'none';
    },

    get selectedTab() {
      // Make sure we process any pending children additions / removals, before
      // trying to select a tab. Otherwise, we might not find some children.
      this.childrenUpdated_(
        this.childrenObserver_.takeRecords(), this.childrenObserver_);

      // Do not give access to the user to the inner data structure.
      // A user should only be able to mutate the added tab content.
      if (this.selectedTab_)
        return this.selectedTab_.content;
      return undefined;
    },

    set selectedTab(content) {
      // Make sure we process any pending children additions / removals, before
      // trying to select a tab. Otherwise, we might not find some children.
      this.childrenUpdated_(
        this.childrenObserver_.takeRecords(), this.childrenObserver_);

      if (content === undefined || content === null) {
        this.changeSelectedTabById_(undefined);
        return;
      }

      // Search for the specific node in our tabs list.
      // If it is not there print a warning.
      var contentTabId = undefined;
      for (var i = 0; i < this.tabs_.length; i++)
        if (this.tabs_[i].content === content) {
          contentTabId = this.tabs_[i].id;
          break;
        }

      if (contentTabId === undefined)
        return;

      this.changeSelectedTabById_(contentTabId);
    },

    get tabsHidden() {
      var ts = this.shadowRoot.querySelector('tab-strip');
      return ts.hasAttribute('tabs-hidden');
    },

    set tabsHidden(tabsHidden) {
      tabsHidden = !!tabsHidden;
      var ts = this.shadowRoot.querySelector('tab-strip');
      if (tabsHidden)
        ts.setAttribute('tabs-hidden', true);
      else
        ts.removeAttribute('tabs-hidden');
    },

    get tabs() {
      return this.tabs_.map(function(tabObject) {
        return tabObject.content;
      });
    },

    /**
     * Function called on light-dom child addition.
     */
    processAddedChild_: function(child) {
      var observerAttributeSelected = new MutationObserver(
          this.childAttributesChanged_.bind(this));
      var observerAttributeTabLabel = new MutationObserver(
          this.childAttributesChanged_.bind(this));
      var tabObject = {
        id: this.tabs_.length,
        content: child,
        label: child.getAttribute('tab-label'),
        observers: {
          forAttributeSelected: observerAttributeSelected,
          forAttributeTabLabel: observerAttributeTabLabel
        }
      };

      this.tabs_.push(tabObject);
      if (child.hasAttribute('selected')) {
        // When receiving a child with the selected attribute, if we have no
        // selected tab, mark the child as the selected tab, otherwise keep
        // the previous selection.
        if (this.selectedTab_)
          child.removeAttribute('selected');
        else
          this.setSelectedTabById_(tabObject.id);
      }

      // This is required because the user might have set the selected
      // property before we got to process the child.
      var previousSelected = child.selected;

      var tabView = this;

      Object.defineProperty(
          child,
          'selected', {
            configurable: true,
            set: function(value) {
              if (value) {
                tabView.changeSelectedTabById_(tabObject.id);
                return;
              }

              var wasSelected = tabView.selectedTab_ === tabObject;
              if (wasSelected)
                tabView.changeSelectedTabById_(undefined);
            },
            get: function() {
              return this.hasAttribute('selected');
            }
          });

      if (previousSelected)
        child.selected = previousSelected;

      observerAttributeSelected.observe(child,
          { attributeFilter: ['selected'] });
      observerAttributeTabLabel.observe(child,
          { attributeFilter: ['tab-label'] });

    },

    /**
     * Function called on light-dom child removal.
     */
    processRemovedChild_: function(child) {
      for (var i = 0; i < this.tabs_.length; i++) {
        // Make sure ids are the same as the tab position after removal.
        this.tabs_[i].id = i;
        if (this.tabs_[i].content === child) {
          this.tabs_[i].observers.forAttributeSelected.disconnect();
          this.tabs_[i].observers.forAttributeTabLabel.disconnect();
          // The user has removed the currently selected tab.
          if (this.tabs_[i] === this.selectedTab_) {
            this.clearSelectedTab_();
            this.fire('selected-tab-change');
          }
          child.removeAttribute('selected');
          delete child.selected;
          // Remove the observer since we no longer care about this child.
          this.tabs_.splice(i, 1);
          i--;
        }
      }
    },


    /**
     * This function handles child attribute changes. The only relevant
     * attributes for the tab-view are 'tab-label' and 'selected'.
     */
    childAttributesChanged_: function(mutations, observer) {
      var tabObject = undefined;
      // First figure out which child has been changed.
      for (var i = 0; i < this.tabs_.length; i++) {
        var observers = this.tabs_[i].observers;
        if (observers.forAttributeSelected === observer ||
            observers.forAttributeTabLabel === observer) {
            tabObject = this.tabs_[i];
            break;
        }
      }

      // This should not happen, unless the user has messed with our internal
      // data structure.
      if (!tabObject)
        return;

      // Next handle the attribute changes.
      for (var i = 0; i < mutations.length; i++) {
        var node = tabObject.content;
        // 'tab-label' attribute has been changed.
        if (mutations[i].attributeName === 'tab-label')
          tabObject.label = node.getAttribute('tab-label');
        // 'selected' attribute has been changed.
        if (mutations[i].attributeName === 'selected') {
          // The attribute has been set.
          var nodeIsSelected = node.hasAttribute('selected');
          if (nodeIsSelected)
            this.changeSelectedTabById_(tabObject.id);
          else
            this.changeSelectedTabById_(undefined);
        }
      }
    },

    /**
     * This function handles light-dom additions and removals from the
     * tab-view component.
     */
    childrenUpdated_: function(mutations, observer) {
      mutations.forEach(function(mutation) {
        for (var i = 0; i < mutation.removedNodes.length; i++)
          this.processRemovedChild_(mutation.removedNodes[i]);
        for (var i = 0; i < mutation.addedNodes.length; i++)
          this.processAddedChild_(mutation.addedNodes[i]);
      }, this);
    },

    /**
     * Handler called when a click event happens on any of the tab buttons.
     */
    tabButtonSelectHandler_: function(event, detail, sender) {
      this.changeSelectedTabById_(sender.getAttribute('button-id'));
    },

    /**
     * This does the actual work. :)
     */
    changeSelectedTabById_: function(id) {
      var newTab = id !== undefined ? this.tabs_[id] : undefined;
      var changed = this.selectedTab_ !== newTab;
      this.saveCurrentTabScrollPosition_();
      this.clearSelectedTab_();
      if (id !== undefined) {
        this.setSelectedTabById_(id);
        this.restoreCurrentTabScrollPosition_();
      }

      if (changed)
        this.fire('selected-tab-change');
    },

    /**
     * This function updates the currently selected tab based on its internal
     * id. The corresponding light-dom element receives the selected attribute.
     */
    setSelectedTabById_: function(id) {
      this.selectedTab_ = this.tabs_[id];
      // Disconnect observer while we mutate the child.
      this.selectedTab_.observers.forAttributeSelected.disconnect();
      this.selectedTab_.content.setAttribute('selected', 'selected');
      // Reconnect the observer to watch for changes in the future.
      this.selectedTab_.observers.forAttributeSelected.observe(
          this.selectedTab_.content, { attributeFilter: ['selected'] });

    },

    saveTabStates: function() {
      // Scroll positions of unselected tabs have already been saved.
      this.saveCurrentTabScrollPosition_();
    },

    saveCurrentTabScrollPosition_: function() {
      if (this.selectedTab_) {
        this.selectedTab_.content._savedScrollTop =
            this.$['content-container'].scrollTop;
        this.selectedTab_.content._savedScrollLeft =
            this.$['content-container'].scrollLeft;
      }
    },

    restoreCurrentTabScrollPosition_: function() {
      if (this.selectedTab_) {
        this.$['content-container'].scrollTop =
            this.selectedTab_.content._savedScrollTop || 0;
        this.$['content-container'].scrollLeft =
            this.selectedTab_.content._savedScrollLeft || 0;
      }
    },

    /**
     * This function clears the currently selected tab. This handles removal
     * of the selected attribute from the light-dom element.
     */
    clearSelectedTab_: function() {
      if (this.selectedTab_) {
        // Disconnect observer while we mutate the child.
        this.selectedTab_.observers.forAttributeSelected.disconnect();
        this.selectedTab_.content.removeAttribute('selected');
        // Reconnect the observer to watch for changes in the future.
        this.selectedTab_.observers.forAttributeSelected.observe(
            this.selectedTab_.content, { attributeFilter: ['selected'] });
        this.selectedTab_ = undefined;
      }
    }
  });
  </script>
</polymer-element>
