<?xml version="1.0" encoding="UTF-8"?>
-<widget
- xmlns="http://www.w3.org/ns/widgets"
- xmlns:tizen="http://tizen.org/ns/widgets"
- id="http://sample-web-application.tizen.org/ExercisePlanner"
- version="2.2.0" viewmodes="maximized">
-
- <tizen:app-control>
- <tizen:src name="index.html"/>
- <tizen:operation name="http://tizen.org/appcontrol/operation/exercise"/>
- </tizen:app-control>
-
- <tizen:application
- id="zED1oRD3Hv.ExercisePlanner"
- package="zED1oRD3Hv"
- required_version="2.2"/>
-
- <content src="index.html"/>
- <feature name="http://tizen.org/feature/screen.size.normal.720.1280"/>
- <icon src="icon.png"/>
- <name>Exercise Planner</name>
-
- <tizen:privilege name="http://tizen.org/privilege/alarm"/>
- <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
- <tizen:privilege name="http://tizen.org/privilege/time"/>
-
- <tizen:setting
- screen-orientation="portrait"
- context-menu="disable"
- background-support="disable"
- encryption="disable"
- install-location="auto"
- hwkey-event="enable"/>
+<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://sample-web-application.tizen.org/ExercisePlanner" version="2.2.0" viewmodes="maximized">
+ <tizen:application id="zED1oRD3Hv.ExercisePlanner" package="zED1oRD3Hv" required_version="2.2"/>
+ <content src="index.html"/>
+ <icon src="icon.png"/>
+ <name>Exercise Planner</name>
+ <feature name="http://tizen.org/feature/screen.size.normal.720.1280"/>
+ <tizen:privilege name="http://tizen.org/privilege/alarm"/>
+ <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
+ <tizen:privilege name="http://tizen.org/privilege/time"/>
+ <tizen:setting screen-orientation="portrait" context-menu="disable" background-support="disable" encryption="disable" install-location="auto"/>
</widget>
--- /dev/null
+.GraphSchedule {
+ position: relative;
+ overflow-x: scroll;
+ width: 100%;
+ height: 100px;
+ background-color: transparent;
+ z-index: 1000;
+}
+
+.GraphSchedule .container {
+ width: 600px;
+ bottom: 5px;
+ position: absolute;
+}
+
+.GraphSchedule table {
+ pointer-events: none;
+}
+
+.GraphSchedule td {
+ width: 70px;
+ text-align: left;
+ color: gray;
+ height: 10px;
+}
+
+.GraphSchedule table .grid td {
+ border-width: 1px 0 0px 1px;
+ border-style: solid;
+ border-color: white;
+ font-size: 13px;
+ font-family: Helvetica;
+ position: relative;
+}
+
+.GraphSchedule table .ranges td {
+ border-width: 1px 0 0 1px;
+ border-style: solid;
+ border-color: gray;
+ position: relative;
+}
+
+.GraphSchedule table .ranges .th {
+ border-width: 0px;
+ background-color: rgba(50, 50, 50, 0.2);
+ position: relative;
+ padding: 0;
+}
+
+.GraphSchedule table .rangesWeekend td {
+ border-width: 1px 0 0 1px;
+ border-style: solid;
+ border-color: gray;
+ position: relative;
+}
+
+.GraphSchedule table .rangesWeekend .th {
+ border-width: 0px;
+ background-color: rgba(50, 50, 250, 0.2);
+ position: relative;
+ padding: 0;
+}
+
+.GraphSchedule .flag {
+ position: absolute;
+ width: 10px;
+ height: 60px;
+ background-color: transparent;
+ bottom: 19px;
+}
+
+.GraphSchedule .flag .container {
+ position: relative;
+ width: 10px;
+ bottom: -1px;
+ height: 60px;
+}
+
+.GraphSchedule .flag .rod {
+ position: absolute;
+ width: 2px;
+ height: 55px;
+ left: 0;
+ background-color: brown;
+ bottom: 0;
+ border-width: 0 1px 0 0;
+ border-style: solid;
+ border-color: #aaa;
+}
+
+.GraphSchedule .flag p {
+ position: absolute;
+ width: 15px;
+ left: 3px;
+ background-color: #f88;
+ height: 15px;
+ top: -10px;
+ background-image: -webkit-linear-gradient(left, #F88 18%, #E31448 59%);
+}
+
+.GraphSchedule .flag .hint {
+ display: none;
+ position: absolute;
+ width: 42px;
+ height: 18px;
+ top: 8px;
+ left: 2px;
+ background-color: #FF9;
+ -webkit-border-radius: 5px 5px 5px;
+ position: absolute;
+}
+
+.currentTimeBar {
+ position: absolute;
+ height: 100px;
+ background-color: yellow;
+ width: 2px;
+ bottom: -20px;
+ border-width: 0 1px 0 0;
+ border-style: solid;
+ border-color: #FC0;
+}
\ No newline at end of file
--- /dev/null
+.ui-myHeader {\r
+ background-color: #293d5e;\r
+ height: 70px;\r
+}\r
+\r
+.ui-myContent {\r
+ overflow: auto;\r
+ -webkit-box-flex: 1;\r
+ height: 0px;\r
+}\r
+\r
+.ui-myFooter {\r
+ background-color: #192333;\r
+ height: 70px;\r
+}\r
+\r
+.ui-myExit {\r
+ float: right;\r
+ background-color: #555;\r
+ width: 70px;\r
+ height: 50px;\r
+ margin-top: 10px;\r
+ margin-right: 10px;\r
+ border-radius: 5px;\r
+ background-image: url('../images/00_winset_Back.png');\r
+ background-repeat: no-repeat;\r
+ background-position: center center;\r
+ background-size: 50%;\r
+}\r
+\r
+.ui-myHeader {\r
+ text-align: center;\r
+}
\ No newline at end of file
-html, body {
- overflow: hidden;
+#one {
+ background-image: url('../images/background.png');
}
-.text-center {
- text-align: center;
+.screen {
+ font-family: serif;
+ color: white;
+ font-size: 17pt;
}
-body {
- -webkit-user-select: none;
- font-family: serif;
- color: white;
- font-size: 17pt;
+#sentence {
+ margin: 10px 30px 0 30px;
+ position: relative;
+ float: right;
+ text-indent: 30px;
}
-#home,#notification {
- background-image: url('../img/background.png');
+#signature {
+ margin: 0px 30px 0 auto;
+ position: relative;
+ float: right;
}
-.transparentheader {
- background: none;
+#logo {
+ font-family: courier;
+ font-size: 36px;
+ width: 100%;
+ background-repeat: no-repeat;
+ margin: 0px 40px 0 auto;
+ color: white;
+ border-bottom: 1px solid white;
+ font-weight: bolder;
+ text-align: right;
+ line-height: 43px;
}
-.transparentheader h1 {
- color: white !important;
- text-shadow: none !important;
+#status {
+ width: 400px;
+ height: 350px;
+ margin: 0 auto;
+ background-repeat: no-repeat;
}
-.transparentheader .hearderline {
- position: absolute;
- bottom: 0px;
- width: 100%;
- border-bottom: solid 1px white;
+#status.lazy {
+ background-image: url('../images/state_lazy.png');
}
-#status {
- width: 400px;
- height: 350px;
- margin: 0 auto;
- background-repeat: no-repeat;
+#status.run {
+ background-image: url('../images/state_run.png');
}
-#status.run {
- background-image: url('../img/state_run.png');
+#communicate {
+ font-size: 17pt;
+ text-align: center;
+ min-height: 50px;
+}
+
+#communicate.onAlert {
+ font-size: 60px;
+ text-align: center;
+ text-shadow: 5px 5px 5px black;
+}
+
+#communicate b {
+ font-size: 25px;
+}
+
+#communicate div {
+ font-size: 32px;
+ font-weight: bold;
+}
+
+.schedule {
+ height: 100px;
+}
+
+.scheduleOptions {
+ height: 100px;
+}
+
+.increasingStrength {
+ display: none;
+}
+
+.typeOfPeriods, .typeOfPeriods ul li {
+ height:60px;
+}
+
+.strength {
+ margin: 0 0 20px 0;
+}
+
+.timeRangeLabel {
+ height: 50px;
+}
+
+.activeStatus {
+ display: inline;
+ float: right;
+ color: blue;
+}
+
+.activeStatusDisable {
+ color: red;
+}
+
+.times li {
+ display: inline-block;
+ width: 200px;
+}
+
+.times {
+ width: 100%;
+ float: left;
+ margin: 0;
+ padding: 10px;
+}
+
+.times .ui-datefield {
+ font-size: 60px;
+}
+
+h2.ui-title {
+ width:99%;
+ text-overflow: ellipsis;
+}
+
+/**
+ * Removing disturbing paddings from wide button
+ **/
+#addTimeRange .ui-btn-inner.ui-btn-hastxt,
+#selectExercises .ui-btn-inner.ui-btn-hastxt {
+ padding-left:0;
+ padding-right:0;
+}
+#addTimeRange .ui-btn-text.ui-btn-text-padding-left,
+#selectExercises .ui-btn-text.ui-btn-text-padding-left {
+ padding:0;
+}
+
+/**
+* Removing unnecessary line before the first button
+**/
+#workdaysType span.ui-btn-inner.ui-btn-hastxt {
+ border-left: none;
+}
+
+old styles;
+
+*/
+.exerciseView {
+ width: 80%;
+ height: 200px;
+ border-width: 1px;
+ border-color: #888 #DDD #DDD #888;
+ border-style: solid;
+ background-color: #578;
+ -webkit-border-radius: 0.6em;
+ -webkit-box-align: center;
+ margin: 0 auto;
+ box-shadow: 0px 0px 20px #000;
+ position: relative;
+}
+
+.optionsExercises label {
+ line-height: 44px;
+}
+
+#exercises {
+ margin-bottom: 10px;
}
-.field {
- margin: 15px 0;
+.myHeader {
+
+}
+
+.ui-controlgroup .ui-radio {
+ width: 20%;
+}
+
+.myContent {
+ margin: auto 10px 10px 10px;
+}
+
+.footerContent {
+ margin: 0 auto;
+ text-align: center;
+ padding-top: 20px;
+}
+
+.newExerciseName label {
+ width: 100%;
+}
+
+.newExerciseName input { /*background-color:white;*/
+
+}
+
+.ui-footer {
+ z-index: 1000;
+}
+
+#availableTime {
+ margin-top: 12px;
+ overflow: hidden;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+#availableTime li {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+.ui-swipelist-item .ui-btn {
+ padding: 4px;
+ margin-right: 12px;
+}
+.ui-li-text-sub-right {
+ font-size: 18px;
+ margin-right: 17px;
+ float: right;
+ margin-top: 2px;
+ color: #08f;
+}
+
+.disabled {
+ color: #f00;
}
-#name {
- width: 96%;
+ul {
+ list-style-type: none;
}
-#comment {
- height: 70px;
+.goToOptionsPack {
+ width: 100%;
}
-#alarms_list, .notificationContainer {
- clear: both;
- margin: 5px 0;
+.goToOptions {
+ width: 80%;
+ margin-left: 10%;
+ margin-right: 10%;
}
-.exercise {
- padding-bottom: 5px;
- color: white;
+.buttonOptions {
+ float: right;
+ box-shadow: 0px 0px 10px #000;
}
-#alarms_list .exercise {
- border-bottom: 1px solid white;
+.buttonStop {
+ background-color: #F40;
+ box-shadow: 0px 0px 10px #000;
}
-.exercise .name {
- font-size: 25px;
- font-weight: bold;
+.selectPeriodType .ui-radio {
+ width: 100%;
}
-.exercise .startTime {
- font-size: 20px;
+#formEnablePeriod {
+ margin-bottom: 20px;
}
-.exercise .comment {
- font-size: 20px;
+#ok_wait {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
}
-.exercise .days {
- font-size: 16px;
+#ok_wait .ok {
+ left: 50px;
}
-.exercise .removeExercise {
- float: right;
- width: 80px;
- height: 36px;
- font-size: 18px;
- margin-top: -9px;
- margin-right: 6px;
+#ok_wait .wait {
+ right: 50px;
+ position: absolute;
}
-.exerciseNotification {
- text-align: center;
+span.meterDesc {
+ position: absolute;
+ z-index: 100;
+ display: block;
+ text-align: center;
+ width: inherit;
+ padding-top: 8px;
+ color: #333;
+}
+
+.enableOption {
+ padding-bottom: 20px;
+}
+
+.enableOption>div {
+ display: table-cell;
+}
+
+.enableOption>label {
+ float: left;
+ padding-right: 20px;
+ padding-top: 8px;
+ vertical-align: middle;
+}
+
+div.period {
+ padding-left: 10px;
+}
+
+.center {
+ text-align: center;
+}
+
+#progress {
+ display: none;
+ z-index: 1001;
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ background-color: rgba(0, 2, 0, 0.7);
+}
+#progresscenter {
+ position:absolute;
+ width:100%;
+ top: 40%;
+}
+#progresstitle {
+ color:#FFF;
+ text-align:center;
+ margin-bottom: 20px;
+}
+#progressbar {
+ display:none;
+}
+#loader {
+ margin: 0 auto;
+ width:35px;
+ height: 35px;
+}
+#loader-image {
+ -webkit-animation: rotation 2s infinite linear;
+}
+@-webkit-keyframes rotation {
+ from {-webkit-transform: rotate(0deg);}
+ to {-webkit-transform: rotate(359deg);}
+}
+
+.timeRangeButtons .enableStatusButton {
+ min-width: 95px;
+}
+
+#frontPageContent {
+ padding: 15px;
+ max-width: 450px;
+}
+ul.times .ui-btn-picker {
+ width: 150px;
+ line-height: 70px;
}
-.exerciseNotification .comment,
-.exerciseNotification .startTime
-{
- margin-top: 20pt;
+#exercises li {
+ text-overflow: ellipsis;
+ overflow: hidden;
}
<!DOCTYPE html>
<html>
+
<head>
- <meta charset="utf-8" />
- <meta name="description" content="Event manager" />
- <meta name="viewport" content="width=480, user-scalable=no" />
+<meta charset="utf-8" />
+<meta name="description" content="Alerts" />
+<meta name="viewport" content="width=480, user-scalable=no" />
+
+<title>Exercise planner</title>
+
+<script src="tizen-web-ui-fw/latest/js/jquery.min.js"></script>
+<script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js"></script>
+<script src="tizen-web-ui-fw/latest/js/tizen-web-ui-fw.min.js"
+ data-framework-theme="tizen-white"></script>
- <title>Event manager</title>
+<script defer="defer" src="./js/UI.js"></script>
+<script defer="defer" src="./js/UI.simpleTemplate.js"></script>
+<script defer="defer" src="./js/ext.jqMobile.js"></script>
+<script defer="defer" src="./js/GraphSchedule.js"></script>
- <script src="/usr/share/tizen-web-ui-fw/latest/js/jquery.min.js"></script>
- <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.min.js"></script>
- <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.min.js"
- data-framework-theme="tizen-white"></script>
+<script defer="defer" src="./js/app.js"></script>
+<script defer="defer" src="./js/app.alarms.js"></script>
+<script defer="defer" src="./js/app.timeRange.js"></script>
+<script defer="defer" src="./js/app.alarmsGenerating.js"></script>
+<script defer="defer" src="./js/app.onAlarm.js"></script>
+<script defer="defer" src="./js/main.js"></script>
- <script type="text/javascript" src="js/main.js"></script>
- <link rel="stylesheet" type="text/css" href="css/style.css" />
+<link rel="stylesheet" type="text/css" href="./css/style.css" />
+<link rel="stylesheet" type="text/css" href="./css/GraphSchedule.css" />
</head>
+
<body>
- <div data-role="page" id="mock"></div>
- <!-- necessary for cross page popup -->
-
- <div data-role="page" id="popup_page">
- <div data-role="popup" id="popup">
- <div class="ui-popup-text">
- <p></p>
- </div>
- <div class="ui-popup-button-bg"></div>
- </div>
- </div>
+ <div data-role="page" id="one" data-footer-exist="true">
+ <div data-role="content" data-scroll="none" class="screen" id="frontPageContent">
+ <div id="logo">Exercise planner</div>
+ <div id="status"></div>
+ <div class="schedule"></div>
+ <div id="communicate"></div>
+ <div id="sentence"></div>
+ <div id="signature"></div>
+ </div>
+
+ <div data-role="footer" data-position="fixed">
+ <div data-role="tabbar" id="mainControl" data-style="tabbar">
+ <ul>
+ <li><a href="#" id="startStop">Stop Training</a></li>
+ <li><a href="#two" id="options">Options</a></li>
+ </ul>
+ </div>
+
+ <div id="onAlertControl" data-style="tabbar"
+ style="display: none;">
+ <ul>
+ <li><a href="#" id="ok">OK</a></li>
+ <li><a href="#" id="wait">Wait</a></li>
+ <li><a href="#" id="todayOffAll">Today Off All</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div data-role="page" id="two">
+ <div data-role="header" data-position="fixed">
+ <h1>Exercise planner ≫ options</h1>
+ </div>
+
+ <div data-role="content">
+ <div class="myContent">
+
+ <div data-role="fieldcontain" class="frequency">
+ <div>Frequency</div>
+ <fieldset data-role="controlgroup" data-type="horizontal" id="frequency">
+ <input type="radio" name="radioFrequency"
+ data-icon="segment-titlestyle-segonly" id="freq1" value="1" />
+ <label for="freq1">1</label>
+ <input type="radio" name="radioFrequency"
+ data-icon="segment-titlestyle-segonly" id="freq2" value="2" />
+ <label for="freq2">2</label>
+ <input type="radio" name="radioFrequency"
+ data-icon="segment-titlestyle-segonly" id="freq3" value="3" />
+ <label for="freq3">3</label>
+ <input type="radio" name="radioFrequency"
+ data-icon="segment-titlestyle-segonly" id="freq4" value="4" />
+ <label for="freq4">4</label>
+ <input type="radio" name="radioFrequency"
+ data-icon="segment-titlestyle-segonly" id="freq5" value="5" />
+ <label for="freq5">5</label>
+ </fieldset>
+ </div>
+
+ <div class="scheduleOptions"></div>
+
+ <div data-role="tabbar" data-style="tabbar" class="typeOfPeriods">
+ <ul>
+ <li id="workdaysType"><a>Workday</a></li>
+ <li id="weekendType"><a>Weekend</a></li>
+ </ul>
+ </div>
+
+ <div data-role="fieldcontain" class="strength">
+ <div>Strength</div>
+ <fieldset data-role="controlgroup" data-type="horizontal"
+ id="strength">
+ <input type="radio" name="radioStrength"
+ data-icon="segment-titlestyle-segonly" id="stre1" value="1" />
+ <label for="stre1">1</label>
+ <input type="radio" name="radioStrength"
+ data-icon="segment-titlestyle-segonly" id="stre2" value="2" />
+ <label for="stre2">2</label>
+ <input type="radio" name="radioStrength"
+ data-icon="segment-titlestyle-segonly" id="stre3" value="3" />
+ <label for="stre3">3</label>
+ <input type="radio" name="radioStrength"
+ data-icon="segment-titlestyle-segonly" id="stre4" value="4" />
+ <label for="stre4">4</label>
+ <input type="radio" name="radioStrength"
+ data-icon="segment-titlestyle-segonly" id="stre5" value="5" />
+ <label for="stre5">5</label>
+ </fieldset>
+ </div>
+
+ <div class="increasingStrength">
+ <input type="checkbox" name="tizen-check1-1"
+ id="increasingStrength" />
+ <label for="increasingStrength">Progressive Effort</label>
+ </div>
+
+ <a data-role="button" data-icon="plus" id="addTimeRange" data-inline="false">Add Time</a>
+ <ul data-role="swipelist" id="availableTime"></ul>
+
+ </div>
+ </div>
+
+ <div data-role="footer" data-position="fixed">
+ <div id="selectExercisesBar" data-role="tabbar" data-style="toolbar">
+ <ul>
+ <li><a href="#selectExercises">Select Workouts</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+
+ <div data-role="page" id="selectExercises">
+ <div data-role="header" data-position="fixed">
+ <h2>Exercise planner ≫ select workouts</h2>
+ </div>
+
+ <div data-role="content">
+ <div class="optionsExercises">
+ <div>Select Workouts</div>
+ <ul data-role="listview" id="exercises"></ul>
+ </div>
+ </div>
+
+ <div data-role="footer" data-position="fixed">
+ <div data-role="tabbar" data-style="tabbar">
+ <ul>
+ <li><a href="#customExercises" id="add_custom_workout_btn">Add Custom Workout</a></li>
+ </ul>
+ </div>
+ </div>
+
+ </div>
+
+ <div data-role="page" id="customExercises">
+ <div data-role="header" data-position="fixed">
+ <h1>Exercise planner ≫ add custom workout</h1>
+ </div>
+
+ <div data-role="content">
+ <div class="newExerciseName">
+ <div>Enter workout name:</div>
+ <input data-role="input" type="text" name="newExercise"
+ id="newExerciseName" maxlength="20"/>
+ </div>
+ </div>
+
+ <div data-role="footer" data-position="fixed">
+ <div data-role="tabbar" data-style="tabbar">
+ <ul>
+ <li><a href="#" id="btnNewExercise">Add</a></li>
+ </ul>
+ </div>
+ </div>
+
+ </div>
+
+ <div data-role="page" id="rangesOfTimes">
+ <div data-role="header">
+ <h1>Add Time</h1>
+ </div>
+
+ <div data-role="content">
+ <div>
+ <ul class="times">
+ <li class="ui-li-3-2-2 center">Start: <span class="ui-li-text-main">
+ <input type="time" name="dateStart" id="startTime"
+ data-format="H" />
+ </span>hour
+ </li>
+ <li class="ui-li-3-2-2 center">Duration: <span class="ui-li-text-main">
+ <input type="time" name="duration" id="duration" data-format="H" />
+ </span> hours
+ </li>
+ </ul>
+
+ <fieldset data-role="controlgroup" class="selectPeriodType">
+ <legend>Choose a type of period:</legend>
+ <input type="radio" name="periodType" id="periodType1"
+ value="everyday" checked="checked" />
+ <label for="periodType1">Everyday</label>
+
+ <input type="radio" name="periodType" id="periodType2"
+ value="weekend" />
+ <label for="periodType2">Weekend</label>
+
+ <input type="radio" name="periodType" id="periodType3"
+ value="workday" />
+ <label for="periodType3">Workday</label>
+ </fieldset>
+ <div class="enableOption">
+ <span>Enabled</span>
+ <select id="formEnablePeriod" data-role="slider">
+ <option value="off"></option>
+ <option value="on"></option>
+ </select>
+ </div>
+ </div>
+
+ <input data-role="button" data-inline="true" type="button"
+ id="updateTime" value="add" />
+ </div>
+
+ </div>
+
+ <div data-role="page" id="popupPage">
+ <div data-role="popup" id="popup">
+ <div class="ui-popup-text">
+ <p class="text"></p>
+ </div>
+ <div class="ui-popup-button-bg"></div>
+ </div>
+ </div>
+
+ <div id="progress">
+ <div id="progresscenter">
+ <div id="progresstitle"></div>
+ <div id="progressbar"></div>
+ <div id="loader"><img id="loader-image" src="tizen-web-ui-fw/latest/themes/tizen-white/images/ajax-loader.png"/></div>
+ </div>
+ </div>
+
</body>
</html>
--- /dev/null
+/*jslint devel: true*/
+/*global $ */
+/**
+ * Constructor
+ *
+ * @param {object} params
+ * @returns
+ */
+function GraphSchedule(params) {
+ "use strict";
+ this.init(params);
+}
+
+(function () {
+ "use strict";
+ GraphSchedule.prototype = {
+ template: '',
+ ui: null,
+ $flag: null,
+ $graph: null,
+ timeRanges: {
+ workday: [],
+ weekend: []
+ },
+ flags: []
+ };
+
+ GraphSchedule.prototype.createUI = function createUI() {
+ var $tmp = $('<div></div>');
+
+ $tmp.html(this.template);
+ this.$flag = $tmp.find('.flag');
+ this.$graph = $tmp.find('.GraphSchedule');
+ this.ui = this.$graph;
+
+ this.addCurrentTimeBar();
+ this.showFlags();
+
+ this.center();
+ };
+
+ GraphSchedule.prototype.center = function center() {
+ // set scroll position;
+ this.$graph[0].scrollLeft = 1000 * ((new Date().getHours() - 4) / 24);
+ };
+
+ GraphSchedule.prototype.refresh = function refresh() {
+ this.updateTimeRanges();
+ this.showFlags();
+ this.center();
+ };
+
+ GraphSchedule.prototype.onTemplateLoad = function onTemplateLoad() {
+ };
+
+ GraphSchedule.prototype.init = function init(params) {
+ var $loader = $('<div></div>');
+
+ if (params && params.onSuccess) {
+ this.onTemplateLoad = params.onSuccess;
+ }
+
+ this.flags = [];
+ $loader.load('templates/GraphSchedule.tmpl', null, function (data) {
+ this.template = data;
+ this.createUI();
+ this.onTemplateLoad();
+ }.bind(this));
+ };
+
+ /**
+ *
+ * @param {Array} times
+ * @returns
+ */
+ GraphSchedule.prototype.pushTimeOfFlags = function pushTimeOfFlags(times) {
+ var i, count;
+
+ // clear previous times;
+ this.flags = [];
+
+ if (times instanceof Array) {
+ count = times.length;
+ for (i = 0; i < count; i += 1) {
+ if (times[i] instanceof Date) {
+ this.flags.push({ time: times[i] });
+ } else {
+ throw {message: 'Bag argument at [' + i + '] element of Array. Expected {Date}'};
+ }
+ }
+ } else {
+ throw {message: 'Bad argument. Expected {Array} of {Date}'};
+ }
+ };
+
+ GraphSchedule.prototype.addCurrentTimeBar = function addCurrentTimeBar() {
+ // remove old time bar;
+ var $currentTimeBar = this.$graph.find('.currentTimeBar'),
+ currentTime = new Date(),
+ hours = currentTime.getHours();
+
+ if ($currentTimeBar.length === 0) {
+ // add new;
+ $currentTimeBar = $('<div class="currentTimeBar"></div>');
+ }
+
+ if (hours < 10) {
+ hours = '0' + hours;
+ }
+
+ this.$graph.find('.ranges .h' + hours).append($currentTimeBar);
+ $currentTimeBar.css('left', 100 * currentTime.getMinutes() / 60 + '%');
+
+ setTimeout(this.addCurrentTimeBar.bind(this), 5 * 60 * 1000);
+ };
+
+ GraphSchedule.prototype.addFlag = function addFlag(newFlag) {
+ var $flagClone, hours = newFlag.time.getHours();
+ if (hours < 10) {
+ hours = '0' + hours;
+ }
+ $flagClone = this.$flag.clone();
+ this.$graph.find('.grid td:contains(' + hours + ')').append($flagClone);
+ $flagClone.css('left', 100 * newFlag.time.getMinutes() / 60 + '%');
+ };
+
+ GraphSchedule.prototype.showFlags = function showFlags() {
+ var i, len = this.flags.length;
+ // remove old flags;
+ this.removeFlags();
+
+ // add all flags to view;
+ for (i = 0; i < len; i += 1) {
+ this.addFlag(this.flags[i]);
+ }
+
+ this.center();
+ };
+
+ GraphSchedule.prototype.removeFlags = function removeFlags() {
+ this.$graph.find('.flag').remove();
+ };
+
+ GraphSchedule.prototype.setTimeRanges = function setTimeRanges(ranges) {
+ this.timeRanges = ranges;
+ };
+
+ GraphSchedule.prototype.setVisibleWeekend = function (bool) {
+ var row = this.ui.find('.rangesWeekend');
+ return bool ? row.show() : row.hide();
+ };
+
+ GraphSchedule.prototype.setVisibleWorkdays = function (bool) {
+ var row = this.ui.find('.ranges');
+ return bool ? row.show() : row.hide();
+ };
+
+ /**
+ * Update time ranges on graph
+ * @param ranges {array} array of boolen, keys are hours, example: [false, false, false, true, true]
+ */
+ GraphSchedule.prototype.updateTimeRanges = function updateTimeRanges() {
+ var i, len, hours;
+
+ this.$graph.find('.th').removeClass('th');
+
+ // workdays;
+ hours = this.timeRanges.workday;
+ len = hours.length;
+ for (i = 0; i < len; i += 1) {
+ if (hours[i]) {
+ this.$graph.find('.ranges .h' + ((i < 10) ? '0' + i : i)).addClass('th');
+ }
+ }
+
+ //weekends;
+ hours = this.timeRanges.weekend;
+ len = hours.length;
+ for (i = 0; i < len; i += 1) {
+ if (hours[i]) {
+ this.$graph.find('.rangesWeekend .h' + ((i < 10) ? '0' + i : i)).addClass('th');
+ }
+ }
+ };
+
+}());
--- /dev/null
+/*jslint nomen: true*/
+/*global $, GraphSchedule, range, history, setTimeout */
+function UI() {
+ "use strict";
+}
+
+(function () {
+ "use strict";
+ UI.prototype = {
+ sentence : {
+ 'lazy' : {
+ text : 'He does not seem to me to be a free man who does not sometimes do nothing.',
+ signature : 'Marcus T. Cicero'
+ },
+ 'run' : {
+ text : 'A journey of a thousand miles begins with a single step.',
+ signature : 'Lao-tzu'
+ }
+ },
+ graphSchedule : null,
+ app : null
+ };
+
+ UI.prototype.fillExercises = function (exercisesData) {
+ var i, len, self = this;
+
+ $('#exercises').replaceWith(
+ $('<ul data-role="listview" id="exercises"></ul>')
+ );
+ for (i = 0, len = exercisesData.length; i < len; i += 1) {
+ $('#exercises').append(
+ $(this.getExercisesTemplate(exercisesData[i], i))
+ );
+ }
+ $('#exercises').listview();
+ $('#exercises :jqmData(role="slider")').slider();
+ $('#exercises li').on('click', function () {
+ var $toggle = $(this).find(':jqmData(role="slider")');
+ $toggle.val(($toggle.val() === 'off') ? 'on' : 'off');
+ $toggle.slider('refresh');
+ self.app.saveExercises(self.getExercisesList());
+ });
+ $('#exercises :jqmData(role="slider")').on('change', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ self.app.saveExercises(self.getExercisesList());
+ });
+ };
+
+ UI.prototype.popup = function (text, callback) {
+ var i, popup = $("#popup"),
+ buttons = {'Cancel': function () { $("#popup").popup('close') }};
+ // to hide default button give {'Cancel': false} in callback
+
+ for (i in callback) {
+ if (callback.hasOwnProperty(i)) {
+ buttons[i] = callback[i];
+ }
+ }
+
+ $(".ui-popup-button-bg", popup).empty();
+ for (i in buttons) {
+ if (buttons.hasOwnProperty(i)) {
+ if (buttons[i]) {
+ $('<a/>')
+ .text(i)
+ .attr({'data-role': 'button', 'data-inline': 'true'})
+ .bind('click', buttons[i])
+ .appendTo($(".ui-popup-button-bg", popup));
+ }
+ }
+ }
+ $(".text", popup).text(text);
+
+ popup.trigger("create");
+ popup.popup('open', {positionTo: 'window'});
+
+ // N_SE-49979 workaround to unlock forbidden keys
+ popup.one("popupafterclose", function () {
+ $(document).off('keydown');
+ });
+ };
+
+ UI.prototype.clearTabbars = function () {
+ $('[data-role = "tabbar"] li > a').removeClass('ui-focus, ui-btn-active');
+ };
+
+ UI.prototype.fillTimesRanges = function (timesData) {
+ var self = this, len, i;
+
+ $('#availableTime').replaceWith(
+ $('<ul data-role="listview" id="availableTime"></ul>')
+ );
+ for (i = 0, len = timesData.length; i < len; i += 1) {
+ $('#availableTime')
+ .append($(this.getAvailableTimeTemplate(timesData[i])));
+ }
+ $('#availableTime').trigger('create');
+ $('#availableTime').listview().listview('refresh');
+ $('#availableTime :jqmData(name=edit)').on('click', function (e) {
+ if (self.app.config.trainingEnabled) {
+ self.popup('You should stop the training first.');
+ } else {
+ e.preventDefault();
+ e.stopPropagation();
+ self.editTimeRange($(this).data('val'));
+ }
+ });
+ $('#availableTime :jqmData(name=disable)').on('click', function (e) {
+ if (self.app.config.trainingEnabled) {
+ self.popup('You should stop the training first.');
+ } else {
+ e.stopPropagation();
+ self.app.disableTimeRange($(this).data('val'));
+ }
+ });
+ $('#availableTime :jqmData(name=delete)').on('click', function (e) {
+ var value = $(this).data('val');
+ e.stopPropagation();
+ if (self.app.config.trainingEnabled) {
+ self.popup('You should stop the training first.');
+ return;
+ }
+ self.popup('Are you sure?', {
+ 'Delete': function () {
+ self.app.deleteTimeRange(value);
+ $("#popup").popup('close');
+ }
+ });
+ });
+ };
+
+ UI.prototype.fillTimeRangeForm = function fillTimeRangeForm(timeRange) {
+ var tmpData = new Date();
+ // Filling form;
+ $('#startTime').attr('data-val',
+ new Date(tmpData.setHours(timeRange.start)));
+ $('#duration').attr('data-val', timeRange.duration);
+
+ if ($('#startTime').data('datetimepicker')) {
+ $('#startTime').data('datetimepicker').options.date
+ .setHours(timeRange.start);
+ $('#startTime').data('datetimepicker').ui
+ .find('.ui-datefield-hour').html(
+ (timeRange.start < 10) ? '0' + timeRange.start : timeRange.start
+ );
+ }
+ if ($('#duration').data('datetimepicker')) {
+ $('#duration').data('datetimepicker').options.date
+ .setHours(timeRange.duration);
+ $('#duration').data('datetimepicker').ui.find('.ui-datefield-hour')
+ .html(
+ (timeRange.duration < 10) ? '0'
+ + timeRange.duration : timeRange.duration
+ );
+ $('#duration').data('datetimepicker')._populateDataSelector = function (field, pat) {
+ var result = $.tizen.datetimepicker.prototype._populateDataSelector
+ .call(this, field, pat);
+ result.values = range(1, 20);
+ result.data = range(1, 20);
+ result.current -= 1;
+ return result;
+ };
+ }
+ $.each($("input[name='periodType']"), function () {
+ $(this).attr('checked', $(this).val() === timeRange.style)
+ .checkboxradio('refresh');
+ });
+ $('#formEnablePeriod')[0].value = timeRange.enabled ? 'on' : 'off';
+ $('#formEnablePeriod').slider('refresh');
+ };
+
+ UI.prototype.editTimeRange = function (nr, event) {
+ if (event && typeof event.stopPropagation === 'function') {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ if (this.app.editTimeRange(nr) >= 0) {
+ $('#updateTime').val('modify');
+ $('#rangesOfTimes h1').text('Edit Time');
+ } else {
+ $('#updateTime').val('add');
+ $('#rangesOfTimes h1').text('Add Time');
+ }
+
+ // change page to form;
+ $.mobile.changePage("#rangesOfTimes");
+ };
+
+ UI.prototype.getExercisesList = function () {
+ return $('#exercises :jqmData(role=slider)').map(function (o, v) {
+ return ({
+ index : $(v).attr('data-index'),
+ checked : ($(v).val() === 'on') ? true : false
+ });
+ });
+ };
+
+ UI.prototype.addExercise = function () {
+ var trimmedName = $("#newExerciseName").val().trim();
+ trimmedName = $('<span>').text(trimmedName).html();
+ if (trimmedName !== '') {
+ if (this.app.addExercise(trimmedName)) {
+ $("#newExerciseName").trigger('blur');
+ setTimeout(history.back.bind(history), 50);
+ }
+ } else {
+ this.showErrors([ {
+ name : 'Name of exercise is not correct.',
+ code : 100
+ } ]);
+ }
+ };
+
+ UI.prototype.configToUI = function () {
+ };
+
+ UI.prototype.updateMainUI = function () {
+ this.setStatusRun(this.app.config.trainingEnabled);
+ this.graphSchedule.setTimeRanges(this.app.periodsWeekToBoolArray());
+ };
+
+ UI.prototype.getTimeRangeFromForm = function () {
+ return {
+ start : $('#startTime').data('datetimepicker').options.date
+ .getHours(),
+ duration : $('#duration').data('datetimepicker').options.date
+ .getHours(),
+ stop : $('#startTime').data('datetimepicker').options.date
+ .getHours()
+ + $('#duration').data('datetimepicker').options.date
+ .getHours(),
+ style : $('.selectPeriodType :radio:checked').val(),
+ enabled : ($('#formEnablePeriod')[0].value === 'on' ? true : false)
+ };
+ };
+
+ UI.prototype.editTimeRangeAction = function (nr) {
+ if (this.app.saveTimeRange(nr, this.getTimeRangeFromForm())) {
+ history.back();
+ } else {
+ throw ({
+ message : 'Time start and stop is not present.',
+ code : 1
+ });
+ }
+ };
+
+ UI.prototype.showNoticeInMonitor = function (notice, alarm) {
+ $('#communicate').html(notice);
+ $('#communicate').toggleClass('onAlert', alarm);
+ };
+
+ UI.prototype.changeButtonAddTime = function (text) {
+ $('#addTime').html(text);
+ };
+
+ UI.prototype.showErrors = function (errors) {
+ var i; // count;
+ for (i = 0; i < errors.length; i += 1) {
+ this.popup(errors[i].name);
+ }
+ this.unblockButtons();
+ };
+
+ UI.prototype.unblockButtons = function () {
+ $('#btnNewExercise').data('disabled', false);
+ };
+
+ UI.prototype.showAlarmInMonitor = function (data) {
+ var notice = '';
+ function formatNN(val) {
+ return (val < 10) ? ('0' + val) : val;
+ }
+
+ if (data && data.alarm && this.app.config.trainingEnabled) {
+ this.app.currentAlarm = this.app.findCurrentAlarm();
+ if (this.app.currentAlarm.length > 0) {
+ notice += 'Go... go... go...!<br>' + data.exerciseName + ' x '
+ + data.numberOfTimes;
+ } else {
+ notice += 'Next exercises set at: '
+ + formatNN(data.alarm.getHours()) + ':'
+ + formatNN(data.alarm.getMinutes()) + '<br>'
+ + data.exerciseName + ' x ' + data.numberOfTimes;
+ }
+ } else {
+ notice += '<br/>You have no workouts scheduled for now.<br/>';
+ }
+ this.showNoticeInMonitor(notice, false);
+ };
+
+ UI.prototype.getSentence = function UI_getSentence(type) {
+ return (this.sentence[type] || {
+ text : 'No sentence',
+ signature : 'anonymous'
+ });
+ };
+
+ UI.prototype.setSentence = function (type) {
+ var sentence = this.getSentence(type);
+ $('#sentence').html('"' + sentence.text + '"');
+ $('#signature').html('- ' + sentence.signature);
+ };
+
+ UI.prototype.showWaitOk = function () {
+ $('#mainControl').hide();
+ $('#one .ui-btn-back').hide();
+
+ $('#onAlertControl').tabbar();
+ $('#onAlertControl').show();
+ $('#onAlertControl').css('width', '');
+ };
+
+ UI.prototype.setStatusRun = function (bool) {
+ if (bool) {
+ // icon;
+ $('#status').removeClass('lazy').addClass('run');
+ // sentence;
+ this.setSentence('run');
+ // button in control bar;
+ $('#startStop .ui-btn-text').html('Stop Training');
+ } else {
+ $('#status').removeClass('run').addClass('lazy');
+ this.setSentence('lazy');
+ $('#communicate').html('');
+ $('#startStop .ui-btn-text').html('Start Training');
+ }
+ };
+
+ UI.prototype.bindEvents = function bindEvents() {
+ var self = this;
+
+ // bind events;
+ $("#popup").popup();
+
+ $('#one .ui-btn-back').on('click', this.app.exit.bind(this.app));
+
+ $('#ok').on('click', self.app.ok.bind(self.app));
+ $('#wait').on('click', self.app.wait.bind(self.app));
+ $('#todayOffAll').on('click', self.app.todayOffAll.bind(self.app));
+
+ $('[data-role = "tabbar"] li > a').on('click', function () {
+ self.clearTabbars();
+ });
+
+ $('#startStop').on('click', function () {
+ self.app.appStartStop();
+ });
+
+ window.addEventListener('tizenhwkey', function(e) {
+ if (e.keyName == 'back') {
+ if ($.mobile.popup.active) {
+ $.mobile.popup.active.close();
+ } else if ($.mobile.activePage.attr('id') === 'one') {
+ tizen.application.getCurrentApplication().exit();
+ } else {
+ history.back();
+ }
+ }
+ });
+
+ $('#one').on(
+ 'pageshow',
+ function (page, options) {
+ if (self.graphSchedule.ui) {
+ $('#one .schedule').append(self.graphSchedule.ui);
+ self.app.updateGraph();
+ self.graphSchedule.refresh();
+ self.graphSchedule.setVisibleWeekend(!self.app
+ .todayIsWorkday());
+ self.graphSchedule.setVisibleWorkdays(self.app
+ .todayIsWorkday());
+ }
+ $('#one .schedule').on('touchstart', function (ev) {
+ ev.stopPropagation();
+ });
+
+ // workaround for scroll lock;
+ $.mobile.activePage.css('position', 'fixed');
+
+ if ($('a.ui-btn-back').is(':hidden')) {
+ $('div#mainControl').removeClass('ui-tabbar-margin-back');
+ }
+ }
+ );
+
+ $('#two').on('pageshow', function (page, options) {
+ self.fixPageHeight('#two');
+
+ if (self.graphSchedule.ui) {
+ $('#two .scheduleOptions').append(self.graphSchedule.ui);
+ self.graphSchedule.refresh();
+ self.graphSchedule.setVisibleWeekend(true);
+ self.graphSchedule.setVisibleWorkdays(true);
+ }
+
+ if ($('a.ui-btn-back').is(':hidden')) {
+ $('div#selectExercisesBar').removeClass('ui-tabbar-margin-back');
+ }
+ });
+
+ $('#two').on('pageinit', function (page, options) {
+ $('.ui-radio input', $('#frequency')).change(function (ev) {
+ var that = this;
+ self.startProgress();
+ setTimeout(function (){
+ self.app.setFrequency(that.value);
+ self.updateMainUI();
+ self.endProgress();
+ }, 100);
+ });
+
+ $('.ui-radio input', $('#strength')).change(function (ev) {
+ self.app.setStrength(this.value);
+ self.updateMainUI();
+ });
+
+ $('#frequency')[0].select(self.app.config.frequency);
+ $('#strength')[0].select(self.app.config.strength);
+
+ $('#two .scheduleOptions').append(self.graphSchedule.ui);
+ $('#two .scheduleOptions').on('touchstart', function (ev) {
+ ev.stopPropagation();
+ });
+
+ $('#workdaysType').on('click', function (ev) {
+ var that = $(this).children("a");
+ setTimeout(function(){
+ that.removeClass("ui-btn-active");
+ }, 400);
+
+ self.app.changeTypeOfPeriods('workday');
+ });
+
+ $('#weekendType').on('click', function (ev) {
+ var that = $(this).children("a");
+ setTimeout(function(){
+ that.removeClass("ui-btn-active");
+ }, 400);
+
+ self.app.changeTypeOfPeriods('weekend');
+ });
+
+ $('#addTimeRange').on('click', function (e) {
+ if (self.app.config.trainingEnabled) {
+ self.popup('You should stop the training first.');
+ } else {
+ self.editTimeRange(-1, e);
+ }
+ });
+
+ self.app.updateTimesRanges();
+ self.configToUI();
+ });
+
+ $('#selectExercises').on('pageinit', function (page, options) {
+ self.app.updateExercises();
+ self.configToUI();
+ });
+
+ $('#selectExercises').on('pageshow', function (page, options) {
+ self.fixPageHeight('#selectExercises');
+ });
+
+ $('#customExercises').on('pageinit', function (page, options) {
+ $('#btnNewExercise').on('click', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ if ($(this).data('disabled') !== true) {
+ $(this).data('disabled', true);
+ self.addExercise();
+ }
+ });
+ });
+
+ $('#customExercises').on('pageshow', function (page, options) {
+ self.unblockButtons();
+
+ $('#newExerciseName').val('');
+ });
+
+ $('#rangesOfTimes').on('pageinit', function (page, options) {
+ $("#updateTime").on("click", function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ self.startProgress('Saving');
+ self.editTimeRangeAction(self.app.currentEditingTimePeriodId);
+ });
+ });
+
+ $('#rangesOfTimes').on('pageshow', function (page, options) {
+ self.fixPageHeight('#rangesOfTimes');
+
+ $('#updateTime').data('button').refresh();
+ self.fillTimeRangeForm(self.app.currentEditingTimePeriod);
+ });
+
+ $('#increasingStrength').on('change', function () {
+ self.app.config.increasingStrength = this.checked;
+ self.app.saveConfig();
+
+ self.configToUI();
+ });
+
+ $('#add_custom_workout_btn').on('click', function (e) {
+ e.preventDefault();
+ e.stopPropagation();
+ $.mobile.changePage('#customExercises');
+ });
+ };
+
+ UI.prototype.onGraphSchedule = function onGraphSchedule(onInitEnd) {
+ this.updateMainUI();
+
+ $('#one .schedule').append(this.graphSchedule.ui);
+ this.app.updateGraph();
+ this.graphSchedule.refresh();
+ this.graphSchedule.setVisibleWeekend(!this.app.todayIsWorkday());
+ this.graphSchedule.setVisibleWorkdays(this.app.todayIsWorkday());
+
+ if (typeof onInitEnd === 'function') {
+ onInitEnd();
+ }
+ };
+
+ UI.prototype.initialize = function (onInitEnd) {
+ $.mobile.tizen.disableSelection(document);
+
+ this.bindEvents();
+
+ $('html, body').css('font-size', '');
+ $('[data-role=footer]').height('');
+
+ this.graphSchedule = new GraphSchedule({
+ onSuccess : this.onGraphSchedule.bind(this, onInitEnd)
+ });
+
+ this.fixContentHeight();
+ };
+
+ UI.prototype.fixPageHeight = function (element) {
+ //FIXME (two scrollbar workaround)
+ setTimeout(
+ function () {
+ var newHeight = $(element).find('[data-role="content"]').prop('style').height;
+ $(element).css({'min-height': newHeight, 'height': newHeight});
+ },
+ 0
+ );
+ };
+
+ UI.prototype.fixContentHeight = function () {
+ var contentHeight = screen.availHeight - $('div[data-role="header"]').outerHeight() - $('div[data-role="footer"]').outerHeight();
+ $('div[data-role="content"]').css('height', contentHeight);
+ };
+
+ UI.prototype.startProgress = function (title) {
+ title = title || "Updating schedule";
+ $("#progress").show();
+ $("#progresstitle").text(title);
+ $("#progressbar").progressbar({value: false});
+ };
+
+ UI.prototype.endProgress = function () {
+ $("#progress").fadeOut();
+ };
+}());
--- /dev/null
+/*global UI */
+(function () {
+ "use strict";
+ UI.prototype.getAvailableTimeTemplate = function getAvailableTimeTemplate(obj) {
+ return '<li>' + '<div class="timeRangeLabel">Start: ' + obj.start
+ + ' (Duration: ' + obj.duration + 'h) ' + obj.style + '</div>'
+ + '<div class="timeRangeButtons">'
+ + '<div data-role="button" data-inline="true" data-name="edit" data-val="' + obj.nr + '">Edit</div>'
+ + '<div data-role="button" class="enableStatusButton" data-inline="true" data-name="disable" data-val="' + obj.nr + '">'
+ + ((obj.enabled) ? 'Dis' : 'En') + 'able</div>'
+ + '<div data-role="button" data-inline="true" data-name="delete" data-val="' + obj.nr + '">Delete</div>'
+ + '<div class="activeStatus' + ((obj.enabled) ? '' : ' activeStatusDisable') + '" data-inline="true">' + ((obj.enabled) ? 'En' : 'Dis') + 'abled</div>'
+ + '</div>' + '</li>';
+ };
+
+ UI.prototype.getExercisesTemplate = function (obj, i) {
+ return '<li>'
+ + '<span>' + obj.name + '</span>'
+ + '<select data-role="slider" data-index="' + i + '">'
+ + '<option value="off" ' + (obj.enabled ? '' : 'selected="selected"') + '></option>'
+ + '<option value="on" ' + (obj.enabled ? 'selected="selected"' : '') + '></option>'
+ + '</select>' + '</li>';
+ };
+}());
+
+++ /dev/null
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*jslint devel:true*/
-/*global tizen, app */
-
-/**
- * @class Alarm
- */
-var Alarm = function Alarm() {
- 'use strict';
-};
-
-(function () { // strict mode wrapper
- 'use strict';
-
- Alarm.prototype = {
- /**
- * Create new system alarm connected with exercise
- * @param {Object} exercise
- * @param {String} id of added alarm
- */
- add: function addAlarm(exercise) {
- var alarm = {}, date, appControl;
-
- try {
- // change datetimepicker returned object into Date type object
- date = this.datapickerValue2Date(exercise.startTime);
- // create new Alarm object
- alarm = new tizen.AlarmAbsolute(date, exercise.days);
- // create ApplicationControl object
- appControl = new tizen.ApplicationControl(
- app.APP_CONTROL_OPERATION_URI
- );
-
- // add new alarm and connect it with appControl object
- tizen.alarm.add(alarm, app.getId(), appControl);
- } catch (e) {
- console.error(e);
- } finally {
- return alarm.id;
- }
- },
-
- /**
- * Remove system alarm connected to exercise
- * @param {Object} exercise
- * @return {Boolean} returns result of operation
- */
- remove: function removeAlarm(exercise) {
- try {
- tizen.alarm.remove(exercise.id);
- } catch (e) {
- console.error(e);
- return false;
- }
- return true;
- },
-
- /**
- * Change datetimepicker returned object into Date type object
- * @param {String} value
- * @return {Date} js date object
- */
- datapickerValue2Date: function (value) {
- var dateTime = value.split('T'),
- date,
- time,
- year,
- month,
- day,
- hours,
- minutes;
-
- date = dateTime[0].split('-');
- time = dateTime[1].split(':');
-
- year = date[0];
- month = date[1] - 1;
- day = date[2];
-
- hours = time[0];
- minutes = time[1];
-
- return new Date(year, month, day, hours, minutes);
- }
- };
-}());
--- /dev/null
+/*jslint devel:true*/
+/*global ExercisePlanner:false, tizen:false*/
+/**
+ * Methods for add / remove alarms by API;
+ */
+(function () {
+ "use strict";
+ /**
+ * Wrapper on remove all alarms joined with app
+ */
+ ExercisePlanner.prototype.removeAllAlarms = function () {
+ tizen.alarm.removeAll();
+ };
+
+ ExercisePlanner.prototype.WORKDAYS = ["MO", "TU", "WE", "TH", "FR"];
+ ExercisePlanner.prototype.WEEKEND = ["SA", "SU"];
+
+ /**
+ * Add alarms from Array
+ *
+ * @param tabOfAlarm
+ * @param defOfPeriod
+ */
+ ExercisePlanner.prototype.addAlarmFromArray = function addAlarmFromArray(tabOfAlarm, defOfPeriod) {
+ var i, len = tabOfAlarm.length, alarm;
+
+ for (i = 0; i < len; i += 1) {
+ alarm = new tizen.AlarmAbsolute(tabOfAlarm[i], defOfPeriod);
+ try {
+ tizen.alarm.add(alarm, this.selfId);
+ } catch (e) {
+ console.error(e.message);
+ }
+ }
+ };
+
+ /**
+ * Add alarms to API DataBase
+ *
+ * @param {object} alarms
+ */
+ ExercisePlanner.prototype.addAlarmsAllWeek = function addAlarmsAllWeek(alarms) {
+ if (alarms.everyday.length > 0) {
+ this.addAlarmFromArray(alarms.everyday, tizen.alarm.PERIOD_DAY);
+ }
+ if (alarms.workday.length > 0) {
+ this.addAlarmFromArray(alarms.workday, this.WORKDAYS);
+ }
+ if (alarms.weekend.length > 0) {
+ this.addAlarmFromArray(alarms.weekend, this.WEEKEND);
+ }
+ };
+
+}());
+
--- /dev/null
+/*jslint devel: true*/
+/*global ExercisePlanner: true, ONE_DAY:false, TIME_OF_SLEEP:false */
+/**
+ *
+ */
+(function () {
+ "use strict";
+ /**
+ *
+ *
+ * @param availableTime
+ * @param typeOfPeriod
+ * @returns {object}
+ */
+ ExercisePlanner.prototype.calculateFactor = function calculateFactors(availableTime, typeOfPeriod) {
+ var factor,
+ result = {
+ count: 0,
+ period: 0
+ };
+
+ if (availableTime === 0) {
+ return result;
+ }
+
+ factor = availableTime / (this.ONE_DAY - this.TIME_OF_SLEEP);
+ result.proportionalFrequency = this.getNumberOfWorkoutsByFrequency(this.config.frequency[typeOfPeriod]) * factor;
+
+ if ((Math.round(result.proportionalFrequency) - 1) > 0) {
+ result.count = (Math.round(result.proportionalFrequency));
+ result.period = availableTime / (result.count - 1);
+ } else {
+ result.count = 1;
+ result.period = 0;
+ }
+
+ return result;
+ };
+
+ /**
+ *
+ *
+ * @param availableTime
+ * @returns {object}
+ */
+ ExercisePlanner.prototype.calculateFactors = function calculateFactors(availableTime) {
+ return {
+ weekend: this.calculateFactor(availableTime.weekend, 'weekend'),
+ workday: this.calculateFactor(availableTime.workday, 'workday'),
+ everyday: this.calculateFactor(availableTime.everyday, 'workday')
+ };
+ };
+
+ /**
+ *
+ *
+ * @param factor
+ * @param tmpPeriods
+ * @returns {Array}
+ */
+ ExercisePlanner.prototype.generateAlarmsByFactor = function (factor, tmpPeriods) {
+ var i, numberOfPeriods = tmpPeriods.length,
+ period,
+ begin,
+ end = 0,
+ tableOfAlarms = [],
+ optimalTime,
+ deltaTime = 0,
+ dayTime = this.beginDate || new Date();
+
+ if (numberOfPeriods === 0) {
+ return [];
+ }
+
+ begin = tmpPeriods[0].start;
+
+ for (i = 0; i < numberOfPeriods; i += 1) {
+ if (tmpPeriods[i].stop > end) {
+ end = tmpPeriods[i].stop;
+ }
+ }
+
+ dayTime.setSeconds(0);
+
+ if (factor.count === 1) {
+ // One alarm per day, default placed in middle of available time;
+ optimalTime = this.findNearestTimeRange((end + begin) / 2, tmpPeriods);
+
+ dayTime.setHours(parseInt(optimalTime.optimalHour, 10));
+ dayTime.setMinutes(60 * (optimalTime.optimalHour - parseInt(optimalTime.optimalHour, 10)));
+ tableOfAlarms.push(new Date(dayTime.getTime()));
+ } else {
+ // set time for begin;
+ dayTime.setHours(tmpPeriods[0].start);
+ dayTime.setMinutes(0);
+ tableOfAlarms.push(new Date(dayTime.getTime()));
+
+ // set time for next hop;
+ for (i = 0; i < numberOfPeriods; i += 1) {
+ period = tmpPeriods[i];
+ deltaTime += period.duration;
+ // if available period is too small, then accumulate time
+ // and continue to next period;
+ while (deltaTime >= factor.period * 0.999) {
+ deltaTime -= factor.period;
+
+ dayTime.setHours(parseInt(period.stop - deltaTime, 10));
+ dayTime.setMinutes(60 * (period.stop - deltaTime - parseInt(period.stop - deltaTime, 10)));
+
+ tableOfAlarms.push(new Date(dayTime.getTime()));
+ }
+ }
+ }
+ return tableOfAlarms;
+ };
+
+ /**
+ * Generate table of alarms => this.alarms
+ * @param {Date} customDate;
+ */
+ ExercisePlanner.prototype.generateAlarms = function () {
+ var factors,
+ alarms = this.alarms,
+ periodsWeek = {
+ everyday: [],
+ workday: [],
+ weekend: []
+ };
+
+ // some periods may overlap, must be merged
+ periodsWeek = this.mergePeriods();
+ // store in cache for later reuse
+ this.cache.periodsWeek = periodsWeek;
+
+ // factors to correct how often may workouts per day
+ factors = this.calculateFactors(this.getSummaryAvailableTime());
+
+ // Set new alarms;
+ alarms.everyday = this.generateAlarmsByFactor(factors.everyday, periodsWeek.everyday);
+ alarms.workday = this.generateAlarmsByFactor(factors.workday, periodsWeek.workday);
+ alarms.weekend = this.generateAlarmsByFactor(factors.weekend, periodsWeek.weekend);
+
+ // if trainig is in run then resinstall alarm imediately
+ if (this.config.trainingEnabled) {
+ this.startAlarms();
+ }
+ };
+}());
+
+++ /dev/null
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*global tizen */
-
-/**
- * @class Config
- */
-function Config() {
- 'use strict';
-}
-
-(function () { // strict mode wrapper
- 'use strict';
- Config.prototype = {
-
- properties: {
- 'systemContactImageDirPath': '/opt/data/contacts-svc/img/',
- 'defaultAvatarUrl': 'images/default.jpg',
- 'templateDir': 'templates',
- 'localstorageConfigKey': 'configData',
- 'templateExtension': '.tpl',
- 'convertedPhotoUrl': 'file:///opt/media/Images/output.png'
- },
-
- /**
- * Returns config value
- * @return {String} value connected to key or defaultValue
- */
- get: function (value, defaultValue) {
- defaultValue = defaultValue || '';
-
- if (this.properties.hasOwnProperty(value)) {
- return this.properties[value];
- } else {
- return defaultValue;
- }
- }
- };
-}());
\ No newline at end of file
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
/*jslint devel:true*/
-/*global Config, Model, Ui, app, tizen */
-
-var App = null;
-
-(function () { // strict mode wrapper
- 'use strict';
-
- /**
- * Creates a new application object
- *
- * @class Application
- */
- App = function App() {};
-
- App.prototype = {
- /**
- * @type Array
- */
- requires: ['js/app.config.js', 'js/app.model.js', 'js/app.alarm.js', 'js/app.ui.js',
- 'js/app.ui.templateManager.js', 'js/app.ui.templateManager.modifiers.js'],
- /**
- * @type Config
- */
- config: null,
- /**
- * @type Model
- */
- model: null,
- /**
- * @type Ui
- */
- ui: null,
- /**
- * @type bool
- */
- APP_CONTROL_DATA_KEY: 'http://tizen.org/appcontrol/data/alarm_id',
- APP_CONTROL_OPERATION_URI: 'http://tizen.org/appcontrol/operation/exercise',
-
- /**
- * Initialisation function
- */
- init: function init() {
- // instantiate the libs
- this.config = new Config();
- this.model = new Model();
- this.ui = new Ui();
-
- // initialise the modules
- this.model.init(this);
- this.ui.init(this, this.getRequestedAppControlData());
-
- return this;
- },
-
- /**
- * Returns this application id
- * @return {Number} application id
- */
- getId: function getId() {
- return tizen.application.getCurrentApplication().appInfo.id;
- },
-
- /**
- * Parse request AppControl object and retrieve connected exercise info
- * @return {String} exercise id or undefined
- */
- getRequestedAppControlData: function getRequestedAppControlData() {
- var reqAppControl = tizen
- .application
- .getCurrentApplication()
- .getRequestedAppControl(),
- data,
- len,
- exerciseId;
-
- if (reqAppControl) {
- data = reqAppControl.appControl.data;
- len = data.length - 1;
-
- while (len >= 0) {
- if (data[len].key === this.APP_CONTROL_DATA_KEY) {
- exerciseId = data[len].value[0];
- break;
- }
- len -= 1;
- }
-
- return exerciseId;
- }
- },
-
- /**
- * Application exit from model
- */
- exit: function exit() {
- tizen.application.getCurrentApplication().exit();
- },
-
- /**
- * Adds exercise to storage
- * @param {Object} exercise
- * @param {Function} success callback
- * @param {Function} failure callback
- */
- addExercise: function addExercise(exercise, success, failure) {
- // if add was successful
- if (this.model.add(exercise)) {
- if (success instanceof Function) {
- success();
- }
- } else { // if add fail
- console.log('problem with adding');
- if (failure instanceof Function) {
- failure();
- }
- }
- },
-
- /**
- * Gets all stored exercises
- * @return {Array} list of exercises
- */
- getAllExercises: function getAllExercises() {
- return this.model.getAll();
- },
-
- /**
- * Single exercise which match value in corresponding key
- * @param {String} attr name
- * @param {*} value
- * @return {Object|undefined} exercise object
- */
- getExercise: function getExercise(attr, value) {
- return this.model.find(attr, value)[0];
- },
-
- /**
- * Adds exercise to storage
- * @param {String} exerciseId
- * @param {Function} success callback
- * @param {Function} failure callback
- */
- removeExercise: function removeExercise(exerciseId, success, failure) {
- // if removed was successfully completed
- if (this.model.remove(exerciseId)) {
- if (success instanceof Function) {
- success();
- }
- } else { // if there was problem with removing exercise
- console.log('problem with removing');
- if (failure instanceof Function) {
- failure();
- }
- }
- }
-
- };
+/*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
+ }],
+
+ /**
+ * List of generate available exercises;
+ */
+ availableExercises: null,
+
+ // 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.availableExercises.length > 0) {
+ this.ui.showAlarmInMonitor({
+ alarm: alarms[0],
+ exerciseName: this.config.availableExercises[this.config.nearestExercise].name,
+ numberOfTimes: this.getStrength(this.config.strength.workday, this.config.count)
+ });
+ }
+ 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;
+ name = $.trim(name);
+
+ for (i = 0, l = this.config.exercises.length; i < l; i += 1) {
+ if (this.config.exercises[i].name === name) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * Add new exercise sent from UI
+ * @param name
+ * @returns {Boolean}
+ */
+ ExercisePlanner.prototype.addExercise = function (name) {
+ if (this.checkExerciseName(name) === true) {
+ this.config.exercises.push({
+ name: name,
+ enabled: false
+ });
+ this.saveConfig();
+ this.ui.fillExercises(this.config.exercises);
+ return true;
+ }
+
+ this.ui.showErrors([{name: 'Given exercise already 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 () {
+ this.config.availableExercises = this.config.exercises.filter(function (item) {
+ return item.enabled;
+ });
+ this.config.nearestExercise = parseInt(Math.random() * this.config.availableExercises.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);
+ };
}());
+++ /dev/null
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*jslint devel:true*/
-/*global tizen, window, Alarm, app */
-
-/**
- * @class Model
- */
-var Model = function Model() {
- 'use strict';
-};
-
-(function () { // strict mode wrapper
- 'use strict';
- Model.prototype = {
-
- /**
- * Initialization function
- * @param {Object} app object
- */
- init: function Model_init(app) {
- var exercises = window.localStorage.getItem('exercises');
-
- this.app = app;
- this.exercises = exercises ? JSON.parse(exercises) : [];
- this.alarmHelper = new Alarm();
- },
-
- /**
- * Adds new exercise and save it in local storage and set new alarm
- * @param {Object} exercise new object
- * @return {Object|undefined} exercise object
- */
- add: function Model_saveAlarm(exercise) {
- var alarmId = this.alarmHelper.add(exercise);
-
- if (alarmId) {
- exercise.id = alarmId;
-
- // add to session storage
- this.exercises.push(exercise);
-
- // add to localStorage
- this.updateStorage();
- return exercise;
- }
- },
-
- /**
- * Remove exercise with a given id
- * @param {String} exerciseId
- * @return {Boolean} result of remove
- */
- remove: function Model_remove(exerciseId) {
- // find exercise to remove
- var exercise = this.find('id', exerciseId)[0], index;
- // if exercise remove connected alarm
- if (exercise) {
- if (this.alarmHelper.remove(exercise)) {
- // if alarm removed update session store
- index = this.exercises.indexOf(exercise);
- this.exercises.splice(index, 1);
- //update localStorage
- this.updateStorage();
- return true;
- }
- }
- // error removing
- return false;
- },
-
- /**
- * Finds list of exercises matching values with given attribute name
- * @param {String} attr name
- * @param {*} value of attr
- * @return {Array} list of exercises
- */
- find: function Model_find(attr, value) {
- var result = this.exercises.filter(
- function (el) {
- return el[attr] === value.toString();
- }
- );
- return result;
- },
-
- /**
- * Save exercises in local storage
- */
- updateStorage: function () {
- try {
- window.localStorage.setItem(
- 'exercises',
- JSON.stringify(this.exercises)
- );
- } catch (e) {
- if (e.code === 22) {
- //QuotaExceededError
- app.ui.popup(
- 'Not enough memory to save data.' +
- ' Please remove unnecessary files.'
- );
- }
- }
- },
-
- /**
- * Returns array of all currently stored exercises
- * @return {Array} list of exercises
- */
- getAll: function Model_getAll() {
- return this.exercises;
- }
-
- };
-}());
--- /dev/null
+/*jslint devel:true*/
+/*global ExercisePlanner:false, tizen:false, Audio:false*/
+/**
+ * These method are using when alarm is call.
+ */
+(function () {
+ "use strict";
+ ExercisePlanner.prototype.findCurrentAlarm = function () {
+ var currentTimeInMinutes = parseInt(this.applicationStartTime.getTime() / 1000, 10),
+ listOfAlarms = tizen.alarm.getAll();
+
+ return listOfAlarms.filter(function (item) {
+ // alarm relative has not date property;
+ if (!item.date) {
+ return false;
+ }
+
+ // +40/-10 seconds tolerance;
+ if (parseInt(item.date.getTime() / 1000, 10) < (currentTimeInMinutes + 40)
+ && parseInt(item.date.getTime() / 1000, 10) > (currentTimeInMinutes - 10)) {
+ return true;
+ }
+ });
+ };
+
+ ExercisePlanner.prototype.wait = function () {
+ // lastAlert -> change +1min
+ var snozeTime = 1, currentAlarm = this.currentAlarm, newDate = new Date(), alarm;
+
+ if (currentAlarm) {
+ newDate.setMinutes(newDate.getMinutes() + snozeTime);
+ // period value must be set so application started by alert will know current alert;
+ alarm = new tizen.AlarmAbsolute(newDate, tizen.alarm.PERIOD_WEEK * 10);
+ tizen.alarm.add(alarm, this.selfId);
+ // -- remove old snooze alarm
+ if (currentAlarm.period === tizen.alarm.PERIOD_WEEK * 10) {
+ tizen.alarm.remove(currentAlarm.id);
+ }
+ this.stopMusic();
+ }
+
+ this.exit();
+ // or tizen.application.hide();
+ };
+
+ ExercisePlanner.prototype.ok = function () {
+ this.config.count += 1;
+ this.exit();
+ };
+
+ ExercisePlanner.prototype.startMusic = function () {
+
+ if (!this.audioOfAlert) {
+ this.audioOfAlert = new Audio();
+ }
+ this.audioOfAlert.src = 'WebContent/Runner.mp3';
+ this.audioOfAlert.load();
+ this.audioOfAlert.play();
+ };
+
+ ExercisePlanner.prototype.stopMusic = function () {
+ if (this.audioOfAlert) {
+ this.audioOfAlert.pause();
+ }
+ };
+}());
+
--- /dev/null
+/*jslint devel: true*/
+/*global $, ExercisePlanner: true*/
+/**
+ *
+ */
+(function () {
+ "use strict";
+ ExercisePlanner.prototype.checkNewTimeRange = function (start, duration, style) {
+ var result = [];
+ if (duration < 1 || duration > 24) {
+ result.push({
+ name: 'Duration is not set properly.',
+ code: 2
+ });
+ }
+ return result;
+ };
+
+ /**
+ * Sort method for time ranges;
+ */
+ ExercisePlanner.prototype.sortTimeRanges = function () {
+ this.config.timesRanges.sort(function (a, b) {
+ return a.start - b.start;
+ });
+ };
+
+ /**
+ * Find and return max value of nr in time ranges array;
+ * @returns {Number}
+ */
+ ExercisePlanner.prototype.getMaxNrOfTimeRange = function getMaxNrOfTimeRange() {
+ var maxNr = -1, i, len = this.config.timesRanges.length;
+ for (i = 0; i < len; i += 1) {
+ if (maxNr < this.config.timesRanges[i].nr) {
+ maxNr = this.config.timesRanges[i].nr;
+ }
+ }
+ return maxNr;
+ };
+
+ /**
+ *
+ * @param nr
+ * @returns {Boolean}
+ */
+ ExercisePlanner.prototype.getTimeRangeByNr = function getTimeRangeByNr(nr) {
+ var result = this.config.timesRanges.filter(function (item) {
+ return (item.nr === nr);
+ });
+ return result[0];
+ };
+
+ /**
+ * Save time range
+ *
+ * @param nr
+ * @param timeRange
+ * @returns {Boolean}
+ */
+ ExercisePlanner.prototype.saveTimeRange = function (nr, timeRange) {
+ var index = -1,
+ errors = this.checkNewTimeRange(timeRange.start, timeRange.duration, timeRange.style);
+
+ // new timeRanges has nr === -1; this mean we must get max number from config
+ if (nr === -1) {
+ nr = this.getMaxNrOfTimeRange() + 1;
+ } else {
+ index = this.config.timesRanges.indexOf(this.getTimeRangeByNr(nr));
+ }
+
+ timeRange.nr = nr;
+
+ if (errors.length > 0) {
+ this.ui.showErrors(errors);
+ return false;
+ }
+
+ if (index !== -1) {
+ this.config.timesRanges[index] = timeRange;
+ } else {
+ this.config.timesRanges.push(timeRange);
+ }
+
+ this.sortTimeRanges();
+ this.saveConfig();
+ this.ui.fillTimesRanges(this.config.timesRanges);
+ this.generateAlarms();
+ this.updateGraph();
+
+ this.ui.endProgress();
+ return true;
+ };
+
+ /**
+ *
+ * @param {nymber}
+ * @returns {number}
+ */
+ ExercisePlanner.prototype.editTimeRange = function editTimeRange(nr) {
+ var timeRange = this.getTimeRangeByNr(nr);
+
+ if (timeRange !== undefined) {
+ this.currentEditingTimePeriod = timeRange;
+ this.currentEditingTimePeriodId = timeRange.nr;
+ } else {
+ this.currentEditingTimePeriod = {
+ nr: -1,
+ start: 10,
+ duration: 1,
+ stop: 11,
+ enabled: true,
+ style: 'everyday'
+ };
+ this.currentEditingTimePeriodId = -1;
+ }
+ return this.currentEditingTimePeriodId;
+ };
+
+ /**
+ * Delete time range by number on list
+ *
+ * @param nr
+ * @returns {Boolean}
+ */
+ ExercisePlanner.prototype.deleteTimeRange = function (nr) {
+
+ var index,
+ timeRange = this.getTimeRangeByNr(nr);
+
+ if (timeRange === undefined) {
+ return false;
+ }
+
+ index = this.config.timesRanges.indexOf(timeRange);
+ if (index === -1) {
+ return false;
+ }
+
+ // delete time range from array;
+ this.config.timesRanges.splice(index, 1);
+
+ this.saveConfig();
+ this.ui.fillTimesRanges(this.config.timesRanges);
+ this.generateAlarms();
+ // update time periods on graph;
+ this.ui.graphSchedule.setTimeRanges(this.periodsWeekToBoolArray());
+ this.ui.graphSchedule.refresh();
+
+ this.updateGraph();
+ this.showNextAlarm();
+ return true;
+ };
+
+ /**
+ * Disable time range by number on list
+ *
+ * @param nr
+ * @returns {Boolean}
+ */
+ ExercisePlanner.prototype.disableTimeRange = function (nr) {
+ var timeRange = this.getTimeRangeByNr(nr);
+
+ if (timeRange === undefined) {
+ return false;
+ }
+
+ timeRange.enabled = !timeRange.enabled;
+
+ this.saveConfig();
+ this.ui.fillTimesRanges(this.config.timesRanges);
+ this.generateAlarms();
+ // update time periods on graph;
+ this.ui.graphSchedule.setTimeRanges(this.periodsWeekToBoolArray());
+ this.ui.graphSchedule.refresh();
+
+ this.updateGraph(this.config.currentTypeOfPeriods);
+ this.showNextAlarm();
+ return true;
+ };
+
+ /**
+ * Combines a overlapped time periods & delete not necesary
+ * This method modifies exisiting array in cache.
+ *
+ * @param periods
+ * @returns
+ */
+ ExercisePlanner.prototype.mergeOverlapPeriods = function mergeOverlapPeriods(periods) {
+ var i, len = periods.length, wasOverlap = true, mergePeriod;
+
+ periods.sort(function (a, b) {
+ return a - b;
+ });
+
+ if (len < 2) {
+ return periods;
+ }
+
+ while (wasOverlap) {
+ wasOverlap = false;
+ len = periods.length;
+ for (i = 0; i < len - 1; i += 1) {
+ if (periods[i].stop > periods[i + 1].start) {
+ mergePeriod = $.extend({}, periods[i]);
+ if (mergePeriod.stop < periods[i + 1].stop) {
+ mergePeriod.stop = periods[i + 1].stop;
+ mergePeriod.duration = mergePeriod.stop - mergePeriod.start;
+ }
+ mergePeriod.nr = -1;
+ periods.splice(i, 2, mergePeriod);
+ wasOverlap = true;
+ break;
+ }
+ }
+ }
+
+ return periods;
+ };
+
+ ExercisePlanner.prototype.mergePeriods = function mergePeriods() {
+ var i, len, onlyEveryDay = true,
+ ranges = this.config.timesRanges,
+ result = {
+ everyday : [],
+ weekend: [],
+ workday: []
+ };
+
+ // checking time ranges for different to the "everyday"
+ for (i = 0, len = ranges.length; i < len; i += 1) {
+ if (ranges[i].style !== 'everyday') {
+ onlyEveryDay = false;
+ break;
+ }
+ }
+
+ if (onlyEveryDay) {
+ for (i = 0, len = this.config.timesRanges.length; i < len; i += 1) {
+ if (this.config.timesRanges[i].enabled) {
+ result.everyday.push(this.config.timesRanges[i]);
+ }
+ }
+ } else {
+ // divide 'everyday' periods at workday/weekend
+ for (i = 0, len = this.config.timesRanges.length; i < len; i += 1) {
+ // if time range is disabled do not append to cache;
+ if (this.config.timesRanges[i].enabled) {
+ switch (this.config.timesRanges[i].style) {
+ case 'everyday':
+ result.workday.push(this.config.timesRanges[i]);
+ result.weekend.push(this.config.timesRanges[i]);
+ break;
+ case 'workday':
+ result.workday.push(this.config.timesRanges[i]);
+ break;
+ case 'weekend':
+ result.weekend.push(this.config.timesRanges[i]);
+ break;
+ }
+ }
+ }
+ }
+
+ // check and correct overlaped time periods
+ this.mergeOverlapPeriods(result.everyday);
+ this.mergeOverlapPeriods(result.workday);
+ this.mergeOverlapPeriods(result.weekend);
+
+ return result;
+ };
+
+ ExercisePlanner.prototype.getSummaryAvailableTime = function getSummaryAvailableTime() {
+ var i, len,
+ periods = this.cache.periodsWeek,
+ sum = {
+ weekend: 0,
+ workday: 0,
+ everyday: 0
+ };
+
+ for (i = 0, len = periods.everyday.length; i < len; i += 1) {
+ if (periods.everyday[i].enabled) {
+ sum.everyday += periods.everyday[i].duration;
+ }
+ }
+ for (i = 0, len = periods.workday.length; i < len; i += 1) {
+ if (periods.workday[i].enabled) {
+ sum.workday += periods.workday[i].duration;
+ }
+ }
+ for (i = 0, len = periods.weekend.length; i < len; i += 1) {
+ if (periods.weekend[i].enabled) {
+ sum.weekend += periods.weekend[i].duration;
+ }
+ }
+
+ return sum;
+ };
+
+ ExercisePlanner.prototype.findNearestTimeRange = function (hour, ranges) {
+ var nearResult,
+ result = {
+ requestedHour: hour,
+ optimalHour: -1
+ };
+
+ if (!ranges.length) {
+ return result;
+ }
+
+ /**
+ * Function search ranges of time for nearest to a hour
+ */
+ nearResult = ranges.reduce(function (previous, element, index) {
+ var delta = 0;
+
+ if (element.start < hour && element.stop < hour) {
+ delta = hour - element.stop;
+ }
+
+ if (element.start > hour && element.stop > hour) {
+ delta = element.start - hour;
+ }
+
+ return (delta < previous.delta) ? { index: index, delta: delta } : previous;
+ }, { index: -1, delta: 100 });
+
+ if (ranges[nearResult.index].start <= hour && ranges[nearResult.index].stop >= hour) {
+ result.optimalHour = Math.round((ranges[nearResult.index].start + ranges[nearResult.index].stop) / 2);
+ } else {
+ result.optimalHour = (ranges[nearResult.index].start > hour) ? ranges[nearResult.index].start : ranges[nearResult.index].stop;
+ }
+
+ return result;
+ };
+
+ /**
+ * Export time period to array of boolen [boolean x 24]
+ * @returns {object}
+ */
+ ExercisePlanner.prototype.periodsWeekToBoolArray = function periodsWeekToBoolArray() {
+ var i, j, len, periods,
+ result = {
+ workday: [],
+ weekend: []
+ };
+
+ // fill default result;
+ for (i = 0; i < 24; i += 1) {
+ result.workday[i] = false;
+ result.weekend[i] = false;
+ }
+
+ // set values;
+ periods = this.cache.periodsWeek.everyday;
+ len = periods.length;
+ for (i = 0; i < len; i += 1) {
+ for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
+ result.workday[j % 24] = true;
+ result.weekend[j % 24] = true;
+ }
+ }
+
+ // set values;
+ periods = this.cache.periodsWeek.workday;
+ len = periods.length;
+ for (i = 0; i < len; i += 1) {
+ for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
+ result.workday[j % 24] = true;
+ }
+ }
+
+ // set values;
+ periods = this.cache.periodsWeek.weekend;
+ len = periods.length;
+ for (i = 0; i < len; i += 1) {
+ for (j = periods[i].start; j < periods[i].start + periods[i].duration; j += 1) {
+ result.weekend[j % 24] = true;
+ }
+ }
+ return result;
+ };
+
+
+}());
+
+++ /dev/null
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*jslint devel: true*/
-/*global $, app, tizen, TemplateManager, window */
-
-/**
- * @class Ui
- */
-
-function Ui() {
- 'use strict';
-}
-
-(function () { // strict mode wrapper
- 'use strict';
- Ui.prototype = {
-
- templateManager: null,
-
- /**
- * UI module initialisation
- */
- init: function UI_init(app, exerciseId) {
- this.app = app;
- this.currentExercise = this.app.getExercise('id', exerciseId);
- this.templateManager = new TemplateManager();
- $(document).ready(this.domInit.bind(this));
-
- // init inner objects
- this.home.context = this;
- this.new_exercise.context = this;
- this.notification.context = this;
- },
-
- /**
- * When DOM is ready, initialise it
- */
- domInit: function UI_domInit() {
- this.templateManager.loadToCache(
- [
- 'home',
- 'exercise',
- 'new_exercise',
- 'notification',
- 'exerciseNotification'
- ],
- this.initPages.bind(this)
- );
- // Disable text selection
- $.mobile.tizen.disableSelection(document);
- },
-
- /**
- * Append pages to body and initialise them
- */
- initPages: function UI_initPages() {
- var pages = [];
-
- pages.push(this.templateManager.get('home'));
- pages.push(this.templateManager.get('new_exercise'));
- pages.push(this.templateManager.get('notification'));
-
- $('body').append(pages.join(''));
-
- this.home.init();
- this.new_exercise.init();
- this.notification.init();
-
- window.addEventListener('tizenhwkey', function (e) {
- var activePageId = $.mobile.activePage.attr('id');
- if (e.keyName === 'back') {
- if (activePageId === 'home') {
- app.exit();
- } else if (activePageId === 'notification') {
- app.exit();
- } else if (activePageId === 'new_exercise') {
- $.mobile.changePage('#home');
- } else {
- history.back();
- }
- }
- });
-
- $('input[type=checkbox]').change(function () {
- $('#name').blur();
- });
-
- $('#name').on('keyup change', function () {
- var checked = $('#newExerciseDays input:checkbox:checked');
- if (checked.length > 0) {
- $('#add-exercise-btn').removeClass('ui-disabled');
- } else {
- $('#add-exercise-btn').addClass('ui-disabled');
- }
- });
-
- if (this.currentExercise) {
- // app run from alarm
- $.mobile.changePage('#notification', 'pop', false, true);
- } else {
- $.mobile.changePage('#home', 'pop', false, true);
- }
- },
-
- /**
- * Contains methods related to the home page
- * @namespace
- */
- home: {
-
- /**
- * Initialize home page
- */
- init: function UI_home_init() {
- this.addEvents();
- },
-
- /**
- * Bind events to the home page
- */
- addEvents: function () {
- var self = this;
-
- $('#home').on('pagebeforeshow', function () {
- this.displayList();
- }.bind(this));
-
- $('.removeExercise').live('click', function () {
- var exerciseId = $(this).data('exerciseid');
- app.ui.popup('Are you sure?', {
- 'No': function () {
- $('#popup').popup('close');
- },
- 'Yes': function () {
- self.context.app.removeExercise(
- exerciseId,
- self.displayList.bind(self)
- );
- $('#popup').popup('close');
- }
- });
- });
- },
-
- /**
- * Build exercises HTML list and adds it to page
- * @param {Array|undefined} exercises list
- */
- displayList: function (exercises) {
- var len, list = '', exercise;
- exercises = exercises || this.context.app.getAllExercises();
- len = exercises.length - 1;
- while (len >= 0) {
- exercise = $.extend({}, exercises[len]); // copy object
- exercise.startTime = exercise
- .startTime
- .match(/.+T([0-9]+\:[0-9]+)\:[0-9]+/)[1];
- list += this.context.templateManager.get(
- 'exercise',
- exercise
- );
- len -= 1;
- }
- $('#alarms_list').html(list);
- }
-
- },
-
- /**
- * Contains methods related to the new exercise page
- * @namespace
- */
- new_exercise: {
-
- /**
- * Initialize new exercise page
- */
- init: function () {
- this.addEvents();
- },
-
- /**
- * Bind events to new exercise page
- */
- addEvents: function () {
- var self = this,
- numberOfChecked = 0,
- isName = false,
- toggleSaveButton = function () {
- var $button = $('#add-exercise-btn');
- if (numberOfChecked && isName) {
- $button.removeClass('ui-disabled');
- } else {
- $button.addClass('ui-disabled');
- }
- };
-
- $('#new_exercise').on('pagebeforeshow', function () {
- var checked, len;
- // clear everything
- numberOfChecked = 0;
- isName = false;
- $('#name').val('');
- $('#comment').val('');
- checked = $('#newExerciseDays input:checkbox:checked');
- len = checked.length - 1;
- while (len >= 0) {
- $(checked[len])
- .attr('checked', false)
- .data('checkboxradio')
- .refresh();
- len -= 1;
- }
- toggleSaveButton();
- });
-
- // bind buttons
- $('#add-exercise-btn').on('click', function () {
- var exercise = {}, days, len;
-
- days = $('#newExerciseDays input:checkbox:checked');
- len = days.length - 1;
- exercise.days = [];
- while (len >= 0) {
- exercise.days.unshift($(days[len]).data('day'));
- len -= 1;
- }
-
- exercise.name = $('#name').val();
- exercise.startTime = $('#startTime')
- .datetimepicker('value');
- exercise.comment = $('#comment').val();
-
- this.app.addExercise(exercise, function () {
- $.mobile.changePage('#home');
- });
-
- }.bind(this.context));
-
- $('#add-exercise-cancel-btn').on('click', function () {
- history.back();
- });
-
- $('#name').on('focusout', function () {
- isName = ($(this).val().length > 0);
- toggleSaveButton();
- });
-
- $('#newExerciseDays [type=checkbox]').on('change', function () {
- if ($(this).is(':checked')) {
- numberOfChecked += 1;
- } else {
- numberOfChecked -= 1;
- }
-
- toggleSaveButton();
- });
- }
-
- },
-
- /**
- * Contains methods related to the notification page
- * @namespace
- */
- notification: {
-
- /**
- * Initialize notification page
- */
- init: function () {
- this.addEvents();
- },
-
- /**
- * Bind events to notification page
- */
- addEvents: function () {
- $('#notification').on('pagebeforeshow', function () {
- var exercise, html;
- // copy object
- exercise = $.extend({}, this.context.currentExercise);
- exercise.startTime = exercise
- .startTime
- .match(/.+T([0-9]+\:[0-9]+)\:[0-9]+/)[1];
- html = this.context.templateManager.get(
- 'exerciseNotification',
- exercise
- );
- $('.notificationContainer').html(html);
- }.bind(this));
-
- $('.exit').on('click', function () {
- app.exit();
- });
- }
-
- }
-
- };
-
- /**
- * Create and display popup widget
- * @param {String} text information
- * @param {Object} buttons template object
- */
- Ui.prototype.popup = function (text, buttons) {
- var i, popup = $('#popup'), popupNumber = Object.keys(buttons).length;
-
- // if the popup HTML wasn't initialized
- // init it
- if (!popup.hasClass('ui-popup')) {
- popup.popup();
- }
-
- // if buttons template wasn't add,
- // use default template
- if (!buttons) {
- buttons = {
- 'OK': function () {
- $('#popup').popup('close');
- }
- };
- }
-
- // clear popup
- $('.ui-popup-button-bg', popup).empty();
-
- popup[0].className = popup[0]
- .className
- .replace(/\bcenter_basic.*?\b/g, '');
- popup.addClass('center_basic_' + popupNumber + 'btn');
-
- // adds buttons to popup HTML element
- for (i in buttons) {
- if (buttons.hasOwnProperty(i)) {
- if (buttons[i]) {
- $('<a/>').text(i).attr({
- 'data-role': 'button',
- 'data-inline': 'true'
- }).bind('click', buttons[i]).appendTo(
- $('.ui-popup-button-bg', popup)
- );
- }
- }
- }
- // adds text to popup HTML element
- $('.ui-popup-text p', popup).text(text);
-
- popup.trigger('create');
- // open popup
- popup.popup('open', {
- positionTo: 'window'
- });
- };
-
-}());
\ No newline at end of file
+++ /dev/null
-/*
-* Copyright 2013 Samsung Electronics Co., Ltd
-*
-* Licensed under the Flora License, Version 1.1 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://floralicense.org/license/
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-/*global tizen, $, app, ModifierManager */
-
-/**
-* @class TemplateManager
-*/
-function TemplateManager() {
- 'use strict';
- this.init();
-}
-
-(function () { // strict mode wrapper
- 'use strict';
-
- TemplateManager.prototype = {
-
- /**
- * Template cache
- */
- cache: {},
-
- /**
- * UI module initialisation
- */
- init: function init() {
- this.modifiers = new ModifierManager().getAll();
- },
-
- /**
- * Returns template html (from cache)
- * @param {string} tplName
- * @param {string} tplParams
- */
- get: function TemplateManager_get(tplName, tplParams) {
- if (this.cache[tplName] !== undefined) {
- return this.getCompleted(this.cache[tplName], tplParams);
- }
- return '';
- },
-
- /**
- * Load templates to cache
- * @param {string} tplNames
- * @param {function} onSuccess
- */
- loadToCache: function TemplateManager_loadToCache(tplNames, onSuccess) {
- var self = this,
- cachedTemplates = 0,
- tplName,
- tplPath;
-
- if ($.isArray(tplNames)) {
-
- // for each template
- $.each(tplNames, function (index, fileName) {
-
- // cache template html
- if (self.cache[fileName] === undefined) {
- tplName = [
- fileName,
- app.config.get('templateExtension')
- ].join('');
- tplPath = [
- app.config.get('templateDir'),
- tplName
- ].join('/');
-
- $.ajax({
- url: tplPath,
- cache: true,
- dataType: 'html',
- async: true,
- success: function (data) {
- // increase counter
- cachedTemplates += 1;
-
- // save to cache
- self.cache[fileName] = data;
-
- // if all templates are cached launch callback
- if (
- cachedTemplates >= tplNames.length &&
- typeof onSuccess === 'function'
- ) {
- onSuccess();
- }
- },
- error: function (jqXHR, textStatus, errorThrown) {
- console.error(
- 'templateManagerError: ' +
- errorThrown
- );
- }
- });
- } else {
- // template is already cached
- cachedTemplates += 1;
- // if all templates are cached launch callback
- if (
- cachedTemplates >= tplNames.length &&
- typeof onSuccess === 'function'
- ) {
- onSuccess();
- }
- }
- });
-
- }
- },
-
- /**
- * Returns template completed by specified params
- * @param {string} tplHtml
- * @param {string} tplParams
- */
- getCompleted: function TemplateManager_getCompleted(
- tplHtml,
- tplParams
- ) {
- var tplParam;
-
- for (tplParam in tplParams) {
- if (tplParams.hasOwnProperty(tplParam)) {
- tplHtml = this.passThruModifiers(
- tplHtml,
- tplParam,
- tplParams[tplParam]
- );
- }
- }
-
- return tplHtml;
- },
-
- /**
- * Returns template completed by specified params
- * including modifiers
- * @param {string} tplHtml
- * @param {string} tplParams
- * @param {string} content
- */
- passThruModifiers: function (tplHtml, tplParam, content) {
- var regModOn = new RegExp('%' + tplParam + '(\\|(.+?)){1,}%', 'g'),
- regModOff = new RegExp(['%', tplParam, '%'].join(''), 'g'),
- regModGet = new RegExp('%' + tplParam + '\\|(.+?)%'),
- regModPut = new RegExp('%' + tplParam + '\\|(.+?)%', 'g'),
- specRegExp = new RegExp('\\$', 'g'),
- modifiers,
- i;
-
- if (content && (typeof content === 'string')) {
- content = content.replace(specRegExp, '$$$$');
- }
-
- if (regModOn.test(tplHtml)) {
- modifiers = tplHtml.match(regModGet)[1].split('|');
- for (i in modifiers) {
- if (this.modifiers[modifiers[i]] instanceof Function) {
- content = this.modifiers[modifiers[i]](content);
- } else {
- console.error('unknown modifier: ' + modifiers[i]);
- }
- }
- tplHtml = tplHtml.replace(regModPut, content);
- }
- tplHtml = tplHtml.replace(regModOff, content);
-
- return tplHtml;
- }
- };
-
-}());
+++ /dev/null
-/*
- * Copyright 2013 Samsung Electronics Co., Ltd
- *
- * Licensed under the Flora License, Version 1.1 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*global $*/
-/**
- * @class ModifierManager
- */
-function ModifierManager() {
- 'use strict';
- this.init();
-}
-
-(function () {
- 'use strict';
- ModifierManager.prototype = {
-
- /**
- * UI module initialisation
- */
- init: function () {},
-
- /**
- * @return modifiers object
- */
- getAll: function () {
- return this.modifiers;
- },
-
- /**
- * modifiers definitions
- */
- modifiers: {
- escape: function (str) {
- return $('<span>').text(str).html();
- }
- }
- };
-}());
\ No newline at end of file
--- /dev/null
+/*global $*/
+// customize JQueryMobile controlgroup
+$.fn.oldControlgroup = $.fn.controlgroup;
+$.fn.controlgroup = function (options) {
+ "use strict";
+ return this.oldControlgroup(options).each(function () {
+ this.deselectAll = function () {
+ return $('input', this).attr('checked', false).checkboxradio('refresh');
+ };
+
+ this.select = function (value) {
+ this.deselectAll();
+ return $('input[value$="' + value + '"]', this).attr('checked', true).checkboxradio('refresh');
+ };
+ });
+};
+
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/*global ExercisePlanner, tizen, $, document*/
+var c = null, exercisePlanner = null, appService = null, ui = null;
-/*jslint devel: true*/
-/*global $, tizen, App */
+exercisePlanner = new ExercisePlanner();
+$(document).ready(exercisePlanner.init.bind(exercisePlanner));
-/**
- * This file acts as a loader for the application and its dependencies
- *
- * First, the 'app.js' script is loaded .
- * Then, scripts defined in 'app.requires' are loaded.
- * Finally, the app is initialised - the app is instantiated ('app = new App()')
- * and 'app.init()' is called.
- */
-
-var app = null;
-
-(function () { // strict mode wrapper
- 'use strict';
-
- ({
- /**
- * Loader init - load the App constructor
- */
- init: function init() {
- var self = this;
- $.getScript('js/app.js').done(function onAppLoaded() {
- // once the app is loaded, create the app object
- // and load the libraries
- app = new App();
- self.loadLibs();
- }).fail(this.onGetScriptError);
- },
- /**
- * Load dependencies
- */
- loadLibs: function loadLibs() {
- var loadedLibs = 0;
- if ($.isArray(app.requires)) {
- $.each(app.requires, function onLibLoaded(index, filename) {
- $.getScript(filename).done(function () {
- loadedLibs += 1;
- if (loadedLibs >= app.requires.length) {
- // All dependencies are loaded - initialise the app
- app.init();
- }
- }).fail(function (e) {
- console.error('Loading libs failed');
- });
- });
- }
- },
- /**
- * Handle ajax errors
- */
- onGetScriptError: function onGetScriptError(
- e,
- jqxhr,
- setting,
- exception
- ) {
- alert('An error occurred: ' + e.message);
- }
- }).init(); // run the loader
-
-}());
--- /dev/null
+<div class="GraphSchedule">
+ <div class="container">
+ <table>
+ <tr class="rangesWeekend">
+ <td class="h00"></td>
+ <td class="h01"></td>
+ <td class="h02"></td>
+ <td class="h03"></td>
+ <td class="h04"></td>
+ <td class="h05 th"></td>
+ <td class="h06 th"></td>
+ <td class="h07"></td>
+ <td class="h08"></td>
+ <td class="h09"></td>
+ <td class="h10"></td>
+ <td class="h11"></td>
+ <td class="h12"></td>
+ <td class="h13"></td>
+ <td class="h14"></td>
+ <td class="h15"></td>
+ <td class="h16"></td>
+ <td class="h17"></td>
+ <td class="h18"></td>
+ <td class="h19"></td>
+ <td class="h20"></td>
+ <td class="h21"></td>
+ <td class="h22"></td>
+ <td class="h23"></td>
+ </tr>
+ <tr class="ranges">
+ <td class="h00"></td>
+ <td class="h01"></td>
+ <td class="h02"></td>
+ <td class="h03"></td>
+ <td class="h04"></td>
+ <td class="h05"></td>
+ <td class="h06"></td>
+ <td class="h07"></td>
+ <td class="h08"></td>
+ <td class="h09"></td>
+ <td class="h10"></td>
+ <td class="h11"></td>
+ <td class="h12"></td>
+ <td class="h13"></td>
+ <td class="h14"></td>
+ <td class="h15"></td>
+ <td class="h16"></td>
+ <td class="h17"></td>
+ <td class="h18"></td>
+ <td class="h19"></td>
+ <td class="h20"></td>
+ <td class="h21"></td>
+ <td class="h22"></td>
+ <td class="h23"></td>
+ </tr>
+ <tr class="grid">
+ <td>00</td>
+ <td>01</td>
+ <td>02</td>
+ <td>03</td>
+ <td>04</td>
+ <td>05</td>
+ <td>06</td>
+ <td>07</td>
+ <td>08</td>
+ <td>09</td>
+ <td>10</td>
+ <td>11</td>
+ <td>12</td>
+ <td>13</td>
+ <td>14</td>
+ <td>15</td>
+ <td>16</td>
+ <td>17</td>
+ <td>18</td>
+ <td>19</td>
+ <td>20</td>
+ <td>21</td>
+ <td>22</td>
+ <td>23</td>
+ </tr>
+ </table>
+ </div>
+</div>
+<div class="flag">
+ <div class="container">
+ <div class="rod"></div>
+ <p></p>
+ <div class="hint"></div>
+ </div>
+</div>
+++ /dev/null
-<li class="exercise" data-exerciseid="%id%">
- <div class="name">%name%</div>
- <input type="button" class="removeExercise" data-inline="true" value="Remove" data-exerciseid="%id%" />
- <div class="startTime">%startTime%</div>
- <div class="days">%days%</div>
- </div>
-</li>
+++ /dev/null
-<div class="exerciseNotification">
- <div class="name">%name%</div>
- <div class="startTime">%startTime%</div>
- <div class="days">%days%</div>
- <div class="comment">%comment%</div>
-</div>
+++ /dev/null
-<!-- Start of first page: #home -->
-<div data-role="page" id="home" data-add-back-btn="false">
-
- <div data-role="header" data-position="fixed" class="transparentheader">
- <h1>Exercise planner</h1>
- <div class="hearderline"></div>
- </div><!-- /header -->
-
- <div data-role="content">
- <div>
- <ul id="alarms_list" data-role="listview" data-inset="true">
- </ul>
- </div>
- </div><!-- /content -->
-
- <div data-role="footer" data-position="fixed">
- <div data-role="tabbar" data-style="tabbar">
- <ul>
- <li><a href="#new_exercise" id="newExerciseBtn">Add New Exercise</a></li>
- </ul>
- </div>
- </div><!-- /footer -->
-
-</div><!-- /home -->
+++ /dev/null
-<!-- Start of the new exercise form: #new_exercise -->
-<div data-role="page" id="new_exercise">
-
- <div data-role="header" data-position="fixed">
- <h1>New exercise</h1>
- </div><!-- /header -->
-
- <div data-role="content">
- <form>
- <div class='field'>
- <label for="setName">Name</label>
- <div id="newExerciseName" class="inputs">
- <input type="text" id="name" name="name" maxlength="20"/>
- </div>
- </div>
- <div class="field">
- <label for="setDays">Type</label>
- <div id="newExerciseDays" class="inputs">
- <label><input type="checkbox" name="monday" data-day="MO"/>Monday</label>
- <label><input type="checkbox" name="tuesday" data-day="TU"/>Tuesday</label>
- <label><input type="checkbox" name="wednesday" data-day="WE"/>Wednesday</label>
- <label><input type="checkbox" name="thursday" data-day="TH"/>Thursday</label>
- <label><input type="checkbox" name="friday" data-day="FR"/>Friday</label>
- <label><input type="checkbox" name="saturday" data-day="SA"/>Saturday</label>
- <label><input type="checkbox" name="sunday" data-day="SU"/>Sunday</label>
- </div>
- </div>
- <div class='field'>
- <label for="setStartTime">Start time</label>
- <div id="newExercisestartTime" class="inputs">
- <span class="ui-li-text-main">
- <input type="datetime" name="startTime" id="startTime" data-format="HH:mm"/>
- </span>
- </div>
- </div>
- <div class='field'>
- <label for="setComment">Comment</label>
- <div id="newExercisesComment">
- <textarea name="comment" id="comment"></textarea>
- </div>
- </div>
- </form>
- </div><!-- /content -->
-
- <div data-role="footer" data-position="fixed">
- <div data-role="tabbar" data-style="tabbar">
- <ul>
- <li><a id="add-exercise-cancel-btn" data-inline="true">Cancel</a></li>
- <li><a id="add-exercise-btn" data-inline="true" class='ui-disabled'>Save</a></li>
- </ul>
- </div><!-- /tabbar -->
- </div><!-- /footer -->
-
-</div><!-- /new_exercise -->
+++ /dev/null
-<!-- Start of first page: #notification -->
-<div data-role="page" id="notification" data-add-back-btn="false">
-
- <div data-role="header" data-position="fixed" class="transparentheader">
- <h1>Exercise planner</h1>
- <div class="hearderline"></div>
- </div><!-- /header -->
-
- <div data-role="content">
- <div id="status" class="run"></div>
- <div class="notificationContainer exercise"></div>
- </div><!-- /content -->
-
- <div data-role="footer" data-position="fixed">
- <div data-role="tabbar" data-style="tabbar">
- <ul>
- <li><a href="#home">Exercises list</a></li>
- <li><a class="exit">Exit</a></li>
- </ul>
- </div>
- </div><!-- /footer -->
-
-</div><!-- /home -->
-