Fix Driving/NightMode; remove 'use strict'.
[profile/ivi/cowhide.git] / src / javascripts / cowhide-core.js
1 /*
2  * Copyright (c) 2012, Intel Corporation.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9
10 (function($, _, undefined) {
11     $.cowhide = $.cowhide || {}
12     $.extend($.cowhide, {
13         version: '0.0.1',
14         options: {
15           monitorFrameworkRestrictions: false
16         },
17         themeEngineOptions: {
18             path: 'css',
19             initial: 'default',
20             minified: false
21         },
22
23         // List of registered widgets
24         registeredWidgets: [],
25
26         drivingMode: false,
27         nightMode: false,
28         currentTheme: 'default',
29
30         GUID: function() {
31             var S4 = function () {
32                 return Math.floor(
33                     Math.random() * 0x10000 /* 65536 */
34                     ).toString(16);
35             };
36
37             return (
38                 S4() + S4() + "-" +
39                 S4() + "-" +
40                 S4() + "-" +
41                 S4() + "-" +
42                 S4() + S4() + S4()
43                 );
44         },
45
46         // Registers a widget
47         register: function(widget) {
48             var self = this;
49             var guids = _.map(self.registeredWidgets, function(w) {
50                 return w.guid;
51             });
52
53             if (_.indexOf(guids, widget.guid) == -1) {
54                 self.registeredWidgets.push(widget);
55             }
56
57             /* TODO: core should ask `page` what a page looks like. */
58             if(!(widget.$element[0].tagName == 'DIV' && widget.$element.hasClass('page'))) {
59                 var $page = widget.$element.parent().closest('div.page');
60                 if ($page.length === 0) {
61                     $.cowhide.fatal("#30: every widget must be within a div with class='page'.", this.$element);
62                 } else {
63                     $page.ch_page('register', widget);
64                 }
65             }
66         },
67
68         // TODO: use `backdrop` from Bootstrap's modal
69         backdrop: function (callback) {
70             var $backdrop = $('<div class="modal-backdrop theme-change-backdrop fade" />');
71
72             $backdrop.appendTo(document.body);
73             $backdrop[0].offsetWidth; // force reflow
74             $backdrop.addClass('in');
75
76             return $backdrop;
77         },
78
79         initThemeEngine: function(options) {
80             $.extend(this.themeEngineOptions, options);
81             this.currentTheme = this.themeEngineOptions.initial;
82
83             var $link = $('link#cowhide-theme');
84             if ($link.length === 0) {
85                 this.fatal("#40: could not find <link> with id 'cowhide-theme'.");
86             }
87         },
88
89         setTheme: function(name, nightMode) {
90             if (name === this.currentTheme && nightMode == this.nightMode) {
91                 return;
92             }
93
94             var $link = $('link#cowhide-theme');
95             var theme =
96                 this.themeEngineOptions.path +
97                 '/cowhide-' +
98                 name || 'default';
99
100             if (nightMode === true || (nightMode === undefined && this.nightMode === true)) {
101                 theme += '-night';
102             }
103
104             if (this.themeEngineOptions.minified) {
105                 theme += '.min';
106             }
107
108             theme += '.css';
109
110             var $backdrop = this.backdrop();
111             setTimeout(function() {
112                 $link.attr('href', theme);
113                 $backdrop.remove();
114             }, 200);
115
116             this.currentTheme = name;
117             if (nightMode !== undefined) {
118                 this.nightMode = nightMode;
119             }
120         },
121
122         setNightMode: function(value) {
123           if (this.nightMode == value)
124             return;
125
126           this.setTheme(this.currentTheme, !this.nightMode);
127         },
128
129         toggleNightMode: function() {
130             this.setNightMode(!this.nightMode);
131         },
132
133         toggleDrivingMode: function() {
134             this.setDrivingMode(!this.drivingMode);
135         },
136
137         setDrivingMode: function(value) {
138             var self = this;
139
140             if (self.drivingMode == value)
141                 return;
142
143             self.drivingMode = value;
144             _.each(this.registeredWidgets, function(w) {
145                 if (w.setDrivingMode)
146                     w.setDrivingMode(self.drivingMode);
147             });
148         },
149
150         initialize: function() {
151             var self = this;
152
153             if (window.tizen !== undefined &&
154                 window.tizen.vehicle !== undefined)
155             {
156                 window.tizen.vehicle.getAsync("DrivingMode", function(data) {
157                     self.setNightMode(data.drivingMode);
158                 });
159
160                 window.tizen.vehicle.getAsync("NightMode", function(data) {
161                     self.setNightMode(data.nightMode);
162                 });
163             }
164         },
165
166         listenToVehicle: function() {
167             var self = this;
168
169             if (window.tizen !== undefined &&
170                 window.tizen.vehicle !== undefined)
171             {
172                 window.tizen.vehicle.subscribe("DrivingMode", function(data) {
173                     self.setDrivingMode(data.drivingMode);
174                 });
175
176                 window.tizen.vehicle.subscribe("NightMode", function(data) {
177                     self.setNightMode(data.nightMode);
178                 });
179             }
180         },
181
182         verifyFrameworkRestrictions: function() {
183             _.each(this.registeredWidgets, function(w) {
184                 w.verifyMinFontSize();
185                 w.verifyMaxFontSize();
186                 w.verifyMinWidth();
187             });
188         },
189
190         fatal: function(msg, $element) {
191             var output = "";
192
193             output += "[Cowhide] Fatal error";
194             if ($element !== undefined) {
195                 output += " (offending widget: ";
196                 var id = $element.attr('id');
197                 var classes = $element.attr('class');
198
199                 if (id)
200                     output += "#(" + id + ")";
201                 if (classes)
202                     output += ".(" + classes + ")";
203
204                 output += ")";
205             }
206
207             output += ": " + msg;
208             throw new Error(output);
209         }
210     });
211
212     $(function() {
213         $.cowhide.initialize();
214         $.cowhide.listenToVehicle();
215         if ($.cowhide.options.monitorFrameworkRestrictions) {
216           setInterval(function() {
217               $.cowhide.verifyFrameworkRestrictions();
218           }, 1000);
219         }
220     });
221 })(window.jQuery, window._);