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