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.SettingsSection}
14   */
15  function MediaSizeSettings(ticketItem) {
16    print_preview.SettingsSection.call(this);
17
18    /** @private {!print_preview.ticket_items.MediaSize} */
19    this.ticketItem_ = ticketItem;
20  };
21
22  MediaSizeSettings.prototype = {
23    __proto__: print_preview.SettingsSection.prototype,
24
25    /** @override */
26    isAvailable: function() {
27      return this.ticketItem_.isCapabilityAvailable();
28    },
29
30    /** @override */
31    hasCollapsibleContent: function() {
32      return this.isAvailable();
33    },
34
35    /** @override */
36    set isEnabled(isEnabled) {
37      this.select_.disabled = !isEnabled;
38    },
39
40    /** @override */
41    enterDocument: function() {
42      print_preview.SettingsSection.prototype.enterDocument.call(this);
43      this.tracker.add(this.select_, 'change', this.onSelectChange_.bind(this));
44      this.tracker.add(
45          this.ticketItem_,
46          print_preview.ticket_items.TicketItem.EventType.CHANGE,
47          this.onTicketItemChange_.bind(this));
48    },
49
50    /**
51     * @return {HTMLSelectElement} Select element containing media size options.
52     * @private
53     */
54    get select_() {
55      return this.getElement().getElementsByClassName(
56          'media-size-settings-select')[0];
57    },
58
59    /**
60     * Makes sure the content of the select element matches the capabilities of
61     * the destination.
62     * @private
63     */
64    updateSelect_: function() {
65      var select = this.select_;
66      if (!this.isAvailable()) {
67        select.innerHTML = '';
68        return;
69      }
70      // Should the select content be updated?
71      var sameContent =
72          this.ticketItem_.capability.option.length == select.length &&
73          this.ticketItem_.capability.option.every(function(option, index) {
74            return select.options[index].value == JSON.stringify(option);
75          });
76      var indexToSelect = select.selectedIndex;
77      if (!sameContent) {
78        select.innerHTML = '';
79        // TODO: Better heuristics for the display name and options grouping.
80        this.ticketItem_.capability.option.forEach(function(option, index) {
81          var selectOption = document.createElement('option');
82          var displayName = option.custom_display_name;
83          if (!displayName && option.custom_display_name_localized) {
84            var getLocaleToCompare = function(locale, languageOnly) {
85              var code = languageOnly ? locale.split('-')[0] : locale;
86              return code.toLowerCase();
87            };
88            var getItemForLocale = function(items, locale, languageOnly) {
89              locale = getLocaleToCompare(locale, languageOnly);
90              for (var i = 0; i < items.length; i++) {
91                if (getLocaleToCompare(items[i].locale) == locale)
92                  return items[i].value;
93              }
94              return '';
95            };
96            var items = option.custom_display_name_localized;
97            displayName =
98                getItemForLocale(items, navigator.language, false) ||
99                getItemForLocale(items, navigator.language, true);
100          }
101          selectOption.text = displayName || option.name;
102          selectOption.value = JSON.stringify(option);
103          select.add(selectOption);
104          if (option.is_default) {
105            indexToSelect = index;
106          }
107        });
108      }
109      // Try to select current ticket item.
110      var valueToSelect = JSON.stringify(this.ticketItem_.getValue());
111      for (var i = 0, option; option = select.options[i]; i++) {
112        if (option.value == valueToSelect) {
113          indexToSelect = i;
114          break;
115        }
116      }
117      select.selectedIndex = indexToSelect;
118      this.onSelectChange_();
119    },
120
121    /**
122     * Called when the select element is changed. Updates the print ticket.
123     * @private
124     */
125    onSelectChange_: function() {
126      var select = this.select_;
127      var mediaSize = JSON.parse(select.options[select.selectedIndex].value);
128      this.ticketItem_.updateValue(mediaSize);
129    },
130
131    /**
132     * Called when the print ticket store changes. Selects the corresponding
133     * select option.
134     * @private
135     */
136    onTicketItemChange_: function() {
137      this.updateSelect_();
138      this.updateUiStateInternal();
139    }
140  };
141
142  // Export
143  return {
144    MediaSizeSettings: MediaSizeSettings
145  };
146});
147