add patches
[webos-internals:modifications.git] / calendar / calendar-ubercalendar.patch
1 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/app-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/app-assistant.js
2 index 5375929..83b4060 100644
3 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/app-assistant.js
4 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/app-assistant.js
5 @@ -8,6 +8,27 @@ var AppAssistant = Class.create({
6                 this.appController = appController;
7                 this.openReminderAlert = null;
8                 
9 +               //get snooze cookie -- renamed because of bug in cookie names
10 +               this.snoozeCookie = new Mojo.Model.Cookie("snoozeCookie");      
11 +               if (this.snoozeCookie) {
12 +                       var snzcookie = this.snoozeCookie.get();
13 +                       if (snzcookie) {                        
14 +                               if(snzcookie.showReminderDashboard !== undefined) {
15 +                                       this.showReminderDashboard = snzcookie.showReminderDashboard;
16 +                               } else {
17 +                                       this.showReminderDashboard = false;
18 +                               }
19 +                               if(snzcookie.snoozethrob !== undefined) {
20 +                                       this.snoozeThrob = snzcookie.snoozethrob;
21 +                               } else {
22 +                                       this.snoozeThrob = false;
23 +                               }
24 +                       }
25 +               } else {
26 +                       this.snoozeThrob = false;
27 +                       this.showReminderDashboard = false;
28 +               }
29 +               
30                 // CURRENT DATE & TIME - Keeps track of the current day/month/time in view
31                 this.currentDateTime = new Date();
32                 this.currentDateTimeObservers = new Hash();
33 @@ -77,9 +98,9 @@ var AppAssistant = Class.create({
34                 // TEMP Ignore the first time we get called which is at boot time. We need this until framework
35                 // gives us a flag to let us now if this being called at boot.
36                 this.handlelaunchCount++;
37 -               if (this.handlelaunchCount <= 1)
38 +               if (this.handlelaunchCount <= 1) {
39                         return; 
40 -                       
41 +               }
42                 //if this failed during initialization, try again       
43                 if (!this.calendarsManager.accounts) {                  
44                         this.calendarsManager.getCalendarsByAccount();
45 @@ -116,7 +137,10 @@ var AppAssistant = Class.create({
46                 else if (launchParams.alarmclose){
47                         Mojo.Log.info("$$$$$$$$ AppAssistant handleLaunch : alarmclose");
48                         this.closeReminder(launchParams.alarmclose);
49 -               } 
50 +               }
51 +               else if (launchParams.playalarmsound){
52 +                       this.playAlarmSound();
53 +               }
54                 else if (launchParams.dayChange){
55                         this.dayChange();
56                 }
57 @@ -267,6 +291,13 @@ var AppAssistant = Class.create({
58                 Mojo.Log.info("$$$$$$$$ AppAssistant closeReminder:end");
59         },
60         
61 +       playAlarmSound: function() {
62 +               if (this.openReminderAlert) {
63 +                       this.openReminderAlert.playAlarmSound();
64 +                       this.openReminderAlert = null;
65 +               }
66 +       },
67 +
68         scheduleNextReminder: function(eventId) {
69                 Mojo.Log.info("$$$$$$$$ AppAssistant scheduleNextReminder: for event:"+eventId);
70                 new Mojo.Service.Request('palm://com.palm.calendar', {
71 @@ -398,10 +429,15 @@ var AppAssistant = Class.create({
72                 var height;
73                 var reminder = getReminderManager().getReminder(eventId);
74                 reminder.userClosed = false;
75 -               if (reminder.attendees.length > 1 /*now we include the organizer in attendee list*/)
76 -                       height = 203;
77 -               else
78 -                       height = 149;
79 +               if(reminder.attendees) {
80 +                       if (reminder.attendees.length > 1 /*now we include the organizer in attendee list*/) {
81 +                               height = 280; //203 orig; 74 + a couple to get more choices
82 +                       } else {
83 +                       height = 160; //149 orig;
84 +                       }
85 +               } else {
86 +                       height = 160;
87 +               }
88                 
89                 var needThrobbing =(hasNewContent || !isSnoozedReminder) ? true:false;
90                 Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:createStageWithCallback for stage: "+this.createAlarmStageName(eventId)+", stage height is: "+height);
91 @@ -435,23 +471,25 @@ var AppAssistant = Class.create({
92                                 }, pushReminderScene.bind(this, eventId, needThrobbing), 'popupalert');
93                         }
94                 }
95 -               
96 -               Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling getStageController for calendar-dashboard");
97 -               var dashboardStageController = Mojo.Controller.getAppController().getStageController("calendar-dashboard");
98 -               if (!dashboardStageController) {
99 -                       Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling getStageProxy for calendar-dashboard");
100 -                       dashboardStageController = Mojo.Controller.getAppController().getStageProxy("calendar-dashboard");
101 -               }
102 -               if (!dashboardStageController) {
103 -                       var pushDashboardScene = function(stageController){
104 -                               stageController.pushScene('dashboard');
105 +               //Optionally disable reminder dashboard
106 +               if(this.showReminderDashboard || this.snoozeThrob) {
107 +                       Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling getStageController for calendar-dashboard");
108 +                       var dashboardStageController = Mojo.Controller.getAppController().getStageController("calendar-dashboard");
109 +                       if (!dashboardStageController) {
110 +                               Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling getStageProxy for calendar-dashboard");
111 +                               dashboardStageController = Mojo.Controller.getAppController().getStageProxy("calendar-dashboard");
112 +                       }
113 +                       if (!dashboardStageController) {
114 +                               var pushDashboardScene = function(stageController){
115 +                                       stageController.pushScene('dashboard');
116 +                               }
117 +                               Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling createStageWithCallback for calendar-dashboard");
118 +                               Mojo.Controller.getAppController().createStageWithCallback({
119 +                                       name: "calendar-dashboard",
120 +                                       lightweight: true,
121 +                                       applicationStylesheets: ["stylesheets/notification.css"],
122 +                               }, pushDashboardScene, "dashboard");
123                         }
124 -                       Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm:calling createStageWithCallback for calendar-dashboard");
125 -                       Mojo.Controller.getAppController().createStageWithCallback({
126 -                               name: "calendar-dashboard",
127 -                               lightweight: true,
128 -                               applicationStylesheets: ["stylesheets/notification.css"],
129 -                       }, pushDashboardScene, "dashboard");
130                 }
131                 Mojo.Log.info("$$$$$$$$ AppAssistant doAlarm :end");
132         },
133 @@ -488,8 +526,38 @@ var AppAssistant = Class.create({
134                         // If this is the first use of Calendar, show the first use scene
135                         this.firstUseManager = new FirstUseManager(stageController);
136                 } else {
137 +                       this.uberOpenInView = 'last';
138 +                       this.snoozeThrob = false;
139 +                       this.snoozeCookie = new Mojo.Model.Cookie("snoozeCookie");      
140 +                       if (this.snoozeCookie) {
141 +                               var snzcookie = this.snoozeCookie.get();
142 +                               if (snzcookie) {
143 +                                       if(snzcookie.uberopeninview !== undefined) {
144 +                                               this.uberOpenInView = snzcookie.uberopeninview;
145 +                                       } else {
146 +                                               this.uberOpenInView = 'last';
147 +                                       }
148 +                                       if(snzcookie.snoozethrob !== undefined) {
149 +                                               this.snoozeThrob = snzcookie.snoozethrob;
150 +                                       } else {
151 +                                               this.snoozeThrob = false;
152 +                                       }
153 +                               }
154 +                       }
155 +               
156                         // Otherwise show the Day View
157 -                       stageController.pushScene({name: "day", transition: Mojo.Transition.crossFade, disableSceneScroller: true});
158 +                       var view = "day";
159 +                       var cookie = new Mojo.Model.Cookie("LastView");
160 +                       try {
161 +                               view = cookie.get();
162 +                       } catch (e) {}
163 +                       if ((view != "month") && (view != "week")) {
164 +                               view = "day";
165 +                       }
166 +                       if(this.uberOpenInView !== 'last' && this.uberOpenInView !== undefined) {
167 +                               view = this.uberOpenInView;
168 +                       }
169 +                       stageController.pushScene({name: view, transition: Mojo.Transition.crossFade, disableSceneScroller: true});
170                 }
171         },
172         
173 @@ -863,7 +931,15 @@ function notifyTimeFormatObservers() {
174  }
175  
176  function getTimeFormat() {
177 -       return getAppAssistant().timeFormat;
178 +       //if getAppAssistant is not valid yet return the default setting of this.timeFormat.
179 +       if(getAppAssistant() != undefined)
180 +       {
181 +               return getAppAssistant().timeFormat;
182 +       }
183 +       else
184 +       {
185 +               return this.timeFormat;
186 +       }
187  }
188  // **System  Time Change
189  function observeTimeChange(sceneName, controller){
190 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/dashboard-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/dashboard-assistant.js
191 index a667ac9..81ac2a6 100644
192 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/dashboard-assistant.js
193 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/dashboard-assistant.js
194 @@ -14,6 +14,21 @@ var DashboardAssistant = Class.create({
195                 
196                 this.service = getCalendarService();
197                 
198 +               this.snoozeThrob = false;
199 +               
200 +               //get default snooze duration from cookie
201 +               this.snoozeCookie = new Mojo.Model.Cookie("snoozeCookie");
202 +
203 +               if (this.snoozeCookie) {
204 +                       var snzcookie = this.snoozeCookie.get();
205 +                       if (snzcookie) {
206 +                               if(snzcookie.snoozethrob)       {
207 +                                       this.snoozeThrob = snzcookie.snoozethrob;
208 +                               } else {
209 +                                       this.snoozeThrob = false;
210 +                               }
211 +                       }
212 +               }
213                 this.controller.get('calendar-dashboard').addEventListener(Mojo.Event.tap, this.tapHandler.bindAsEventListener(this));
214                 this.controller.get('dashboard-icon').addEventListener(Mojo.Event.tap, this.reminderList.bindAsEventListener(this));
215                 this.controller.get('dashboard-count').addEventListener(Mojo.Event.tap, this.reminderList.bindAsEventListener(this));
216 @@ -24,7 +39,10 @@ var DashboardAssistant = Class.create({
217         cleanup: function() {
218                 Mojo.Log.info("$$$$$$$$ Dashboard-assistant cleanup: start ");
219                 this.reminders.stopObservingReminders('dashboard');
220 -               this.reminders.removeAllReminders();
221 +//Do not remove the scheduled reminders
222 +//This is so that if the dashboard event is swiped away the reminder is not removed
223 +//to support reminders that are far in the future but may not want the icon in the dashboard.
224 +//             this.reminders.removeAllReminders();
225                 Mojo.Log.info("$$$$$$$$ Dashboard-assistant cleanup: end ");
226         },
227         
228 @@ -35,6 +53,7 @@ var DashboardAssistant = Class.create({
229                         Mojo.Log.info("$$$$$$$$ Dashboard-assistant updateMostRecentReminder: recent Reminder is "+this.reminder.id);
230                         this.updateHTML(this.controller.get('dashboard-subject'), (this.reminder.subject != null) ? this.reminder.subject : '');
231                         this.updateHTML(this.controller.get('dashboard-timeloc'), (this.reminder.subtitle != null) ? this.reminder.subtitle : '');
232 +                       if(this.snoozeThrob) {this.controller.stageController.indicateNewContent(true);}
233                 }
234                 else
235                 {
236 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/datetime-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/datetime-assistant.js
237 index 1bc0374..57cf2cb 100644
238 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/datetime-assistant.js
239 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/datetime-assistant.js
240 @@ -140,10 +140,540 @@ var DatetimeAssistant = Class.create({
241                  break;
242          }
243      },
244 -    
245 +       
246 +       // From monthview (Feb is fixed up by hand as necessary)
247 +       // We try to avoid the DateJS stuff because it's indescribably slow.
248 +       _monthDays: [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],
249 +       
250 +       rdayNames: function() {
251 +               var stday = 0;
252 +               if(this.startOfWeek==null || this.startOfWeek == 'undefined')
253 +                       this.startOfWeek = 1;
254 +               stday = this.startOfWeek - 1;
255 +               var tday = new Date();
256 +               tday.moveToDayOfWeek(stday);
257 +               for (var i = 0; i < 7; i++) {
258 +                       this._rdNames[i] = Mojo.Format.formatDate(tday, "E");
259 +                       tday.addDays(1);
260 +               }
261 +       },
262 +       
263 +       radvanceWk: function(wk, month, year, maxwkn) {
264 +               var wkn = parseInt(wk, 10);
265 +               if(this.weekModulusNum != undefined && this.weekModulusNum <= 52 && this.weekModulusNum != 1) {
266 +                       var maxwkn = this.weekModulusNum;
267 +               }
268 +               if((wkn > 8) && (wkn < maxwkn)) {
269 +                       return (wkn + 1);
270 +               } else if((wkn <= 8) && (wkn < maxwkn)) {
271 +                       wkn +=1;
272 +                       var zd = '0';
273 +                       return zd + wkn.toString();
274 +               } else if(wkn == maxwkn) {
275 +                       var zd = '01';
276 +                       return zd;
277 +               }
278 +       },
279 +       
280 +       // draw month function, expects numbers 0 based month
281 +       canvasRM: function(month, year, context) {
282 +               // date object
283 +               var rmon = new Date(year, month, 1);
284 +               
285 +               //setup number of days, 1st day(day of week), week number, number of weeks
286 +               var rd1dayOfMon = rmon.getDay();
287 +               var rwkNum = rmon.getISO8601Week();
288 +               var maxwkn = new Date(year, 11, 31).getISO8601Week();
289 +               if(this.weekNumOffset !== undefined && this.weekNumOffset !=0) {
290 +                       var wkNum = parseInt(rwkNum,10) + this.weekNumOffset;
291 +                       rwkNum = wkNum > maxwkn ? (wkNum - maxwkn) : wkNum;
292 +                       rwkNum = rwkNum < 10 ? '0' + rwkNum : rwkNum;
293 +               }
294 +               if(this.weekModulusNum != undefined && this.weekModulusNum <= 52 && this.weekModulusNum != 1) {
295 +                       rwkNum = (parseInt(rwkNum, 10) % this.weekModulusNum) + 1;
296 +                       rwkNum = rwkNum < 10 ? '0' + rwkNum : rwkNum;
297 +               }
298 +               var r1offset = rd1dayOfMon - (this.startOfWeek - 1);
299 +               if (r1offset < 0) {r1offset += 7;}  //num of days of prev mon
300 +               if(isLeapYear(year)) {
301 +                       this._monthDays[1] = 29;
302 +               } else {
303 +                       this._monthDays[1] = 28;
304 +               }
305 +               this.RM[context].maxdays = this._monthDays[month];              
306 +               //setup fonts and spacing
307 +               this.mthctx[context].fillStyle = "rgb(0, 0, 0)";
308 +               this.mthctx[context].font = "bold 14px Prelude";
309 +               this.mthctx[context].textAlign = "left";
310 +               this.mthctx[context].textBaseline = "top";
311 +               var top = 2;
312 +               var leftmargin = 2;
313 +               var left = 0 + leftmargin;
314 +               var txt = "";
315 +               this.colHW = 30;
316 +               var maxW = 30;
317 +               this.topCor = 42 + (this.colHW/2); //top margin + half-cell
318 +               this.leftCor = this.colHW;
319 +               this.RM[context].fstDayLidx = r1offset;
320 +               this.RM[context].fstDayTidx = 1;
321 +               // setup title and week header
322 +               var titleTxt = Mojo.Format.formatDate(rmon, $L("MMM yyyy"));
323 +               this.mthctx[context].strokeText(titleTxt, left + 90, top);
324 +               this.mthctx[context].textAlign = "center";
325 +               for (var i = 0; i < 7; i++) {
326 +                       txt = this._rdNames[i];
327 +                       left = (i * this.colHW) + this.leftCor + 13;//13 is for font &txt to ctr
328 +                       top = 22;
329 +                       this.mthctx[context].strokeText(txt, left, top);        
330 +               }
331 +               this.mthctx[context].fillStyle = "rgb(104, 104, 104)";
332 +               this.mthctx[context].font = "14px Prelude";
333 +               this.mthctx[context].textAlign = "left";
334 +               this.mthctx[context].textBaseline = "alphabetic";
335 +               for (var j = 0; j < 6; j++) {
336 +                       txt = rwkNum;
337 +                       left = leftmargin;
338 +                       top = (j * this.colHW) + this.topCor + 3; // 3 is for font correction
339 +                       this.mthctx[context].strokeText(txt, left, top);
340 +                       rwkNum = this.radvanceWk(rwkNum, month, year, maxwkn);
341 +               }
342 +               //iterate through the date rows
343 +               var num = 1;
344 +               this.mthctx[context].fillStyle = "rgb(0, 0, 0)";
345 +               this.mthctx[context].font = "bold 14px Prelude";
346 +               this.mthctx[context].textAlign = "center";
347 +               for (var j=0; j<6; j++) {
348 +                       if (num > this.RM[context].maxdays) {
349 +                               break; }
350 +                       top = (j * this.colHW) + this.topCor + 3;
351 +                       for (var i=0; i<7; i++) {
352 +                               if (j==0 && i ==0) {i = r1offset;}
353 +                               txt = num;
354 +                               left =  (i * this.colHW) + this.leftCor + 13;
355 +                               this.mthctx[context].strokeText(txt, left, top);
356 +                               num +=1;
357 +                               if (num > this.RM[context].maxdays) {
358 +                                       break; }
359 +                       }
360 +               }
361 +       },
362 +       
363 +       RMnextM: function(index) {
364 +               this.RM[index].month = this.RM[index - 1].month;
365 +               this.RM[index].year = this.RM[index - 1].year;
366 +               if(this.RM[index].month == 11) {
367 +                       this.RM[index].month = 0;
368 +                       this.RM[index].year += 1;
369 +               } else {
370 +                       this.RM[index].month += 1;
371 +               }
372 +       },
373 +       
374 +       RMprevM: function(index) {
375 +               this.RM[index].month = this.RM[index + 1].month;
376 +               this.RM[index].year = this.RM[index + 1].year;
377 +               if(this.RM[index].month == 0) {
378 +                       this.RM[index].month = 11;
379 +                       this.RM[index].year -= 1;
380 +               } else {
381 +                       this.RM[index].month -= 1;
382 +               }
383 +       },
384 +       
385 +       // determin calendar order for the canvas's
386 +       orderRM: function( stDate, eDate, isAllDay) {
387 +               //check first
388 +               if(stDate.getTime() > eDate.getTime) {
389 +                       Mojo.Log.error ("start after end");
390 +                       return;
391 +               }
392 +               for(var i=0; i<6; i++) {
393 +                       this.RM[i] = {};
394 +                       this.RM[i].month = "";
395 +                       this.RM[i].year = "";
396 +                       this.RM[i].fstDayLidx = 1;
397 +                       this.RM[i].fstDayTidx = 1;
398 +                       this.RM[i].maxdays = 1;
399 +               }
400 +               // date objects
401 +               var curD = new Date();
402 +               var curMY = {month: curD.getMonth(), year: curD.getFullYear() };
403 +               var stMY = {month: stDate.getMonth(), year: stDate.getFullYear() };
404 +               var eMY = {month: eDate.getMonth(), year: eDate.getFullYear() };
405 +               this.RMlast.duration = getTimePeriodParts(stDate, eDate, isAllDay);
406 +               var rwhen = {};
407 +               rwhen = getTimePeriodParts(curD, stDate, isAllDay);
408 +               var dura = this.RMlast.duration;
409 +               // determine duration case
410 +               if ( (dura.years == 0) && (((dura.months == 5) && (dura.days == 0)) || (dura.months < 5)) ) {
411 +                       if ( (dura.months <=1) && ((rwhen.months <= 3) && (rwhen.years <=0)) ){
412 +                               // we can fit in 6 months try to get today in the 6 months
413 +                               if(curD.getTime() < stDate.getTime()) {
414 +                                       //close future start with curDate 
415 +                                       this.redlineSplit.setStyle({borderRight: '1px solid black'});
416 +                                       this.RM[0].month = curMY.month;
417 +                                       this.RM[0].year = curMY.year;
418 +                                       for (var i = 1; i < 6; i++) {
419 +                                               this.RMnextM(i);
420 +                                       }
421 +                               } else {
422 +                                       // in close past start with stDate
423 +                                       this.redlineSplit.setStyle({borderRight: '1px solid black'});
424 +                                       this.RM[0].month = stMY.month;
425 +                                       this.RM[0].year = stMY.year;
426 +                                       for (var i = 1; i < 6; i++) {
427 +                                               this.RMnextM(i);
428 +                                       }
429 +                               }
430 +                       } else {
431 +                               if((curD.getTime() < stDate.getTime()) && (((dura.months == 4) && (dura.days == 0) && (dura.years ==0)) || ((dura.months <4) && (dura.years==0)))){
432 +                                       // in 6 months, too far away for today, in future do prev 
433 +                                       this.redlineSplit.setStyle({borderRight: '1px solid black'});
434 +                                       this.RM[1].month = stMY.month;
435 +                                       this.RM[1].year = stMY.year;
436 +                                       this.RMprevM(0);
437 +                                       this.RMnextM(2);
438 +                                       this.RMnextM(3);
439 +                                       this.RMnextM(4);
440 +                                       this.RMnextM(5);
441 +                               } else {
442 +                                       // in past or could be 6 cal months do start + 5
443 +                                       this.redlineSplit.setStyle({borderRight: '1px solid black'});
444 +                                       this.RM[0].month = stMY.month;
445 +                                       this.RM[0].year = stMY.year;
446 +                                       for (var i = 1; i < 6; i++) {
447 +                                               this.RMnextM(i);
448 +                                       }
449 +                               }
450 +                       }
451 +               } else { //duration won't fit in 6 months
452 +                       if( ((stMY.year == curMY.year) && (stMY.month == curMY.month)) ||
453 +                         ((stMY.year < curMY.year) ||  ((stMY.year == curMY.year) && (stMY.month < curMY.month))) ){
454 +                       //past or present month - do start + next + next redline split then -- prev + end + next
455 +                               this.redlineSplit.setStyle({borderRight: '2px solid red'});
456 +                               this.RM[0].month = stMY.month;
457 +                               this.RM[0].year = stMY.year;
458 +                               this.RMnextM(1);
459 +                               this.RMnextM(2);
460 +                               this.RM[4].month = eMY.month;
461 +                               this.RM[4].year = eMY.year;
462 +                               this.RMprevM(3);
463 +                               this.RMnextM(5);
464 +                       } else if((stMY.year > curMY.year) ||  ((stMY.year == curMY.year) && (stMY.month > curMY.month))) {
465 +                       // future - do prev + start + next redline split prev + end + next
466 +                               this.redlineSplit.setStyle({borderRight: '2px solid red'});
467 +                               this.RM[1].month = stMY.month;
468 +                               this.RM[1].year = stMY.year;
469 +                               this.RMprevM(0);
470 +                               this.RMnextM(2);
471 +                               this.RM[4].month = eMY.month;
472 +                               this.RM[4].year = eMY.year;
473 +                               this.RMprevM(3);
474 +                               this.RMnextM(5);
475 +                       }
476 +               }       
477 +               // call canvasRM
478 +               for(var k=0; k<6; k++){
479 +                       this.canvasRM(this.RM[k].month, this.RM[k].year, k);
480 +               }
481 +
482 +               // record for next time comparisons
483 +               this.RMlast.stMY = stMY;
484 +               this.RMlast.eMY = eMY;
485 +               this.RMlast.curMY = curMY;
486 +       },
487 +       
488 +       risRendered: function( year, month) {
489 +               for(var i=0; i<6; i++) {
490 +                       if((this.RM[i].month == month) && (this.RM[i].year == year)) {
491 +                               return i;
492 +                       }
493 +               }
494 +               return -1;
495 +       },
496 +       
497 +       //mark days in calendar
498 +       markDay: function(rdate, imgsrc, color, rx, ry, rwt, rht) {
499 +               // determine which month, year, date
500 +               if (rdate instanceof Date == true) { 
501 +                       var whatMn = rdate.getMonth();
502 +                       var whatYr = rdate.getFullYear();
503 +                       var whatDt = rdate.getDate();
504 +               } else if(rdate !== undefined) {
505 +                       this.rtdate = new Date(rdate);
506 +                       var whatMn = this.rtdate.getMonth();
507 +                       var whatYr = this.rtdate.getFullYear();
508 +                       var whatDt = this.rtdate.getDate();
509 +               }
510 +               var rmimgsrc = imgsrc;
511 +               var idx = this.risRendered(whatYr, whatMn);
512 +               if(idx == -1) { return; }
513 +               var fstDayLidx = this.RM[idx].fstDayLidx;
514 +               var fstDayTidx = this.RM[idx].fstDayTidx;
515 +               var rRow = Math.floor((whatDt + fstDayLidx -1) / 7);
516 +               var col = (whatDt + fstDayLidx - 1) % 7;
517 +               var itop = (rRow * this.colHW) + 40;
518 +               var ileft = (col * this.colHW) + this.colHW;
519 +               itop = (ry !== undefined) ? itop + ry : itop;
520 +               ileft = (rx !== undefined) ? ileft + rx : ileft;
521 +               if (rmimgsrc !== undefined) {
522 +                       this.mthctx[idx].drawImage(rmimgsrc, ileft, itop, (rwt !== undefined)? rwt : this.colHW,(rht !== undefined)? rht : this.colHW);
523 +               } else if(color !== undefined) {
524 +                       this.mthctx[idx].fillStyle = color;
525 +                       this.mthctx[idx].fillRect(ileft, itop, this.colHW-2, this.colHW-2);
526 +               } else {
527 +                       this.mthctx[idx].fillStyle = "rgba(232,227,124,0.5)";
528 +                       this.mthctx[idx].fillRect(ileft, itop, this.colHW-2, this.colHW-2);
529 +               }
530 +       },
531 +       
532 +       rmMarkD: function() {
533 +               if(this.RMlast.duration.months > 7) {
534 +                       return;
535 +               }
536 +               if((this.RMlast.stMY.month == this.RMlast.eMY.month) && (this.RMlast.stD.getDate() == this.RMlast.eD.getDate())) {
537 +                       this.RMlast.HMDB = 1;
538 +                       return;
539 +               }
540 +               var stTS = new Date(this.RMlast.stMY.year, this.RMlast.stMY.month, this.RMlast.stD.getDate(), 12).getTime();
541 +               var daylen = 3600000*24;
542 +               var end = howManyDaysBetween(this.RMlast.stD, this.RMlast.eD) +1;
543 +               this.RMlast.HMDB = end;
544 +               this.RMlast.stTS = stTS;
545 +               for (var z = 0; z < end; z++) {
546 +                       this.markDay(stTS + (z*daylen),
547 +                                                       this.dImg, 
548 +                                                       null/*color*/,
549 +                                                       null/*x adjust*/,
550 +                                                       this.colHW-2/*y adjust*/ ,
551 +                                                       this.colHW/*wd adjust*/,
552 +                                                       2 /*ht adjust*/)
553 +               }
554 +       },
555 +       
556 +       rmRecur: function() {
557 +               // this function is after it is a known recurrent model
558 +               // time of when -- occuring each
559 +               var rcfrequency = this.targetEvent.rruleModel.frequency;
560 +               var rccount = this.targetEvent.rruleModel.count;
561 +               // this is week day names array
562 +               var rcbyday =  this.targetEvent.rruleModel.byday;
563 +               // this is the date of the month
564 +               var rcbymonthday = this.targetEvent.rruleModel.bymonthday;
565 +               // end day
566 +               var rcuntil = this.targetEvent.rruleModel.until;
567 +               // howmany times between
568 +               var rcint = this.targetEvent.rruleModel.interval;
569 +               // take stTS and duradays to create the base event from the curent event
570 +               var rcduraD = this.RMlast.HMDB;
571 +               var rcstTS = this.targetEvent.startTimestamp;
572 +               var rcstDy = new Date(rcstTS);
573 +               var rcstD = new Date(rcstDy.getFullYear(), rcstDy.getMonth(), rcstDy.getDate(), 12);
574 +               rcstTS = rcstD.getTime();
575 +               var stDoW = rcstD.getDay();
576 +               var dlen = 3600000*24;
577 +               var rcdaysofwk = [];
578 +               this.recTS = []; // array of timestamps of the recurring evt
579 +               switch (rcfrequency) {
580 +                               case 'DAILY':
581 +                                       var recfreqTS = dlen;
582 +                                       break;
583 +                               case 'WEEKLY':
584 +                                       var recfreqTS = dlen * 7;
585 +                                       break;
586 +                               case 'MONTHLY':
587 +                                       var recfreqTS = -1;
588 +                                       break;
589 +                               case 'YEARLY':
590 +                                       var recfreqTS = -1;
591 +                                       break;
592 +               }
593 +
594 +               if(rcuntil !== "" && rcuntil !== undefined) {
595 +                       // until is in UTC jan = 1, need local for cal
596 +                       var rcyear = rcuntil.substring(0,4);
597 +                       var rcmon = parseInt(rcuntil.substring(4,6), 10) -1;
598 +                       var rcday = parseInt(rcuntil.substring(6,8), 10);
599 +                       var rchour = parseInt(rcuntil.substring(9,11), 10);
600 +                       var rcmin = parseInt(rcuntil.substring(11, 13), 10);
601 +                       this.RMlast.recD = new Date(Date.UTC(rcyear, rcmon, rcday, rchour, rcmin));
602 +               } else if(this.targetEvent.isRecurringForever) {
603 +                       if(rcfrequency == "DAILY" || recfreqTS == -1) {
604 +                       // go out 6 months
605 +                               this.RMlast.recD = new Date(this.RMlast.eMY.month + 6 > 11 ? this.RMlast.eMY.year + 1 : this.RMlast.eMY.year, this.RMlast.eMY.month + 6 > 11 ? this.RMlast.eMY.month - 6 : this.RMlast.eMY.month + 6, this.RMlast.eD.getDate());
606 +                       } else {        // go out 1 year from the end date
607 +                               this.RMlast.recD = new Date(this.RMlast.eMY.year + 1, this.RMlast.eMY.month, this.RMlast.eD.getDate());
608 +                       }
609 +               } else if((rccount !== -1) && (recfreqTS !== -1)) {
610 +                       this.RMlast.recD = new Date(rcstTS + (recfreqTS*rcint*rccount));
611 +               }
612 +               this.RMlast.recD.setHours(12); // set end to noon local to match start, UTC get's the right day
613 +               var recHMDB = howManyDaysBetween(rcstD, this.RMlast.recD) +1;
614 +               // detect recurr model
615 +               switch (rcfrequency) {
616 +                       case 'DAILY' : // Do Not Localize
617 +                               // get how many intervals
618 +                               var rcdays = 1 + Math.floor((recHMDB*dlen) / (recfreqTS*rcint));
619 +                               for(var k=0; k < rcdays; k++) { // cycle through intervals
620 +                                       this.recTS.push((dlen*k*rcint) + rcstTS);       
621 +                               }
622 +                               while(this.recTS[this.recTS.length -1] > this.RMlast.recD.getTime()){
623 +                                       this.recTS.pop();
624 +                               }
625 +                               break;
626 +                               
627 +            case 'WEEKLY': // Do NOT Localize
628 +                               // find the day numbers from their names
629 +                               var rci = this.targetEvent.rruleModel.byday.length;
630 +                               var rcSundayTS = rcstTS - (stDoW*dlen); 
631 +                               for(var i=0; i < rci; i++) {
632 +                                       rcdaysofwk[i] = this.recurrenceRule.dayMap.indexOf(rcbyday[i]);
633 +                               }
634 +                               if(rci > 1) {
635 +                               // get start day dow because it has to be in rcdaysofwk
636 +                                       var rcpos = rcdaysofwk.indexOf(stDoW);
637 +                                       //need to get to the last of the array before start of next week
638 +                                       if(rcpos !== rci - 1){
639 +                                               for(var i = rcpos; i <= rci; i++) {
640 +                                                       for(var j = 0; j < rcduraD; j++) {
641 +                                                       // array's TS = duration days *milliseconds in a day + (sundays TS + day of week adjustment) 
642 +                                                       this.recTS.push((dlen*j) + (rcSundayTS + dlen*rcdaysofwk[i]));  
643 +                                                       }
644 +                                               }
645 +                                       }
646 +                               }
647 +                               //should be at the first day of the week after start day's week
648 +                               // need to get how many intervals until GetHowManyDays / 7*interval
649 +                               var rcwks = 1 + Math.floor((recHMDB*dlen) / (recfreqTS*rcint)); 
650 +                               for(var k=1; k <= rcwks; k++) { // cycle through intervals
651 +                                       var rcwkSunTS = rcSundayTS + (rcint * recfreqTS * k);
652 +                                       for(var i = 0; i < rci; i++) { // cycle through days of week
653 +                                               for(var j = 0; j < rcduraD; j++) { //cycle duration
654 +                                               this.recTS.push((dlen*j) + (rcwkSunTS + dlen*rcdaysofwk[i]));   
655 +                                               }
656 +                                       }
657 +                               }
658 +                               while(this.recTS[this.recTS.length -1] > this.RMlast.recD.getTime()){
659 +                                       this.recTS.pop();
660 +                               }
661 +               break;
662 +                
663 +            case 'MONTHLY': // Do NOT Localize
664 +                //Monthly by date
665 +                               var rcmonths = 1 + Math.floor(howManyMonthsBetween(rcstD ,this.RMlast.recD)/rcint);
666 +                if (this.targetEvent.rruleModel.bymonthday.length > 0) {
667 +                    var rcmonthday = this.targetEvent.rruleModel.bymonthday[0];
668 +                                       var rcstmon = rcstD.getMonth();
669 +                                       var rcstyear = rcstD.getFullYear();
670 +                                       for(var i=0; i<rcmonths; i++) { //cycle through intervals
671 +                                               var rcmon = (rcstmon + (i*rcint)) > 11 ? rcstmon + (i*rcint) - 12 : rcstmon + (i*rcint);
672 +                                               var rcyear = (rcstmon + (i*rcint)) > 11 ? rcstyear + 1 : rcstyear; 
673 +                                               var rcmonTS = new Date(rcyear, rcmon, rcmonthday, 12).getTime();
674 +                                               for(var j=0; j<rcduraD; j++) { // cycle through duration
675 +                                                       this.recTS.push(rcmonTS + (j*dlen));
676 +                                               }
677 +                                       }
678 +                } else {
679 +                    var nth = getDOWCount(this.targetEvent.startTimestamp);
680 +                                       var rcmonths = 1 + Math.floor(howManyMonthsBetween(rcstD ,this.RMlast.recD)/rcint);
681 +                                       var rcstmon = rcstD.getMonth();
682 +                                       var rcstyear = rcstD.getFullYear();
683 +                                       var rcwantday = rcstD.getDay();
684 +                                       for(var i=0; i<rcmonths; i++) { // cycle through intervals
685 +                                               var rcmon = (rcstmon + (i*rcint)) > 11 ? rcstmon + (i*rcint) - 12 : rcstmon + (i*rcint);
686 +                                               var rcyear = (rcstmon + (i*rcint)) > 11 ? rcstyear + 1 : rcstyear;
687 +                                               var rcmonD = new Date(rcyear, rcmon, 1, 12);
688 +                                               var rcfstday = rcmonD.getDay();
689 +                                               var rcaddTS = ((rcwantday - rcfstday) < 0) ? ((rcwantday - rcfstday) + 7)*dlen : (rcwantday - rcfstday)*dlen;
690 +                                               var rcmonTS = rcmonD.getTime() + rcaddTS + 7*dlen*(nth-1);
691 +                                               for(var j=0; j<rcduraD; j++) { // cycle through duration
692 +                                                       this.recTS.push(rcmonTS + (j*dlen));
693 +                                               }
694 +                                       }
695 +                               }
696 +                               while(this.recTS[this.recTS.length -1] > this.RMlast.recD.getTime()){
697 +                                       this.recTS.pop();
698 +                               }
699 +                               break;
700 +                               
701 +                       default:                
702 +                               break;
703 +               }
704 +               // pull out the exceptions
705 +               if(this.targetEvent.exdates !== undefined) {
706 +                       if(this.targetEvent.exdates !== "") {
707 +                               var rcexTS = [];
708 +                               var rcexstr = this.targetEvent.exdates.split("\r\n");
709 +                               for(var i=0; i<rcexstr.length; i++){
710 +                                       var idx = rcexstr[i].indexOf(":");
711 +                                       if(idx !== -1) {
712 +                                               rcexstr[i] = rcexstr[i].substring(idx +1);
713 +                                       }
714 +                               }
715 +                               for(var j=0; j<rcexstr.length; j++) {
716 +                                       var rcyear = rcexstr[j].substring(0,4);
717 +                                       var rcmon = parseInt(rcexstr[j].substring(4,6), 10) -1;
718 +                                       var rcday = parseInt(rcexstr[j].substring(6,8), 10);
719 +                                       rcexTS[j] = new Date(rcyear, rcmon, rcday, 12).getTime();
720 +                               }
721 +                               // pull exdates out of array
722 +                               for(var k=0; k<rcexTS.length; k++) {
723 +                                       var idx = this.recTS.indexOf(rcexTS[k]);
724 +                                       if(idx !== -1) {
725 +                                               this.recTS.splice(idx,1);
726 +                                       }
727 +                               }
728 +                       }
729 +               }
730 +               // mark the recurrence days
731 +               var rcstop = this.recTS.length;
732 +               for(var k=0; k<rcstop; k++){
733 +                       this.markDay(this.recTS[k],
734 +                                                       this.rImg, 
735 +                                                       null/*color*/,
736 +                                                       null/*x adjust*/,
737 +                                                       this.colHW-2/*y adjust*/ ,
738 +                                                       this.colHW/*wd adjust*/,
739 +                                                       2 /*ht adjust*/)
740 +               }
741 +               
742 +       },
743 +       
744 +       rmEval: function() {
745 +               if(this.targetModifiedTime) {                   
746 +                       this.RMlast.stD = new Date(this.targetModifiedTime.start);
747 +                       this.RMlast.eD = new Date(this.targetModifiedTime.end);
748 +               } else {
749 +                       this.RMlast.stD = new Date(this.targetEvent.startTimestamp);
750 +                       this.RMlast.eD = new Date(this.targetEvent.endTimestamp);
751 +               }
752 +               if(this.targetEvent.rruleModel) {
753 +                       
754 +                       this.rmdoRec = true;
755 +                       return;
756 +               }
757 +       },
758 +       
759      setup: function(){
760          //Mojo.Log.info("datetime-assistant:setup");
761 -        
762 +        this.weekModulusNum = 1;
763 +               this.weekNumOffset = 0;
764 +               this.weekCookie = new Mojo.Model.Cookie('WeekViewEnhanced');
765 +               if (this.weekCookie) {
766 +                       var weekcookie = this.weekCookie.get();
767 +                       if(weekcookie) {
768 +                               if(weekcookie.weeknumoffset !== undefined) {
769 +                                               this.weekNumOffset = weekcookie.weeknumoffset;
770 +                               } else {
771 +                                               this.weekNumOffset = 0;
772 +                               }
773 +                               if(weekcookie.weekmodulusnum !== undefined) {
774 +                                               this.weekModulusNum = weekcookie.weekmodulusnum;
775 +                               } else {
776 +                                               this.weekModulusNum = 1;
777 +                               }
778 +                       }
779 +               }
780                 this.appMenuModel= { visible:true, 
781              label: $L('Calendar'),
782                                                         items: [ Mojo.Menu.editItem,
783 @@ -168,7 +698,40 @@ var DatetimeAssistant = Class.create({
784          this.startDateModel = {
785              date: new Date(this.targetModifiedTime.start)
786          };
787 +         var startDiv = this.controller.get("edit_startDate").parentNode.parentNode;
788 +        startDiv.style.paddingTop = "0px";
789 +        startDiv.style.marginTop = "-20px";
790 +        startDiv.removeChild(startDiv.firstChild);
791 +        startDiv.innerHTML = '<table width="100%"><tr><td width="10%"><div x-mojo-element="Button" id="popCanvasBtn2" class="popCanvas"></div></td><td width="90%"><div class="title datetime-picker"><div id="edit_startDate" x-mojo-element="DatePicker"></div></div></td></tr></table>';
792 +
793 +        var endDiv = this.controller.get("edit_endDate").parentNode.parentNode;
794 +        endDiv.style.paddingTop = "0px";
795 +        endDiv.style.marginTop = "-20px";
796 +        endDiv.removeChild(endDiv.firstChild);
797 +        endDiv.innerHTML = '<table width="100%"><tr><td width="10%"><div x-mojo-element="Button" id="popCanvasBtn" class="popCanvas"></div></td><td width="90%"><div class="title datetime-picker"><div id="edit_endDate" x-mojo-element="DatePicker"></div></div></td></tr></table>';
798 +               var startdatePalmListDiv = this.controller.get("start_date_row").parentNode;
799 +        var parentDiv = this.controller.get("datetime_view");
800 +        var newDiv = this.controller.document.createElement("div");
801 +        newDiv.setAttribute("id", "lDrawer");
802 +        newDiv.setAttribute("x-mojo-element", "Drawer");
803 +        newDiv.setAttribute("class", "drawerClass");
804 +        newDiv.setAttribute("name", "DPmonth_view");
805 +        newDiv.innerHTML = '<div id="DPscrol" x-mojo-element="Scroller"><div id="DPscrolct">' +
806 +                               '<div id="DPmonth_0" class="DPmv">' +
807 +                               '<canvas id="left0" width="240" height="220" left="0"></canvas>' +
808 +                               '</div><div id="DPmonth_1" class="DPmv">' +
809 +                               '<canvas id="left1" width="240" height="220"></canvas>' +
810 +                               '</div><div id="DPmonth_2" class="DPmv">' +
811 +                               '<canvas id="left2" width="240" height="220"></canvas>' +
812 +                               '</div><div id="DPmonth_3" class="DPmv">' +
813 +                               '<canvas id="right0" width="240" height="220"></canvas>' +
814 +                               '</div><div id="DPmonth_4" class="DPmv">' +
815 +                               '<canvas id="right1" width="240" height="220"></canvas>' +
816 +                               '</div><div id="DPmonth_5" class="DPmv">' +
817 +                               '<canvas id="right2" width="280" height="220"></canvas></div></div></div>';
818 +        parentDiv.insertBefore(newDiv, startdatePalmListDiv.nextSibling);
819          
820 +               
821         this.controller.setupWidget('edit_startDate',{label: $L('Date'),modelProperty:'date'}, this.startDateModel);
822          this.controller.listen('edit_startDate', Mojo.Event.propertyChange, this.startDateCallback.bindAsEventListener(this));
823          
824 @@ -204,10 +767,133 @@ var DatetimeAssistant = Class.create({
825          this.controller.setupWidget('dtl_allday_cb', this.allDayCheckboxAttribute, this.allDayCheckboxModel);
826          
827          this.updateTimedAllDay(false);
828 -        
829 -        
830 -    },
831 +               // button setup
832 +               this.controller.setupWidget("popCanvasBtn",
833 +                       {},
834 +                       {
835 +                               label : "",
836 +                               disabled: false
837 +                       }
838 +               );
839 +               this.popCanvasBtn = this.controller.get('popCanvasBtn');
840 +               this.controller.setupWidget("popCanvasBtn2",
841 +                       {},
842 +                       {
843 +                               label : "",
844 +                               disabled: false
845 +                       }
846 +               );
847 +               this.canvasBtnHandler = this.DPtoggleDrawer.bind(this);
848 +               this.popCanvasBtn2 = this.controller.get('popCanvasBtn2');
849 +               Mojo.Event.listen(this.popCanvasBtn, Mojo.Event.tap, this.canvasBtnHandler);
850 +               Mojo.Event.listen(this.popCanvasBtn2, Mojo.Event.tap, this.canvasBtnHandler);
851 +               // drawer setup
852 +               this.controller.setupWidget("DPscrol",{mode: 'horizontal'});
853 +               this.dModel = {open:false};
854 +               this.controller.setupWidget('lDrawer', {property:'open', drawerBottomOffset: 50}, this.dModel);
855 +               this.ldrawer = this.controller.get('lDrawer');          
856 +               // setup month canvas context
857 +               this.redlineSplit = this.controller.get("DPmonth_2");
858 +               this.mthctx = [];
859 +               this.left0 = this.controller.get("left0");
860 +               this.mthctx[0] = this.left0.getContext('2d');
861 +               this.left1 = this.controller.get("left1");
862 +               this.mthctx[1] = this.left1.getContext('2d');
863 +               this.left2 = this.controller.get("left2");
864 +               this.mthctx[2] = this.left2.getContext('2d');
865 +               this.right0 = this.controller.get("right0");
866 +               this.mthctx[3] = this.right0.getContext('2d');
867 +               this.right1 = this.controller.get("right1");
868 +               this.mthctx[4] = this.right1.getContext('2d');
869 +               this.right2 = this.controller.get("right2");
870 +               this.mthctx[5] = this.right2.getContext('2d');
871 +               // setup vars
872 +               this.startOfWeek = getPrefs().startOfWeek;
873 +               this._rdNames = [];
874 +               this.RMlast = {};
875 +               this.RMlast.duration = {years: 0, months: 0, days: 0, hours: 0, minutes: 0};
876 +               this.RM = [];
877 +               this.topCor = "";
878 +               this.leftCor = "";
879 +               this.rtdayimg = new Image();
880 +               this.rtdayimg.src = "./images/week-current-day.png";
881 +               this.rmdoRec = false;
882 +               this.rdayNames();
883 +               this.rmEval();
884 +               this.orderRM(this.RMlast.stD, this.RMlast.eD, this.targetEvent.allDay);
885 +               this.stImg = new Image();
886 +               this.stImg.src = "./images/day-allday-event-green-center.png";
887 +               this.eImg = new Image();
888 +               this.eImg.src = "./images/day-allday-event-red-center.png";
889 +               this.dImg = new Image();
890 +               this.dImg.src = "./images/day-event-green.png";
891 +               this.rImg = new Image();
892 +               this.rImg.src = "./images/day-event-yellow.png";
893 +               this.rmScroller = this.controller.get('DPscrol');
894 +               //this.rmScrollP = {x : 0, y : 0};
895 +               this.rmlastBtn = null;
896 +               this.rtDate = new Date();
897 +               this.rmcalHold = false;
898 +       },
899      
900 +       
901 +       // toggle drawer function:
902 +       DPtoggleDrawer: function(e) {
903 +               var curBtn = e.currentTarget.id;
904 +               if(curBtn == "popCanvasBtn2") {
905 +                       this.rmScrollTo(this.RMlast.stD);
906 +               } else {
907 +                       this.rmScrollTo(this.RMlast.eD);
908 +               }
909 +               if (curBtn == this.rmlastBtn)  {
910 +                       this.ldrawer.mojo.setOpenState(false);
911 +                       this.rmlastBtn = null;
912 +                       if(!this.targetEvent.allDay) {
913 +                               this.slideDown(this.controller.get('start_time_row'), 0.4);             
914 +                               this.slideDown(this.controller.get('end_time_row'), 0.4);
915 +                       }
916 +               } else {
917 +                       this.rmlastBtn = curBtn;
918 +                       var state = this.ldrawer.mojo.getOpenState();
919 +                       if(!state) {
920 +                       
921 +                               this.ldrawer.mojo.setOpenState(true);
922 +                               if(!this.targetEvent.allDay) {
923 +                                       this.slideUp(this.controller.get('start_time_row'), 0.4);
924 +                                       this.slideUp(this.controller.get('end_time_row'), 0.4);
925 +                               }
926 +                       }
927 +               }
928 +       },      
929 +       
930 +       rmScrollTo: function(x) {
931 +               if (x instanceof Date == true) { 
932 +                       var whatMn = x.getMonth();
933 +                       var whatYr = x.getFullYear();
934 +                       var idx = this.risRendered(whatYr, whatMn);
935 +               } else if(x >= 0 && x <= 6) {
936 +                       var idx = x;
937 +               }
938 +               idx = idx * 241;
939 +               idx = -idx;
940 +               this.controller.get('DPscrol').mojo.scrollTo(idx, true, true);
941 +       },
942 +       
943 +       rmHandleUpdate: function() {
944 +               // date picker model changed do redraw
945 +               for(var i = 0;i<6; i++) {
946 +                       this.mthctx[i].clearRect(0, 0, 240,220);
947 +               }
948 +               this.rmEval();
949 +               this.orderRM(this.RMlast.stD, this.RMlast.eD, this.targetEvent.allDay);
950 +               this.markDay(new Date(), this.rtdayimg);
951 +               this.markDay(this.RMlast.stD, this.stImg , null/*color*/, 1/*x adjust*/,null/*y adjust*/ ,2 /*wd adjust*/,this.colHW /*ht adjust*/);
952 +               this.markDay(this.RMlast.eD, this.eImg , null/*color*/, this.colHW-2/*x adjust*/,null/*y adjust*/ ,2 /*wd adjust*/,this.colHW /*ht adjust*/);
953 +               this.rmMarkD();
954 +               if(this.rmdoRec) {this.rmRecur(); }
955 +               this.rmScrollTo(this.RMlast.stD);
956 +       },
957 +       
958      checktargetEventDirty: function(){
959          //construct rrule
960                 if(this.targetEvent.rruleModel)
961 @@ -431,12 +1117,47 @@ var DatetimeAssistant = Class.create({
962      },
963      
964      activate: function(){
965 -    },
966 +               this.markDay(new Date(), this.rtdayimg);
967 +               this.markDay(this.RMlast.stD, this.stImg , null/*color*/,0/*x adjust*/,null/*y adjust*/ ,2 /*wd adjust*/,this.colHW /*ht adjust*/);
968 +               this.markDay(this.RMlast.eD, this.eImg , null/*color*/, this.colHW-2/*x adjust*/,null/*y adjust*/ ,2 /*wd adjust*/,this.colHW /*ht adjust*/);
969 +               this.rmMarkD();
970 +               if(this.rmdoRec) {this.rmRecur(); }
971 +               this.rmScrollTo(this.RMlast.stD);
972 +               //tap handlers
973 +               this.calTapHandler = this.handleCalTap.bind(this);
974 +               this.calHoldHandler = this.handleCalHold.bind(this);
975 +               Mojo.Event.listen(this.left0, Mojo.Event.tap, this.calTapHandler);
976 +               Mojo.Event.listen(this.left1, Mojo.Event.tap, this.calTapHandler);
977 +               Mojo.Event.listen(this.left2, Mojo.Event.tap, this.calTapHandler);
978 +               Mojo.Event.listen(this.right0, Mojo.Event.tap, this.calTapHandler);
979 +               Mojo.Event.listen(this.right1, Mojo.Event.tap, this.calTapHandler);
980 +               Mojo.Event.listen(this.right2, Mojo.Event.tap, this.calTapHandler);
981 +               Mojo.Event.listen(this.left0, Mojo.Event.hold, this.calHoldHandler);
982 +               Mojo.Event.listen(this.left1, Mojo.Event.hold, this.calHoldHandler);
983 +               Mojo.Event.listen(this.left2, Mojo.Event.hold, this.calHoldHandler);
984 +               Mojo.Event.listen(this.right0, Mojo.Event.hold, this.calHoldHandler);
985 +               Mojo.Event.listen(this.right1, Mojo.Event.hold, this.calHoldHandler);
986 +               Mojo.Event.listen(this.right2, Mojo.Event.hold, this.calHoldHandler);
987 +               },
988      
989      deactivate: function(){
990 -        //Mojo.Log.info("datetime-assistant:deactivate");      
991 -        this.controller.stopListening(this.controller.document, Mojo.Event.deactivate, this.blurStage);
992 -    },
993 +               Mojo.Event.stopListening(this.popCanvasBtn, Mojo.Event.tap, this.canvasBtnHandler);
994 +               Mojo.Event.stopListening(this.popCanvasBtn, Mojo.Event.tap, this.canvasBtnHandler);
995 +               //Mojo.Log.info("datetime-assistant:deactivate");       
996 +               this.controller.stopListening(this.controller.document, Mojo.Event.deactivate, this.blurStage);
997 +               Mojo.Event.stopListening(this.left0, Mojo.Event.tap, this.calTapHandler);
998 +               Mojo.Event.stopListening(this.left1, Mojo.Event.tap, this.calTapHandler);
999 +               Mojo.Event.stopListening(this.left2, Mojo.Event.tap, this.calTapHandler);
1000 +               Mojo.Event.stopListening(this.right0, Mojo.Event.tap, this.calTapHandler);
1001 +               Mojo.Event.stopListening(this.right1, Mojo.Event.tap, this.calTapHandler);
1002 +               Mojo.Event.stopListening(this.right2, Mojo.Event.tap, this.calTapHandler);
1003 +               Mojo.Event.stopListening(this.left0, Mojo.Event.hold, this.calHoldHandler);
1004 +               Mojo.Event.stopListening(this.left1, Mojo.Event.hold, this.calHoldHandler);
1005 +               Mojo.Event.stopListening(this.left2, Mojo.Event.hold, this.calHoldHandler);
1006 +               Mojo.Event.stopListening(this.right0, Mojo.Event.hold, this.calHoldHandler);
1007 +               Mojo.Event.stopListening(this.right1, Mojo.Event.hold, this.calHoldHandler);
1008 +               Mojo.Event.stopListening(this.right2, Mojo.Event.hold, this.calHoldHandler);
1009 +       },
1010         
1011         //When the start date of the event is changed, WEEKLY:single day, WEEKLY:custom, MONTHLY repeating events 
1012         //must update their rruleModel. DAILY, YEARLY, and WEEKLY:weekdays repeating events do not need to be changed.
1013 @@ -553,6 +1274,7 @@ var DatetimeAssistant = Class.create({
1014              this.targetEvent.alldayReservedStartTimestamp = this.targetModifiedTime.start;
1015              this.targetEvent.alldayReservedEndTimestamp = this.targetModifiedTime.end;
1016          }
1017 +               this.rmHandleUpdate();
1018      },
1019      
1020      endDateSet: function(isOnBack){
1021 @@ -642,8 +1364,10 @@ var DatetimeAssistant = Class.create({
1022                                 }
1023              }
1024              
1025 -            if (isOnBack == false) 
1026 +            if (isOnBack == false) {
1027                  this.calcDuration();
1028 +                               this.rmHandleUpdate();
1029 +                       }
1030              this.targetModifiedTime.changed = true;
1031              if (this.datetimeoutID) {
1032                  this.controller.window.clearTimeout(this.datetimeoutID);
1033 @@ -751,6 +1475,7 @@ var DatetimeAssistant = Class.create({
1034          this.controller.modelChanged(this.startTimeModel);
1035          this.controller.modelChanged(this.endTimeModel);
1036          this.targetModifiedTime.changed = false;
1037 +               this.rmHandleUpdate();
1038          //Mojo.Log.info("Old event all day %o, new Event all day %o",this.oldEvent.allDay,this.allDayCheckboxModel);
1039          if (this.oldEvent.allDay != this.allDayCheckboxModel.value) {
1040          
1041 @@ -761,6 +1486,85 @@ var DatetimeAssistant = Class.create({
1042          this.targetCallBack(this.targetEvent, null);
1043          
1044      },
1045 -
1046 +       
1047 +       //Calendar Tap Handlers
1048 +       handleCalHold: function(event) {
1049 +               // set the hold var, send to tap handler
1050 +               this.rmcalHold = true;
1051 +               this.handleCalTap(event);
1052 +       },
1053 +       
1054 +       handleCalTap: function(event) {
1055 +               Event.stop(event);
1056 +               var x = event.down.offsetX;
1057 +               var y = event.down.offsetY;
1058 +               //get rid of tap areas not in calendar day area
1059 +               if(x <= 30 || y <= 40 || x>= 241) {
1060 +                       this.rmcalHold = false;
1061 +                       return;
1062 +               }
1063 +               var rmcan = event.target.id;
1064 +               switch (rmcan) {
1065 +                       case 'left0':
1066 +                               var rmindex = 0;
1067 +                               break;
1068 +                       case 'left1':
1069 +                               var rmindex = 1;
1070 +                               break;
1071 +                       case 'left2':
1072 +                               var rmindex = 2;
1073 +                               break;
1074 +                       case 'right0':
1075 +                               var rmindex = 3;
1076 +                               break;
1077 +                       case 'right1':
1078 +                               var rmindex = 4;
1079 +                               break;
1080 +                       case 'right2':
1081 +                               var rmindex = 5;
1082 +                               break;
1083 +               }
1084 +               // get first day index month year
1085 +               if (x && y && (rmindex !== undefined)) {
1086 +                       var calx = x - 30;
1087 +                       var caly = y - 40;
1088 +                       var cald1idx = this.RM[rmindex].fstDayLidx;
1089 +                       var calcol = Math.floor(calx/this.colHW);
1090 +                       var calrow = Math.floor(caly/this.colHW);
1091 +                       var caldate = ((calrow * 7) + calcol +1) - cald1idx;
1092 +                       if((caldate > this.RM[rmindex].maxdays) || (caldate <= 0)) {
1093 +                               // tapped an area with invalid date
1094 +                               this.rmcalHold = false;
1095 +                               return;
1096 +                       }
1097 +                       var calmon = this.RM[rmindex].month;
1098 +                       var calyear = this.RM[rmindex].year;
1099 +                       if((calyear !== undefined) && (calmon !== undefined) && (caldate !== undefined)) {
1100 +                               if(this.rmlastBtn != null && this.rmlastBtn == "popCanvasBtn2") {
1101 +                                       // start date
1102 +                                       this.startDateModel.date = new Date(calyear, calmon, caldate);
1103 +                                       this.controller.modelChanged(this.startDateModel);
1104 +                                       Mojo.Event.send(this.controller.get('edit_startDate'), 'mojo-property-change', {value: this.startDateModel.date} )
1105 +                               } else if(this.rmlastBtn !== null && this.rmlastBtn == "popCanvasBtn") {
1106 +                                       // end date
1107 +                                       this.endDateModel.date = new Date(calyear, calmon, caldate);
1108 +                                       this.controller.modelChanged(this.endDateModel);
1109 +                                       Mojo.Event.send(this.controller.get('edit_endDate'), 'mojo-property-change', {value: this.endDateModel.date} )
1110 +                               }
1111 +                               // check whether drawer should close
1112 +                               if(this.rmcalHold == false) {
1113 +                                       this.ldrawer.mojo.setOpenState(false);
1114 +                                       this.rmlastBtn = null;
1115 +                                       if(!this.targetEvent.allDay) {
1116 +                                               this.slideDown(this.controller.get('start_time_row'), 0.4);             
1117 +                                               this.slideDown(this.controller.get('end_time_row'), 0.4);
1118 +                                       }
1119 +                               } else {
1120 +                                       this.rmcalHold = false;
1121 +                                       return;
1122 +                               }
1123 +                       }
1124 +               }
1125 +       },
1126  
1127  });
1128 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/day-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/day-assistant.js
1129 index 84263c0..4381545 100644
1130 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/day-assistant.js
1131 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/day-assistant.js
1132 @@ -11,8 +11,8 @@ var DayAssistant = Class.create({
1133                 this.appMenuModel = { visible:true, 
1134                                                                         label:$L('Calendar'), 
1135                                                                         items: [ Mojo.Menu.editItem,
1136 -                                                                                       {label:$L('New'), items: [{label:$L('Event'), command:'newtimed', disabled:false},
1137 -                                                                                                                               {label:$L('All day event'), command:'newallday', disabled:false}] 
1138 +                                                                                       {label:$L('New'), items: [{label:$L('Event'), shortcut:'n', command:'newtimed', disabled:false},
1139 +                                                                                                                               {label:$L('All day event'), shortcut:'d', command:'newallday', disabled:false}] 
1140                                                                                                                                                                 
1141                                                                                         },                                                                                      
1142                                                                                         {label:$L('Sync Now'), command:'sync', id: 2},
1143 @@ -20,8 +20,41 @@ var DayAssistant = Class.create({
1144                                                                                         {label:$L('Jump to...'), command:'jumpto', id: 4},
1145                                                                                         {label:$L('Missed reminders...'), command:'reminders', id: 5},
1146                                                                                         {label:$L('Preferences & Accounts'), command:Mojo.Menu.prefsCmd, disabled: false},
1147 +                                                                                       //this.compressedMenuItem = {label:$L('Compressed View'), command:'compressed', chosen: true},
1148                                                                                         {label:$L('Help'), command:Mojo.Menu.helpCmd, disabled:false}]
1149                                                                 };
1150 +
1151 +               this.compressedView = false;
1152 +               this.enhancedView = false;
1153 +               this.weekNumOffset = 0;
1154 +               this.weekModulusNum = 1;
1155 +               this.dayCookie = new Mojo.Model.Cookie('DayEnhanced');
1156 +               if (this.dayCookie !== undefined) {
1157 +                       var daycookie = this.dayCookie.get();
1158 +                       if(daycookie !== undefined) {
1159 +                               if(daycookie.dayviewcompressed !== undefined) {
1160 +                                       this.compressedView = daycookie.dayviewcompressed;
1161 +                               } else {
1162 +                                       this.compressedView = false;
1163 +                               }
1164 +                               if(daycookie.dayviewenhanced !== undefined) {
1165 +                                       this.enhancedView = daycookie.dayviewenhanced;
1166 +                               } else {
1167 +                                       this.enhancedView = false;
1168 +                               }
1169 +                               if(daycookie.weeknumoffset !== undefined) {
1170 +                                       this.weekNumOffset = daycookie.weeknumoffset;
1171 +                               } else {
1172 +                                       this.weekNumOffset = 0;
1173 +                               }
1174 +                               if(daycookie.weekmodulusnum !== undefined) {
1175 +                                       this.weekModulusNum = daycookie.weekmodulusnum;
1176 +                               } else {
1177 +                                       this.weekModulusNum = 1;
1178 +                               }
1179 +                       }
1180 +               }
1181 +
1182                 this.colors = {
1183                                 'cal-color-blue':       {background: 'rgb(145, 211, 234)', border: 'rgb(99, 165, 188)', text: 'rgb(5, 32, 41)'},
1184                                 'cal-color-green':      {background: 'rgb(140, 240, 140)', border: 'rgb(77, 206, 77)',  text: 'rgb(1, 52, 1)'},
1185 @@ -31,7 +64,7 @@ var DayAssistant = Class.create({
1186                                 'cal-color-pink':       {background: 'rgb(245, 156, 188)', border: 'rgb(209, 104, 147)',text: 'rgb(40, 0, 0)'},
1187                                 'cal-color-red':        {background: 'rgb(255, 151, 151)', border: 'rgb(224, 98, 98)',  text: 'rgb(45, 8, 21)'},
1188                                 'cal-color-purple': {background: 'rgb(217, 183, 255)', border: 'rgb(177, 128, 232)',text: 'rgb(38, 22, 56)'},
1189 -                               'cal-color-teal':       {background: 'rgb(114, 223, 210)', border: 'rgb(68, 177, 164)', text: 'rgb(0, 42, 36)'},
1190 +                               'cal-color-teal':       {background: 'rgb(114, 223, 210)', border: 'rgb(68, 177, 164)', text: 'rgb(0, 42, 36)'}
1191                         };
1192                         
1193                 this.PREV_DAY = 1;
1194 @@ -42,7 +75,9 @@ var DayAssistant = Class.create({
1195                 this.pendingCalendarSettingsUpdate = false;
1196                 //this.pendingOpenScratchEventInDetails = false;
1197                 this.snapEffectCount = 0;
1198 -
1199 +               this.imgAlarm = new Image();
1200 +               this.imgAlarm.src = "/media/internal/scrims/ubercalendar/alarm-icon.png";
1201 +               this.imgIcons = new Object();
1202                 
1203                 this.hourHeight = 48;
1204                 this.halfHourHeight = 24;
1205 @@ -211,18 +246,35 @@ var DayAssistant = Class.create({
1206                 
1207         buildDayTitle: function(doScrim) {
1208                 var today = Date.today().clearTime();
1209 +               var year = new Date(this.dayDate).getFullYear();
1210 +               var maxwkn = new Date(year, 11, 31).getISO8601Week();
1211                 var dayDateNoTime = new Date(this.dayDate).clearTime();
1212 +               var weekNumber = new Date(this.dayDate).getISO8601Week();
1213 +               if(this.weekNumOffset !== undefined && this.weekNumOffset !=0) {
1214 +                       var wkNum = parseInt(weekNumber,10) + this.weekNumOffset;
1215 +                       weekNumber = wkNum > maxwkn ? (wkNum - maxwkn) : wkNum;
1216 +                       weekNumber = weekNumber < 10 ? '0' + weekNumber : weekNumber;
1217 +               }
1218 +               if(this.weekModulusNum != undefined && this.weekModulusNum <= 52 && this.weekModulusNum != 1) {
1219 +                       modNumber = (parseInt(weekNumber, 10) % this.weekModulusNum) + 1;
1220 +                       weekNumber = weekNumber + ' (' + modNumber +')';
1221 +               }
1222                 
1223                 if (dayDateNoTime.compareTo(today) == 0) {
1224 -                       var template = new Template($L("#{todayStr}, #{dateStr}"));
1225 +                       var template = new Template($L("#{todayStr}, #{dateStr}") + ", W#{weekStr}");
1226                         var todayStr= Mojo.Format.formatRelativeDate(today, {date: "short"}).capitalize();
1227                         
1228                         var templateModel = {};
1229                         templateModel.todayStr = todayStr;
1230 +                       templateModel.weekStr = weekNumber;
1231                         templateModel.dateStr = Mojo.Format.formatDate(this.dayDate, $L("EEE MMM d"));
1232                         this.controller.get('dv_title').update(template.evaluate(templateModel)); // Localize this date format string
1233                 } else {
1234 -                       this.controller.get('dv_title').update(Mojo.Format.formatDate(this.dayDate, $L("EEE MMM d, yyyy"))); // Localize this date format string
1235 +                       var template = new Template($L("#{dateStr}") + ", W#{weekStr}");
1236 +                       var templateModel = {};
1237 +                       templateModel.weekStr = weekNumber;
1238 +                       templateModel.dateStr = Mojo.Format.formatDate(this.dayDate, $L("EEE MMM d, yyyy"));
1239 +                       this.controller.get('dv_title').update(template.evaluate(templateModel)); // Localize this date format string
1240                 }
1241                 
1242                 if (doScrim) {
1243 @@ -504,7 +556,7 @@ var DayAssistant = Class.create({
1244                 return {left: left, top: top, width: width, height: height};
1245         },
1246  
1247 -               chopText:function(buf1,maxWidth,context){
1248 +       chopText:function(buf1,maxWidth,context){
1249                 var buf2;
1250                 var index=0;
1251                 
1252 @@ -702,6 +754,8 @@ var DayAssistant = Class.create({
1253                 //Mojo.Log.info("day-assistant: renderEvent");
1254                 if (this.animating && !event.animatible)
1255                         return;
1256 +
1257 +//Mojo.Log.error(Object.toJSON(event));
1258         
1259                 var ctx = this.divs[whichDay].ctxEvents;
1260                 var marginLeft = 28;
1261 @@ -743,7 +797,15 @@ var DayAssistant = Class.create({
1262                 ctx.fillRect(left+1, top+height-3, width-2, 1);
1263                 
1264                 var textTop = top + 30;
1265 -               
1266 +
1267 +               // get more details
1268 +               if (!event.subject && event.gotFullDetails === undefined) {
1269 +                       // get more infos for this event
1270 +                       getCalendarService().getEvent(event.id,
1271 +                               this.getEventDetails.bind(this, whichDay, event, selected, ghost),
1272 +                               function(response) {Mojo.Log.error(response.errorText);},
1273 +                               this.controller);
1274 +               }
1275                 // Subject
1276                 ctx.fillStyle = this.colors[event.calendarColor].text;
1277                 if (selected)
1278 @@ -753,8 +815,27 @@ var DayAssistant = Class.create({
1279                 var subjectTop = top+15;
1280                 if (bottom >= (top + height))
1281                         subjectTop = top+17;    // no room for location or note, therefore vertically center subject text
1282 -               this.fillText(event.subject, ctx, left+4, subjectTop, width, bottom, 15 /*line height*/);       
1283 -               
1284 +               this.fillText(event.subject, ctx, left+4, subjectTop, width-30, bottom, 15 /*line height*/);    
1285 +
1286 +               // Alarm
1287 +               if ((event.alarm !== undefined) && (event.alarm != "none")) {
1288 +                       try{ ctx.drawImage(this.imgAlarm, left+4+width-18, subjectTop+1, 12, 12); }catch(e) {}
1289 +               }
1290 +               // Icon
1291 +               if (event.note !== undefined) {
1292 +                       try {
1293 +                               var start = event.note.indexOf("ICON=");
1294 +                               if (start > -1) {
1295 +                                       start += 5;
1296 +                                       var end = event.note.indexOf(";");
1297 +                                       if (end > start) {
1298 +                                               var icon = event.note.substring(start, end);
1299 +                                               ctx.drawImage(this.imgIcons[icon], left+4+width-30, subjectTop+12, 12, 12);
1300 +                                       }
1301 +                               }
1302 +                       } catch(e) {}
1303 +               }
1304 +
1305                 // Location
1306                 if (event.location && (event.location.length > 0) && (textTop < (top + height))) {
1307                         ctx.font = "italic bold 14px Prelude";
1308 @@ -769,7 +850,7 @@ var DayAssistant = Class.create({
1309                         bottom = top+height;
1310                         this.fillText(event.note, ctx, left+4, textTop-2, width, bottom-2, 12 /*line height*/);                 
1311                 }
1312 -               
1313 +
1314                 if (ghost) {
1315                         var selectedColor = "rgba(228, 228, 226, 0.85)"
1316                         ctx.fillStyle = selectedColor;
1317 @@ -789,6 +870,13 @@ var DayAssistant = Class.create({
1318                   ctx.fillRect(left, top, width, height);
1319                 }
1320         },
1321 +
1322 +       getEventDetails: function(whichDay, event, selected, ghost, details) {
1323 +               event.alarm = details.alarm;
1324 +               event.note = details.note;
1325 +               event.gotFullDetails = true;
1326 +               this.renderEvent(whichDay, event, selected, ghost);
1327 +       },
1328         
1329         getAllDayDimensions: function(index, event) {
1330                 var marginLeft = 4;
1331 @@ -822,13 +910,41 @@ var DayAssistant = Class.create({
1332                                            dim.top, 
1333                                            dim.width, 
1334                                            this.colors[event.calendarColor].allday.syCenter);
1335 +
1336 +               // get more details
1337 +               if (!event.subject && event.gotFullDetails === undefined) {
1338 +                       // get more infos for this event
1339 +                       getCalendarService().getEvent(event.id,
1340 +                                       this.getAllDayEventDetails.bind(this, whichDay, index, event, selected),
1341 +                                       function(response) {Mojo.Log.error(response.errorText);},
1342 +                                       this.controller);
1343 +               }
1344                 
1345                 // Subject
1346                 ctx.fillStyle = this.colors[event.calendarColor].text;
1347                 if (selected)
1348                         ctx.fillStyle = "rgb(255, 255, 255)";
1349                 ctx.font = "bold 14px Prelude";
1350 -               this.fillText(event.subject, ctx, dim.left+10, dim.top+17, dim.width-10, dim.top+30, 15 /*line height*/);
1351 +               this.fillText(event.subject, ctx, dim.left+10, dim.top+17, dim.width-30, dim.top+30, 15 /*line height*/);
1352 +
1353 +               // Alarm
1354 +               if ((event.alarm !== undefined) && (event.alarm != "none")) {
1355 +                       try{ ctx.drawImage(this.imgAlarm, dim.left+dim.width-18, dim.top+(dim.height-12)/2, 12, 12); }catch(e) {}
1356 +               }
1357 +               // Icon
1358 +               if (event.note !== undefined) {
1359 +                       try {
1360 +                               var start = event.note.indexOf("ICON=");
1361 +                               if (start > -1) {
1362 +                                       start += 5;
1363 +                                       var end = event.note.indexOf(";");
1364 +                                       if (end > start) {
1365 +                                               var icon = event.note.substring(start, end);
1366 +                                               ctx.drawImage(this.imgIcons[icon], dim.left+dim.width-30, dim.top+(dim.height-12)/2, 12, 12);
1367 +                                       }
1368 +                               }
1369 +                       } catch(e) {}
1370 +               }
1371                 
1372                 if (selected) {
1373                         var selectedColor = "rgba(4, 4, 4, 0.5)"
1374 @@ -837,14 +953,39 @@ var DayAssistant = Class.create({
1375                 }
1376         },
1377         
1378 +       getAllDayEventDetails: function(whichDay, index, event, selected, details) {
1379 +               event.alarm = details.alarm;
1380 +               event.note = details.note;
1381 +               event.gotFullDetails = true;
1382 +               this.renderAllDayEvent(whichDay, index, event, selected);
1383 +       },
1384 +
1385         calcEventCompression: function(day) {
1386                 var i;
1387                 
1388                 // Make sure that free times, busy times, and events are sorted by start times
1389 -               day.freeTimes = day.freeTimes.sortBy(function(f) { return f.start_decimal; })
1390 +               //day.freeTimes = day.freeTimes.sortBy(function(f) { return f.start_decimal; })
1391                 day.events = day.events.sortBy(function(e) { return e.start_decimal; })
1392                 day.busyTimes = day.busyTimes.sortBy(function(b) { return b.start_decimal; })
1393  
1394 +               if (this.compressedView && this.enhancedView) {
1395 +                       if (day.events.length == 0) {
1396 +                               day.freeTimes.push({start_decimal: 0, end_decimal: 2400, duration: 2400});
1397 +                       } else {
1398 +                               if (day.events[0].start_decimal > 0) {
1399 +                                       day.freeTimes.push({start_decimal: 0, end_decimal: day.events[0].start_decimal, duration: day.events[0].start_decimal});
1400 +                               }
1401 +                               // sort by end times to get last time
1402 +                               var last = day.events.sortBy(function(f) { return f.end_decimal; });
1403 +                               if (last[last.length-1].end_decimal < 2400) {
1404 +                                       day.freeTimes.push({start_decimal: last[last.length-1].end_decimal, end_decimal: 2400, duration: 2400 - last[last.length-1].end_decimal});
1405 +                               }
1406 +                       }
1407 +               }
1408 +               // Make sure that free times, busy times, and events are sorted by start times
1409 +               day.freeTimes = day.freeTimes.sortBy(function(f) { return f.start_decimal; })
1410 +
1411 +
1412                 day.animationTop = 0;
1413                 
1414                 var compressDelta = 0;
1415 @@ -1556,10 +1697,31 @@ var DayAssistant = Class.create({
1416                 this.dvScratchEventsDiv = this.controller.get('dv_scratch_events');
1417                 this.scratchEventActive = false;
1418                 this.scratchEvent = null;
1419 -               
1420 +               this.copyEvt = null;
1421 +               
1422 +               this.imgIcons.birthday = new Image();
1423 +               this.imgIcons.birthday.src = "/media/internal/scrims/ubercalendar/icon-birthday.png";
1424 +               this.imgIcons.car = new Image();
1425 +               this.imgIcons.car.src = "/media/internal/scrims/ubercalendar/icon-car.png";
1426 +               this.imgIcons.kids = new Image();
1427 +               this.imgIcons.kids.src = "/media/internal/scrims/ubercalendar/icon-kids.png";
1428 +               this.imgIcons.doctor = new Image();
1429 +               this.imgIcons.doctor.src = "/media/internal/scrims/ubercalendar/icon-doctor.png";
1430 +               this.imgIcons.plane = new Image();
1431 +               this.imgIcons.plane.src = "/media/internal/scrims/ubercalendar/icon-plane.png";
1432 +               this.imgIcons.holiday = new Image();
1433 +               this.imgIcons.holiday.src = "/media/internal/scrims/ubercalendar/icon-holiday.png";
1434 +               this.imgIcons.vacation = new Image();
1435 +               this.imgIcons.vacation.src = "/media/internal/scrims/ubercalendar/icon-vacation.png";
1436 +               this.imgIcons.party = new Image();
1437 +               this.imgIcons.party.src = "/media/internal/scrims/ubercalendar/icon-party.png";
1438 +
1439                 // Used to detect Orange key + tap to delete inline events
1440                 this.orangeKeyDown = false;
1441 -       
1442 +               
1443 +               //Used to detect gesture area hold
1444 +               this.metaKeyDown = false;
1445 +               
1446                 this.firstActivated = true;
1447                 
1448                 this.buildViewHeader();
1449 @@ -1824,17 +1986,20 @@ var DayAssistant = Class.create({
1450                 this.menuModel = {
1451                         visible:true,
1452                         items: [
1453 -                                       {},
1454 +                                       {label: $L('Event'), icon: 'new-timed', command: 'newtimed'},
1455                                                 {label:$L('Views'), 
1456                                                 toggleCmd:'day', 
1457                                                 items:[
1458 +                                                       {label:$L('Agenda'), icon: 'menu-agenda', command:'agenda'},
1459                                                         {label:$L('Day'), icon: 'menu-day', command:'day'}, 
1460                                                         {label:$L('Week'), icon: 'menu-week', command:'week'}, 
1461                                                         {label:$L('Month'), icon: 'menu-month', command:'month'}
1462                                          ]},
1463 -                                       {},
1464 +                                       {label: $L('All day event'), icon: 'new-allday', command: 'newallday'},
1465                                         ]};
1466 -                       
1467 +
1468 +               //this.compressedMenuItem.chosen = this.compressedView;
1469 +
1470                 this.controller.setupWidget(Mojo.Menu.commandMenu, undefined, this.menuModel);
1471                 this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems:true}, this.appMenuModel);
1472                 this.remindersUpdated();        // Update missed reminders menu item
1473 @@ -1854,6 +2019,9 @@ var DayAssistant = Class.create({
1474                 this.controller.setupWidget(this.divs[this.PREV_DAY].alldayevents_scroller, undefined, {mode: 'vertical'});
1475                 this.controller.setupWidget(this.divs[this.NEXT_DAY].alldayevents_scroller, undefined, {mode: 'vertical'});
1476  
1477 +               var cookie = new Mojo.Model.Cookie("LastView");
1478 +               cookie.put("day");
1479 +
1480                 this.CalSelectorHandler = this.calSelector.bindAsEventListener(this);
1481                 
1482                 // IMPORTANT: Set up the height of the scrollers.  If this is not done
1483 @@ -2008,6 +2176,7 @@ var DayAssistant = Class.create({
1484                 // Find all the EAS accounts if there are any
1485                 this.easAccountIds = null;
1486                 response.list.each(function(acct){
1487 +//Mojo.Log.error("accid", acct.accountId, Object.toJSON(acct));
1488                         //Mojo.Log.info("acct domain %s", acct.domain);
1489                         if (acct.domain == 'eas') {
1490                                 // Keep track of the list of eas accounts for Sync Accounts button
1491 @@ -2075,11 +2244,11 @@ var DayAssistant = Class.create({
1492                                 this.maybeCommitScratchEvent();
1493                         } else if(event.command =="newtimed"){
1494                                 Event.stop(event);
1495 -                               this.controller.stageController.pushScene('edit', 0, 0, false,this.getCalId()/*calendarId*/,0/*subject*/);
1496 +                               this.controller.stageController.pushScene('edit', 0, 0, false, this.getCalId()/*calendarId*/,0/*subject*/);
1497                                 this.maybeCommitScratchEvent();
1498                         } else if(event.command=="newallday"){
1499                                 Event.stop(event);
1500 -                               this.controller.stageController.pushScene('edit', 0, 0, true,this.getCalId(),0/*subject*/);
1501 +                               this.controller.stageController.pushScene('edit', 0, 0, true, this.getCalId(),0/*subject*/);
1502                                 this.maybeCommitScratchEvent();
1503                         } else if(event.command == Mojo.Menu.helpCmd){
1504                                 this.maybeCommitScratchEvent(true);
1505 @@ -2087,6 +2256,13 @@ var DayAssistant = Class.create({
1506                         } else if (event.command == 'jumpto') {
1507                                 Event.stop(event);
1508                                 this.showJumpTo(); // this may also commit the scratch event
1509 +                       //} else if (event.command == 'compressed') {
1510 +                       //      Event.stop(event);
1511 +                       //      this.compressedView = !this.compressedView;
1512 +                       //      var cookie = new Mojo.Model.Cookie('DayViewCompressed');
1513 +                       //      cookie.put(this.compressedView);
1514 +                       //      this.compressedMenuItem.chosen = this.compressedView;
1515 +                       //      this.controller.modelChanged(this.appMenuModel);
1516                         } else if (event.command == 'reminders') {
1517                                 Event.stop(event);
1518                                 this.maybeCommitScratchEvent();
1519 @@ -2095,15 +2271,27 @@ var DayAssistant = Class.create({
1520                                 Event.stop(event);
1521                                 this.maybeCommitScratchEvent(true);
1522                                 this.syncAllCalendars();
1523 +                       } else if (event.command == 'agenda') {
1524 +                               Event.stop(event);
1525 +                               this.maybeCommitScratchEvent(true);
1526 +                               this.controller.serviceRequest('palm://com.palm.applicationManager', {
1527 +                                       method: 'launch',
1528 +                                       parameters: {
1529 +                                               id: 'com.palm.app.agenda'
1530 +                                       }
1531 +                               });
1532 +                               this.menuModel.items[1].toggleCmd = 'day';
1533 +                               this.controller.modelChanged(this.menuModel, this);
1534                         }                               
1535                 } else if(event.type == Mojo.Event.commandEnable && event.command == Mojo.Menu.prefsCmd) {
1536                         // Enable prefs menuitem for this scene.
1537                         event.stopPropagation();
1538 -               } else if(event.type == Mojo.Event.back){
1539 +               } else if (event.type == Mojo.Event.back) {
1540                         // If there's a scratch event, possibly commit it, and then override default back handling.
1541 -                       if (this.maybeCommitScratchEvent(true)) {
1542 -                               Event.stop(event);
1543 -                       }
1544 +                       event.preventDefault();
1545 +                       event.stopPropagation();
1546 +                       this.maybeCommitScratchEvent(true);
1547 +                       this.handleMonthView();
1548                 }
1549                         
1550         },
1551 @@ -2406,7 +2594,12 @@ var DayAssistant = Class.create({
1552                 if (event.originalEvent.altKey || event.originalEvent.keyCode === 129) {
1553         //Mojo.Log.info("handleKeyUp detected ORANGE key");
1554                         this.orangeKeyDown = false;
1555 -               } 
1556 +               }
1557 +               // getsure area up
1558 +               if (event.originalEvent.metaKey || event.originalEvent.keyCode === 231) {
1559 +               //Mojo.Log.info("handleKeyUp detected gesture up key");
1560 +                       this.metaKeyDown = false;
1561 +               }               
1562         },
1563         
1564         handleKeyDown: function(event) {
1565 @@ -2414,7 +2607,12 @@ var DayAssistant = Class.create({
1566                 if (event.originalEvent.altKey || event.originalEvent.keyCode === 129) {
1567         //Mojo.Log.info("handleKeyDown detected ORANGE key");
1568                         this.orangeKeyDown = true;
1569 -               } 
1570 +               }
1571 +               // getsure area down
1572 +               if (event.originalEvent.metaKey || event.originalEvent.keyCode === 231) {
1573 +       //Mojo.Log.info("handleKeyUp detected gesture key");
1574 +                       this.metaKeyDown = true;
1575 +               }               
1576         },
1577         
1578         updateSceneScrollerSize: function(event) {
1579 @@ -2865,14 +3063,14 @@ var DayAssistant = Class.create({
1580         
1581         handleAllDayTap: function(index, event) {
1582                 this.deletedeventId = undefined;
1583 -               if (this.orangeKeyDown == true) {
1584 +               if (this.metaKeyDown == true) {
1585                         // Confirm with the user they want to delete the event
1586                         this.eventToBeDeleted = event;
1587                         this.allDayEventToBeDeletedIndex = index;
1588                         this.deletedeventId = event.id;
1589 -                       // Reset the orangeKeyDown to handle the case the user lets go
1590 -                       // of the Orange key when the Delete confirmation dialog is up
1591 -                       this.orangeKeyDown = false;
1592 +                       // Reset the metaKeyDown to handle the case the user lets go
1593 +                       // of the meta key when the Delete confirmation dialog is up
1594 +                       this.metaKeyDown = false;
1595                         getCalendarService().getEvent(event.id, this.gotEventInlineDelete.bind(this),this.gotEventInlineDeleteFailed.bind(this), this.controller);
1596                 } else {
1597                         // Show the Event Details for the tapped all day event
1598 @@ -2941,6 +3139,18 @@ var DayAssistant = Class.create({
1599                         getReminderManager().removeReminder(this.deletedeventId);
1600         },
1601         
1602 +       copiedEvent: function(response) {
1603 +               //copied event saved open in edit scene
1604 +               if(this.copyEvt) {
1605 +                       if(response.id == this.copyEvt.id || this.copyEvt.id == undefined || this.copyEvt.id.match(response.id)) {
1606 +                 
1607 +                               // NOTE: Event Ids are strings NOT longs
1608 +                               if (this.copyEvt.id == undefined)       this.copyEvt.id = response.id + "";     // Do NOT Localize
1609 +                               this.controller.stageController.pushScene('edit', this.copyEvt.id, new Date(this.copyEvt.startTimestamp), false, this.copyEvt.calendarId, this.copyEvt.subject, false, this.updatingEventHandler);
1610 +                       }
1611 +               }
1612 +       },
1613 +       
1614         handleEventsTap: function(event, tapEvent) {
1615                 //Mojo.Log.info("day-assistant: handleEventsTap event_being_held " + Object.toJSON(this.event_being_held));
1616                 
1617 @@ -2967,18 +3177,41 @@ var DayAssistant = Class.create({
1618                                 }
1619                         }
1620                 } else {
1621 -                       if (this.orangeKeyDown == true) {
1622 +                       if (this.metaKeyDown == true) {
1623                                 // Confirm with the user they want to delete the event
1624 -                               //Mojo.Log.info("handleEventsTap: Orange key + tap = Delete event " + Object.toJSON(event));
1625 +                               //Mojo.Log.info("handleEventsTap: meta key + tap = Delete event " + Object.toJSON(event));
1626                                 // Retrieve the event from the calendar service so we can figure
1627                                 // out whether it's recurring or not
1628                                 this.eventToBeDeleted = event;
1629                                 this.deletedeventId = event.id;
1630 -                               // Reset the orangeKeyDown to handle the case the user lets go
1631 -                               // of the Orange key when the Delete confirmation dialog is up
1632 -                               this.orangeKeyDown = false;
1633 +                               // Reset the metaKeyDown to handle the case the user lets go
1634 +                               // of the meta key when the Delete confirmation dialog is up
1635 +                               this.metaKeyDown = false;
1636                                 getCalendarService().getEvent(event.id, this.gotEventInlineDelete.bind(this),this.gotEventInlineDeleteFailed.bind(this), this.controller);
1637                         } else {
1638 +                               if (this.orangeKeyDown == true) {
1639 +                                       //create new from old
1640 +                                       var start = new Date();
1641 +                                       start.set({     minute: 0, second: 0, millisecond: 0 });
1642 +                                       var startTS = start.getTime(); //set it up on today's current hour
1643 +                                       var duration = event.end - event.start;
1644 +                                       var endTS = startTS + duration;
1645 +                                       this.orangeKeyDown = false;
1646 +                                       var tfParams = {
1647 +                                                               subject: event.subject,
1648 +                                                               allday: false,
1649 +                                                               location: event.location,
1650 +                                                               startTimestamp: startTS,
1651 +                                                               endTimestamp: endTS,
1652 +                                                               note: event.note
1653 +                                                       };
1654 +                                       this.copyEvt = new CalendarEvent(tfParams);
1655 +                                       this.copyEvt.calendarId = event.calendarId;
1656 +                                       getCalendarService().setEvent(this.copyEvt, 
1657 +                                                                               this.copiedEvent.bind(this),
1658 +                                                                               this.controller,
1659 +                                                                               function(response) {Mojo.Log.error(response.errorText)});
1660 +                               } else {
1661                                 this.controller.stageController.pushScene('edit', 
1662                                                                                                           event.id, 
1663                                                                                                           new Date(event.startTimestamp), 
1664 @@ -2987,6 +3220,7 @@ var DayAssistant = Class.create({
1665                                                                                                           event.subject, 
1666                                                                                                           false, 
1667                                                                                                           this.updatingEventHandler);
1668 +                               }
1669                         }
1670                 }
1671         },
1672 @@ -3182,6 +3416,7 @@ var DayAssistant = Class.create({
1673                         this.event_being_dragged = this.controller.get("dragging_event");
1674                         // Keep track of the initial hit point
1675                         this.dragLastPointY = event.down.y;
1676 +                       this.dragLastPointX = event.down.X;
1677                         Event.stop(event);
1678                         return Mojo.Gesture.CONSUMED_EVENT;
1679                 }
1680 @@ -3197,6 +3432,21 @@ var DayAssistant = Class.create({
1681                 return newTop;
1682         },
1683         
1684 +       // Move the element... NOTE: This assumes that the element is 
1685 +       // positioned absolutely
1686 +       moveElementX: function(element, dx) {
1687 +               var newLeft = parseInt(element.getStyle('left'), 10) + dx;
1688 +               //Mojo.Log.info("day-assistant: moveElement: %s %d",element.id,newTop)
1689 +               
1690 +               element.setStyle({left: newLeft + 'px'});
1691 +               if (newLeft > 100) {
1692 +                       element.setStyle({opacity: 0.5});
1693 +               } else {
1694 +                       element.setStyle({opacity: 1.0});
1695 +               }
1696 +               return newLeft;
1697 +       },
1698 +       
1699         handleEventsDragging: function(event) {
1700                 //Mojo.Log.info("day-assistant handleEventsDragging");
1701                 if (this.event_being_dragged) {
1702 @@ -3213,6 +3463,15 @@ var DayAssistant = Class.create({
1703                                 this.dragLastPointY = pointerY;
1704                         }
1705                 
1706 +                       var pointerX = event.move.x;
1707 +           if (this.dragLastPointX != pointerX) {
1708 +                               // Calculate the delta of the current point and the last point
1709 +                       var newOffsetX = pointerX - this.dragLastPointX;
1710 +                               // Move the element based off of the delta
1711 +                       this.moveElementX(target, newOffsetX);
1712 +                               this.dragLastPointX = pointerX;
1713 +                       }
1714 +               
1715                         return Mojo.Gesture.CONSUMED_EVENT;
1716                 }
1717         },
1718 @@ -3362,31 +3621,43 @@ var DayAssistant = Class.create({
1719                 //Mojo.Log.info("day-assistant handleEventsDragEnd");
1720                 
1721                 if (this.event_being_dragged) {
1722 -                       var itemTop = this.event_being_dragged.positionedOffset().top;
1723 -                       
1724 -                       // Calculate how much "time" the user has moved the event.  When the event is retrieved
1725 -                       // we use this delta to calculate the new start time.  Can not calculate the new start
1726 -                       // time here, because for events that overlap days, this.dragStartHour may not reflect
1727 -                       // the actual start time of the event
1728 -                       this.newTimeDeltaInMinutes = this.ptToHalfHour(itemTop-this.event_being_held.top) * 30;
1729 -                       
1730 -                       // Set these to undefined since we use newTimeDeltaInMinutes to determing the new start time
1731 -                       // in gotEventForUpdateTime
1732 -                       this.newHour = undefined;
1733 -                       this.newMinutes = undefined;
1734 -                       
1735 -                       // Show the event in its new position.  At this point, the CalendarEvent in the
1736 -                       // database hasn't been updated with the new time, but we can move the event
1737 -                       // visually first
1738 -                       this.event_being_held.origDragTop = this.event_being_held.top;
1739 -                       
1740 -                       this.event_being_held.top = itemTop;
1741 -                       this.renderEvent(this.THIS_DAY, this.event_being_held, false);
1742 +                       var itemLeft = this.event_being_dragged.positionedOffset().left;
1743 +                       if (itemLeft > 100) {
1744 +                               this.eventToBeDeleted = this.event_being_held;
1745 +                               this.deletedeventId = this.event_being_held.id;
1746 +                               getCalendarService().getEvent(this.event_being_held.id, this.gotEventInlineDelete.bind(this),this.gotEventInlineDeleteFailed.bind(this), this.controller);
1747 +                               // Reset the dragging state
1748 +                               this.resetEventBeingDragged();
1749  
1750 -                       // Retrieve the event from the calendar service so we can set the new start time
1751 -                       getCalendarService().getEvent(this.event_being_held.id, this.gotEventForUpdateTime.bind(this),this.gotEventFailed.bind(this), this.controller);
1752 -                       
1753 -                       return Mojo.Gesture.CONSUMED_EVENT;
1754 +                               return Mojo.Gesture.CONSUMED_EVENT;
1755 +                       } else {
1756 +                               var itemTop = this.event_being_dragged.positionedOffset().top;
1757 +                               
1758 +                               // Calculate how much "time" the user has moved the event.  When the event is retrieved
1759 +                               // we use this delta to calculate the new start time.  Can not calculate the new start
1760 +                               // time here, because for events that overlap days, this.dragStartHour may not reflect
1761 +                               // the actual start time of the event
1762 +                               this.newTimeDeltaInMinutes = this.ptToHalfHour(itemTop-this.event_being_held.top) * 30;
1763 +                               
1764 +                               // Set these to undefined since we use newTimeDeltaInMinutes to determing the new start time
1765 +                               // in gotEventForUpdateTime
1766 +                               this.newHour = undefined;
1767 +                               this.newMinutes = undefined;
1768 +                               
1769 +                               // Show the event in its new position.  At this point, the CalendarEvent in the
1770 +                               // database hasn't been updated with the new time, but we can move the event
1771 +                               // visually first
1772 +                               this.event_being_held.origDragTop = this.event_being_held.top;
1773 +                               
1774 +                               this.event_being_held.top = itemTop;
1775 +                               this.event_being_held.left = 0;
1776 +                               this.renderEvent(this.THIS_DAY, this.event_being_held, false);
1777 +       
1778 +                               // Retrieve the event from the calendar service so we can set the new start time
1779 +                               getCalendarService().getEvent(this.event_being_held.id, this.gotEventForUpdateTime.bind(this),this.gotEventFailed.bind(this), this.controller);
1780 +                               
1781 +                               return Mojo.Gesture.CONSUMED_EVENT;
1782 +                       }
1783                 }
1784         },
1785         
1786 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/edit-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/edit-assistant.js
1787 index 9ba9c70..1188336 100644
1788 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/edit-assistant.js
1789 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/edit-assistant.js
1790 @@ -8,6 +8,7 @@ var EditAssistant = Class.create({
1791                                                                                                                  {label:$L('Get Directions'), command:'direction', disabled:false}] 
1792                                                                                                                                                                 
1793                                                         },
1794 +                                                       {label:$L('Edit event as new'), command:'editAsNewEvent', disabled:false},
1795                                                         {label:$L('Delete event'), command:'deleteEvent', disabled:false},
1796                                                         {label:$L('Preferences & Accounts'), command:Mojo.Menu.prefsCmd, disabled: true},
1797                                                         {label:$L('Help'), command:Mojo.Menu.helpCmd, disabled:false}]
1798 @@ -297,6 +298,12 @@ var EditAssistant = Class.create({
1799                 
1800                 // Delete event menu item.  Users can delete new and existing events
1801                 if(!this.isReadOnlyEvent)
1802 +                       this.appMenuModel.items[3].disabled = false;   
1803 +               else
1804 +                       this.appMenuModel.items[3].disabled = true; 
1805 +
1806 +               // Edit as new event menu item. Users cannot edit new items as a new item
1807 +               if(this.targetEvent.id > 0)
1808                         this.appMenuModel.items[2].disabled = false;   
1809                 else
1810                         this.appMenuModel.items[2].disabled = true; 
1811 @@ -443,18 +450,68 @@ var EditAssistant = Class.create({
1812                                                  '-PT5M', // Do Not Localize
1813                                                  '-PT10M', //Do not localize
1814                                                  '-PT15M', // Do NOT Localize
1815 +                                                '-PT20M', // Do NOT Localize
1816 +                                                '-PT25M', // Do NOT Localize
1817                                                  '-PT30M', // Do NOT Localize
1818 +                                                '-PT35M', // Do NOT Localize
1819 +                                                '-PT45M', // Do NOT Localize
1820                                                  '-PT1H', // Do NOT Localize
1821 -                                                '-P1D' // Do NOT Localize
1822 +                                                '-PT90M', // Do NOT Localize
1823 +                                                '-PT2H', // Do NOT Localize
1824 +                                                '-PT150M', // Do NOT Localize
1825 +                                                '-PT3H', // Do NOT Localize
1826 +                                                '-PT220M', // Do NOT Localize
1827 +                                                '-PT4H', // Do NOT Localize
1828 +                                                '-PT5H', // Do NOT Localize
1829 +                                                '-PT6H', // Do NOT Localize
1830 +                                                '-PT7H', // Do NOT Localize
1831 +                                                '-PT8H', // Do NOT Localize
1832 +                                                '-PT10H', // Do NOT Localize
1833 +                                                '-PT12H', // Do NOT Localize   
1834 +                                                '-PT23H', // Do NOT Localize
1835 +                                                '-P1D', // Do NOT Localize
1836 +                                               '-P36H', // Do NOT Localize
1837 +                                               '-P2D', // Do NOT Localize
1838 +                                               '-P60H', // Do NOT Localize     
1839 +                                               '-P3D', // Do NOT Localize
1840 +                                               '-P84H', // Do NOT Localize
1841 +                                               '-P4D', // Do NOT Localize
1842 +                                               '-P5D', // Do NOT Localize
1843 +                                               '-P6D', // Do NOT Localize                      
1844 +                                               '-P1W', // Do NOT Localize
1845 +                                               '-P2W', // Do NOT Localize
1846 +                                               '-P3W', // Do NOT Localize
1847 +                                               '-P4W', // Do NOT Localize
1848 +                                               '-P8W', // Do NOT Localize
1849 +                                               '-P12W', // Do NOT Localize
1850 +                                               '-P16W', // Do NOT Localize
1851 +                                               '-P20W', // Do NOT Localize
1852 +                                               '-P24W', // Do NOT Localize
1853 +                                               '-P52W' // Do NOT Localize
1854                                                 ]
1855                                                 },
1856                         alarmsAllday: {
1857                                 list: [ 'none', // Do NOT Localize
1858                                                 '-PT0M',// DO NOT Localize
1859                                                 '-P1D', // Do NOT Localize
1860 +                                               '-P36H', // Do NOT Localize
1861                                                 '-P2D', // Do NOT Localize
1862 +                                               '-P60H', // Do NOT Localize     
1863                                                 '-P3D', // Do NOT Localize
1864 +                                               '-P84H', // Do NOT Localize
1865 +                                               '-P4D', // Do NOT Localize
1866 +                                               '-P5D', // Do NOT Localize
1867 +                                               '-P6D', // Do NOT Localize                      
1868                                                 '-P1W', // Do NOT Localize
1869 +                                               '-P2W', // Do NOT Localize
1870 +                                               '-P3W', // Do NOT Localize
1871 +                                               '-P4W', // Do NOT Localize
1872 +                                               '-P8W', // Do NOT Localize
1873 +                                               '-P12W', // Do NOT Localize
1874 +                                               '-P16W', // Do NOT Localize
1875 +                                               '-P20W', // Do NOT Localize
1876 +                                               '-P24W', // Do NOT Localize
1877 +                                               '-P52W' // Do NOT Localize
1878                                          ]
1879                                         }
1880                 };
1881 @@ -512,7 +569,8 @@ var EditAssistant = Class.create({
1882                         modelProperty: 'location',
1883                         hintText: $L('Event location'),
1884                         acceptBack:true,
1885 -                       runTextLinker:true
1886 +                       runTextLinker:true,
1887 +                       multiline: true
1888         
1889                 };
1890                  this.locationmodel = {
1891 @@ -644,6 +702,19 @@ var EditAssistant = Class.create({
1892                 if (this.eventCalendarId) {
1893                         this.updateContentCalendarType(this.eventCalendarId.sub('id',''));
1894                 }
1895 +               if (!this.isReadOnlyEvent) {
1896 +                       this.controller.setupWidget(Mojo.Menu.commandMenu,
1897 +                               this.attrCommand = {
1898 +                                       menuClass: 'fade'
1899 +                               },
1900 +                               this.modelCommand = {
1901 +                                       visible: true,
1902 +                                       items: [
1903 +                                       {icon: "make-vip", command: 'toggle_participantrow'},
1904 +                                       {icon: "delete", command:'deleteEvent'}]
1905 +                               }
1906 +                       );
1907 +               }
1908          },
1909          
1910          setUpWidgetListeners: function(){
1911 @@ -664,22 +735,35 @@ var EditAssistant = Class.create({
1912          },
1913          handleCommand: function(event) {
1914                 if(event.type == Mojo.Event.command) {
1915 -                       if(event.command == 'deleteEvent') {
1916 -                               Event.stop(event);
1917 -                               this.deletedeventId = this.targetEvent.id;
1918 -                               this.handleDelete(event);
1919 -                       } else if (event.command == Mojo.Menu.prefsCmd) {
1920 -                               Event.stop(event);
1921 -                               this.controller.stageController.pushScene('prefs');
1922 -                       }else if(event.command =='copy'){
1923 -                               //@todo
1924 -                       }else if(event.command == Mojo.Menu.helpCmd){
1925 -                               getAppManagerService().launchHelp(this.controller);
1926 -                       } else if(event.command == 'map'){
1927 -                               getAppManagerService().launchMaps(this.controller,this.targetEvent.location,false);
1928 -                       }else if(event.command == 'direction'){
1929 -                               getAppManagerService().launchMaps(this.controller,this.targetEvent.location,true);                                                              
1930 -                       }
1931 +                       try {
1932 +                               if(event.command == 'deleteEvent') {
1933 +                                       Event.stop(event);
1934 +                                       this.deletedeventId = this.targetEvent.id;
1935 +                                       this.handleDelete(event);
1936 +                               } else if (event.command == Mojo.Menu.prefsCmd) {
1937 +                                       Event.stop(event);
1938 +                                       this.controller.stageController.pushScene('prefs');
1939 +                               }else if(event.command =='editAsNewEvent'){
1940 +                                       Event.stop(event);
1941 +                                       this.targetEvent = Object.clone(this.targetEvent);
1942 +                                       this.targetId = 0;
1943 +                                       delete this.targetEvent.id;
1944 +                                       this.targetEvent.parentId = 0;
1945 +       
1946 +                                       this.renderEvent(this.targetEvent);
1947 +                                       this.edit_infoHandler();
1948 +                               }else if(event.command =='copy'){
1949 +                                       //@todo
1950 +                               }else if(event.command == Mojo.Menu.helpCmd){
1951 +                                       getAppManagerService().launchHelp(this.controller);
1952 +                               } else if(event.command == 'map'){
1953 +                                       getAppManagerService().launchMaps(this.controller,this.targetEvent.location,false);
1954 +                               }else if(event.command == 'direction'){
1955 +                                       getAppManagerService().launchMaps(this.controller,this.targetEvent.location,true);                                                              
1956 +                               }else if(event.command == 'toggle_participantrow'){
1957 +                                       this.controller.get('edit_participantrow').toggle();
1958 +                               }
1959 +                       } catch (e) {}
1960                 }
1961                 else if(event.type == Mojo.Event.commandEnable && event.command == Mojo.Menu.prefsCmd) {
1962                         // Enable prefs menuitem for this scene.
1963 @@ -1100,7 +1184,7 @@ var EditAssistant = Class.create({
1964  
1965         alarmChoose: function(val) {
1966                 
1967 -               var value = parseInt(val);
1968 +               var value = parseInt(val, 10);
1969                 this.selectedAlarmOption = value;
1970                 if (val != undefined) {
1971                         if (value == 999) {
1972 diff --git a/usr/palm/applications/com.palm.app.calendar/app/controllers/month-assistant.js b/usr/palm/applications/com.palm.app.calendar/app/controllers/month-assistant.js
1973 index 747fcb3..11060b4 100644
1974 --- a/usr/palm/applications/com.palm.app.calendar/app/controllers/month-assistant.js
1975 +++ b/usr/palm/applications/com.palm.app.calendar/app/controllers/month-assistant.js
1976 @@ -5,29 +5,91 @@ var MONTH_DAY_ID_FORMAT = 'MMMM dd yyyy';     // IMPORTANT: DO NOT LOCALIZE!
1977  var MonthAssistant = Class.create({
1978                                 
1979         reminderMenuItemId: 3,
1980 +       //fullEvts: null,
1981 +        
1982         
1983         initialize: function() {
1984                 this.appMenuModel = { visible:true, 
1985                                         label:$L('Calendar'), 
1986                                         items: [
1987                                                 Mojo.Menu.editItem,
1988 +                                               {label:$L('New'), items: [{label:$L('Event'), shortcut:'n', command:'newtimed', disabled:false},
1989 +                                                                                       {label:$L('All day event'), shortcut:'d', command:'newallday', disabled:false}] 
1990 +                                               },
1991                                                 {label:$L('Sync Now'), command:'sync', id: 0},
1992                                                 {label:$L('Show today'), command:'today', id: 1},
1993                                                 {label:$L('Jump to...'), command:'jumpto', id: 2},
1994                                                 {label:$L('Missed reminders...'), command:'reminders', id: 3},
1995                                                 {label:$L('Preferences & Accounts'), command:Mojo.Menu.prefsCmd, checkEnabled: true},
1996 +                                               //this.enhancedMenuItem = {label:$L('Enhanced View'), command:'enhanced', chosen: true},
1997                                                 {label:$L('Help'), command:Mojo.Menu.helpCmd, disabled:false}
1998                                         ]
1999                                 };
2000                                 
2001                 this.scrollerModel = { scrollbars: false, mode: "vertical-snap", snapIndex: 0, snapElements: { y: [] } };
2002 +               this.enhancedView = false;
2003 +               this.monthAllDayColors = false;
2004 +               this.updateFromScroll = false;
2005 +               this.weekNumOffset = 0;
2006 +               this.weekModulusNum = 1;
2007 +               this.monthCookie = new Mojo.Model.Cookie('MonthViewEnhanced');
2008 +               if (this.monthCookie) {
2009 +                       var monthcookie = this.monthCookie.get();
2010 +                       if(monthcookie) {
2011 +                               if(monthcookie.monthalldaycolors !== undefined) {
2012 +                                       this.monthAllDayColors = monthcookie.monthalldaycolors;
2013 +                               } else {
2014 +                                       this.monthAllDayColors = false;
2015 +                               }
2016 +                               if(monthcookie.monthviewenhanced !== undefined) {
2017 +                                       this.enhancedView = monthcookie.monthviewenhanced;
2018 +                               } else {
2019 +                                       this.enhancedView = false;
2020 +                               }
2021 +                               if(monthcookie.weeknumoffset !== undefined) {
2022 +                                               this.weekNumOffset = monthcookie.weeknumoffset;
2023 +                               } else {
2024 +                                               this.weekNumOffset = 0;
2025 +                               }
2026 +                               if(monthcookie.weekmodulusnum !== undefined) {
2027 +&nbs