// Copyright (c) 2012 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.

var SourceRow = (function() {
  'use strict';

  /**
   * A SourceRow represents the row corresponding to a single SourceEntry
   * displayed by the EventsView.
   *
   * @constructor
   */
  function SourceRow(parentView, sourceEntry) {
    this.parentView_ = parentView;

    this.sourceEntry_ = sourceEntry;
    this.isSelected_ = false;
    this.isMatchedByFilter_ = false;

    // Used to set CSS class for display.  Must only be modified by calling
    // corresponding set functions.
    this.isSelected_ = false;
    this.isMouseOver_ = false;

    // Mirror sourceEntry's values, so we only update the DOM when necessary.
    this.isError_ = sourceEntry.isError();
    this.isInactive_ = sourceEntry.isInactive();
    this.description_ = sourceEntry.getDescription();

    this.createRow_();
    this.onSourceUpdated();
  }

  SourceRow.prototype = {
    createRow_: function() {
      // Create a row.
      var tr = addNode(this.parentView_.tableBody_, 'tr');
      tr._id = this.getSourceId();
      tr.style.display = 'none';
      this.row_ = tr;

      var selectionCol = addNode(tr, 'td');
      var checkbox = addNode(selectionCol, 'input');
      checkbox.title = this.getSourceId();
      selectionCol.style.borderLeft = '0';
      checkbox.type = 'checkbox';

      var idCell = addNode(tr, 'td');
      idCell.style.textAlign = 'right';

      var typeCell = addNode(tr, 'td');
      var descriptionCell = addNode(tr, 'td');
      this.descriptionCell_ = descriptionCell;

      // Connect listeners.
      checkbox.onchange = this.onCheckboxToggled_.bind(this);

      var onclick = this.onClicked_.bind(this);
      idCell.onclick = onclick;
      typeCell.onclick = onclick;
      descriptionCell.onclick = onclick;

      tr.onmouseover = this.onMouseover_.bind(this);
      tr.onmouseout = this.onMouseout_.bind(this);

      // Set the cell values to match this source's data.
      if (this.getSourceId() >= 0) {
        addTextNode(idCell, this.getSourceId());
      } else {
        addTextNode(idCell, '-');
      }
      var sourceTypeString = this.sourceEntry_.getSourceTypeString();
      addTextNode(typeCell, sourceTypeString);
      this.updateDescription_();

      // Add a CSS classname specific to this source type (so CSS can specify
      // different stylings for different types).
      var sourceTypeClass = sourceTypeString.toLowerCase().replace(/_/g, '-');
      this.row_.classList.add('source-' + sourceTypeClass);

      this.updateClass_();
    },

    onSourceUpdated: function() {
      if (this.sourceEntry_.isInactive() != this.isInactive_ ||
          this.sourceEntry_.isError() != this.isError_) {
        this.updateClass_();
      }

      if (this.description_ != this.sourceEntry_.getDescription())
        this.updateDescription_();

      // Update filters.
      var matchesFilter = this.parentView_.currentFilter_(this.sourceEntry_);
      this.setIsMatchedByFilter(matchesFilter);
    },

    /**
     * Changes |row_|'s class based on currently set flags.  Clears any previous
     * class set by this method.  This method is needed so that some styles
     * override others.
     */
    updateClass_: function() {
      this.isInactive_ = this.sourceEntry_.isInactive();
      this.isError_ = this.sourceEntry_.isError();

      // Each element of this list contains a property of |this| and the
      // corresponding class name to set if that property is true.  Entries
      // earlier in the list take precedence.
      var propertyNames = [
        ['isSelected_', 'selected'],
        ['isMouseOver_', 'mouseover'],
        ['isError_', 'error'],
        ['isInactive_', 'inactive'],
      ];

      // Loop through |propertyNames| in order, checking if each property
      // is true.  For the first such property found, if any, add the
      // corresponding class to the SourceEntry's row.  Remove classes
      // that correspond to any other property.
      var noStyleSet = true;
      for (var i = 0; i < propertyNames.length; ++i) {
        var setStyle = noStyleSet && this[propertyNames[i][0]];
        if (setStyle) {
          this.row_.classList.add(propertyNames[i][1]);
          noStyleSet = false;
        } else {
          this.row_.classList.remove(propertyNames[i][1]);
        }
      }
    },

    getSourceEntry: function() {
      return this.sourceEntry_;
    },

    setIsMatchedByFilter: function(isMatchedByFilter) {
      if (this.isMatchedByFilter() == isMatchedByFilter)
        return;  // No change.

      this.isMatchedByFilter_ = isMatchedByFilter;

      this.setFilterStyles(isMatchedByFilter);

      if (isMatchedByFilter) {
        this.parentView_.incrementPostfilterCount(1);
      } else {
        this.parentView_.incrementPostfilterCount(-1);
        // If we are filtering an entry away, make sure it is no longer
        // part of the selection.
        this.setSelected(false);
      }
    },

    isMatchedByFilter: function() {
      return this.isMatchedByFilter_;
    },

    setFilterStyles: function(isMatchedByFilter) {
      // Hide rows which have been filtered away.
      if (isMatchedByFilter) {
        this.row_.style.display = '';
      } else {
        this.row_.style.display = 'none';
      }
    },

    isSelected: function() {
      return this.isSelected_;
    },

    setSelected: function(isSelected) {
      if (isSelected == this.isSelected())
        return;

      this.isSelected_ = isSelected;

      this.setSelectedStyles(isSelected);
      this.parentView_.modifySelectionArray(this.getSourceId(), isSelected);
      this.parentView_.onSelectionChanged();
    },

    setSelectedStyles: function(isSelected) {
      this.isSelected_ = isSelected;
      this.getSelectionCheckbox().checked = isSelected;
      this.updateClass_();
    },

    setMouseoverStyle: function(isMouseOver) {
      this.isMouseOver_ = isMouseOver;
      this.updateClass_();
    },

    onClicked_: function() {
      this.parentView_.clearSelection();
      this.setSelected(true);
      if (this.isSelected())
        this.parentView_.scrollToSourceId(this.getSourceId());
    },

    onMouseover_: function() {
      this.setMouseoverStyle(true);
    },

    onMouseout_: function() {
      this.setMouseoverStyle(false);
    },

    updateDescription_: function() {
      this.description_ = this.sourceEntry_.getDescription();
      this.descriptionCell_.innerHTML = '';
      addTextNode(this.descriptionCell_, this.description_);
    },

    onCheckboxToggled_: function() {
      this.setSelected(this.getSelectionCheckbox().checked);
      if (this.isSelected())
        this.parentView_.scrollToSourceId(this.getSourceId());
    },

    getSelectionCheckbox: function() {
      return this.row_.childNodes[0].firstChild;
    },

    getSourceId: function() {
      return this.sourceEntry_.getSourceId();
    },

    /**
     * Returns source ID of the entry whose row is currently above this one's.
     * Returns null if no such node exists.
     */
    getPreviousNodeSourceId: function() {
      var prevNode = this.row_.previousSibling;
      if (prevNode == null)
        return null;
      return prevNode._id;
    },

    /**
     * Returns source ID of the entry whose row is currently below this one's.
     * Returns null if no such node exists.
     */
    getNextNodeSourceId: function() {
      var nextNode = this.row_.nextSibling;
      if (nextNode == null)
        return null;
      return nextNode._id;
    },

    /**
     * Moves current object's row before |entry|'s row.
     */
    moveBefore: function(entry) {
      this.row_.parentNode.insertBefore(this.row_, entry.row_);
    },

    /**
     * Moves current object's row after |entry|'s row.
     */
    moveAfter: function(entry) {
      this.row_.parentNode.insertBefore(this.row_, entry.row_.nextSibling);
    }
  };

  return SourceRow;
})();
