application sources from tizen_2.2
[apps/web/sample/ExercisePlanner.git] / project / js / app.timeRange.js
1 /*jslint devel: true*/
2 /*global $, ExercisePlanner: true*/
3 /**
4  *
5  */
6 (function () {
7         "use strict";
8         ExercisePlanner.prototype.checkNewTimeRange = function (start, duration, style) {
9                 var result = [];
10                 if (duration < 1 || duration > 24) {
11                         result.push({
12                                 name: 'Duration is not set properly.',
13                                 code: 2
14                         });
15                 }
16                 return result;
17         };
18
19         /**
20          * Sort method for time ranges;
21          */
22         ExercisePlanner.prototype.sortTimeRanges = function () {
23                 this.config.timesRanges.sort(function (a, b) {
24                         return a.start - b.start;
25                 });
26         };
27
28         /**
29          * Find and return max value of nr in time ranges array;
30          * @returns {Number}
31          */
32         ExercisePlanner.prototype.getMaxNrOfTimeRange = function getMaxNrOfTimeRange() {
33                 var maxNr = -1, i, len = this.config.timesRanges.length;
34                 for (i = 0; i < len; i += 1) {
35                         if (maxNr < this.config.timesRanges[i].nr) {
36                                 maxNr = this.config.timesRanges[i].nr;
37                         }
38                 }
39                 return maxNr;
40         };
41
42         /**
43          *
44          * @param nr
45          * @returns {Boolean}
46          */
47         ExercisePlanner.prototype.getTimeRangeByNr = function getTimeRangeByNr(nr) {
48                 var result = this.config.timesRanges.filter(function (item) {
49                                 return (item.nr === nr);
50                         });
51                 return result[0];
52         };
53
54         /**
55          * Save time range
56          *
57          * @param nr
58          * @param timeRange
59          * @returns {Boolean}
60          */
61         ExercisePlanner.prototype.saveTimeRange = function (nr, timeRange) {
62                 var index = -1,
63                         errors = this.checkNewTimeRange(timeRange.start, timeRange.duration, timeRange.style);
64
65                 // new timeRanges has nr === -1; this mean we must get max number from config
66                 if (nr === -1) {
67                         nr = this.getMaxNrOfTimeRange() + 1;
68                 } else {
69                         index = this.config.timesRanges.indexOf(this.getTimeRangeByNr(nr));
70                 }
71
72                 timeRange.nr = nr;
73
74                 if (errors.length > 0) {
75                         this.ui.showErrors(errors);
76                         return false;
77                 }
78
79                 if (index !== -1) {
80                         this.config.timesRanges[index] = timeRange;
81                 } else {
82                         this.config.timesRanges.push(timeRange);
83                 }
84
85                 this.sortTimeRanges();
86                 this.saveConfig();
87                 this.ui.fillTimesRanges(this.config.timesRanges);
88                 this.generateAlarms();
89                 this.updateGraph();
90
91                 this.ui.endProgress();
92                 return true;
93         };
94
95         /**
96          *
97          * @param {nymber}
98          * @returns {number}
99          */
100         ExercisePlanner.prototype.editTimeRange = function editTimeRange(nr) {
101                 var timeRange = this.getTimeRangeByNr(nr);
102
103                 if (timeRange !== undefined) {
104                         this.currentEditingTimePeriod = timeRange;
105                         this.currentEditingTimePeriodId = timeRange.nr;
106                 } else {
107                         this.currentEditingTimePeriod = {
108                                 nr: -1,
109                                 start: 10,
110                                 duration: 1,
111                                 stop: 11,
112                                 enabled: true,
113                                 style: 'everyday'
114                         };
115                         this.currentEditingTimePeriodId = -1;
116                 }
117                 return this.currentEditingTimePeriodId;
118         };
119
120         /**
121          * Delete time range by number on list
122          *
123          * @param nr
124          * @returns {Boolean}
125          */
126         ExercisePlanner.prototype.deleteTimeRange = function (nr) {
127
128                 var index,
129                         timeRange = this.getTimeRangeByNr(nr);
130
131                 if (timeRange === undefined) {
132                         return false;
133                 }
134
135                 index = this.config.timesRanges.indexOf(timeRange);
136                 if (index === -1) {
137                         return false;
138                 }
139
140                 // delete time range from array;
141                 this.config.timesRanges.splice(index, 1);
142
143                 this.saveConfig();
144                 this.ui.fillTimesRanges(this.config.timesRanges);
145                 this.generateAlarms();
146                 // update time periods on graph;
147                 this.ui.graphSchedule.setTimeRanges(this.periodsWeekToBoolArray());
148                 this.ui.graphSchedule.refresh();
149
150                 this.updateGraph();
151                 this.showNextAlarm();
152                 return true;
153         };
154
155         /**
156          * Disable time range by number on list
157          *
158          * @param nr
159          * @returns {Boolean}
160          */
161         ExercisePlanner.prototype.disableTimeRange = function (nr) {
162                 var timeRange = this.getTimeRangeByNr(nr);
163
164                 if (timeRange === undefined) {
165                         return false;
166                 }
167
168                 timeRange.enabled = !timeRange.enabled;
169
170                 this.saveConfig();
171                 this.ui.fillTimesRanges(this.config.timesRanges);
172                 this.generateAlarms();
173                 // update time periods on graph;
174                 this.ui.graphSchedule.setTimeRanges(this.periodsWeekToBoolArray());
175                 this.ui.graphSchedule.refresh();
176
177                 this.updateGraph(this.config.currentTypeOfPeriods);
178                 this.showNextAlarm();
179                 return true;
180         };
181
182         /**
183          * Combines a overlapped time periods & delete not necesary
184          * This method modifies exisiting array in cache.
185          *
186          * @param periods
187          * @returns
188          */
189         ExercisePlanner.prototype.mergeOverlapPeriods = function mergeOverlapPeriods(periods) {
190                 var i, len = periods.length, wasOverlap = true, mergePeriod;
191
192                 periods.sort(function (a, b) {
193                         return a - b;
194                 });
195
196                 if (len < 2) {
197                         return periods;
198                 }
199
200                 while (wasOverlap) {
201                         wasOverlap = false;
202                         len = periods.length;
203                         for (i = 0; i < len - 1; i += 1) {
204                                 if (periods[i].stop > periods[i + 1].start) {
205                                         mergePeriod = $.extend({}, periods[i]);
206                                         if (mergePeriod.stop < periods[i + 1].stop) {
207                                                 mergePeriod.stop = periods[i + 1].stop;
208                                                 mergePeriod.duration = mergePeriod.stop - mergePeriod.start;
209                                         }
210                                         mergePeriod.nr = -1;
211                                         periods.splice(i, 2, mergePeriod);
212                                         wasOverlap = true;
213                                         break;
214                                 }
215                         }
216                 }
217
218                 return periods;
219         };
220
221         ExercisePlanner.prototype.mergePeriods = function mergePeriods() {
222                 var i, len, onlyEveryDay = true,
223                         ranges = this.config.timesRanges,
224                         result = {
225                                 everyday : [],
226                                 weekend: [],
227                                 workday: []
228                         };
229
230                 // checking time ranges for different to the "everyday"
231                 for (i = 0, len = ranges.length; i < len; i += 1) {
232                         if (ranges[i].style !== 'everyday') {
233                                 onlyEveryDay = false;
234                                 break;
235                         }
236                 }
237
238                 if (onlyEveryDay) {
239                         for (i = 0, len = this.config.timesRanges.length; i < len; i += 1) {
240                                 if (this.config.timesRanges[i].enabled) {
241                                         result.everyday.push(this.config.timesRanges[i]);
242                                 }
243                         }
244                 } else {
245                         // divide 'everyday' periods at workday/weekend
246                         for (i = 0, len = this.config.timesRanges.length; i < len; i += 1) {
247                                 // if time range is disabled do not append to cache;
248                                 if (this.config.timesRanges[i].enabled) {
249                                         switch (this.config.timesRanges[i].style) {
250                                         case 'everyday':
251                                                 result.workday.push(this.config.timesRanges[i]);
252                                                 result.weekend.push(this.config.timesRanges[i]);
253                                                 break;
254                                         case 'workday':
255                                                 result.workday.push(this.config.timesRanges[i]);
256                                                 break;
257                                         case 'weekend':
258                                                 result.weekend.push(this.config.timesRanges[i]);
259                                                 break;
260                                         }
261                                 }
262                         }
263                 }
264
265                 // check and correct overlaped time periods
266                 this.mergeOverlapPeriods(result.everyday);
267                 this.mergeOverlapPeriods(result.workday);
268                 this.mergeOverlapPeriods(result.weekend);
269
270                 return result;
271         };
272
273         ExercisePlanner.prototype.getSummaryAvailableTime = function getSummaryAvailableTime() {
274                 var i, len,
275                         periods = this.cache.periodsWeek,
276                         sum = {
277                                 weekend: 0,
278                                 workday: 0,
279                                 everyday: 0
280                         };
281
282                 for (i = 0, len = periods.everyday.length; i < len; i += 1) {
283                         if (periods.everyday[i].enabled) {
284                                 sum.everyday += periods.everyday[i].duration;
285                         }
286                 }
287                 for (i = 0, len = periods.workday.length; i < len; i += 1) {
288                         if (periods.workday[i].enabled) {
289                                 sum.workday += periods.workday[i].duration;
290                         }
291                 }
292                 for (i = 0, len = periods.weekend.length; i < len; i += 1) {
293                         if (periods.weekend[i].enabled) {
294                                 sum.weekend += periods.weekend[i].duration;
295                         }
296                 }
297
298                 return sum;
299         };
300
301         ExercisePlanner.prototype.findNearestTimeRange = function (hour, ranges) {
302                 var nearResult,
303                         result = {
304                                 requestedHour: hour,
305                                 optimalHour: -1
306                         };
307
308                 if (!ranges.length) {
309                         return result;
310                 }
311
312                 /**
313                  * Function search ranges of time for nearest to a hour
314                  */
315                 nearResult = ranges.reduce(function (previous, element, index) {
316                         var delta = 0;
317
318                         if (element.start < hour && element.stop < hour) {
319                                 delta = hour - element.stop;
320                         }
321
322                         if (element.start > hour && element.stop > hour) {
323                                 delta = element.start - hour;
324                         }
325
326                         return (delta < previous.delta) ? { index: index, delta: delta } : previous;
327                 }, { index: -1, delta: 100 });
328
329                 if (ranges[nearResult.index].start <= hour && ranges[nearResult.index].stop >= hour) {
330                         result.optimalHour = Math.round((ranges[nearResult.index].start + ranges[nearResult.index].stop) / 2);
331                 } else {
332                         result.optimalHour = (ranges[nearResult.index].start > hour) ? ranges[nearResult.index].start : ranges[nearResult.index].stop;
333                 }
334
335                 return result;
336         };
337
338         /**
339          * Export time period to array of boolen [boolean x 24]
340          * @returns {object}
341          */
342         ExercisePlanner.prototype.periodsWeekToBoolArray = function periodsWeekToBoolArray() {
343                 var i, j, len, periods,
344                         result = {
345                                 workday: [],
346                                 weekend: []
347                         };
348
349                 // fill default result;
350                 for (i = 0; i < 24; i += 1) {
351                         result.workday[i] = false;
352                         result.weekend[i] = false;
353                 }
354
355                 // set values;
356                 periods = this.cache.periodsWeek.everyday;
357                 len = periods.length;
358                 for (i = 0; i < len; i += 1) {
359                         for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
360                                 result.workday[j % 24] = true;
361                                 result.weekend[j % 24] = true;
362                         }
363                 }
364
365                 // set values;
366                 periods = this.cache.periodsWeek.workday;
367                 len = periods.length;
368                 for (i = 0; i < len; i += 1) {
369                         for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
370                                 result.workday[j % 24] = true;
371                         }
372                 }
373
374                 // set values;
375                 periods = this.cache.periodsWeek.weekend;
376                 len = periods.length;
377                 for (i = 0; i < len; i += 1) {
378                         for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
379                                 result.weekend[j % 24] = true;
380                         }
381                 }
382                 return result;
383         };
384
385
386 }());
387