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
5cr.define('ntp4', function() {
6  'use strict';
7
8  var TilePage = ntp4.TilePage;
9
10  /**
11   * Creates a new App object.
12   * @param {Object} appData The data object that describes the app.
13   * @constructor
14   * @extends {HTMLDivElement}
15   */
16  function App(appData) {
17    var el = cr.doc.createElement('div');
18    el.__proto__ = App.prototype;
19    el.appData = appData;
20    el.initialize();
21
22    return el;
23  }
24
25  App.prototype = {
26    __proto__: HTMLDivElement.prototype,
27
28    initialize: function() {
29      assert(this.appData.id, 'Got an app without an ID');
30
31      this.className = 'app';
32      this.setAttribute('app-id', this.appData.id);
33
34      var appImg = this.ownerDocument.createElement('img');
35      appImg.src = this.appData.icon_big;
36      // We use a mask of the same image so CSS rules can highlight just the
37      // image when it's touched.
38      appImg.style.WebkitMaskImage = url(this.appData.icon_big);
39      // We put a click handler just on the app image - so clicking on the
40      // margins between apps doesn't do anything.
41      appImg.addEventListener('click', this.onClick_.bind(this));
42      this.appendChild(appImg);
43      this.appImg_ = appImg;
44
45      var appSpan = this.ownerDocument.createElement('span');
46      appSpan.textContent = this.appData.name;
47      this.appendChild(appSpan);
48
49      /* TODO(estade): grabber */
50    },
51
52    /**
53     * Set the size and position of the app tile.
54     * @param {number} size The total size of |this|.
55     * @param {number} x The x-position.
56     * @param {number} y The y-position.
57     *     animate.
58     */
59    setBounds: function(size, x, y) {
60      this.appImg_.style.width = this.appImg_.style.height =
61          (size * APP_IMG_SIZE_FRACTION) + 'px';
62      this.style.width = this.style.height = size + 'px';
63      this.style.left = x + 'px';
64      this.style.top = y + 'px';
65    },
66
67    /**
68     * Invoked when an app is clicked
69     * @param {Event} e The click event.
70     * @private
71     */
72    onClick_: function(e) {
73      // Tell chrome to launch the app.
74      var NTP_APPS_MAXIMIZED = 0;
75      chrome.send('launchApp', [this.appData.id, NTP_APPS_MAXIMIZED]);
76
77      // Don't allow the click to trigger a link or anything
78      e.preventDefault();
79    },
80  };
81
82  // The fraction of the app tile size that the icon uses.
83  var APP_IMG_SIZE_FRACTION = 4 / 5;
84
85  var appsPageGridValues = {
86    // The fewest tiles we will show in a row.
87    minColCount: 3,
88    // The most tiles we will show in a row.
89    maxColCount: 6,
90
91    // The smallest a tile can be.
92    minTileWidth: 96 / APP_IMG_SIZE_FRACTION,
93    // The biggest a tile can be.
94    maxTileWidth: 128 / APP_IMG_SIZE_FRACTION,
95  };
96  TilePage.initGridValues(appsPageGridValues);
97
98  /**
99   * Creates a new AppsPage object.
100   * @param {string} name The display name for the page.
101   * @constructor
102   * @extends {TilePage}
103   */
104  function AppsPage(name) {
105    var el = new TilePage(name, appsPageGridValues);
106    el.__proto__ = AppsPage.prototype;
107    el.initialize();
108
109    return el;
110  }
111
112  AppsPage.prototype = {
113    __proto__: TilePage.prototype,
114
115    initialize: function() {
116      this.classList.add('apps-page');
117    },
118
119    /**
120     * Creates an app DOM element and places it at the last position on the
121     * page.
122     * @param {Object} appData The data object that describes the app.
123     */
124    appendApp: function(appData) {
125      this.appendTile(new App(appData));
126    },
127  };
128
129  return {
130    AppsPage: AppsPage,
131  };
132});
133