diff options
Diffstat (limited to 'js/app.js')
-rw-r--r-- | js/app.js | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..3ab9bd8 --- /dev/null +++ b/js/app.js @@ -0,0 +1,450 @@ +/*jslint devel:true*/ +/*global tizen, $, app, localStorage, Audio, document, unlockScreen, UI */ +var ExercisePlanner = function () { + "use strict"; +}; + +(function () { + "use strict"; + + ExercisePlanner.prototype = { + /** + * Definition of time for sleep + */ + TIME_OF_SLEEP: 8, + + /** + * Definition one day in hours + */ + ONE_DAY: 24, + + /** + * Stored time of application start + */ + applicationStartTime: new Date(), + + /** + * Cofiguration data will saved for next launch; + * There are default values after install; + */ + config: { + + frequency: { + workday: 3, // 6 for test + weekend: 3 + }, + + strength: { + workday: 1, + weekend: 1 + }, + + /** + * List of workouts; + * - timeRanges:style [ everyday, weekend, workday ]; ( workday : mon-fri ) + */ + exercises: [{ + name: 'bends', + enabled: true + }, { + name: 'squats', + enabled: true + }, { + name: 'push-ups', + enabled: false + }], + + // deprecated for this version; + increasingStrength: true, + + /** + * Default time ranges + */ + timesRanges: [{ + nr: 0, + start: 8, + stop: 16, + duration: 8, + enabled: true, + style: 'everyday' + }, { + nr: 1, + start: 18, + stop: 22, + duration: 4, + enabled: true, + style: 'weekend' + }], + + nearestExercise: -1, + + count: 0, + + trainingEnabled: false + }, + alarms: { + everyday: [], + workday: [], + weekend: [] + }, + + /** + * Used for update GraphSchedule; + * [ workday / weekend ] + */ + currentTypeOfPeriods: 'workday', + /** + * Use on form to edit time period; + */ + currentEditingTimePeriod: null, + currentEditingTimePeriodId: -1, + + /** + * Date when alarm will start generating + */ + beginDate: null, + + /** + * use store temporary data for alarms; + */ + cache: {}, + + /** + * HTML5 audio element for play audio when alarm is called + */ + audioOfAlert: null, + + /** + * Instance of User Interface + */ + ui: null + }; + + /** + * Load configuration of application + * (use localStorage) + */ + ExercisePlanner.prototype.loadConfig = function () { + var configStr = localStorage.getItem('config'); + if (configStr) { + this.config = JSON.parse(configStr); + } else { + this.removeAllAlarms(); + this.sortTimeRanges(); + } + }; + + /** + * Save configuration of application + * (use localStorage) + */ + ExercisePlanner.prototype.saveConfig = function () { + localStorage.setItem('config', JSON.stringify(this.config)); + }; + + ExercisePlanner.prototype.stopTraining = function () { + this.removeAllAlarms(); + this.ui.setStatusRun(this.config.trainingEnabled); + }; + + ExercisePlanner.prototype.startTraining = function () { + this.ui.setStatusRun(this.config.trainingEnabled); + this.startAlarms(); + }; + + /** + * Toggle start/stop alarms for workouts + */ + ExercisePlanner.prototype.appStartStop = function () { + this.config.trainingEnabled = !this.config.trainingEnabled; + if (this.config.trainingEnabled) { + this.startTraining(); + } else { + this.stopTraining(); + } + this.saveConfig(); + }; + + /** + * Closing application with the configuration data saving + */ + ExercisePlanner.prototype.exit = function () { + this.saveConfig(); + this.stopMusic(); + tizen.application.getCurrentApplication().exit(); + }; + + /** + * Sets frequency value and calculates new alarms + * @param value + */ + ExercisePlanner.prototype.setFrequency = function (value) { + this.config.frequency[this.config.currentTypeOfPeriods] = parseInt(value, 10); + + this.saveConfig(); + this.generateAlarms(); + this.updateGraph(this.config.currentTypeOfPeriods); + this.showNextAlarm(); + }; + + /** + * Set Strength value + * @param value + */ + ExercisePlanner.prototype.setStrength = function (value) { + this.config.strength[this.config.currentTypeOfPeriods] = parseInt(value, 10); + this.saveConfig(); + }; + + /** + * Sending array of exercises to UI for update + */ + ExercisePlanner.prototype.updateExercises = function () { + this.ui.fillExercises(this.config.exercises); + }; + + /** + * Sending array of time ranges to UI for update + * & update graph schedule + */ + ExercisePlanner.prototype.updateTimesRanges = function () { + + this.ui.fillTimesRanges(this.config.timesRanges); + this.ui.graphSchedule.updateTimeRanges(); + }; + + /** + * Store exercises in config (and save) + * @param newData + */ + ExercisePlanner.prototype.saveExercises = function (newData) { + var i, l; + + if (newData) { + for (i = 0, l = newData.length; i < l; i += 1) { + this.config.exercises[i].enabled = newData[i].checked; + } + this.generateNearestExercise(); + this.saveConfig(); + } + }; + + /** + * When will earliest workout + * and show in UI + */ + ExercisePlanner.prototype.showNextAlarm = function showNextAlarm() { + var alarms, + currentDate = new Date(); + + if (this.alarms.everyday.length > 0) { + alarms = this.alarms.everyday; + } else { + alarms = (this.todayIsWorkday()) ? this.alarms.workday : this.alarms.weekend; + } + + alarms = alarms.filter(function (item) { + return (item.getTime() > currentDate.getTime()); + }).sort(function (a, b) { + return a.date - b.date; + }); + + if (this.config.nearestExercise > -1) { + this.ui.showAlarmInMonitor({ + alarm: alarms[0], + exerciseName: this.config.exercises[this.config.nearestExercise].name, + numberOfTimes: this.getStrength(this.config.strength.workday, this.config.count) + }); + + this.config.count += 1; + } + this.saveConfig(); + }; + + /** + * Change type of periods [workday/weekend] and update graph + * @param type + */ + ExercisePlanner.prototype.changeTypeOfPeriods = function changeTypeOfPeriods(type) { + if (this.config.currentTypeOfPeriods !== type) { + this.config.currentTypeOfPeriods = type; + this.updateGraph(this.config.currentTypeOfPeriods); + } + }; + + /** + * Check new exercise name for duplication in existings; + * @param name + * @returns + */ + ExercisePlanner.prototype.checkExerciseName = function (name) { + var i, l; + + if (name) { + for (i = 0, l = this.config.exercises.length; i < l; i += 1) { + if (this.config.exercises[i].name === name) { + return i; + } + } + return -1; + } + return undefined; + }; + + /** + * Add new exercise sent from UI + * @param name + * @returns {Boolean} + */ + ExercisePlanner.prototype.addExercise = function (name) { + if (this.checkExerciseName(name) < 0) { + this.config.exercises.push({ + name: name, + enabled: false + }); + this.saveConfig(); + this.ui.fillExercises(this.config.exercises); + return true; + } + this.ui.showErrors([{name: 'Element exists!'}]); + return false; + }; + + /** + * Get number of workouts by frequency + * @param value + * @returns {number} + */ + ExercisePlanner.prototype.getNumberOfWorkoutsByFrequency = function getNumberOfWorkoutsByFrequency(value) { + var iMap = [1, 2, 4, 8, 16, 24, 150], + // -- times per 24h; proportion to set periods of available time; + numberOfWorkouts = iMap[value]; + + return numberOfWorkouts || 2; + }; + + /** + * Get number of exercises in workout by strength value and optional ; + * @param value + * @param count + * @returns {number} + */ + ExercisePlanner.prototype.getStrength = function strengthMap(value, count) { + var sMap = [1, 1, 2, 4, 10, 20], + base = sMap[value] || 2; + + count = count || 1; + return Math.round(base * (count / 10 + 1)); + }; + + /** + * Generate name of exercise for nearest workout + */ + ExercisePlanner.prototype.generateNearestExercise = function () { + var tmp = this.config.exercises.filter(function (item) { + return item.enabled; + }); + this.config.nearestExercise = parseInt(Math.random() * tmp.length, 10); + }; + + + /** + * If user want change work days this method will changing; + * @returns {Boolean} + */ + ExercisePlanner.prototype.todayIsWorkday = function todayIsWorkday() { + var day = (new Date()).getDay(); + return (day >= 1 && day <= 5); + }; + + /** + * Activate alarms in API. + */ + ExercisePlanner.prototype.startAlarms = function startAlarms() { + // clear old alarms; + this.removeAllAlarms(); + + // add new alarms + this.addAlarmsAllWeek(this.alarms); + + this.generateNearestExercise(); + this.showNextAlarm(); + }; + + /** + * Update Graph object + * @param {String} typeOfPeriods ['workday'|'weekend'] + */ + ExercisePlanner.prototype.updateGraph = function updateGraph(typeOfPeriods) { + var alarms; + if (!this.ui.graphSchedule) { + throw { + message: 'graph schedule not exists.' + }; + } + + typeOfPeriods = typeOfPeriods || ((this.todayIsWorkday()) ? 'workday' : 'weekend'); + + if (typeOfPeriods === 'workday') { + alarms = this.alarms.workday; + } else { + alarms = this.alarms.weekend; + } + if (alarms.length === 0) { + alarms = this.alarms.everyday; + } + this.ui.graphSchedule.setTimeRanges(this.periodsWeekToBoolArray()); + this.ui.graphSchedule.pushTimeOfFlags(alarms); + this.ui.graphSchedule.showFlags(); + }; + + /** + * Callback function on visibility change; + */ + ExercisePlanner.prototype.onVisibilityChange = function () { + + switch (document.webkitVisibilityState) { + case 'visible': + this.applicationStartTime = new Date(); + this.currentAlarm = this.findCurrentAlarm(); + if (this.currentAlarm.length > 0) { + this.ui.showWaitOk(); + this.startMusic(); + } + break; + } + }; + + /** + * Turn off all alarms today + */ + ExercisePlanner.prototype.todayOffAll = function todayOffAll() { + // set begin date to tomorrow; + this.beginDate = new Date(); + this.beginDate.setDate(this.beginDate.getDate() + 1); + // recreate alarms; + this.generateAlarms(); + this.exit(); + }; + + // Initialize function + ExercisePlanner.prototype.init = function init() { + var onUiInitialize = function onUiInitialize() { + // register watcher on visibility change; + document.addEventListener('webkitvisibilitychange', this.onVisibilityChange.bind(this)); + this.showNextAlarm(); + this.onVisibilityChange(); + }.bind(this); + + this.selfId = tizen.application.getAppContext().appId; + this.ui = new UI(); + this.ui.app = this; + + this.loadConfig(); + this.config.currentTypeOfPeriods = (this.todayIsWorkday()) ? 'workday' : 'weekend'; + + this.generateAlarms(); + + this.ui.initialize(onUiInitialize); + }; +}()); |