<!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/range.html">
<link rel="import" href="/ui/side_panel/side_panel.html">
<link rel='import' href='/ui/base/polymer_utils.html'>

<polymer-element name='tr-ui-side-panel-container' is='HTMLUnknownElement'>
  <template>
    <style>
    :host {
      align-items: stretch;
      display: -webkit-flex;
    }

    :host([expanded]) > active-panel-container {
      -webkit-flex: 1 1 auto;
      border-left: 1px solid black;
      display: -webkit-flex;
    }

    :host(:not([expanded])) > active-panel-container {
      display: none;
    }

    active-panel-container {
      display: flex;
    }

    tab-strip {
      -webkit-flex: 0 0 auto;
      -webkit-flex-direction: column;
      -webkit-user-select: none;
      background-color: rgb(236, 236, 236);
      border-left: 1px solid black;
      cursor: default;
      display: -webkit-flex;
      min-width: 18px; /* workaround for flexbox and writing-mode mixing bug */
      padding: 10px 0 10px 0;
      font-size: 12px;
    }

    tab-strip > tab-strip-label {
      -webkit-writing-mode: vertical-rl;
      display: inline;
      margin-right: 1px;
      min-height: 20px;
      padding: 15px 3px 15px 1px;
    }

    tab-strip >
        tab-strip-label:not([enabled]) {
      color: rgb(128, 128, 128);
    }

    tab-strip > tab-strip-label[selected] {
      background-color: white;
      border: 1px solid rgb(163, 163, 163);
      border-left: none;
      padding: 14px 2px 14px 1px;
    }
    </style>

    <active-panel-container id='active_panel_container'>
    </active-panel-container>
    <tab-strip id='tab_strip'></tab-strip>
  </template>

  <script>
  'use strict';
  Polymer({
    ready: function() {
      this.activePanelContainer_ = this.$.active_panel_container;
      this.tabStrip_ = this.$.tab_strip;

      this.rangeOfInterest_ = new tr.b.Range();
      this.brushingStateController_ = undefined;
      this.onSelectionChanged_ = this.onSelectionChanged_.bind(this);
      this.onModelChanged_ = this.onModelChanged_.bind(this);
    },

    get brushingStateController() {
      return this.brushingStateController_;
    },

    set brushingStateController(brushingStateController) {
      if (this.brushingStateController) {
        this.brushingStateController_.removeEventListener(
            'change', this.onSelectionChanged_);
        this.brushingStateController_.removeEventListener(
            'model-changed', this.onModelChanged_);
      }
      this.brushingStateController_ = brushingStateController;
      if (this.brushingStateController) {
        this.brushingStateController_.addEventListener(
            'change', this.onSelectionChanged_);
        this.brushingStateController_.addEventListener(
            'model-changed', this.onModelChanged_);
      }
    },

    get selection() {
      return this.brushingStateController_.selection;
    },

    onSelectionChanged_: function() {
      if (this.activePanel)
        this.activePanel.selection = this.selection;
    },

    get model() {
      return this.brushingStateController_.model;
    },

    onModelChanged_: function() {
      this.activePanelType_ = undefined;
      this.updateContents_();
    },

    get expanded() {
      this.hasAttribute('expanded');
    },

    get activePanel() {
      if (this.activePanelContainer_.children.length === 0)
        return undefined;
      return this.activePanelContainer_.children[0];
    },

    get activePanelType() {
      return this.activePanelType_;
    },

    set activePanelType(panelType) {
      if (this.model === undefined)
        throw new Error('Cannot activate panel without a model');

      var panel = undefined;
      if (panelType)
          panel = document.createElement(panelType);

      if (panel !== undefined && !panel.supportsModel(this.model))
        throw new Error('Cannot activate panel: does not support this model');

      if (this.activePanelType) {
        this.getLabelElementForPanelType_(
            this.activePanelType).removeAttribute('selected');
      }
      this.activePanelContainer_.textContent = '';

      if (panelType === undefined) {
        this.removeAttribute('expanded');
        this.activePanelType_ = undefined;
        return;
      }

      this.getLabelElementForPanelType_(panelType).
          setAttribute('selected', true);
      this.setAttribute('expanded', true);

      this.activePanelContainer_.appendChild(panel);
      panel.rangeOfInterest = this.rangeOfInterest_;
      panel.selection = this.selection_;
      panel.model = this.model;

      this.activePanelType_ = panelType;
    },

    getPanelTypeForConstructor_: function(constructor) {
      for (var i = 0; i < this.tabStrip_.children.length; i++) {
        if (this.tabStrip_.children[i].panelType.constructor == constructor)
          return this.tabStrip_.children[i].panelType;
      }
    },

    getLabelElementForPanelType_: function(panelType) {
      for (var i = 0; i < this.tabStrip_.children.length; i++) {
        if (this.tabStrip_.children[i].panelType == panelType)
          return this.tabStrip_.children[i];
      }
      return undefined;
    },

    updateContents_: function() {
      var previouslyActivePanelType = this.activePanelType;

      this.tabStrip_.textContent = '';
      var supportedPanelTypes = [];

      var panelTypes =
          tr.ui.b.getPolymerElementsThatSubclass('tr-ui-side-panel');
      panelTypes.forEach(function(panelType) {
        var labelEl = document.createElement('tab-strip-label');
        var panel = document.createElement(panelType);

        labelEl.textContent = panel.textLabel;
        labelEl.panelType = panelType;

        var supported = panel.supportsModel(this.model);
        if (this.model && supported.supported) {
          supportedPanelTypes.push(panelType);
          labelEl.setAttribute('enabled', true);
          labelEl.addEventListener('click', function() {
            this.activePanelType =
                this.activePanelType === panelType ? undefined : panelType;
          }.bind(this));
        } else {
          labelEl.title = 'Not supported for the current trace: ' +
              supported.reason;
          labelEl.style.display = 'none';
        }
        this.tabStrip_.appendChild(labelEl);
      }, this);

      // Restore the active panel, or collapse
      if (previouslyActivePanelType &&
          supportedPanelTypes.indexOf(previouslyActivePanelType) != -1) {
        this.activePanelType = previouslyActivePanelType;
        this.setAttribute('expanded', true);
      } else {
        this.activePanelContainer_.textContent = '';
        this.removeAttribute('expanded');
      }
    },

    get rangeOfInterest() {
      return this.rangeOfInterest_;
    },

    set rangeOfInterest(range) {
      if (range == undefined)
        throw new Error('Must not be undefined');
      this.rangeOfInterest_ = range;
      if (this.activePanel)
        this.activePanel.rangeOfInterest = range;
    }
  });
  </script>
</polymer-element>

