1// Copyright 2014 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
5cr.define('print_preview', function() {
6  'use strict';
7
8  /**
9   * Encapsulates all settings and logic related to the media size selection UI.
10   * @param {!print_preview.ticket_items.MediaSize} ticketItem Used to read and
11   *     write the media size ticket item.
12   * @constructor
13   * @extends {print_preview.Component}
14   */
15  function MediaSizeSettings(ticketItem) {
16    print_preview.Component.call(this);
17
18    /** @private {!print_preview.ticket_items.MediaSize} */
19    this.ticketItem_ = ticketItem;
20  };
21
22  MediaSizeSettings.prototype = {
23    __proto__: print_preview.Component.prototype,
24
25    /** @param {boolean} isEnabled Whether this component is enabled. */
26    set isEnabled(isEnabled) {
27      this.select_.disabled = !isEnabled;
28    },
29
30    /** @override */
31    enterDocument: function() {
32      print_preview.Component.prototype.enterDocument.call(this);
33      fadeOutOption(this.getElement(), true);
34      this.tracker.add(this.select_, 'change', this.onSelectChange_.bind(this));
35      this.tracker.add(
36          this.ticketItem_,
37          print_preview.ticket_items.TicketItem.EventType.CHANGE,
38          this.onTicketItemChange_.bind(this));
39    },
40
41    /**
42     * @return {HTMLSelectElement} Select element containing media size options.
43     * @private
44     */
45    get select_() {
46      return this.getElement().getElementsByClassName(
47          'media-size-settings-select')[0];
48    },
49
50    /**
51     * Makes sure the content of the select element matches the capabilities of
52     * the destination.
53     * @private
54     */
55    updateSelect_: function() {
56      var select = this.select_;
57      if (!this.ticketItem_.isCapabilityAvailable()) {
58        select.innerHTML = '';
59        return;
60      }
61      // Should the select content be updated?
62      var sameContent =
63          this.ticketItem_.capability.option.length == select.length &&
64          this.ticketItem_.capability.option.every(function(option, index) {
65            return select.options[index].value == JSON.stringify(option);
66          });
67      var indexToSelect = select.selectedIndex;
68      if (!sameContent) {
69        select.innerHTML = '';
70        // TODO: Better heuristics for the display name and options grouping.
71        this.ticketItem_.capability.option.forEach(function(option, index) {
72          var selectOption = document.createElement('option');
73          selectOption.text = option.custom_display_name || option.name;
74          selectOption.value = JSON.stringify(option);
75          select.add(selectOption);
76          if (option.is_default) {
77            indexToSelect = index;
78          }
79        });
80      }
81      // Try to select current ticket item.
82      var valueToSelect = JSON.stringify(this.ticketItem_.getValue());
83      for (var i = 0, option; option = select.options[i]; i++) {
84        if (option.value == valueToSelect) {
85          indexToSelect = i;
86          break;
87        }
88      }
89      select.selectedIndex = indexToSelect;
90      this.onSelectChange_();
91    },
92
93    /**
94     * Called when the select element is changed. Updates the print ticket.
95     * @private
96     */
97    onSelectChange_: function() {
98      var select = this.select_;
99      var mediaSize = JSON.parse(select.options[select.selectedIndex].value);
100      this.ticketItem_.updateValue(mediaSize);
101    },
102
103    /**
104     * Called when the print ticket store changes. Selects the corresponding
105     * select option.
106     * @private
107     */
108    onTicketItemChange_: function() {
109      if (this.ticketItem_.isCapabilityAvailable()) {
110        this.updateSelect_();
111        fadeInOption(this.getElement());
112      } else {
113        fadeOutOption(this.getElement());
114      }
115    }
116  };
117
118  // Export
119  return {
120    MediaSizeSettings: MediaSizeSettings
121  };
122});
123