Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 17:12:54 +0000 (02:12 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 17:12:54 +0000 (02:12 +0900)
21 files changed:
AUTHORS [new file with mode: 0644]
LICENSE.Flora [new file with mode: 0644]
NOTICE.Flora [new file with mode: 0644]
config.xml [new file with mode: 0644]
css/style.css [new file with mode: 0644]
icon.png [new file with mode: 0755]
img/clock.png [new file with mode: 0644]
img/green_point.png [new file with mode: 0644]
img/red_x.gif [new file with mode: 0644]
index.html [new file with mode: 0644]
js/app.config.js [new file with mode: 0644]
js/app.js [new file with mode: 0644]
js/app.model.js [new file with mode: 0644]
js/app.ui.js [new file with mode: 0644]
js/app.ui.templateManager.js [new file with mode: 0644]
js/main.js [new file with mode: 0644]
signature1.xml [new file with mode: 0644]
templates/alarm.tpl [new file with mode: 0644]
templates/event.tpl [new file with mode: 0644]
templates/home.tpl [new file with mode: 0644]
templates/new_event.tpl [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..410ea3b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,5 @@
+Pawel Sierszen <p.sierszen at samsung dot com>
+Tomasz Lukawski <t.lukawski at samsung dot com>
+Piotr Wronski <p.wronski at samsung dot com>
+Artur Kobylinski <a.kobylinski at samsung dot com>
+Tomasz Paciorek <t.paciorek at samsung dot com>
diff --git a/LICENSE.Flora b/LICENSE.Flora
new file mode 100644 (file)
index 0000000..9c95663
--- /dev/null
@@ -0,0 +1,206 @@
+Flora License
+
+Version 1.0, May, 2012
+
+http://floralicense.org/license/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and
+all other entities that control, are controlled by, or are
+under common control with that entity. For the purposes of
+this definition, "control" means (i) the power, direct or indirect,
+to cause the direction or management of such entity,
+whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
+or more of the outstanding shares, or (iii) beneficial ownership of
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source,
+and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice
+that is included in or attached to the work (an example is provided
+in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form,
+that is based on (or derived from) the Work and for which the editorial
+revisions, annotations, elaborations, or other modifications represent,
+as a whole, an original work of authorship. For the purposes of this License,
+Derivative Works shall not include works that remain separable from,
+or merely link (or bind by name) to the interfaces of, the Work and
+Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor
+for inclusion in the Work by the copyright owner or by an individual or
+Legal Entity authorized to submit on behalf of the copyright owner.
+For the purposes of this definition, "submitted" means any form of
+electronic, verbal, or written communication sent to the Licensor or
+its representatives, including but not limited to communication on
+electronic mailing lists, source code control systems, and issue
+tracking systems that are managed by, or on behalf of, the Licensor
+for the purpose of discussing and improving the Work, but excluding
+communication that is conspicuously marked or otherwise designated
+in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+"Tizen Certified Platform" shall mean a software platform that complies
+with the standards set forth in the Compatibility Definition Document
+and passes the Compatibility Test Suite as defined from time to time
+by the Tizen Technical Steering Group and certified by the Tizen
+Association or its designated agent.
+
+2. Grant of Copyright License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work
+solely as incorporated into a Tizen Certified Platform, where such
+license applies only to those patent claims licensable by such
+Contributor that are necessarily infringed by their Contribution(s)
+alone or by combination of their Contribution(s) with the Work solely
+as incorporated into a Tizen Certified Platform to which such
+Contribution(s) was submitted. If You institute patent litigation
+against any entity (including a cross-claim or counterclaim
+in a lawsuit) alleging that the Work or a Contribution incorporated
+within the Work constitutes direct or contributory patent infringement,
+then any patent licenses granted to You under this License for that
+Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.  You may reproduce and distribute copies of the
+Work or Derivative Works thereof pursuant to the copyright license
+above, in any medium, with or without modifications, and in Source or
+Object form, provided that You meet the following conditions:
+
+  1. You must give any other recipients of the Work or Derivative Works
+     a copy of this License; and
+  2. You must cause any modified files to carry prominent notices stating
+     that You changed the files; and
+  3. You must retain, in the Source form of any Derivative Works that
+     You distribute, all copyright, patent, trademark, and attribution
+     notices from the Source form of the Work, excluding those notices
+     that do not pertain to any part of the Derivative Works; and
+  4. If the Work includes a "NOTICE" text file as part of its distribution,
+     then any Derivative Works that You distribute must include a readable
+     copy of the attribution notices contained within such NOTICE file,
+     excluding those notices that do not pertain to any part of
+     the Derivative Works, in at least one of the following places:
+     within a NOTICE text file distributed as part of the Derivative Works;
+     within the Source form or documentation, if provided along with the
+     Derivative Works; or, within a display generated by the Derivative Works,
+     if and wherever such third-party notices normally appear.
+     The contents of the NOTICE file are for informational purposes only
+     and do not modify the License.
+
+You may add Your own attribution notices within Derivative Works
+that You distribute, alongside or as an addendum to the NOTICE text
+from the Work, provided that such additional attribution notices
+cannot be construed as modifying the License. You may add Your own
+copyright statement to Your modifications and may provide additional or
+different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works
+as a whole, provided Your use, reproduction, and distribution of
+the Work otherwise complies with the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+6. Trademarks.  This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Flora License to your work
+
+To apply the Flora License to your work, attach the following
+boilerplate notice, with the fields enclosed by brackets "[]"
+replaced with your own identifying information. (Don't include
+the brackets!) The text should be enclosed in the appropriate
+comment syntax for the file format. We also recommend that a
+file or class name and description of purpose be included on the
+same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Flora License, Version 1.0 (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.
+
diff --git a/NOTICE.Flora b/NOTICE.Flora
new file mode 100644 (file)
index 0000000..fdb699a
--- /dev/null
@@ -0,0 +1,4 @@
+Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Flora License, Version 1.
+Please, see the LICENSE file for Flora License terms and conditions.
+
diff --git a/config.xml b/config.xml
new file mode 100644 (file)
index 0000000..24bbc15
--- /dev/null
@@ -0,0 +1,14 @@
+<?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/EventManager" version="2.0.0" viewmodes="maximized">
+    <tizen:application id="zdFoL1Ufrq" required_version="1.0"/>
+    <content src="index.html"/>
+    <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
+    <tizen:privilege name="http://tizen.org/privilege/application.read"/>
+    <tizen:privilege name="http://tizen.org/privilege/calendar.read"/>
+    <tizen:privilege name="http://tizen.org/privilege/calendar.write"/>
+    <tizen:privilege name="http://tizen.org/privilege/time"/>
+    <tizen:privilege name="http://tizen.org/privilege/tizen"/>
+    <icon src="icon.png"/>
+    <name>EventManager</name>
+    <tizen:setting screen-orientation="portrait" context-menu="enable"/>
+</widget>
diff --git a/css/style.css b/css/style.css
new file mode 100644 (file)
index 0000000..9537107
--- /dev/null
@@ -0,0 +1,55 @@
+body {
+}
+
+#new_event label {
+       font-weight: bold !important;
+       margin-top: .3em !important;
+}
+
+#new_event input {
+       width: 94%;
+}
+
+#events_list {
+       word-wrap: break-word;
+}
+
+li.event {
+       font-size: 0.8rem;
+}
+
+.ul-li-desc {
+       display: inline-block;
+}
+
+li.event .ui-li-aside {
+       display: inline-block;
+       margin-right: 10px;
+       font-size: 0.8rem;
+       font-weight: bold;
+}
+
+.green_dot, .red_dot {
+       width: 9px;
+       height: 9px;
+       float: left;
+       margin:1px;
+       margin-top:3px;
+}
+
+.deleteEvent {
+       display: inline-block;
+       position: absolute;
+       right: 0px;
+       top: 46%;
+}
+
+.green_dot {
+       background-image: url('/img/green_point.png');
+}
+.red_dot {
+       background-image: url('/img/red_x.gif');
+}
+.ui-btn-icon-top .ui-btn-inner {
+       padding-top: 0 !important; /* overwrite broken tizen-white settings */
+}
\ No newline at end of file
diff --git a/icon.png b/icon.png
new file mode 100755 (executable)
index 0000000..983c883
Binary files /dev/null and b/icon.png differ
diff --git a/img/clock.png b/img/clock.png
new file mode 100644 (file)
index 0000000..dca2c7e
Binary files /dev/null and b/img/clock.png differ
diff --git a/img/green_point.png b/img/green_point.png
new file mode 100644 (file)
index 0000000..2f4d4f0
Binary files /dev/null and b/img/green_point.png differ
diff --git a/img/red_x.gif b/img/red_x.gif
new file mode 100644 (file)
index 0000000..25fd4c5
Binary files /dev/null and b/img/red_x.gif differ
diff --git a/index.html b/index.html
new file mode 100644 (file)
index 0000000..f789ff9
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8"/>
+    <meta name="description" content="A Tizen Web UI FW multi-page template generated by Tizen Web IDE"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1"/>
+    <title>EventManager</title>
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/jquery.js"></script>
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw-libs.js"></script>
+    <script src="/usr/share/tizen-web-ui-fw/latest/js/tizen-web-ui-fw.js"
+        data-framework-theme="tizen-white" data-framework-viewport-scale="false"></script>
+    <script type="text/javascript" src="./js/main.js"></script>
+    <link rel="stylesheet" type="text/css" href="./css/style.css"/>
+</head>
+<body>
+    <div data-role="page" id="mock" data-title="mock" data-add-back-btn="false">
+    </div>
+</body>
+</html>
diff --git a/js/app.config.js b/js/app.config.js
new file mode 100644 (file)
index 0000000..a2bd848
--- /dev/null
@@ -0,0 +1,37 @@
+/*jslint devel: true*/
+/*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
+         */
+        get: function (value, defaultValue) {
+            defaultValue = defaultValue || '';
+
+            if (this.properties.hasOwnProperty(value)) {
+                return this.properties[value];
+            } else {
+                return defaultValue;
+            }
+        }
+    };
+}());
\ No newline at end of file
diff --git a/js/app.js b/js/app.js
new file mode 100644 (file)
index 0000000..49612a5
--- /dev/null
+++ b/js/app.js
@@ -0,0 +1,201 @@
+/*jslint devel: true*/
+/*global Config, Model, Ui*/
+
+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.ui.js', 'js/app.ui.templateManager.js'],
+        /**
+         * @type Config
+         */
+        config: null,
+        /**
+         * @type Model
+         */
+        model: null,
+        /**
+         * @type Ui
+         */
+        ui: null,
+        /**
+         * @type bool
+         */
+        fullDay: false,
+        /**
+         * @type bool
+         */
+        alarm: false,
+        /**
+         * @type CalendarAlarm
+         */
+        alarmN: null,
+
+        /**
+         * @type Date
+         */
+        lastDateLoaded: null,
+
+        /**
+         * 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);
+
+            return this;
+        },
+
+        /**
+         * Application exit from model
+         */
+        exit: function exit() {
+            console.log('app.exit()');
+            this.model.exit();
+        },
+
+        /**
+         * Toggle this.fullDay
+         * @returns {boolean} variable state after the toggle
+         */
+        switchFullDay: function switchFullDay() {
+            console.log('switchFullDay()');
+            this.fullDay = !this.fullDay;
+            return this.fullDay;
+        },
+
+        /**
+         * Read the radio buttons and set this.alarm and this.alarmN accordingly
+         */
+        switchAlarm: function switchAlarm() {
+            var duration = 0;
+            duration = this.ui.alarm.getDuration();
+
+            if (duration) {
+                this.alarmN = this.model.getCalendarAlarm(duration, "EventManager Reminder");
+                this.alarm = true;
+            } else {
+                this.alarm = false;
+            }
+        },
+
+        /**
+         * Create a new event in the default calendar,
+         * based on values found in #title, #des, #location
+         * and this.fullDay variable
+         */
+        addEvent: function addEvent() {
+            var selectedDate = '',
+                eventDate = null,
+                duration = 0,
+                calendarItemInit = null,
+                fullDay = false;
+
+            fullDay = this.fullDay;
+            selectedDate = this.ui.home.getStartDate();
+
+            duration = this.calculateDuration(
+                selectedDate,
+                this.ui.home.getEndDate(),
+                fullDay
+            );
+
+            eventDate = this.createTZDateFromString(selectedDate);
+
+            calendarItemInit = {
+                startDate: eventDate,
+                isAllDay: fullDay,
+                duration: duration,
+                summary: this.ui.home.getTitle(),
+                description: this.ui.home.getDescription(),
+                location: this.ui.home.getLocation()
+            };
+
+            this.calendarItemInit = calendarItemInit;
+
+            if (this.alarmN) {
+                calendarItemInit.alarms = [this.alarmN];
+            }/*
+            else{
+                ev.alarms = null;
+            }*/
+            try {
+                this.model.addEventToDefaultCalendar(calendarItemInit);
+            } catch (e) {
+                console.error(e);
+            }
+            this.loadEvents(eventDate);
+        },
+
+        /**
+         * Calculates time duration
+         *
+         * If fullDay, then duration  The duration must be n*60*24 minutes for an event lasting n days.
+         *
+         * @param {string} startDate
+         * @param {string} endDate
+         * @param {bool=} fullDay 'false' by default
+         * @returns {TimeDuration}
+         */
+        calculateDuration: function calculateDuration(startDate, endDate, fullDay) {
+            var duration = 0;
+
+            if (fullDay === undefined) {
+                fullDay = false;
+            }
+
+            startDate = new Date(startDate);
+            endDate = new Date(endDate);
+
+            duration = Math.round((endDate.getTime() - startDate.getTime()) / 60000); // needs duration in minutes;
+
+            return this.model.getTimeDuration(duration);
+        },
+
+        /**
+         * Create a TZDate object for the given date string, all assuming
+         * using the local timezone
+         *
+         * @param {string} dateString Local date/datetime
+         */
+        createTZDateFromString: function (dateString) {
+            var date = null,
+                tzDate = null;
+            date = new Date(dateString);
+            tzDate = this.model.createTZDateFromDate(date);
+            return tzDate;
+        },
+
+        /**
+         * Load all scheduled events
+         */
+        loadEvents: function loadEvents() {
+            console.log("App.loadEvents()");
+
+            this.model.getEventsFromDefaultCalendar(
+                undefined, // we always load all events now
+                this.ui.home.onEventSearchSuccess.bind(this.ui.home), // Load events into the UI
+                this.ui.home.onEventSearchError.bind(this.ui.home)
+            );
+        }
+
+    };
+}());
diff --git a/js/app.model.js b/js/app.model.js
new file mode 100644 (file)
index 0000000..b3f0b97
--- /dev/null
@@ -0,0 +1,186 @@
+/*jslint devel: true*/
+/*global tizen  */
+
+/**
+ * @class Model
+ */
+var Model = function Model() {
+    'use strict';
+};
+
+(function () { // strict mode wrapper
+    'use strict';
+    Model.prototype = {
+
+        /**
+         * Model module initialisation
+         */
+        init: function Model_init(app) {
+            console.log('Model.init');
+            this.app = app;
+        },
+
+        /**
+         * Creates a TimeDuration object corresponding to the given duration
+         * in minutes
+         *
+         * @param {int} mins Duration in minutes
+         * @return {TimeDuration}
+         */
+        getTimeDuration: function Model_getTimeDuration(mins) {
+            return new tizen.TimeDuration(mins, "MINS");
+        },
+
+        /**
+         * Creates a CalendarAlarm with the given duration
+         *
+         * @param {int} minutes Alarm duration in minutes
+         * @returns {CalendarAlarm}
+         */
+        getCalendarAlarm: function Model_getCalendarAlarm(minutes, description) {
+            var timeDuration,
+                calendarAlarm;
+
+            timeDuration = this.getTimeDuration(minutes);
+            calendarAlarm = new tizen.CalendarAlarm(timeDuration, "DISPLAY", description);
+
+            return calendarAlarm;
+        },
+
+        /**
+         * Create a new event and add it to the default calendar
+         *
+         * @param {Object} calendarItemInit
+         * @config {TZDate} [startDate]
+         * @config {bool} [isAllDay]
+         * @config {TimeDuration} [duration]
+         * @config {string} [summary]
+         * @config {string} [description]
+         * @config {string} [location]
+         */
+        addEventToDefaultCalendar: function Model_addEventToDefaultCalendar(calendarItemInit) {
+            var calendar = null,
+                event = null;
+
+            console.log('Model.addEventToDefaultCalendar()');
+            console.log(calendarItemInit);
+
+            calendar = this.getCalendar();
+            event = new tizen.CalendarEvent(calendarItemInit);
+            calendar.add(event);
+        },
+
+        getCalendar: function Model_getCalendar() {
+            return tizen.calendar.getDefaultCalendar("EVENT"); // get the default calendar
+        },
+
+        /**
+         * Find all events in the default calendar on the given date
+         *
+         * @param {string} date date (in local time)
+         * @param {function} onSuccess success callback
+         * @param {function} onError error callback
+         */
+        getEventsFromDefaultCalendar: function Model_getEventsFromDefaultCalendar(date, onSuccess, onError) {
+            var
+                /**
+                 * @type {Calendar}
+                 */
+                calendar = null,
+                /**
+                 * @type {AttributeRangeFilter}
+                 */
+                filter = null;
+
+            console.log('Model.getEventsFromDefaultCalendar');
+
+            calendar = this.getCalendar();
+
+            if (date) {
+                // events on 'date''
+                filter = this.getStartDateFilter(new Date(date));
+            } else {
+                // all future events
+                filter = this.getStartDateFilter(new Date(), true);
+            }
+
+            calendar.find(onSuccess, onError, filter);
+        },
+
+        /**
+         * Create a startDate attribute range filter for the given day
+         *
+         * @param {Date} date
+         * @param {bool} noEndDate
+         * @returns {AttributeRangeFilter}
+         */
+        getStartDateFilter: function Model_getStartDateFilter(date, noEndDate) {
+            var tzDate = null,
+                endTzDate = null,
+                filter = null;
+
+            // calculate start date for the filter
+            console.log('Filter1: ' + date.toString());
+            tzDate = new tizen.TZDate(date.getFullYear(), date.getMonth(), date.getDate());
+            console.log('Filter2: ' + tzDate.toString());
+            if (noEndDate) {
+                endTzDate = undefined;
+            } else {
+                endTzDate = tzDate.addDuration(new tizen.TimeDuration("1", "DAYS")); // calculate end date
+                console.log('Filter3: ' + endTzDate.toString());
+            }
+            filter = new tizen.AttributeRangeFilter("startDate", tzDate, endTzDate);
+            console.log("Start Date filter: ", filter);
+            return filter;
+        },
+
+               /**
+                * @param {string} event_id
+                */
+        deleteEvent: function Model_deleteEvent(event_id) {
+            var myCalendar = this.getCalendar();
+            myCalendar.remove(new tizen.CalendarEventId(event_id));
+            this.app.loadEvents(); // reload the list
+        },
+
+               /**
+                * @param {string} event_id
+                * @param {Object} new_values
+                */
+        updateEvent: function Model_updateEvent(event_id, new_values) {
+            var myCalendar = this.getCalendar(),
+                event,
+                prop = '';
+
+            event = myCalendar.get(new tizen.CalendarEventId(event_id));
+
+            console.log(event);
+
+            for (prop in new_values) {
+                if (new_values.hasOwnProperty(prop)) {
+                    event[prop] = new_values[prop]; // copy new values into the event object
+                }
+            }
+
+            myCalendar.update(event); // save to myCalendar
+        },
+
+        /**
+         * @param {Date} date
+         * @returns {TZDate} date with timezone info
+         */
+        createTZDateFromDate: function Model_createTZDateFromDate(date) {
+                       console.log("    [Creating TZDate] from " + date);
+            return new tizen.TZDate(date);
+        },
+
+        /**
+         * Exit from the application
+         */
+        exit: function () {
+            tizen.application.getCurrentApplication().exit();
+        }
+    };
+}());
+
+
diff --git a/js/app.ui.js b/js/app.ui.js
new file mode 100644 (file)
index 0000000..3b4be96
--- /dev/null
@@ -0,0 +1,393 @@
+/*jslint devel: true*/
+/*global $, TemplateManager */
+
+/**
+ * @class Ui
+ */
+function Ui() {
+    'use strict';
+}
+
+(function () { // strict mode wrapper
+    'use strict';
+    Ui.prototype = {
+
+        templateManager: null,
+
+        /**
+         * UI module initialisation
+         */
+        init: function UI_init(app) {
+            console.log('Ui.init');
+            this.app = app;
+            this.templateManager = new TemplateManager();
+            $(document).ready(this.domInit.bind(this));
+
+            // init inner objects
+            this.home.context = this;
+            this.alarm.context = this;
+            this.new_event.context = this;
+        },
+
+        /**
+         * When DOM is ready, initialise it
+         */
+        domInit: function UI_domInit() {
+            console.log("domInit()", this);
+
+            this.templateManager.loadToCache(['home', 'alarm', 'new_event', 'event'], this.initPages.bind(this));
+
+            // immediately load events for today
+            //self.app.loadEvents(new Date());
+
+        },
+
+        /**
+         * Append pages to body and initialise them
+         */
+        initPages: function UI_initPages() {
+            console.log('initPages');
+            var pages = [];
+
+            pages.push(this.templateManager.get('home'));
+            pages.push(this.templateManager.get('alarm'));
+            pages.push(this.templateManager.get('new_event'));
+
+            $('body').append(pages.join(''));
+
+            this.home.init();
+            this.alarm.init();
+            this.new_event.init();
+
+            console.log('changePage');
+            $.mobile.changePage('#home', 'pop', false, true);
+        },
+
+
+        /**
+         * Contains methods related to the #home page
+         * @namespace
+         */
+        home: {
+            init: function UI_home_init() {
+                var app = this.context.app;
+
+                $('#exit_btn').on('tap', app.exit.bind(app));
+
+//                $('#date_search').bind("date-changed", this.loadEvents.bind(this));
+
+                // buttons in the events list
+                $('#events_list').on('tap', '.remove_event_btn', function () {
+                    var eventId = $(this).parents('.event').data('eventid');
+                    app.model.deleteEvent(eventId);
+                });
+
+                $('#newEventBtn').on('tap', function () {
+                                       $('#des').val('');
+                });
+
+                this.loadEvents();
+            },
+            /**
+             * Get start date value from the form (#demo-date-1 field)
+             *
+             * @returns {string}
+             */
+            getStartDate: function UI_home_getStartDate() {
+                               var startDate = $('#demo-date-1').attr('data-date');
+                               console.log('UI_home_getStartDate: ', startDate);
+                return startDate;
+            },
+            /**
+             * Get end date value from the form (#demo-date-2 field)
+             *
+             * @returns {string}
+             */
+            getEndDate: function UI_home_getEndDate() {
+                               var endDate = $('#demo-date-2').attr('data-date');
+                               console.log('UI_home_getEndDate: ', endDate);
+                return endDate;
+            },
+            /**
+             * Get the title from the form (#title field)
+             *
+             * @returns {string}
+             */
+            getTitle: function UI_home_getTitle() {
+                return $('#title').val();
+            },
+            /**
+             * Get the description from the form (#des field)
+             *
+             * @returns {string}
+             */
+            getDescription: function UI_home_getDescription() {
+                return $('#des').val();
+            },
+            /**
+             * Get the location from the form (#location field)
+             *
+             * @returns {string}
+             */
+            getLocation: function UI_home_getLocation() {
+                return $('#location').val();
+            },
+            /**
+             * Wrapper for app.loadEvents
+             * @param {Object} e event
+             * @param {Date} date selected date
+             */
+            loadEvents: function UI_home_loadEvents(e, date) {
+//                date = $(':jqmData(role="datetimepicker")').data('datetimepicker').options.date;
+                console.log('Ui.loadEvents', this);
+                this.context.app.loadEvents(date);
+            },
+
+                       /**
+                        * Returns text for separating list items with events
+                        * Skips repeated values
+                        *
+                        * @param {Object} event
+                        * @returns {string}
+                        */
+                       getSeparatorText: function UI_home_getSeparatorText(event) {
+                               var previous = '';
+
+                               // redefine itself
+                               this.getSeparatorText = function (event) {
+                                       if (event === undefined) {
+                                               previous = '';
+                                               return undefined;
+                                       }
+
+                                       var startDate = event.startDate,
+                                               str = this.formatDate(startDate);
+
+                                       if (previous === str) {
+                                               return ''; // skip it - already returned
+                                       }
+                                       previous = str; // store in the closure for future comparison
+
+                                       return str;
+                               };
+
+                               return this.getSeparatorText(event);
+                       },
+
+                       formatDate: function UI_home_formatDate(date) {
+                               var monthNames = [
+                                       "January", "February", "March", "April", "May", "June",
+                                       "July", "August", "September", "October", "November", "December" ];
+
+                               this.formatDate = function UI_home_formatDate(date) {
+                                       return date.getDate() + ". " + monthNames[date.getMonth()] + " " + date.getFullYear();
+                               };
+                               return this.formatDate(date);
+                       },
+
+                       /**
+                        * Format hour
+                        * @param {TZDate} date
+                        * @returns {string}
+                        */
+                       formatHour: function UI_home_formatHour(date) {
+                               return date.getHours() + ':' + this.pad(date.getMinutes());
+                       },
+
+                       /**
+                        * Zero-pads a positive number to 2 digits
+                        */
+                       pad: function UI_home_pad(number) {
+                               return number < 10 ? '0' + number : number;
+                       },
+
+                       /**
+                        * Creates HTML representing the given array of alarms
+                        *
+                        * @param {Alarm[]} alarms
+                        * @returns {string}
+                        */
+                       getAlarmsHtml: function UI_home_getAlarmsHtml(alarms) {
+                               var alarm = '', j, len;
+
+                               len = alarms.length;
+
+                               if (len) {
+                                       alarm += '<p class="ui-li-aside ui-li-desc"><img src="img/clock.png"/>';
+
+                                       for (j = 0; j < len; j += 1) {
+                                               alarm += alarms[j].before.length;
+                                               alarm += ' ' + alarms[j].before.unit;
+                                       }
+                                       alarm += '</p>';
+                               }
+                               return alarm;
+                       },
+            /**
+             * Load the events into the #event_popup.
+             *
+             * Callback function for app.loadEvents.
+             * @param {Array} events
+             */
+            onEventSearchSuccess: function UI_home_onEventSearchSuccess(events) {
+                var i = 0, j = 0,
+                    str = "",
+                    event,
+                    alarm = '',
+                    dividerText = '',
+                    templateParameters = {},
+                    endDate = null;
+
+
+                console.log('Ui.home.onEventSearchSuccess()', events);
+
+                // content
+                str = '';
+
+                for (i = 0; i < events.length; i += 1) {
+                    event = events[i];
+
+                    dividerText = this.getSeparatorText(event);
+
+                    if (dividerText) {
+                        str += '<li data-role="list-divider">' + dividerText + '</li>';
+                    }
+
+                    alarm = this.getAlarmsHtml(event.alarms);
+
+                    endDate = event.startDate.addDuration(event.duration);
+
+                    console.log('[Event Loaded] Start Date:' + event.startDate);
+
+                    templateParameters = {
+                        uid: event.id.uid,
+                        startDate: this.formatHour(event.startDate),
+                        endDate: this.formatHour(endDate),
+                        summary: event.summary || '[No title]',
+                        location: event.location,
+                        description: event.description,
+                        alarm: alarm
+                    };
+
+                    str += this.context.templateManager.get('event', templateParameters);
+
+
+                }
+                this.getSeparatorText(); // clear the separator state
+
+                $('#events_list ul').html(str);
+                $('#events_list ul').listview();
+                $('#events_list ul').data('listview').refresh();
+                $('#events_list ul input.remove_event_btn').button();
+            },
+
+            /**
+             * Error handler for event search
+             */
+            onEventSearchError: function UI_home_onEventSearchError() {
+                console.error("event search error");
+            }
+        },
+
+        /**
+         * Contains methods related to the #alarm page
+         * @namespace
+         */
+        alarm: {
+            init: function UI_alarm_init() {
+            },
+            /**
+             * Read alarm duration from the UI
+             *
+             * @returns {int} Alarm duration in minutes
+             */
+            getDuration: function UI_alarm_getDuration() {
+                var radioValue = 0,
+                    radiobutton = null;
+
+                radiobutton = $('#new_alarm :jqmData(role=controlgroup) input:radio[checked]');
+
+                radioValue = parseInt(radiobutton.val(), 10);
+
+                switch (radioValue) {
+                case 1: // no alarm
+                    return 0;
+                case 2: // 5 minutes before
+                    return 5;
+                case 3: // 30 minutes before
+                    return 30;
+                case 4: // 1 hour before
+                    return 60;
+                default:
+                    console.warn('Unexpected value');
+                    return 0;
+                }
+            }
+        },
+
+        /**
+         * Contains methods related to the new event page
+         * @namespace
+         */
+        new_event: {
+            init: function UI_newEvent_init() {
+                var app = this.context.app;
+
+                               $("#demo-date-1").bind("date-changed", function UI_newEvent_onDateChanged(e, newStartDate) {
+                                       var startOptions = $("#demo-date-1").data('datetimepicker').options,
+                                               endData = $("#demo-date-2").data('datetimepicker'),
+                                               endOptions = typeof endData === 'object' ? endData.options : null,
+                                               oldStartDate,
+                                               diff,
+                                               endDate;
+                                       // get the old date
+                                       oldStartDate = startOptions.oldDate;
+                                       startOptions.oldDate = newStartDate;
+
+                                       if (!oldStartDate) {
+                                               console.warn('date-changed handler: old date empty');
+                                               return;
+                                       }
+
+                                       // calculate time difference in minutes
+                                       diff = (newStartDate.getTime() - oldStartDate.getTime()) / 1000 / 60;
+
+                                       endDate = endOptions.date;
+
+                                       // move the end date by 'diff'
+                                       endDate.setMinutes(endDate.getMinutes() + diff);
+
+                                       $("#demo-date-2").datetimepicker('value', endDate);
+                               });
+
+                               $('#new_event').on('pageshow', function UI_newEvent_onPageShow(event) {
+                                       var options = $("#demo-date-1").data('datetimepicker').options,
+                                               tmpDate;
+                                       // get the start date
+                                       tmpDate = new Date(options.date.getTime());
+
+                                       // store it for future use
+                                       options.oldDate = new Date(options.date.getTime());
+
+                                       // add 1 hour
+                                       tmpDate.setHours(tmpDate.getHours() + 1);
+
+                                       if (typeof $("#demo-date-2").datetimepicker === 'function') {
+                                               // set end date
+                                               console.log('pageinit: set default end time' + tmpDate);
+                                               $("#demo-date-2").datetimepicker('value', tmpDate);
+                                       } else {
+                                               console.log('pageinit: cant set end time');
+                                       }
+                               });
+
+                $('#switch-1').bind('changed', app.switchFullDay.bind(app));
+
+                $('#add-event-btn').bind('tap', app.addEvent.bind(app));
+
+                $('#add-alarm').bind('tap', app.switchAlarm.bind(app));
+            }
+        }
+    };
+
+}());
diff --git a/js/app.ui.templateManager.js b/js/app.ui.templateManager.js
new file mode 100644 (file)
index 0000000..f62f7f0
--- /dev/null
@@ -0,0 +1,112 @@
+/*jslint devel: true*/
+/*global tizen, $, app */
+/**
+ * @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() {
+
+        },
+
+        /**
+         * Returns template html (from cache)
+         */
+        get: function TemplateManager_get(tplName, tplParams) {
+            console.log('TemplateManager_get:' + tplName);
+
+            if (this.cache[tplName] !== undefined) {
+                return this.getCompleted(this.cache[tplName], tplParams);
+            } else {
+                console.warn('Template "' + tplName + '" not found in cache');
+                return '';
+            }
+        },
+
+        /**
+         * Load templates to cache
+         */
+        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 (typeof 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;
+                                console.log('Cached template: ' + fileName);
+
+                                // if all templates are cached launch callback
+                                if (cachedTemplates >= tplNames.length && typeof onSuccess === 'function') {
+                                    onSuccess();
+                                }
+                            },
+                            error: function (jqXHR, textStatus, errorThrown) {
+                                alert(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
+         */
+        getCompleted: function TemplateManager_getCompleted(tplHtml, tplParams) {
+            var tplParam, replaceRegExp;
+
+            for (tplParam in tplParams) {
+                if (tplParams.hasOwnProperty(tplParam)) {
+                    replaceRegExp = new RegExp(['%', tplParam, '%'].join(''), 'g');
+                    tplHtml = tplHtml.replace(replaceRegExp, tplParams[tplParam]);
+                }
+            }
+
+            return tplHtml;
+        }
+    };
+
+}());
\ No newline at end of file
diff --git a/js/main.js b/js/main.js
new file mode 100644 (file)
index 0000000..ef27b68
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *      Copyright 2012  Samsung Electronics Co., Ltd
+ *
+ *      Licensed under the Flora License, Version 1.0 (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  */
+
+/**
+ * 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() {
+            console.log('Loader 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() {
+            console.log('Loader loadLibs()');
+            var loadedLibs = 0;
+            if ($.isArray(app.requires)) {
+                $.each(app.requires, function onLibLoaded(index, filename) {
+                    console.log('Trying to load ' + filename + '...');
+                    $.getScript(filename)
+                        .done(function () {
+                            loadedLibs += 1;
+                            console.log(loadedLibs + ' libs loaded');
+                            if (loadedLibs >= app.requires.length) {
+                                // All dependencies are loaded - initialise the app
+                                console.log('App.init()');
+                                app.init();
+                            }
+                        })
+                        .fail(function (e) {
+                            console.error('Loading libs failed');
+                            console.log(e);
+                        });
+                });
+            }
+        },
+        /**
+         * Handle ajax errors
+         */
+        onGetScriptError: function onGetScriptError(e, jqxhr, setting, exception) {
+            alert('An error occurred: ' + e.message);
+        }
+    }).init(); // run the loader
+
+}());
\ No newline at end of file
diff --git a/signature1.xml b/signature1.xml
new file mode 100644 (file)
index 0000000..1d4f0e8
--- /dev/null
@@ -0,0 +1,132 @@
+<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="DistributorSignature">
+<SignedInfo>
+<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
+<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
+<Reference URI="templates/new_event.tpl">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>IZ9vBr/4ZWWg03AP4912GiE/RWa8qWT8+gO8as/ZRGs=</DigestValue>
+</Reference>
+<Reference URI="templates/alarm.tpl">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>gsmrWMNCZ6uy2D/ASHsYhd/g6nMbnK4UJJRhtEUoDtg=</DigestValue>
+</Reference>
+<Reference URI="templates/home.tpl">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>BzaWSVTnAck4FVwDyey03oPE4jiyxqBg/2hyFMiGuG4=</DigestValue>
+</Reference>
+<Reference URI="templates/event.tpl">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>EgqsBEZmuzaLiyGepzFMppV2NXSHksL3RMq1c/JfnXA=</DigestValue>
+</Reference>
+<Reference URI="img/green_point.png">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>9eceoe+7L/Gfpee0m0zdq53QZ76D7505bGrZVEjCiIk=</DigestValue>
+</Reference>
+<Reference URI="img/clock.png">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>DdzCxv6/A+0BEWdevQ96usrqx+xJ1efaPoj1/K4kdv4=</DigestValue>
+</Reference>
+<Reference URI="img/red_x.gif">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>VyTua+tcEllksTxNwMB+I2GUQ6by+oqQ02Mpt2hyVjs=</DigestValue>
+</Reference>
+<Reference URI="AUTHORS">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>/VZK9Vhlp+agybPGg/PRoNHt2iPtyC6St0KvR+3OGZ0=</DigestValue>
+</Reference>
+<Reference URI="LICENSE.Flora">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>fskt8W7B8EMb3DQsvwT98x4fPKKIjY9sS5E0eSGenFA=</DigestValue>
+</Reference>
+<Reference URI="js/app.ui.templateManager.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>4BsWLWLIwTjbE4XNedESi/Wey3HYeOUZRHjqNhQ0w6w=</DigestValue>
+</Reference>
+<Reference URI="js/app.ui.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>moQFBK1765R02VyW68YPPhEPKbmS3wqQb9nj/vPpHsI=</DigestValue>
+</Reference>
+<Reference URI="js/app.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>OwY6tomdo6yVcUVZvEC47I/gIhwRFsOofr3DlW4qxBk=</DigestValue>
+</Reference>
+<Reference URI="js/main.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>yZg4Ne6HiNL/ma8mSjviPJK2XE2vWd19F/qvhVDPfZ0=</DigestValue>
+</Reference>
+<Reference URI="js/app.model.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>Q69O4vQgTnsGCcAguxPS1wodXf8+VBu4tgLWd8HNDl4=</DigestValue>
+</Reference>
+<Reference URI="js/app.config.js">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>gNDCg6HzujZb+wq9fpPnJR6gRCHrSOyCf4pWHBE/XBc=</DigestValue>
+</Reference>
+<Reference URI="config.xml">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>qAD0Mk4THB1B+zPPGJPjwN8nCj8ScYPC9dqmIod2ohM=</DigestValue>
+</Reference>
+<Reference URI="icon.png">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>Nz+SecsjmNuidhKNvmQ5+3nasrw8vI4q/bjPgbfx5fI=</DigestValue>
+</Reference>
+<Reference URI="index.html">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>gSCcp8/fJmY/4jfgeouqP4HiK/4+wt8075P0OcT0yXg=</DigestValue>
+</Reference>
+<Reference URI="css/style.css">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>CwNXKN99NNrR/5d96LmGgzW7BrFWTeHZdABTe9tfwr0=</DigestValue>
+</Reference>
+<Reference URI="NOTICE.Flora">
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>M7oEsiEdLNeaSAYdtR7uR5WGeAELG/V70u7Huzl42Xs=</DigestValue>
+</Reference>
+<Reference URI="#prop">
+<Transforms>
+<Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"></Transform>
+</Transforms>
+<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
+<DigestValue>u/jU3U4Zm5ihTMSjKGlGYbWzDfRkGphPPHx3gJIYEJ4=</DigestValue>
+</Reference>
+</SignedInfo>
+<SignatureValue>
+XVI2FRIFKFI+g9kdvjyq4k6KPsdSjjeDtWH6zsXFFKxw4Tl74f5i6xGePAfx7HWM7eTBj1YVT3pC
+KYuz45gCdM+aS3ElOFUtslTh2NQ2KAP20GN5Hch/sAoYwUJOdmC4cFX+mJT28jOkqNK8X1Dejrmt
+Ft5+x5ayyeEtoGPiUck=
+</SignatureValue>
+<KeyInfo>
+<X509Data>
+<X509Certificate>
+MIICmzCCAgQCCQDXI7WLdVZwiTANBgkqhkiG9w0BAQUFADCBjzELMAkGA1UEBhMCS1IxDjAMBgNV
+BAgMBVN1d29uMQ4wDAYDVQQHDAVTdXdvbjEWMBQGA1UECgwNVGl6ZW4gVGVzdCBDQTEiMCAGA1UE
+CwwZVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEkMCIGA1UEAwwbVGl6ZW4gUHVibGljIERpc3Ry
+aWJ1dG9yIENBMB4XDTEyMTAyOTEzMDMwNFoXDTIyMTAyNzEzMDMwNFowgZMxCzAJBgNVBAYTAktS
+MQ4wDAYDVQQIDAVTdXdvbjEOMAwGA1UEBwwFU3V3b24xFjAUBgNVBAoMDVRpemVuIFRlc3QgQ0Ex
+IjAgBgNVBAsMGVRpemVuIERpc3RyaWJ1dG9yIFRlc3QgQ0ExKDAmBgNVBAMMH1RpemVuIFB1Ymxp
+YyBEaXN0cmlidXRvciBTaWduZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALtMvlc5hENK
+90ZdA+y66+Sy0enD1gpZDBh5T9RP0oRsptJv5jjNTseQbQi0SZOdOXb6J7iQdlBCtR343RpIEz8H
+mrBy7mSY7mgwoU4EPpp4CTSUeAuKcmvrNOngTp5Hv7Ngf02TTHOLK3hZLpGayaDviyNZB5PdqQdB
+hokKjzAzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAvGp1gxxAIlFfhJH1efjb9BJK/rtRkbYn9+Ez
+GEbEULg1svsgnyWisFimI3uFvgI/swzr1eKVY3Sc8MQ3+Fdy3EkbDZ2+WAubhcEkorTWjzWz2fL1
+vKaYjeIsuEX6TVRUugHWudPzcEuQRLQf8ibZWjbQdBmpeQYBMg5x+xKLCJc=
+</X509Certificate>
+<X509Certificate>
+MIICtDCCAh2gAwIBAgIJAMDbehElPNKvMA0GCSqGSIb3DQEBBQUAMIGVMQswCQYDVQQGEwJLUjEO
+MAwGA1UECAwFU3V3b24xDjAMBgNVBAcMBVN1d29uMRYwFAYDVQQKDA1UaXplbiBUZXN0IENBMSMw
+IQYDVQQLDBpUVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEpMCcGA1UEAwwgVGl6ZW4gUHVibGlj
+IERpc3RyaWJ1dG9yIFJvb3QgQ0EwHhcNMTIxMDI5MTMwMjUwWhcNMjIxMDI3MTMwMjUwWjCBjzEL
+MAkGA1UEBhMCS1IxDjAMBgNVBAgMBVN1d29uMQ4wDAYDVQQHDAVTdXdvbjEWMBQGA1UECgwNVGl6
+ZW4gVGVzdCBDQTEiMCAGA1UECwwZVGl6ZW4gRGlzdHJpYnV0b3IgVGVzdCBDQTEkMCIGA1UEAwwb
+VGl6ZW4gUHVibGljIERpc3RyaWJ1dG9yIENBMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDe
+OTS/3nXvkDEmsFCJIvRlQ3RKDcxdWJJp625pFqHdmoJBdV+x6jl1raGK2Y1sp2Gdvpjc/z92yzAp
+bE/UVLPh/tRNZPeGhzU4ejDDm7kzdr2f7Ia0U98K+OoY12ucwg7TYNItj9is7Cj4blGfuMDzd2ah
+2AgnCGlwNwV/pv+uVQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBACqJ
+KO33YdoGudwanZIxMdXuxnnD9R6u72ltKk1S4zPfMJJv482CRGCI4FK6djhlsI4i0Lt1SVIJEed+
+yc3qckGm19dW+4xdlkekon7pViEBWuyHw8OWv3RXtTum1+PGHjBJ2eYY4ZKIpz73U/1NC16sTB/0
+VhfnkHwPltmrpYVe
+</X509Certificate>
+</X509Data>
+</KeyInfo>
+<Object Id="prop"><SignatureProperties xmlns:dsp="http://www.w3.org/2009/xmldsig-properties"><SignatureProperty Id="profile" Target="#DistributorSignature"><dsp:Profile URI="http://www.w3.org/ns/widgets-digsig#profile"></dsp:Profile></SignatureProperty><SignatureProperty Id="role" Target="#DistributorSignature"><dsp:Role URI="http://www.w3.org/ns/widgets-digsig#role-distributor"></dsp:Role></SignatureProperty><SignatureProperty Id="identifier" Target="#DistributorSignature"><dsp:Identifier></dsp:Identifier></SignatureProperty></SignatureProperties></Object>
+</Signature>
\ No newline at end of file
diff --git a/templates/alarm.tpl b/templates/alarm.tpl
new file mode 100644 (file)
index 0000000..0c22f6e
--- /dev/null
@@ -0,0 +1,26 @@
+    <!-- Start of second page: #alarm -->
+    <div data-role="page" id="new_alarm">
+
+        <div data-role="header" data-position="fixed">
+        </div><!-- /header -->
+
+        <div data-role="content">
+            <fieldset data-role="controlgroup">
+                 <input type="radio" name="radio-choice" id="radio-choice-1" value=1 checked="checked" />
+                 <label for="radio-choice-1">Off</label>
+
+                 <input type="radio" name="radio-choice" id="radio-choice-2" value=2 />
+                 <label for="radio-choice-2">5 minute before</label>
+
+                 <input type="radio" name="radio-choice" id="radio-choice-3" value=3 />
+                 <label for="radio-choice-3">30 minute before</label>
+
+                 <input type="radio" name="radio-choice" id="radio-choice-4" value=4 />
+                 <label for="radio-choice-4">1 hour before</label>
+            </fieldset>
+            <a href="#new_event" id="add-alarm" data-role="button">Add alarm</a>
+        </div><!-- /content -->
+
+    <div data-role="footer" data-position ="fixed">
+    </div><!-- /footer -->
+    </div><!-- /page alarm -->
\ No newline at end of file
diff --git a/templates/event.tpl b/templates/event.tpl
new file mode 100644 (file)
index 0000000..a0f536a
--- /dev/null
@@ -0,0 +1,8 @@
+<li class="event" data-eventid="%uid%">
+       <div class="ui-li-aside ui-li-desc">
+               <div class="green_dot"></div>%startDate%<br/>
+               <div class="red_dot"></div>%endDate%<br/>
+       </div>
+       <div class="ul-li-desc"><span class="description">%description%</span></div>
+       <div class="deleteEvent"><form><input type="button" class="remove_event_btn" data-inline="true" value="delete"/></form></div>
+</li>
diff --git a/templates/home.tpl b/templates/home.tpl
new file mode 100644 (file)
index 0000000..e277dad
--- /dev/null
@@ -0,0 +1,30 @@
+    <!-- Start of first page: #home -->
+    <div data-role="page" id="home" data-add-back-btn="false">
+        <div data-role="content">
+            <!--
+            Select a date to view events
+
+            <div data-role="button">
+                <span class="ui-li-text-main">
+                    <input data-role="datetimepicker" data-inline="false" type="datetime" id="date_search" data-enhance="false" data-format="MMMM dd yyyy"/>
+                </span>
+            </div>
+            -->
+            <div id="events_list">
+                <h3>EventManager</h3>
+                <ul 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_event" id="newEventBtn">Add New Event</a></li>
+                    <li><a href="#new_event" id="exit_btn">Exit</a></li>
+                </ul>
+            </div>
+       </div><!-- /footer -->
+
+    </div><!-- /home -->
diff --git a/templates/new_event.tpl b/templates/new_event.tpl
new file mode 100644 (file)
index 0000000..f27a9fd
--- /dev/null
@@ -0,0 +1,68 @@
+    <!-- Start of the new event form: #new_event -->
+    <div data-role="page" id="new_event">
+
+        <div data-role="header" data-position="fixed">
+            <h1>New Event</h1>
+        </div><!-- /header -->
+
+        <div data-role="content">
+
+            <fieldset>
+                <!--
+                <label for="title">Title</label>
+                <div><input type="text" id="title" /></div>
+                -->
+
+                <label for="des">Description</label>
+                <div><input type="text" id="des" maxlength="10"></textarea></div>
+
+                <!--
+                <label for="location">Location</label>
+                <div><input type="text" id="location" value="location" /></div>
+                -->
+
+                <label for="demo-date-1">Start</label>
+                <div>
+                    <span class="ui-li-text-main">
+                        <input type="datetime" id="demo-date-1" data-format="MMM dd yyyy HH:mm"/>
+                    </span>
+                </div>
+
+                <label for="demo-date-2">End</label>
+                <div>
+                    <span class="ui-li-text-main">
+                        <input type="datetime" name="demo-date-2" id="demo-date-2" data-format="MMM dd yyyy HH:mm"/>
+                    </span>
+                </div>
+            </fieldset>
+
+            <!--
+            <fieldset class="ui-grid-a">
+                <div class="ui-block-a"><label for="switch-1">Full Day Event</label></div>
+                <div class="ui-block-b">
+                    <div id="switch-1" data-role="toggleswitch" data-checked="false"></div>
+                </div>
+            </fieldset>
+            -->
+
+            <a id="add_alarm" href="#new_alarm" data-role="button">Add alarm</a>
+        </div><!-- /content -->
+
+        <div data-role="footer" data-position="fixed">
+            <div data-role="tabbar" data-style="tabbar" >
+                <ul>
+                    <li><a href="#home" id="add-event-btn" data-inline="true" data-icon="ctrlbar-check">OK</a></li>
+                    <li><a href="#home" data-inline="true" data-icon="ctrlbar-back">Cancel</a></li>
+                </ul>
+            </div><!-- /controlbar -->
+        </div><!-- /footer -->
+
+        <div id="center_info" data-role="popupwindow" data-style="center_info">
+            <div data-role="text"><p>
+            Pop-up dialog box, a child
+            window that blocks user inter-
+            act to the parent windows
+            </p></div>
+        </div>
+
+    </div><!-- /new_event -->