1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @fileoverview This is a table column model
7 */
8cr.define('cr.ui.table', function() {
9  const EventTarget = cr.EventTarget;
10  const Event = cr.Event;
11
12  /**
13   * A table column model that wraps table columns array
14   * This implementation supports widths in percents.
15   * @param {!Array<cr.ui.table.TableColumn>} columnIds Array of table columns.
16   * @constructor
17   * @extends {EventTarget}
18   */
19  function TableColumnModel(tableColumns) {
20    this.columns_ = [];
21    for (var i = 0; i < tableColumns.length; i++) {
22      this.columns_.push(tableColumns[i].clone());
23    }
24    this.normalizeWidths_();
25  }
26
27  TableColumnModel.prototype = {
28    __proto__: EventTarget.prototype,
29
30    /**
31     * The number of the columns.
32     * @type {number}
33     */
34    get size() {
35      return this.columns_.length;
36    },
37
38    /**
39     * Returns id of column at the given index.
40     * @param {number} index The index of the column.
41     * @return {string} Column id.
42     */
43    getId: function(index) {
44      return this.columns_[index].id;
45    },
46
47    /**
48     * Returns name of column at the given index. Name is used as column header
49     * label.
50     * @param {number} index The index of the column.
51     * @return {string} Column name.
52     */
53    getName: function(index) {
54      return this.columns_[index].name;
55    },
56
57    /**
58     * Sets name of column at the given index.
59     * @param {number} index The index of the column.
60     * @param {string} Column name.
61     */
62    setName: function(index, name) {
63      if (index < 0 || index >= this.columns_.size - 1)
64        return;
65      if (name != this.columns_[index].name)
66        return;
67
68      this.columns_[index].name = name;
69      cr.dispatchSimpleEvent('change');
70    },
71
72    /**
73     * Returns width (in percent) of column at the given index.
74     * @param {number} index The index of the column.
75     * @return {string} Column width.
76     */
77    getWidth: function(index) {
78      return this.columns_[index].width;
79    },
80
81    /**
82     * Sets width of column at the given index.
83     * @param {number} index The index of the column.
84     * @param {number} Column width.
85     */
86    setWidth: function(index, width) {
87      if (index < 0 || index >= this.columns_.size - 1)
88        return;
89
90      var minWidth = 3;
91      var currentPlusNextWidth = this.columns_[index + 1].width +
92          this.columns_[index].width;
93      var nextWidth = currentPlusNextWidth - width;
94      if (width < minWidth) {
95        width = minWidth;
96        nextWidth = currentPlusNextWidth - minWidth;
97      }
98      if (nextWidth < minWidth) {
99        width = currentPlusNextWidth - minWidth;
100        nextWidth = minWidth;
101      }
102      if (width == this.columns_[index].width)
103        return;
104
105      this.columns_[index].width = width;
106      this.columns_[index + 1].width = nextWidth;
107      cr.dispatchSimpleEvent(this, 'resize');
108    },
109
110    /**
111     * Returns render function for the column at the given index.
112     * @param {number} index The index of the column.
113     * @return {Function(*, string, cr.ui.Table): HTMLElement} Render function.
114     */
115    getRenderFunction: function(index) {
116      return this.columns_[index].renderFunction;
117    },
118
119    /**
120     * Sets render function for the column at the given index.
121     * @param {number} index The index of the column.
122     * @param {Function(*, string, cr.ui.Table): HTMLElement} Render function.
123     */
124    setRenderFunction: function(index, renderFunction) {
125      if (index < 0 || index >= this.columns_.size - 1)
126        return;
127      if (renderFunction !== this.columns_[index].renderFunction)
128        return;
129
130      this.columns_[index].renderFunction = renderFunction;
131      cr.dispatchSimpleEvent(this, 'change');
132    },
133
134    /**
135     * The total width of the columns.
136     * @type {number}
137     */
138    get totalWidth() {
139      return this.totalWidth_;
140    },
141
142    /**
143     * Normalizes widths to make their sum 100%.
144     */
145    normalizeWidths_: function() {
146      var total = 0;
147      for (var i = 0; i < this.size; i++) {
148        total += this.columns_[i].width;
149      }
150      for (var i = 0; i < this.size; i++) {
151        this.columns_[i].width = this.columns_[i].width * 100 / total;
152      }
153    },
154
155    /**
156     * Returns index of the column with given id.
157     * @param {string} id The id to find.
158     * @return {number} The index of column with given id or -1 if not found.
159     */
160    indexOf: function(id) {
161      for (var i = 0; i < this.size; i++) {
162        if (element.id == id)
163          return i;
164      }
165      return -1;
166    },
167  };
168
169  return {
170    TableColumnModel: TableColumnModel
171  };
172});
173