]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/SchedulerUI.js
initial sync
[scalable-opengroupware.org] / UI / WebServerResources / SchedulerUI.js
1 var sortOrder = '';
2 var sortKey = '';
3 var listFilter = 'view_today';
4
5 var listOfSelection = null;
6
7 var hideCompletedTasks = 0;
8
9 var currentDay = '';
10 var currentView = "dayview";
11
12 var cachedDateSelectors = new Array();
13
14 var contactSelectorAction = 'calendars-contacts';
15
16 var eventsToDelete = new Array();
17 var ownersOfEventsToDelete = new Array();
18
19 function newEvent(sender, type) {
20   var day = sender.getAttribute("day");
21   if (!day)
22     day = currentDay;
23
24   var hour = sender.getAttribute("hour");
25   var urlstr = ApplicationBaseURL + "new" + type;
26   var params = new Array();
27   if (day)
28     params.push("day=" + day);
29   if (hour)
30     params.push("hm=" + hour);
31   if (params.length > 0)
32     urlstr += "?" + params.join("&");
33
34   window.open(urlstr, "", "width=620,height=600,resizable=0");
35
36   return false; /* stop following the link */
37 }
38
39 function _editEventId(id, owner) {
40   var urlBase;
41   if (owner)
42     urlBase = UserFolderURL + "../" + owner + "/";
43   urlBase += "Calendar/"
44
45   var urlstr = urlBase + id + "/edit";
46
47   var win = window.open(urlstr, "SOGo_edit_" + id,
48                         "width=620,height=600,resizable=0,scrollbars=0,toolbar=0," +
49                         "location=0,directories=0,status=0,menubar=0,copyhistory=0");
50   win.focus();
51 }
52
53 function editEvent() {
54   if (listOfSelection) {
55     var nodes = listOfSelection.getSelectedRows();
56
57     for (var i = 0; i < nodes.length; i++)
58       _editEventId(nodes[i].getAttribute("id"),
59                    nodes[i].getAttribute("owner"));
60   }
61
62   return false; /* stop following the link */
63 }
64
65 function _batchDeleteEvents() {
66   var events = eventsToDelete.shift();
67   var owner = ownersOfEventsToDelete.shift();
68   var urlstr = (UserFolderURL + "../" + owner + "/Calendar/batchDelete?ids="
69                 + events.join('/'));
70   document.deleteEventAjaxRequest = triggerAjaxRequest(urlstr,
71                                                        deleteEventCallback,
72                                                        events);
73 }
74
75 function deleteEvent()
76 {
77   if (listOfSelection) {
78     var nodes = listOfSelection.getSelectedRows();
79
80     if (nodes.length > 0) {
81       var label = "";
82       if (listOfSelection == $("tasksList"))
83         label = labels["taskDeleteConfirmation"].decodeEntities();
84       else
85         label = labels["appointmentDeleteConfirmation"].decodeEntities();
86       
87       if (confirm(label)) {
88         if (document.deleteEventAjaxRequest) {
89           document.deleteEventAjaxRequest.aborted = true;
90           document.deleteEventAjaxRequest.abort();
91         }
92         var sortedNodes = new Array();
93         var owners = new Array();
94
95         for (var i = 0; i < nodes.length; i++) {
96           var owner = nodes[i].getAttribute("owner");
97           if (!sortedNodes[owner]) {
98               sortedNodes[owner] = new Array();
99               owners.push(owner);
100           }
101           sortedNodes[owner].push(nodes[i].getAttribute("id"));
102         }
103         for (var i = 0; i < owners.length; i++) {
104           ownersOfEventsToDelete.push(owners[i]);
105           eventsToDelete.push(sortedNodes[owners[i]]);
106         }
107         _batchDeleteEvents();
108       }
109     }
110   }
111   else
112     window.alert("no selection");
113
114   return false;
115 }
116
117 function modifyEvent(sender, modification) {
118   var currentLocation = '' + window.location;
119   var arr = currentLocation.split("/");
120   arr[arr.length-1] = modification;
121
122   document.modifyEventAjaxRequest = triggerAjaxRequest(arr.join("/"),
123                                                        modifyEventCallback,
124                                                        modification);
125
126   return false;
127 }
128
129 function modifyEventCallback(http) {
130   if (http.readyState == 4) {
131     if (http.status == 200) {
132       log("closing window...?");
133       window.close();
134     }
135     else {
136       log("showing alert...");
137       window.alert(labels["eventPartStatModificationError"]);
138     }
139     document.modifyEventAjaxRequest = null;
140   }
141 }
142
143 function deleteEventCallback(http)
144 {
145   if (http.readyState == 4
146       && http.status == 200) {
147     var nodes = $(http.callbackData);
148     for (var i = 0; i < nodes.length; i++) {
149       var node = $(nodes[i]);
150       node.parentNode.removeChild(node);
151     }
152     if (eventsToDelete.length)
153       _batchDeleteEvents();
154     else {
155       document.deleteEventAjaxRequest = null;
156       refreshAppointments();
157       refreshTasks();
158       changeCalendarDisplay();
159     }
160   }
161   else
162     log ("ajax fuckage");
163 }
164
165 function editDoubleClickedEvent(node)
166 {
167   _editEventId(node.getAttribute("id"),
168                node.getAttribute("owner"));
169   
170   return false;
171 }
172
173 function onSelectAll() {
174   var list = $("appointmentsList");
175   list.selectRowsMatchingClass("appointmentRow");
176
177   return false;
178 }
179
180 function displayAppointment(event) {
181   _editEventId(this.getAttribute("aptCName"),
182                this.getAttribute("owner"));
183
184   event.preventDefault();
185   event.stopPropagation();
186   event.cancelBubble = true;
187   event.returnValue = false;
188 }
189
190 function onDaySelect(node)
191 {
192   var day = node.getAttribute("day");
193   var needRefresh = (listFilter == 'view_selectedday'
194                      && day != currentDay);
195
196   var td = node.getParentWithTagName("td");
197   var table = td.getParentWithTagName("table");
198
199 //   log ("table.selected: " + table.selected);
200
201   if (document.selectedDate)
202     document.selectedDate.deselect();
203
204   td.select();
205   document.selectedDate = td;
206
207   changeCalendarDisplay( { "day": day } );
208   if (needRefresh)
209     refreshAppointments();
210
211   return false;
212 }
213
214 function onDateSelectorGotoMonth(node)
215 {
216   var day = node.getAttribute("date");
217
218   changeDateSelectorDisplay(day, true);
219
220   return false;
221 }
222
223 function onCalendarGotoDay(node)
224 {
225   var day = node.getAttribute("date");
226
227   changeDateSelectorDisplay(day);
228   changeCalendarDisplay( { "day": day } );
229
230   return false;
231 }
232
233 function gotoToday()
234 {
235   changeDateSelectorDisplay('');
236   changeCalendarDisplay();
237
238   return false;
239 }
240
241 function setDateSelectorContent(content)
242 {
243   var div = $("dateSelectorView");
244
245   div.innerHTML = content;
246   if (currentDay.length > 0)
247     restoreCurrentDaySelection(div);
248 }
249
250 function dateSelectorCallback(http)
251 {
252   if (http.readyState == 4
253       && http.status == 200) {
254     document.dateSelectorAjaxRequest = null;
255     var content = http.responseText;
256     setDateSelectorContent(content);
257     cachedDateSelectors[http.callbackData] = content;
258   }
259   else
260     log ("ajax fuckage");
261 }
262
263 function appointmentsListCallback(http)
264 {
265   var div = $("appointmentsListView");
266
267   if (http.readyState == 4
268       && http.status == 200) {
269     document.appointmentsListAjaxRequest = null;
270     div.innerHTML = http.responseText;
271     var params = parseQueryParameters(http.callbackData);
272     sortKey = params["sort"];
273     sortOrder = params["desc"];
274     var list = $("appointmentsList");
275     list.addEventListener("selectionchange",
276                           onAppointmentsSelectionChange, true);
277     configureSortableTableHeaders();
278   }
279   else
280     log ("ajax fuckage");
281 }
282
283 function tasksListCallback(http)
284 {
285   var div = $("tasksListView");
286
287   if (http.readyState == 4
288       && http.status == 200) {
289     document.tasksListAjaxRequest = null;
290     var list = $("tasksList");
291     var scroll = list.scrollTop;
292     div.innerHTML = http.responseText;
293     list = $("tasksList");
294     list.addEventListener("selectionchange",
295                           onTasksSelectionChange, true);
296     list.scrollTop = scroll;
297     if (http.callbackData) {
298       var selectedNodesId = http.callbackData;
299       for (var i = 0; i < selectedNodesId.length; i++)
300         $(selectedNodesId[i]).select();
301     }
302   }
303   else
304     log ("ajax fuckage");
305 }
306
307 function restoreCurrentDaySelection(div)
308 {
309   var elements = div.getElementsByTagName("a");
310   var day = null;
311   var i = 9;
312   while (!day && i < elements.length)
313     {
314       day = elements[i].getAttribute("day");
315       i++;
316     }
317
318   if (day
319       && day.substr(0, 6) == currentDay.substr(0, 6)) {
320       for (i = 0; i < elements.length; i++) {
321         day = elements[i].getAttribute("day");
322         if (day && day == currentDay) {
323           var td = elements[i].getParentWithTagName("td");
324           if (document.selectedDate)
325             document.selectedDate.deselect();
326           td.select();
327           document.selectedDate = td;
328         }
329       }
330     }
331 }
332
333 function changeDateSelectorDisplay(day, keepCurrentDay)
334 {
335   var url = ApplicationBaseURL + "dateselector";
336   if (day)
337     url += "?day=" + day;
338
339   if (day != currentDay) {
340     if (!keepCurrentDay)
341       currentDay = day;
342
343     var month = day.substr(0, 6);
344     if (cachedDateSelectors[month]) {
345 //       log ("restoring cached selector for month: " + month);
346       setDateSelectorContent(cachedDateSelectors[month]);
347     }
348     else {
349 //       log ("loading selector for month: " + month);
350       if (document.dateSelectorAjaxRequest) {
351         document.dateSelectorAjaxRequest.aborted = true;
352         document.dateSelectorAjaxRequest.abort();
353       }
354       document.dateSelectorAjaxRequest
355         = triggerAjaxRequest(url,
356                              dateSelectorCallback,
357                              month);
358     }
359   }
360 }
361
362 function changeCalendarDisplay(time, newView)
363 {
364   var url = ApplicationBaseURL + ((newView) ? newView : currentView);
365
366   var day = null;
367   var hour = null;
368   if (time) {
369     day = time['day'];
370     hour = time['hour'];
371   }
372
373   if (!day)
374     day = currentDay;
375   if (day)
376     url += "?day=" + day;
377
378 //   if (newView)
379 //     log ("switching to view: " + newView);
380 //   log ("changeCalendarDisplay: " + url);
381
382   if (document.dayDisplayAjaxRequest) {
383 //     log ("aborting day ajaxrq");
384     document.dayDisplayAjaxRequest.aborted = true;
385     document.dayDisplayAjaxRequest.abort();
386   }
387   document.dayDisplayAjaxRequest = triggerAjaxRequest(url,
388                                                       calendarDisplayCallback,
389                                                       { "view": newView,
390                                                         "day": day,
391                                                         "hour": hour });
392
393   return false;
394 }
395
396 function _ensureView(view) {
397   if (currentView != view)
398     changeCalendarDisplay(null, view);
399
400   return false;
401 }
402
403 function onDayOverview()
404 {
405   return _ensureView("dayview");
406 }
407
408 function onWeekOverview()
409 {
410   return _ensureView("weekview");
411 }
412
413 function onMonthOverview()
414 {
415   return _ensureView("monthview");
416 }
417
418 function scrollDayView(hour)
419 {
420   log("stest1");
421   var rowNumber;
422   if (hour) {
423     if (hour.length == 3)
424       rowNumber = parseInt(hour.substr(0, 1));
425     else {
426       if (hour.substr(0, 1) == "0")
427         rowNumber = parseInt(hour.substr(1, 1));
428       else
429         rowNumber = parseInt(hour.substr(0, 2));
430     }
431   } else
432     rowNumber = 8;
433
434   var daysView = $("daysView");
435   var hours = daysView.childNodesWithTag("div")[0].childNodesWithTag("div");
436   if (hours.length > 0)
437     daysView.parentNode.scrollTop = hours[rowNumber + 1].offsetTop;
438
439   log("stest2");
440 }
441
442 function onClickableCellsDblClick(event) {
443   newEvent(this, 'event');
444
445   event.cancelBubble = true;
446   event.returnValue = false;
447 }
448
449 function calendarDisplayCallback(http)
450 {
451   var div = $("calendarView");
452
453 //   log ("calendardisplaycallback: " + div);
454   if (http.readyState == 4
455       && http.status == 200) {
456     document.dateSelectorAjaxRequest = null;
457     div.innerHTML = http.responseText;
458     if (http.callbackData["view"])
459       currentView = http.callbackData["view"];
460     if (http.callbackData["day"])
461       currentDay = http.callbackData["day"];
462     var hour = null;
463     if (http.callbackData["hour"])
464       hour = http.callbackData["hour"];
465     var contentView;
466     if (currentView == "monthview")
467       contentView = $("calendarContent");
468     else {
469       scrollDayView(hour);
470 //       log("cbtest1");
471       contentView = $("daysView");
472     }
473     var appointments = document.getElementsByClassName("appointment", contentView);
474     for (var i = 0; i < appointments.length; i++) {
475       appointments[i].addEventListener("mousedown", listRowMouseDownHandler, true);
476       appointments[i].addEventListener("click", onCalendarSelectAppointment, false);
477       appointments[i].addEventListener("dblclick", displayAppointment, true);
478     }
479     var days = document.getElementsByClassName("day", contentView);
480     if (currentView == "monthview")
481       for (var i = 0; i < days.length; i++) {
482         days[i].addEventListener("click", onCalendarSelectDay, true);
483         days[i].addEventListener("dblclick", onClickableCellsDblClick, false);
484       }
485     else
486       for (var i = 0; i < days.length; i++) {
487         days[i].addEventListener("click", onCalendarSelectDay, false);
488         var clickableCells = document.getElementsByClassName("clickableHourCell",
489                                                              days[i]);
490         for (var j = 0; j < clickableCells.length; j++)
491           clickableCells[j].addEventListener("dblclick",
492                                              onClickableCellsDblClick, false);
493       }
494 //     log("cbtest1");
495   }
496   else
497     log ("ajax fuckage");
498 }
499
500 function assignCalendar(name)
501 {
502   var node = $(name);
503
504   node.calendar = new skycalendar(node);
505   node.calendar.setCalendarPage(ResourcesURL + "/skycalendar.html");
506   var dateFormat = node.getAttribute("dateFormat");
507   if (dateFormat)
508     node.calendar.setDateFormat(dateFormat);
509 }
510
511 function popupCalendar(node)
512 {
513   var nodeId = node.getAttribute("inputId");
514   var input = $(nodeId);
515   input.calendar.popup();
516
517   return false;
518 }
519
520 function onAppointmentContextMenu(event, element)
521 {
522   var topNode = $("appointmentsList");
523 //   log(topNode);
524
525   var menu = $("appointmentsListMenu");
526
527   menu.addEventListener("hideMenu", onAppointmentContextMenuHide, false);
528   onMenuClick(event, "appointmentsListMenu");
529
530   var topNode = $("appointmentsList");
531   var selectedNodes = topNode.getSelectedRows();
532   topNode.menuSelectedRows = selectedNodes;
533   for (var i = 0; i < selectedNodes.length; i++)
534     selectedNodes[i].deselect();
535
536   topNode.menuSelectedEntry = element;
537   element.select();
538 }
539
540 function onAppointmentContextMenuHide(event)
541 {
542   var topNode = $("appointmentsList");
543
544   if (topNode.menuSelectedEntry) {
545     topNode.menuSelectedEntry.deselect();
546     topNode.menuSelectedEntry = null;
547   }
548   if (topNode.menuSelectedRows) {
549     var nodeIds = topNode.menuSelectedRows;
550     for (var i = 0; i < nodeIds.length; i++) {
551       var node = $(nodeIds[i]);
552       node.select();
553     }
554     topNode.menuSelectedRows = null;
555   }
556 }
557
558 function onAppointmentsSelectionChange() {
559   listOfSelection = this;
560   this.removeClassName("_unfocused");
561   $("tasksList").addClassName("_unfocused");
562 }
563
564 function onTasksSelectionChange() {
565   listOfSelection = this;
566   this.removeClassName("_unfocused");
567   $("appointmentsList").addClassName("_unfocused");
568 }
569
570 function _loadAppointmentHref(href) {
571   if (document.appointmentsListAjaxRequest) {
572     document.appointmentsListAjaxRequest.aborted = true;
573     document.appointmentsListAjaxRequest.abort();
574   }
575   var url = ApplicationBaseURL + href;
576   document.appointmentsListAjaxRequest
577     = triggerAjaxRequest(url, appointmentsListCallback, href);
578
579   return false;
580 }
581
582 function _loadTasksHref(href) {
583   if (document.tasksListAjaxRequest) {
584     document.tasksListAjaxRequest.aborted = true;
585     document.tasksListAjaxRequest.abort();
586   }
587   url = ApplicationBaseURL + href;
588
589   var selectedIds = $("tasksList").getSelectedNodesId();
590   document.tasksListAjaxRequest
591     = triggerAjaxRequest(url, tasksListCallback, selectedIds);
592
593   return false;
594 }
595
596 function onHeaderClick(event) {
597 //   log("onHeaderClick: " + this.link);
598   _loadAppointmentHref(this.link);
599
600   event.preventDefault();
601 }
602
603 function refreshAppointments() {
604   return _loadAppointmentHref("aptlist?desc=" + sortOrder
605                               + "&sort=" + sortKey
606                               + "&day=" + currentDay
607                               + "&filterpopup=" + listFilter);
608 }
609
610 function refreshTasks() {
611   return _loadTasksHref("taskslist?hide-completed=" + hideCompletedTasks);
612 }
613
614 function refreshAppointmentsAndDisplay()
615 {
616   refreshAppointments();
617   changeCalendarDisplay();
618 }
619
620 function onListFilterChange() {
621   var node = $("filterpopup");
622
623   listFilter = node.value;
624 //   log ("listFilter = " + listFilter);
625
626   return refreshAppointments();
627 }
628
629 function onAppointmentClick(event)
630 {
631   var node = event.target.getParentWithTagName("tr");
632   var day = node.getAttribute("day");
633   var hour = node.getAttribute("hour");
634
635   changeCalendarDisplay( { "day": day, "hour": hour} );
636   changeDateSelectorDisplay(day);
637
638   return onRowClick(event);
639 }
640
641 function selectMonthInMenu(menu, month)
642 {
643   var entries = menu.childNodes[1].childNodesWithTag("LI");
644   for (i = 0; i < entries.length; i++) {
645     var entry = entries[i];
646     var entryMonth = entry.getAttribute("month");
647     if (entryMonth == month)
648       entry.addClassName("currentMonth");
649     else
650       entry.removeClassName("currentMonth");
651   }
652 }
653
654 function selectYearInMenu(menu, month)
655 {
656   var entries = menu.childNodes[1].childNodes;
657   for (i = 0; i < entries.length; i++) {
658     var entry = entries[i];
659     if (entry instanceof HTMLLIElement) {
660       var entryMonth = entry.innerHTML;
661       if (entryMonth == month)
662         entry.addClassName("currentMonth");
663       else
664         entry.removeClassName("currentMonth");
665     }
666   }
667 }
668
669 function popupMonthMenu(event, menuId)
670 {
671   var node = event.target;
672
673   if (event.button == 0) {
674     event.cancelBubble = true;
675     event.returnValue = false;
676
677     if (document.currentPopupMenu)
678       hideMenu(event, document.currentPopupMenu);
679
680     var popup = $(menuId);
681     var id = node.getAttribute("id");
682     if (id == "monthLabel")
683       selectMonthInMenu(popup, node.getAttribute("month"));
684     else
685       selectYearInMenu(popup, node.innerHTML);
686
687     var diff = (popup.offsetWidth - node.offsetWidth) /2;
688
689     popup.style.top = (node.offsetTop + 95) + "px";
690     popup.style.left = (node.offsetLeft - diff) + "px";
691     popup.style.visibility = "visible";
692
693     bodyOnClick = "" + document.body.getAttribute("onclick");
694     document.body.setAttribute("onclick", "onBodyClick('" + menuId + "');");
695     document.currentPopupMenu = popup;
696   }
697 }
698
699 function onMonthMenuItemClick(node)
700 {
701   var month = '' + node.getAttribute("month");
702   var year = '' + $("yearLabel").innerHTML;
703   
704   changeDateSelectorDisplay(year+month+"01", true);
705
706   return false;
707 }
708
709 function onYearMenuItemClick(node) {
710   var month = '' + $("monthLabel").getAttribute("month");;
711   var year = '' + node.innerHTML;
712
713   changeDateSelectorDisplay(year+month+"01", true);
714
715   return false;
716 }
717
718 function onSearchFormSubmit() {
719   log ("search not implemented");
720
721   return false;
722 }
723
724 function onCalendarSelectAppointment() {
725   var list = $("appointmentsList");
726   list.deselectAll();
727
728   var aptCName = this.getAttribute("aptCName");
729   var row = $(aptCName);
730   if (row) {
731     var div = row.parentNode.parentNode.parentNode;
732     div.scrollTop = row.offsetTop - (div.offsetHeight / 2);
733     row.select();
734   }
735 }
736
737 function onCalendarSelectDay(event) {
738   var day = this.getAttribute("day");
739   var needRefresh = (listFilter == 'view_selectedday'
740                      && day != currentDay);
741
742   if (currentView == 'weekview')
743     changeWeekCalendarDisplayOfSelectedDay(this);
744   else if (currentView == 'monthview')
745     changeMonthCalendarDisplayOfSelectedDay(this);
746   changeDateSelectorDisplay(day);
747
748   if (needRefresh)
749     refreshAppointments();
750 }
751
752 function changeWeekCalendarDisplayOfSelectedDay(node) {
753   var days = document.getElementsByClassName("day", node.parentNode);
754
755   for (var i = 0; i < days.length; i++)
756     if (days[i] != node)
757       days[i].removeClassName("selectedDay");
758
759   node.addClassName("selectedDay");
760 }
761
762 function findMonthCalendarSelectedCell(table) {
763   var tbody = table.tBodies[0];
764   var rows = tbody.rows;
765
766   var i = 1;
767   while (i < rows.length && !table.selectedCell) {
768     var cells = rows[i].cells;
769     var j = 0;
770     while (j < cells.length && !table.selectedCell) {
771       if (cells[j].hasClassName("selectedDay"))
772         table.selectedCell = cells[j];
773       else
774         j++;
775     }
776     i++;
777   }
778 }
779
780 function changeMonthCalendarDisplayOfSelectedDay(node)
781 {
782   var tr = node.parentNode;
783   var table = tr.parentNode.parentNode;
784
785   if (!table.selectedCell)
786     findMonthCalendarSelectedCell(table);
787
788   if (table.selectedCell)
789     table.selectedCell.removeClassName("selectedDay");
790   table.selectedCell = node;
791   node.addClassName("selectedDay");
792 }
793
794 function onHideCompletedTasks(node)
795 {
796   hideCompletedTasks = (node.checked ? 1 : 0);
797
798   return refreshTasks();
799 }
800
801 function updateTaskStatus(node)
802 {
803   var taskId = node.parentNode.getAttribute("id");
804   var taskOwner = node.parentNode.getAttribute("owner");
805   var newStatus = (node.checked ? 1 : 0);
806 //   log ("update task status: " + taskId);
807
808   var http = createHTTPClient();
809
810   url = (UserFolderURL + "../" + taskOwner + "/Calendar/"
811          + taskId + "/changeStatus?status=" + newStatus);
812
813   if (http) {
814 //     log ("url: " + url);
815     // TODO: add parameter to signal that we are only interested in OK
816     http.url = url;
817     http.open("GET", url, false /* not async */);
818     http.send("");
819     if (http.status == 200)
820       refreshTasks();
821   } else
822     log ("no http client?");
823
824   return false;
825 }
826
827 function updateCalendarStatus()
828 {
829   var list = new Array();
830
831   var clist = $("calendarsList");
832   var nodes = clist.childNodesWithTag("ul")[0].childNodesWithTag("li");
833   for (var i = 0; i < nodes.length; i++) {
834     var input = nodes[i].childNodesWithTag("input")[0];
835     if (input.checked)
836       list.push(nodes[i].getAttribute("uid"));
837   }
838
839   if (!list.length) {
840     list.push(nodes[0].getAttribute("uid"));
841     nodes[0].childNodesWithTag("input")[0].checked = true;
842   }
843 //   ApplicationBaseURL = (UserFolderURL + "Groups/_custom_"
844 //                      + list.join(",") + "/Calendar/");
845
846   updateCalendarsList();
847   refreshAppointments();
848   refreshTasks();
849   changeCalendarDisplay();
850
851   return false;
852 }
853
854 function calendarUidsList()
855 {
856   var list = "";
857
858   var nodes = $("uixselector-calendarsList-display").childNodesWithTag("li");
859   for (var i = 0; i < nodes.length; i++) {
860     var currentNode = nodes[i];
861     var input = currentNode.childNodesWithTag("input")[0];
862     if (!input.checked)
863       list += "-";
864     list += currentNode.getAttribute("uid") + ",";
865   }
866
867   return list.substr(0, list.length - 1);
868 }
869
870 // function updateCalendarContacts(contacts)
871 // {
872 //   var list = contacts.split(",");
873
874 //   var clist = $("calendarsList");
875 //   var nodes = clist.childNodes[5].childNodes;
876 //   for (var i = 0; i < nodes.length; i++) {
877 //     var currentNode = nodes[i];
878 //     if (currentNode instanceof HTMLLIElement) {
879 //       var input = currentNode.childNodes[3];
880 //       if (!input.checked)
881 //         list += "-";
882 //       list += currentNode.getAttribute("uid") + ",";
883 //     }
884 //   }
885 // }
886
887 function inhibitMyCalendarEntry()
888 {
889   var clist = $("calendarsList");
890   var nodes = clist.childNodes[5].childNodes;
891   var done = false;
892
893   var i = 0;
894   while (!done && i < nodes.length) {
895     var currentNode = nodes[i];
896     if (currentNode instanceof HTMLLIElement) {
897       var input = currentNode.childNodes[3];
898       if (currentNode.getAttribute("uid") == UserLogin) {
899         done = true;
900 //         currentNode.style.color = "#999;";
901         currentNode.style.fontWeight = "bold;";
902 //         currentNode.setAttribute("onclick", "");
903       }
904     }
905     i++;
906   }
907 }
908
909 function userCalendarEntry(user, color) {
910   var li = document.createElement("li");
911   li.setAttribute("uid", user);
912   li.addEventListener("mousedown", listRowMouseDownHandler, false);
913   li.addEventListener("click", onRowClick, false);
914   var colorBox = document.createElement("span");
915   colorBox.addClassName("colorBox");
916   if (color) {
917     log("color:  " + color);
918     colorBox.style.backgroundColor = color + ";";
919   }
920   li.appendChild(colorBox);
921   var checkBox = document.createElement("input");
922   checkBox.addClassName("checkBox");
923   checkBox.type = "checkbox";
924   checkBox.addEventListener("change", updateCalendarStatus, false);
925   li.appendChild(checkBox);
926   var text = document.createTextNode(" " + user);
927   li.appendChild(text);
928
929   return li;
930 }
931
932 function ensureSelfIfPresent() {
933   var ul = $("uixselector-calendarsList-display");
934   var list = ul.childNodesWithTag("li");
935   var selfEntry = userCalendarEntry(UserLogin, indexColor(0));
936   selfEntry.style.fontWeight = "bold;";
937   if (list.length < 1) {
938     ul.appendChild(selfEntry);
939   } else if (list[0].getAttribute("uid") != UserLogin) {
940     ul.insertBefore(selfEntry, list[0]);
941   }
942 }
943
944 function updateCalendarsList(method)
945 {
946   ensureSelfIfPresent();
947   var url = (ApplicationBaseURL + "updateCalendars?ids="
948              + calendarUidsList());
949   if (document.calendarsListAjaxRequest) {
950     document.calendarsListAjaxRequest.aborted = true;
951     document.calendarsListAjaxRequest.abort();
952   }
953   var http = createHTTPClient();
954   if (http) {
955     http.url = url;
956     http.open("GET", url, false);
957     http.send("");
958
959     if (method == "removal")
960       updateCalendarStatus();
961
962     http = createHTTPClient();
963     http.url = ApplicationBaseURL + "checkRights";
964     http.open("GET", http.url, false /* not async */);
965     http.send("");
966     if (http.status == 200
967         && http.responseText.length > 0) {
968       rights = http.responseText.split(",");
969       var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
970       for (var i = 0; i < list.length; i++) {
971         var input = list[i].childNodesWithTag("input")[0];
972         if (rights[i] == "1") {
973           list[i].removeClassName("denied");
974           input.disabled = false;
975         }
976         else {
977           input.checked = false;
978           input.disabled = true;
979           list[i].addClassName("denied");
980         }
981       }
982     }
983   }
984 }
985
986 function addContact(tag, fullContactName, contactId, contactName, contactEmail)
987 {
988   var uids = $("uixselector-calendarsList-uidList");
989 //   log("addContact");
990   if (contactId)
991     {
992       var re = new RegExp("(^|,)" + contactId + "($|,)");
993
994       if (!re.test(uids.value))
995         {
996           if (uids.value.length > 0)
997             uids.value += ',' + contactId;
998           else
999             uids.value = contactId;
1000           var names = $("uixselector-calendarsList-display");
1001           var listElems = names.childNodesWithTag("li");
1002           var colorDef = indexColor(listElems.length);
1003           names.appendChild(userCalendarEntry(contactId, colorDef));
1004
1005           var styles = document.getElementsByTagName("style");
1006           styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
1007                                   + ' background-color: '
1008                                   + colorDef
1009                                   + ' !important; }');
1010         }
1011     }
1012
1013   return false;
1014 }
1015
1016 function onChangeCalendar(list) {
1017    var form = document.forms.editform;
1018    var urlElems = form.getAttribute("action").split("/");
1019    urlElems[urlElems.length-4]
1020       = list.childNodesWithTag("option")[list.value].innerHTML;
1021    form.setAttribute("action", urlElems.join("/"));
1022 }
1023
1024 function validateBrowseURL(input) {
1025   var button = $("browseURLBtn");
1026
1027   if (input.value.length) {
1028     if (!button.enabled)
1029       enableAnchor(button);
1030   } else if (!button.disabled)
1031     disableAnchor(button);
1032 }
1033
1034 function browseURL(anchor, event) {
1035   if (event.button == 0) {
1036     var input = $("url");
1037     var url = input.value;
1038     if (url.length)
1039       window.open(url, '_blank');
1040   }
1041
1042   return false;
1043 }
1044
1045 function initializeMenus() {
1046   var menus = new Array("monthListMenu", "yearListMenu",
1047                         "appointmentsListMenu", "calendarsMenu", "searchMenu");
1048   initMenusNamed(menus);
1049
1050   $("calendarsList").attachMenu("calendarsMenu");
1051
1052   var accessRightsMenuEntry = $("accessRightsMenuEntry");
1053   accessRightsMenuEntry.addEventListener("mouseup",
1054                                          onAccessRightsMenuEntryMouseUp,
1055                                          false);
1056 }
1057
1058 function onAccessRightsMenuEntryMouseUp(event) {
1059   var folders = $("uixselector-calendarsList-display");
1060   var selected = folders.getSelectedNodes()[0];
1061   var uid = selected.getAttribute("uid");
1062   log("application base url: " + ApplicationBaseURL);
1063   if (uid == UserLogin)
1064     url = ApplicationBaseURL + "acls";
1065   else
1066     url = UserFolderURL + "../" + uid + "/Calendar/acls";
1067
1068   openAclWindow(url, uid);
1069 }
1070
1071 function configureDragHandles() {
1072   var handle = $("verticalDragHandle");
1073   if (handle) {
1074     handle.addInterface(SOGoDragHandlesInterface);
1075     handle.leftBlock=$("leftPanel");
1076     handle.rightBlock=$("rightPanel");
1077   }
1078
1079   handle = $("rightDragHandle");
1080   if (handle) {
1081     handle.addInterface(SOGoDragHandlesInterface);
1082     handle.upperBlock=$("appointmentsListView");
1083     handle.lowerBlock=$("calendarView");
1084   }
1085 }
1086
1087 function initCalendarContactsSelector() {
1088   var selector = $("calendarsList");
1089   inhibitMyCalendarEntry();
1090   updateCalendarStatus();
1091   selector.changeNotification = updateCalendarsList;
1092
1093   var list = $("uixselector-calendarsList-display").childNodesWithTag("li");
1094   for (var i = 0; i < list.length; i++) {
1095     var input = list[i].childNodesWithTag("input")[0];
1096     input.addEventListener("change", updateCalendarStatus, false);
1097   }
1098 }
1099
1100 function initCalendars() {
1101   if (!document.body.hasClassName("popup"))
1102     initCalendarContactsSelector();
1103 }
1104
1105 window.addEventListener("load", initCalendars, false);