]> err.no Git - scalable-opengroupware.org/blob - UI/WebServerResources/MailerUI.js
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1261 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / UI / WebServerResources / MailerUI.js
1 /* JavaScript for SOGoMail */
2 var accounts = {};
3 var mailboxTree;
4 var mailAccounts;
5 if (typeof textMailAccounts != 'undefined') {
6   if (textMailAccounts.length > 0)
7     mailAccounts = textMailAccounts.evalJSON(true);
8   else
9     mailAccounts = new Array();
10 }
11
12 var currentMessages = {};
13 var maxCachedMessages = 20;
14 var cachedMessages = new Array();
15 var currentMailbox = null;
16 var currentMailboxType = "";
17
18 var usersRightsWindowHeight = 320;
19 var usersRightsWindowWidth = 400;
20
21 var pageContent;
22
23 var deleteMessageRequestCount = 0;
24
25 var messageCheckTimer;
26
27 /* mail list */
28
29 function openMessageWindow(msguid, url) {
30   var wId = '';
31   if (msguid) {
32     wId += "SOGo_msg_" + msguid;
33     markMailReadInWindow(window, msguid);
34   }
35   var msgWin = openMailComposeWindow(url, wId);
36   msgWin.focus();
37
38   return false;
39 }
40
41 function onMessageDoubleClick(event) {
42   var action;
43
44   if (currentMailboxType == "draft")
45     action = "edit";
46   else
47     action = "popupview";
48
49   return openMessageWindowsForSelection(action, true);
50 }
51
52 function toggleMailSelect(sender) {
53   var row;
54   row = $(sender.name);
55   row.className = sender.checked ? "tableview_selected" : "tableview";
56 }
57
58 function openAddressbook(sender) {
59   var urlstr;
60
61   urlstr = ApplicationBaseURL + "../Contacts/?popup=YES";
62   var w = window.open(urlstr, "Addressbook",
63                       "width=640,height=400,resizable=1,scrollbars=1,toolbar=0,"
64                       + "location=no,directories=0,status=0,menubar=0,copyhistory=0");
65   w.focus();
66
67   return false;
68 }
69
70 function onMenuSharing(event) {
71   var folderID = document.menuTarget.getAttribute("dataname");
72   var type = document.menuTarget.getAttribute("datatype");
73
74   if (type == "additional")
75     window.alert(clabels["The user rights cannot be"
76                          + " edited for this object!"]);
77   else {
78     var urlstr = URLForFolderID(folderID) + "/acls";
79     openAclWindow(urlstr);
80   }
81 }
82
83 /* mail list DOM changes */
84
85 function markMailInWindow(win, msguid, markread) {
86   var row = win.$("row_" + msguid);
87   var subjectCell = win.$("div_" + msguid);
88   if (row && subjectCell) {
89     if (markread) {
90       row.removeClassName("mailer_unreadmail");
91       subjectCell.addClassName("mailer_readmailsubject");
92       var img = win.$("unreaddiv_" + msguid);
93       if (img) {
94         img.removeClassName("mailerUnreadIcon");
95         img.addClassName("mailerReadIcon");
96         img.setAttribute("id", "readdiv_" + msguid);
97         img.setAttribute("src", ResourcesURL + "/icon_read.gif");
98         var title = img.getAttribute("title-markunread");
99         if (title)
100           img.setAttribute("title", title);
101       }
102     }
103     else {
104       row.addClassName("mailer_unreadmail");
105       subjectCell.removeClassName('mailer_readmailsubject');
106       var img = win.$("readdiv_" + msguid);
107       if (img) {
108         img.removeClassName("mailerReadIcon");
109         img.addClassName("mailerUnreadIcon");
110         img.setAttribute("id", "unreaddiv_" + msguid);
111         img.setAttribute("src", ResourcesURL + "/icon_unread.gif");
112         var title = img.getAttribute("title-markread");
113         if (title)
114           img.setAttribute("title", title);
115       }
116     }
117     return true;
118   }
119   else
120     return false;
121 }
122
123 function markMailReadInWindow(win, msguid) {
124   /* this is called by UIxMailView with window.opener */
125   return markMailInWindow(win, msguid, true);
126 }
127
128 /* mail list reply */
129
130 function openMessageWindowsForSelection(action, firstOnly) {
131   if (document.body.hasClassName("popup")) {
132     return true;
133   }
134   else {
135     var messageList = $("messageList");
136     var rows = messageList.getSelectedRowsId();
137     if (rows.length > 0) {
138       for (var i = 0; i < rows.length; i++) {
139         openMessageWindow(rows[i].substr(4),
140                           ApplicationBaseURL + currentMailbox
141                           + "/" + rows[i].substr(4)
142                           + "/" + action);
143         if (firstOnly)
144           break;
145       }
146     } else {
147       window.alert(labels["Please select a message."]);
148     }
149   }
150
151   return false;
152 }
153
154 function mailListMarkMessage(event) {
155   var msguid = this.id.split('_')[1];
156   var action;
157   var markread;
158   if ($(this).hasClassName('mailerUnreadIcon')) {
159     action = 'markMessageRead';
160     markread = true;
161   }
162   else {
163     action = 'markMessageUnread';
164     markread = false;
165   }
166   var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
167
168   var data = { "window": window, "msguid": msguid, "markread": markread };
169   triggerAjaxRequest(url, mailListMarkMessageCallback, data);
170
171   preventDefault(event);
172   return false;
173 }
174
175 function mailListMarkMessageCallback(http) {
176   if (http.readyState == 4)
177     if (isHttpStatus204(http.status)) {
178       var data = http.callbackData;
179       markMailInWindow(data["window"], data["msguid"], data["markread"]);
180     }
181     else {
182       alert("Message Mark Failed (" + http.status + "): " + http.statusText);
183       window.location.reload();
184     }
185 }
186
187 /* maillist row highlight */
188
189 var oldMaillistHighlight = null; // to remember deleted/selected style
190
191 function ml_highlight(sender) {
192   oldMaillistHighlight = sender.className;
193   if (oldMaillistHighlight == "tableview_highlight")
194     oldMaillistHighlight = null;
195   sender.className = "tableview_highlight";
196 }
197
198 function ml_lowlight(sender) {
199   if (oldMaillistHighlight) {
200     sender.className = oldMaillistHighlight;
201     oldMaillistHighlight = null;
202   }
203   else
204     sender.className = "tableview";
205 }
206
207
208 /* bulk delete of messages */
209
210 function deleteSelectedMessages(sender) {
211   var messageList = $("messageList");
212   var rowIds = messageList.getSelectedRowsId();
213
214   for (var i = 0; i < rowIds.length; i++) {
215     var url;
216     var rowId = rowIds[i].substr(4);
217     var messageId = currentMailbox + "/" + rowId;
218     url = ApplicationBaseURL + messageId + "/trash";
219     deleteMessageRequestCount++;
220     var data = { "id": rowId, "mailbox": currentMailbox, "messageId": messageId };
221     triggerAjaxRequest(url, deleteSelectedMessagesCallback, data);
222   }
223
224   return false;
225 }
226
227 function deleteSelectedMessagesCallback(http) {
228   if (http.readyState == 4) {
229     if (isHttpStatus204(http.status)) {
230       var data = http.callbackData;
231       deleteCachedMessage(data["messageId"]);
232       if (currentMailbox == data["mailbox"]) {
233         
234         var div = $('messageContent');
235         if (currentMessages[currentMailbox] == data["id"]) {
236           div.update();
237           currentMessages[currentMailbox] = null;       
238         }
239
240         var row = $("row_" + data["id"]);
241         row.parentNode.removeChild(row);
242 //      row.addClassName("deleted"); // when we'll offer "mark as deleted"
243
244         deleteMessageRequestCount--;
245       }
246     }
247   }
248   else
249     log ("deleteSelectedMessagesCallback: problem during ajax request " + http.status);
250 }
251
252 function deleteDraft(url) {
253   /* this is called by UIxMailEditor with window.opener */
254   new Ajax.Request(url, {
255     method: 'post',
256     onFailure: function(transport) {
257         if (!isHttpStatus204)
258           log("draftDeleteCallback: problem during ajax request: " + transport.status);
259       }
260     });
261 }
262
263 function moveMessages(rowIds, folder) {
264   var failCount = 0;
265
266   for (var i = 0; i < rowIds.length; i++) {
267     var url, http;
268
269     /* send AJAX request (synchronously) */
270           
271     var messageId = currentMailbox + "/" + rowIds[i];
272     url = (ApplicationBaseURL + messageId
273            + "/move?tofolder=" + folder);
274     http = createHTTPClient();
275     http.open("GET", url, false /* not async */);
276     http.send("");
277     if (http.status == 200) {
278       var row = $("row_" + rowIds[i]);
279       row.parentNode.removeChild(row);
280       deleteCachedMessage(messageId);
281       if (currentMessages[currentMailbox] == rowIds[i]) {
282         var div = $('messageContent');
283         div.update();
284         currentMessages[currentMailbox] = null;
285       }
286     }
287     else /* request failed */
288       failCount++;
289
290     /* remove from page */
291
292     /* line-through would be nicer, but hiding is OK too */
293   }
294
295   if (failCount > 0)
296     alert("Could not move " + failCount + " messages!");
297    
298   return failCount;
299 }
300
301 function onMenuDeleteMessage(event) {
302   deleteSelectedMessages();
303   preventDefault(event);
304 }
305
306 function onPrintCurrentMessage(event) {
307   var rowIds = $("messageList").getSelectedRowsId();
308   if (rowIds.length == 0) {
309     window.alert(labels["Please select a message to print."]);
310   }
311   else if (rowIds.length > 1) {
312     window.alert(labels["Please select only one message to print."]);
313   }
314   else
315     window.print();
316
317   preventDefault(event);
318 }
319
320 function onMailboxTreeItemClick(event) {
321   var topNode = $("mailboxTree");
322   var mailbox = this.parentNode.getAttribute("dataname");
323
324   if (topNode.selectedEntry)
325     topNode.selectedEntry.deselect();
326   this.select();
327   topNode.selectedEntry = this;
328
329   search = {};
330   sorting = {};
331   $("searchValue").value = "";
332   initCriteria();
333
334   currentMailboxType = this.parentNode.getAttribute("datatype");
335   if (currentMailboxType == "account" || currentMailboxType == "additional") {
336     currentMailbox = mailbox;
337     $("messageContent").update();
338     var table = $("messageList");
339     var head = table.tHead;
340     var body = table.tBodies[0];
341     for (var i = body.rows.length; i > 0; i--)
342       body.deleteRow(i-1);
343     if (head.rows[1])
344       head.rows[1].firstChild.update();
345   }
346   else
347     openMailbox(mailbox);
348    
349   Event.stop(event);
350 }
351
352 function _onMailboxMenuAction(menuEntry, error, actionName) {
353   var targetMailbox = menuEntry.mailbox.fullName();
354
355   if (targetMailbox == currentMailbox)
356     window.alert(labels[error]);
357   else {
358     var message;
359     if (document.menuTarget.tagName == "DIV")
360       message = currentMessages[currentMailbox];
361     else
362       message = document.menuTarget.getAttribute("id").substr(4);
363
364     var urlstr = (URLForFolderID(currentMailbox) + "/" + message
365                   + "/" + actionName + "?folder=" + targetMailbox);
366     triggerAjaxRequest(urlstr, folderRefreshCallback, currentMailbox);
367   }
368 }
369
370 function onMailboxMenuMove(event) {
371   _onMailboxMenuAction(this,
372                        "Moving a message into its own folder is impossible!",
373                        "move");
374 }
375
376 function onMailboxMenuCopy(event) {
377   _onMailboxMenuAction(this,
378                        "Copying a message into its own folder is impossible!",
379                        "copy");
380 }
381
382 function refreshMailbox() {
383   var topWindow = getTopWindow();
384   if (topWindow)
385     topWindow.refreshCurrentFolder();
386
387   return false;
388 }
389
390 function onComposeMessage() {
391   var topWindow = getTopWindow();
392   if (topWindow)
393     topWindow.composeNewMessage();
394
395   return false;
396 }
397
398 function composeNewMessage() {
399   var account = currentMailbox.split("/")[1];
400   var url = ApplicationBaseURL + "/" + account + "/compose";
401   openMailComposeWindow(url);
402 }
403
404 function openMailbox(mailbox, reload, idx) {
405   if (mailbox != currentMailbox || reload) {
406     currentMailbox = mailbox;
407     var url = ApplicationBaseURL + encodeURI(mailbox) + "/view?noframe=1";
408     var messageContent = $("messageContent");
409     messageContent.update();
410     lastClickedRow = -1; // from generic.js
411
412     var currentMessage;
413     if (!idx) {
414       currentMessage = currentMessages[mailbox];
415       if (currentMessage) {
416         loadMessage(currentMessage);
417         url += '&pageforuid=' + currentMessage;
418       }
419     }
420
421     var searchValue = search["value"];
422     if (searchValue && searchValue.length > 0)
423       url += ("&search=" + search["criteria"]
424               + "&value=" + escape(searchValue));
425     var sortAttribute = sorting["attribute"];
426     if (sortAttribute && sortAttribute.length > 0)
427       url += ("&sort=" + sorting["attribute"]
428               + "&asc=" + sorting["ascending"]);
429     if (idx)
430       url += "&idx=" + idx;
431
432     if (document.messageListAjaxRequest) {
433       document.messageListAjaxRequest.aborted = true;
434       document.messageListAjaxRequest.abort();
435     }
436
437     var mailboxContent = $("mailboxContent");
438     if (mailboxContent.getStyle('visibility') == "hidden") {
439       mailboxContent.setStyle({ visibility: "visible" });
440       var rightDragHandle = $("rightDragHandle");
441       rightDragHandle.setStyle({ visibility: "visible" });
442       messageContent.setStyle({ top: (rightDragHandle.offsetTop
443                                       + rightDragHandle.offsetHeight
444                                       + 'px') });
445     }
446     document.messageListAjaxRequest
447       = triggerAjaxRequest(url, messageListCallback,
448                            currentMessage);
449
450     var quotasUrl = ApplicationBaseURL + mailbox + "/quotas";
451     document.quotasAjaxRequest
452       = triggerAjaxRequest(quotasUrl, quotasCallback);
453   }
454 }
455
456 function openMailboxAtIndex(event) {
457   openMailbox(currentMailbox, true, this.getAttribute("idx"));
458
459   Event.stop(event);
460 }
461
462 function messageListCallback(http) {
463   var div = $('mailboxContent');
464   var table = $('messageList');
465   
466   if (http.readyState == 4
467       && http.status == 200) {
468     document.messageListAjaxRequest = null;    
469
470     if (table) {
471       // Update table
472       var thead = table.tHead;
473       var addressHeaderCell = thead.rows[0].cells[3];
474       var tbody = table.tBodies[0];
475       var tmp = document.createElement('div');
476       $(tmp).update(http.responseText);
477       thead.rows[1].parentNode.replaceChild(tmp.firstChild.tHead.rows[1], thead.rows[1]);
478       addressHeaderCell.replaceChild(tmp.firstChild.tHead.rows[0].cells[3].lastChild, 
479                                      addressHeaderCell.lastChild);
480       table.replaceChild(tmp.firstChild.tBodies[0], tbody);
481     }
482     else {
483       // Add table
484       div.update(http.responseText);
485       table = $('messageList');
486       configureMessageListEvents(table);
487       TableKit.Resizable.init(table, {'trueResize' : true, 'keepWidth' : true});
488     }
489     configureMessageListBodyEvents(table);
490
491     var selected = http.callbackData;
492     if (selected) {
493       var row = $("row_" + selected);
494       if (row) {
495         row.select();
496         lastClickedRow = row.rowIndex - $(row).up('table').down('thead').getElementsByTagName('tr').length;  
497         div.scrollTop = row.rowIndex * row.getHeight(); // scroll to selected message
498       }
499       else
500         $("messageContent").update();
501     }
502     else
503       div.scrollTop = 0;
504     
505     if (sorting["attribute"] && sorting["attribute"].length > 0) {
506       var sortHeader = $(sorting["attribute"] + "Header");
507       
508       if (sortHeader) {
509         var sortImages = $(table.tHead).getElementsByClassName("sortImage");
510         $(sortImages).each(function(item) {
511             item.remove();
512           });
513
514         var sortImage = createElement("img", "messageSortImage", "sortImage");
515         sortHeader.insertBefore(sortImage, sortHeader.firstChild);
516         if (sorting["ascending"])
517           sortImage.src = ResourcesURL + "/title_sortdown_12x12.png";
518         else
519           sortImage.src = ResourcesURL + "/title_sortup_12x12.png";
520       }
521     }
522   }
523   else {
524     var data = http.responseText;
525     var msg = data.replace(/^(.*\n)*.*<p>((.*\n)*.*)<\/p>(.*\n)*.*$/, "$2");
526     log("messageListCallback: problem during ajax request (readyState = " + http.readyState + ", status = " + http.status + ", response = " + msg + ")");
527   }
528 }
529
530 function quotasCallback(http) {
531   if (http.readyState == 4
532       && http.status == 200) {
533     var hasQuotas = false;
534
535     if (http.responseText.length > 0) {
536       var quotas = http.responseText.evalJSON(true);
537       for (var i in quotas) {
538         hasQuotas = true;
539         break;
540       }
541     }
542     
543     if (hasQuotas) {
544       var treePath = currentMailbox.split("/");
545       var quotasMB = new Array();
546       for (var i = 2; i < treePath.length; i++)
547         quotasMB.push(treePath[i].substr(6));
548       var mbQuotas = quotas["/" + quotasMB.join("/")];
549       var used = mbQuotas["usedSpace"];
550       var max = mbQuotas["maxQuota"];
551       var percents = (Math.round(used * 10000 / max) / 100);
552       var format = labels["quotasFormat"];
553       var text = format.formatted(used, max, percents);
554       window.status = text;
555     }
556   }
557 }
558
559 function onMessageContextMenu(event) {
560   var menu = $('messageListMenu');
561   Event.observe(menu, "hideMenu", onMessageContextMenuHide);
562   popupMenu(event, "messageListMenu", this);
563
564   var topNode = $('messageList');
565   var selectedNodes = topNode.getSelectedRows();
566   for (var i = 0; i < selectedNodes.length; i++)
567     selectedNodes[i].deselect();
568   topNode.menuSelectedRows = selectedNodes;
569   topNode.menuSelectedEntry = this;
570   this.select();
571 }
572
573 function onMessageContextMenuHide(event) {
574   var topNode = $('messageList');
575
576   if (topNode.menuSelectedEntry) {
577     topNode.menuSelectedEntry.deselect();
578     topNode.menuSelectedEntry = null;
579   }
580   if (topNode.menuSelectedRows) {
581     var nodes = topNode.menuSelectedRows;
582     for (var i = 0; i < nodes.length; i++)
583       nodes[i].select();
584     topNode.menuSelectedRows = null;
585   }
586 }
587
588 function onFolderMenuClick(event) {
589   var onhide, menuName;
590    
591   var menutype = this.parentNode.getAttribute("datatype");
592   if (menutype) {
593     if (menutype == "inbox") {
594       menuName = "inboxIconMenu";
595     } else if (menutype == "account") {
596       menuName = "accountIconMenu";
597     } else if (menutype == "trash") {
598       menuName = "trashIconMenu";
599     } else {
600       menuName = "mailboxIconMenu";
601     }
602   } else {
603     menuName = "mailboxIconMenu";
604   }
605
606   var menu = $(menuName);
607   Event.observe(menu, "hideMenu", onFolderMenuHide);
608   popupMenu(event, menuName, this.parentNode);
609
610   var topNode = $("mailboxTree");
611   if (topNode.selectedEntry)
612     topNode.selectedEntry.deselect();
613   if (topNode.menuSelectedEntry)
614     topNode.menuSelectedEntry.deselect();
615   topNode.menuSelectedEntry = this;
616   this.select();
617
618   preventDefault(event);
619 }
620
621 function onFolderMenuHide(event) {
622   var topNode = $("mailboxTree");
623
624   if (topNode.menuSelectedEntry) {
625     topNode.menuSelectedEntry.deselect();
626     topNode.menuSelectedEntry = null;
627   }
628   if (topNode.selectedEntry)
629     topNode.selectedEntry.select();
630 }
631
632 function deleteCachedMessage(messageId) {
633   var done = false;
634   var counter = 0;
635
636   while (counter < cachedMessages.length
637          && !done)
638     if (cachedMessages[counter]
639         && cachedMessages[counter]['idx'] == messageId) {
640       cachedMessages.splice(counter, 1);
641       done = true;
642     }
643     else
644       counter++;
645 }
646
647 function getCachedMessage(idx) {
648   var message = null;
649   var counter = 0;
650
651   while (counter < cachedMessages.length
652          && message == null)
653     if (cachedMessages[counter]
654         && cachedMessages[counter]['idx'] == currentMailbox + '/' + idx)
655       message = cachedMessages[counter];
656     else
657       counter++;
658
659   return message;
660 }
661
662 function storeCachedMessage(cachedMessage) {
663   var oldest = -1;
664   var timeOldest = -1;
665   var counter = 0;
666
667   if (cachedMessages.length < maxCachedMessages)
668     oldest = cachedMessages.length;
669   else {
670     while (cachedMessages[counter]) {
671       if (oldest == -1
672           || cachedMessages[counter]['time'] < timeOldest) {
673         oldest = counter;
674         timeOldest = cachedMessages[counter]['time'];
675       }
676       counter++;
677     }
678
679     if (oldest == -1)
680       oldest = 0;
681   }
682
683   cachedMessages[oldest] = cachedMessage;
684 }
685
686 function onMessageSelectionChange() {
687   var rows = this.getSelectedRowsId();
688
689   if (rows.length == 1) {
690     var idx = rows[0].substr(4);
691
692     if (currentMessages[currentMailbox] != idx) {
693       currentMessages[currentMailbox] = idx;
694       loadMessage(idx);
695     }
696   }
697 }
698
699 function loadMessage(idx) {
700   if (document.messageAjaxRequest) {
701     document.messageAjaxRequest.aborted = true;
702     document.messageAjaxRequest.abort();
703   }
704
705   var cachedMessage = getCachedMessage(idx);
706
707   markMailInWindow(window, idx, true);
708   if (cachedMessage == null) {
709     var url = (ApplicationBaseURL + currentMailbox + "/"
710                + idx + "/view?noframe=1");
711     document.messageAjaxRequest
712       = triggerAjaxRequest(url, messageCallback, idx);
713   } else {
714     var div = $('messageContent');
715     div.update(cachedMessage['text']);
716     cachedMessage['time'] = (new Date()).getTime();
717     document.messageAjaxRequest = null;
718     configureLinksInMessage();
719     resizeMailContent();
720   }
721 }
722
723 function configureLinksInMessage() {
724   var messageDiv = $('messageContent');
725   var mailContentDiv = document.getElementsByClassName('mailer_mailcontent',
726                                                        messageDiv)[0];
727   if (!document.body.hasClassName("popup"))
728     Event.observe(mailContentDiv, "contextmenu",
729                   onMessageContentMenu.bindAsEventListener(mailContentDiv));
730   var anchors = messageDiv.getElementsByTagName('a');
731   for (var i = 0; i < anchors.length; i++)
732     if (anchors[i].href.substring(0,7) == "mailto:") {
733       Event.observe(anchors[i], "click",
734                     onEmailAddressClick.bindAsEventListener(anchors[i]));
735       Event.observe(anchors[i], "contextmenu",
736                     onEmailAddressClick.bindAsEventListener(anchors[i]));
737     }
738     else
739       Event.observe(anchors[i], "click",
740                     onMessageAnchorClick.bindAsEventListener(anchors[i]));
741
742   var editDraftButton = $("editDraftButton");
743   if (editDraftButton)
744     Event.observe(editDraftButton, "click",
745                   onMessageEditDraft.bindAsEventListener(editDraftButton));
746
747   configureiCalLinksInMessage();
748 }
749
750 function configureiCalLinksInMessage() {
751   var buttons = { "iCalendarAccept": "accept",
752                   "iCalendarDecline": "decline",
753                   "iCalendarTentative": "tentative",
754                   "iCalendarAddToCalendar": "addToCalendar",
755                   "iCalendarDeleteFromCalendar": "deleteFromCalendar" };
756
757   for (var key in buttons) {
758     var button = $(key);
759     if (button) {
760       button.action = buttons[key];
761       Event.observe(button, "click",
762                     onICalendarButtonClick.bindAsEventListener(button));
763     }
764   }
765 }
766
767 function onICalendarButtonClick(event) {
768   var link = $("iCalendarAttachment").value;
769   if (link) {
770     var urlstr = link + "/" + this.action;
771     triggerAjaxRequest(urlstr, ICalendarButtonCallback,
772                        currentMailbox + "/"
773                        + currentMessages[currentMailbox]);
774     window.alert(urlstr);
775   }
776 }
777
778 function ICalendarButtonCallback(http) {
779   if (http.readyState == 4)
780     if (isHttpStatus204(http.status)) {
781       var oldMsg = http.callbackData;
782       var msg = currentMailbox + "/" + currentMessages[currentMailbox];
783       if (oldMsg == msg) {
784         deleteCachedMessage(oldMsg);
785         loadMessage(currentMessages[currentMailbox]);
786       }
787     }
788 }
789
790 function resizeMailContent() {
791   var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
792   var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
793   
794   contentDiv.setStyle({ 'top':
795         (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
796 }
797
798 function onMessageContentMenu(event) {
799   popupMenu(event, 'messageContentMenu', this);
800 }
801
802 function onMessageEditDraft(event) {
803   return openMessageWindowsForSelection("edit", true);
804 }
805
806 function onEmailAddressClick(event) {
807   popupMenu(event, 'addressMenu', this);
808 }
809
810 function onMessageAnchorClick(event) {
811   window.open(this.href);
812   preventDefault(event);
813 }
814
815 function messageCallback(http) {
816   var div = $('messageContent');
817
818   if (http.readyState == 4
819       && http.status == 200) {
820     document.messageAjaxRequest = null;
821     div.update(http.responseText);
822     configureLinksInMessage();
823     resizeMailContent();
824     
825     if (http.callbackData) {
826       var cachedMessage = new Array();
827       cachedMessage['idx'] = currentMailbox + '/' + http.callbackData;
828       cachedMessage['time'] = (new Date()).getTime();
829       cachedMessage['text'] = http.responseText;
830       if (cachedMessage['text'].length < 30000)
831         storeCachedMessage(cachedMessage);
832     }
833   }
834   else
835     log("messageCallback: problem during ajax request: " + http.status);
836 }
837
838 function processMailboxMenuAction(mailbox) {
839   var currentNode, upperNode;
840   var mailboxName;
841   var action;
842
843   mailboxName = mailbox.getAttribute('mailboxname');
844   currentNode = mailbox;
845   upperNode = null;
846
847   while (currentNode
848          && !currentNode.hasAttribute('mailboxaction'))
849     currentNode = currentNode.parentNode.parentNode.parentMenuItem;
850
851   if (currentNode)
852     {
853       action = currentNode.getAttribute('mailboxaction');
854       //       var rows  = collectSelectedRows();
855       //       var rString = rows.join(', ');
856       //       alert("performing '" + action + "' on " + rString
857       //             + " to " + mailboxName);
858     }
859 }
860
861 var rowSelectionCount = 0;
862
863 validateControls();
864
865 function showElement(e, shouldShow) {
866   e.style.display = shouldShow ? "" : "none";
867 }
868
869 function enableElement(e, shouldEnable) {
870   if(!e)
871     return;
872   if(shouldEnable) {
873     if(e.hasAttribute("disabled"))
874       e.removeAttribute("disabled");
875   }
876   else {
877     e.setAttribute("disabled", "1");
878   }
879 }
880
881 function validateControls() {
882   var e = $("moveto");
883   this.enableElement(e, rowSelectionCount > 0);
884 }
885
886 function moveTo(uri) {
887   alert("MoveTo: " + uri);
888 }
889
890 /* message menu entries */
891 function onMenuOpenMessage(event) {
892   return openMessageWindowsForSelection('popupview');
893 }
894
895 function onMenuReplyToSender(event) {
896   return openMessageWindowsForSelection('reply');
897 }
898
899 function onMenuReplyToAll(event) {
900   return openMessageWindowsForSelection('replyall');
901 }
902
903 function onMenuForwardMessage(event) {
904   return openMessageWindowsForSelection('forward');
905 }
906
907 function onMenuViewMessageSource(event) {
908   var messageList = $("messageList");
909   var rows = messageList.getSelectedRowsId();
910
911   if (rows.length > 0) {
912     var url = (ApplicationBaseURL + currentMailbox + "/"
913                + rows[0].substr(4) + "/viewsource");
914     openMailComposeWindow(url);
915   }
916
917   preventDefault(event);
918 }
919
920 /* contacts */
921 function newContactFromEmail(event) {
922   var mailto = document.menuTarget.innerHTML;
923
924   var email = extractEmailAddress(mailto);
925   var c_name = extractEmailName(mailto);
926   if (email.length > 0)
927     {
928       var url = UserFolderURL + "Contacts/new?contactEmail=" + email;
929       if (c_name)
930         url += "&contactFN=" + c_name;
931       openContactWindow(url);
932     }
933
934   return false; /* stop following the link */
935 }
936
937 function newEmailTo(sender) {
938   return openMailTo(document.menuTarget.innerHTML);
939 }
940
941 function expandUpperTree(node) {
942   var currentNode = node.parentNode;
943
944   while (currentNode.className != "dtree") {
945     if (currentNode.className == 'clip') {
946       var id = currentNode.getAttribute("id");
947       var number = parseInt(id.substr(2));
948       if (number > 0) {
949         var cn = mailboxTree.aNodes[number];
950         mailboxTree.nodeStatus(1, number, cn._ls);
951       }
952     }
953     currentNode = currentNode.parentNode;
954   }
955 }
956
957 function onHeaderClick(event) {
958   var headerId = this.getAttribute("id");
959   var newSortAttribute;
960   if (headerId == "subjectHeader")
961     newSortAttribute = "subject";
962   else if (headerId == "fromHeader")
963     newSortAttribute = "from";
964   else if (headerId == "dateHeader")
965     newSortAttribute = "date";
966   else
967     newSortAttribute = "arrival";
968
969   if (sorting["attribute"] == newSortAttribute)
970     sorting["ascending"] = !sorting["ascending"];
971   else {
972     sorting["attribute"] = newSortAttribute;
973     sorting["ascending"] = true;
974   }
975   refreshCurrentFolder();
976   
977   Event.stop(event);
978 }
979
980 function refreshCurrentFolder() {
981   openMailbox(currentMailbox, true);
982 }
983
984 function refreshFolderByType(type) {
985   if (currentMailboxType == type)
986     refreshCurrentFolder();
987 }
988
989 var mailboxSpanAcceptType = function(type) {
990   return (type == "mailRow");
991 }
992
993 var mailboxSpanEnter = function() {
994   this.addClassName("_dragOver");
995 }
996
997 var mailboxSpanExit = function() {
998   this.removeClassName("_dragOver");
999 }
1000
1001 var mailboxSpanDrop = function(data) {
1002   var success = false;
1003
1004   if (data) {
1005     var folder = this.parentNode.parentNode.getAttribute("dataname");
1006     if (folder != currentMailbox)
1007       success = (moveMessages(data, folder) == 0);
1008   }
1009   else
1010     success = false;
1011
1012   return success;
1013 }
1014
1015 var plusSignEnter = function() {
1016   var nodeNr = parseInt(this.id.substr(2));
1017   if (!mailboxTree.aNodes[nodeNr]._io)
1018     this.plusSignTimer = setTimeout("openPlusSign('" + nodeNr + "');", 1000);
1019 }
1020
1021 var plusSignExit = function() {
1022   if (this.plusSignTimer) {
1023     clearTimeout(this.plusSignTimer);
1024     this.plusSignTimer = null;
1025   }
1026 }
1027         
1028 function openPlusSign(nodeNr) {
1029   mailboxTree.nodeStatus(1, nodeNr, mailboxTree.aNodes[nodeNr]._ls);
1030   mailboxTree.aNodes[nodeNr]._io = 1;
1031   this.plusSignTimer = null;
1032 }
1033
1034 var messageListGhost = function () {
1035   var newDiv = document.createElement("div");
1036   //   newDiv.style.width = "25px;";
1037   //   newDiv.style.height = "25px;";
1038   newDiv.style.backgroundColor = "#aae;";
1039   newDiv.style.border = "2px solid #a3a;";
1040   newDiv.style.padding = "5px;";
1041   newDiv.ghostOffsetX = 10;
1042   newDiv.ghostOffsetY = 5;
1043
1044   var newImg = document.createElement("img");
1045   newImg.src = ResourcesURL + "/message-mail.png";
1046
1047   var list = $("messageList");
1048   var count = list.getSelectedRows().length;
1049   newDiv.appendChild(newImg);
1050   newDiv.appendChild(document.createElement("br"));
1051   newDiv.appendChild(document.createTextNode(count + " messages..."));
1052
1053   return newDiv;
1054 }
1055
1056 var messageListData = function(type) {
1057   var rows = this.parentNode.parentNode.getSelectedRowsId();
1058   var msgIds = new Array();
1059   for (var i = 0; i < rows.length; i++)
1060     msgIds.push(rows[i].substr(4));
1061
1062   return msgIds;
1063 }
1064
1065 /* a model for a futur refactoring of the sortable table headers mechanism */
1066 function configureMessageListEvents(table) {
1067   if (table) {
1068     table.multiselect = true;
1069     // Each body row can load a message
1070     Event.observe(table, "mousedown",
1071                   onMessageSelectionChange.bindAsEventListener(table));    
1072     // Sortable columns
1073     configureSortableTableHeaders(table);
1074   }
1075 }
1076
1077 function configureMessageListBodyEvents(table) {
1078   if (table) {
1079     // Page navigation
1080     var cell = table.tHead.rows[1].cells[0];
1081     if ($(cell).hasClassName("tbtv_navcell")) {
1082       var anchors = $(cell).childNodesWithTag("a");
1083       for (var i = 0; i < anchors.length; i++)
1084         Event.observe(anchors[i], "click", openMailboxAtIndex.bindAsEventListener(anchors[i]));
1085     }
1086
1087     rows = table.tBodies[0].rows;
1088     for (var i = 0; i < rows.length; i++) {
1089       Event.observe(rows[i], "mousedown", onRowClick);
1090       Event.observe(rows[i], "selectstart", listRowMouseDownHandler);
1091       Event.observe(rows[i], "contextmenu", onMessageContextMenu.bindAsEventListener(rows[i]));
1092       
1093       rows[i].dndTypes = function() { return new Array("mailRow"); };
1094       rows[i].dndGhost = messageListGhost;
1095       rows[i].dndDataForType = messageListData;
1096 //       document.DNDManager.registerSource(rows[i]);
1097
1098       for (var j = 0; j < rows[i].cells.length; j++) {
1099         var cell = rows[i].cells[j];
1100         Event.observe(cell, "mousedown", listRowMouseDownHandler);
1101         if (j == 2 || j == 3 || j == 5)
1102           Event.observe(cell, "dblclick", onMessageDoubleClick.bindAsEventListener(cell));
1103         else if (j == 4) {
1104           var img = cell.childNodesWithTag("img")[0];
1105           Event.observe(img, "click", mailListMarkMessage.bindAsEventListener(img));
1106         }
1107       }
1108     }
1109   }
1110 }
1111
1112 function configureDragHandles() {
1113   var handle = $("verticalDragHandle");
1114   if (handle) {
1115     handle.addInterface(SOGoDragHandlesInterface);
1116     handle.leftMargin = 1;
1117     handle.leftBlock=$("leftPanel");
1118     handle.rightBlock=$("rightPanel");
1119   }
1120
1121   handle = $("rightDragHandle");
1122   if (handle) {
1123     handle.addInterface(SOGoDragHandlesInterface);
1124     handle.upperBlock=$("mailboxContent");
1125     handle.lowerBlock=$("messageContent");
1126   }
1127 }
1128
1129 /* dnd */
1130 function initDnd() {
1131   //   log("MailerUI initDnd");
1132
1133   var tree = $("mailboxTree");
1134   if (tree) {
1135     var images = tree.getElementsByTagName("img");
1136     for (var i = 0; i < images.length; i++) {
1137       if (images[i].id[0] == 'j') {
1138         images[i].dndAcceptType = mailboxSpanAcceptType;
1139         images[i].dndEnter = plusSignEnter;
1140         images[i].dndExit = plusSignExit;
1141         document.DNDManager.registerDestination(images[i]);
1142       }
1143     }
1144     var nodes = document.getElementsByClassName("nodeName", tree);
1145     for (var i = 0; i < nodes.length; i++) {
1146       nodes[i].dndAcceptType = mailboxSpanAcceptType;
1147       nodes[i].dndEnter = mailboxSpanEnter;
1148       nodes[i].dndExit = mailboxSpanExit;
1149       nodes[i].dndDrop = mailboxSpanDrop;
1150       document.DNDManager.registerDestination(nodes[i]);
1151     }
1152   }
1153 }
1154
1155 /* stub */
1156
1157 function refreshContacts() {
1158 }
1159
1160 function openInbox(node) {
1161   var done = false;
1162   openMailbox(node.parentNode.getAttribute("dataname"));
1163   var tree = $("mailboxTree");
1164   tree.selectedEntry = node;
1165   node.select();
1166   mailboxTree.o(1);
1167 }
1168
1169 function initMailer(event) {
1170   if (!document.body.hasClassName("popup")) {
1171 //     initDnd();
1172     initMailboxTree();
1173     initMessageCheckTimer();
1174   }
1175 }
1176
1177 function initMessageCheckTimer() {
1178   var messageCheck = userDefaults["MessageCheck"];
1179   if (messageCheck && messageCheck != "manually") {
1180     var interval;
1181     if (messageCheck == "once_per_hour")
1182       interval = 3600;
1183     else if (messageCheck == "every_minute")
1184       interval = 60;
1185     else {
1186       interval = parseInt(messageCheck.substr(6)) * 60;
1187     }
1188     messageCheckTimer = window.setInterval(onMessageCheckCallback,
1189                                            interval * 1000);
1190   }
1191 }
1192
1193 function onMessageCheckCallback(event) {
1194   refreshMailbox();
1195 }
1196
1197 function initMailboxTree() {
1198   mailboxTree = new dTree("mailboxTree");
1199   mailboxTree.config.folderLinks = true;
1200   mailboxTree.config.hideRoot = true;
1201
1202   mailboxTree.icon.root = ResourcesURL + "/tbtv_account_17x17.gif";
1203   mailboxTree.icon.folder = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1204   mailboxTree.icon.folderOpen   = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1205   mailboxTree.icon.node = ResourcesURL + "/tbtv_leaf_corner_17x17.gif";
1206   mailboxTree.icon.line = ResourcesURL + "/tbtv_line_17x17.gif";
1207   mailboxTree.icon.join = ResourcesURL + "/tbtv_junction_17x17.gif";
1208   mailboxTree.icon.joinBottom   = ResourcesURL + "/tbtv_corner_17x17.gif";
1209   mailboxTree.icon.plus = ResourcesURL + "/tbtv_plus_17x17.gif";
1210   mailboxTree.icon.plusBottom   = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1211   mailboxTree.icon.minus = ResourcesURL + "/tbtv_minus_17x17.gif";
1212   mailboxTree.icon.minusBottom = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1213   mailboxTree.icon.nlPlus = ResourcesURL + "/tbtv_corner_plus_17x17.gif";
1214   mailboxTree.icon.nlMinus = ResourcesURL + "/tbtv_corner_minus_17x17.gif";
1215   mailboxTree.icon.empty = ResourcesURL + "/empty.gif";
1216
1217   mailboxTree.add(0, -1, '');
1218
1219   mailboxTree.pendingRequests = mailAccounts.length;
1220   activeAjaxRequests += mailAccounts.length;
1221   for (var i = 0; i < mailAccounts.length; i++) {
1222     var url = ApplicationBaseURL + mailAccounts[i] + "/mailboxes";
1223     triggerAjaxRequest(url, onLoadMailboxesCallback, mailAccounts[i]);
1224   }
1225 }
1226
1227 function updateMailboxTreeInPage() {
1228   $("folderTreeContent").update(mailboxTree);
1229
1230   var inboxFound = false;
1231   var tree = $("mailboxTree");
1232   var nodes = document.getElementsByClassName("node", tree);
1233   for (i = 0; i < nodes.length; i++) {
1234     Event.observe(nodes[i], "click",
1235                   onMailboxTreeItemClick.bindAsEventListener(nodes[i]));
1236     Event.observe(nodes[i], "contextmenu",
1237                   onFolderMenuClick.bindAsEventListener(nodes[i]));
1238     if (!inboxFound
1239         && nodes[i].parentNode.getAttribute("datatype") == "inbox") {
1240       openInbox(nodes[i]);
1241       inboxFound = true;
1242     }
1243   }
1244 }
1245
1246 function mailboxMenuNode(type, name) {
1247   var newNode = document.createElement("li");
1248   var icon = MailerUIdTreeExtension.folderIcons[type];
1249   if (!icon)
1250     icon = "tbtv_leaf_corner_17x17.gif";
1251   var image = document.createElement("img");
1252   image.src = ResourcesURL + "/" + icon;
1253   newNode.appendChild(image);
1254   var displayName = MailerUIdTreeExtension.folderNames[type];
1255   if (!displayName)
1256     displayName = name;
1257   newNode.appendChild(document.createTextNode(" " + displayName));
1258
1259   return newNode;
1260 }
1261
1262 function generateMenuForMailbox(mailbox, prefix, callback) {
1263   var menuDIV = document.createElement("div");
1264   $(menuDIV).addClassName("menu");
1265   menuDIV.setAttribute("id", prefix + "Submenu");
1266   var menu = document.createElement("ul");
1267   menuDIV.appendChild(menu);
1268   pageContent.appendChild(menuDIV);
1269
1270   var callbacks = new Array();
1271   if (mailbox.type != "account") {
1272     var newNode = document.createElement("li");
1273     newNode.mailbox = mailbox;
1274     newNode.appendChild(document.createTextNode(labels["This Folder"]));
1275     menu.appendChild(newNode);
1276     menu.appendChild(document.createElement("li"));
1277     callbacks.push(callback);
1278     callbacks.push("-");
1279   }
1280
1281   var submenuCount = 0;
1282   for (var i = 0; i < mailbox.children.length; i++) {
1283     var child = mailbox.children[i];
1284     var newNode = mailboxMenuNode(child.type, child.name);
1285     menu.appendChild(newNode);
1286     if (child.children.length > 0) {
1287       var newPrefix = prefix + submenuCount;
1288       var newSubmenuId = generateMenuForMailbox(child, newPrefix, callback);
1289       callbacks.push(newSubmenuId);
1290       submenuCount++;
1291     }
1292     else {
1293       newNode.mailbox = child;
1294       callbacks.push(callback);
1295     }
1296   }
1297   initMenu(menuDIV, callbacks);
1298
1299   return menuDIV.getAttribute("id");
1300 }
1301
1302 function updateMailboxMenus() {
1303   var mailboxActions = { move: onMailboxMenuMove,
1304                          copy: onMailboxMenuCopy };
1305
1306   for (key in mailboxActions) {
1307     var menuId = key + "MailboxMenu";
1308     var menuDIV = $(menuId);
1309     if (menuDIV)
1310       menuDIV.parentNode.removeChild(menuDIV);
1311
1312     menuDIV = document.createElement("div");
1313     pageContent = $("pageContent");
1314     pageContent.appendChild(menuDIV);
1315
1316     var menu = document.createElement("ul");
1317     menuDIV.appendChild(menu);
1318
1319     $(menuDIV).addClassName("menu");
1320     menuDIV.setAttribute("id", menuId);
1321
1322     var submenuIds = new Array();
1323     for (var i = 0; i < mailAccounts.length; i++) {
1324       var menuEntry = mailboxMenuNode("account", mailAccounts[i]);
1325       menu.appendChild(menuEntry);
1326       var mailbox = accounts[mailAccounts[i]];
1327       var newSubmenuId = generateMenuForMailbox(mailbox,
1328                                               key, mailboxActions[key]);
1329       submenuIds.push(newSubmenuId);
1330     }
1331     initMenu(menuDIV, submenuIds);
1332   }
1333 }
1334
1335 function onLoadMailboxesCallback(http) {
1336   if (http.readyState == 4
1337       && http.status == 200) {
1338     checkAjaxRequestsState();
1339     if (http.responseText.length > 0) {
1340       var newAccount = buildMailboxes(http.callbackData,
1341                                       http.responseText);
1342       accounts[http.callbackData] = newAccount;
1343       mailboxTree.addMailAccount(newAccount);
1344       mailboxTree.pendingRequests--;
1345       activeAjaxRequests--;
1346       if (!mailboxTree.pendingRequests) {
1347         updateMailboxTreeInPage();
1348         updateMailboxMenus();
1349         checkAjaxRequestsState();
1350       }
1351     }
1352   }
1353
1354   //       var tree = $("mailboxTree");
1355   //       var treeNodes = document.getElementsByClassName("dTreeNode", tree);
1356   //       var i = 0;
1357   //       while (i < treeNodes.length
1358   //         && treeNodes[i].getAttribute("dataname") != currentMailbox)
1359   //     i++;
1360   //       if (i < treeNodes.length) {
1361   //     //     log("found mailbox");
1362   //     var links = document.getElementsByClassName("node", treeNodes[i]);
1363   //     if (tree.selectedEntry)
1364   //        tree.selectedEntry.deselect();
1365   //     links[0].select();
1366   //     tree.selectedEntry = links[0];
1367   //     expandUpperTree(links[0]);
1368   //       }
1369 }
1370
1371 function buildMailboxes(accountName, encoded) {
1372   var account = new Mailbox("account", accountName);
1373   var data = encoded.evalJSON(true);
1374   for (var i = 0; i < data.length; i++) {
1375     var currentNode = account;
1376     var names = data[i].path.split("/");
1377     for (var j = 1; j < (names.length - 1); j++) {
1378       var node = currentNode.findMailboxByName(names[j]);
1379       if (!node) {
1380         node = new Mailbox("additional", names[j]);
1381         currentNode.addMailbox(node);
1382       }
1383       currentNode = node;
1384     }
1385     var basename = names[names.length-1];
1386     var leaf = currentNode.findMailboxByName(basename);
1387     if (leaf)
1388       leaf.type = data[i].type;
1389     else {
1390       leaf = new Mailbox(data[i].type, basename);
1391       currentNode.addMailbox(leaf);
1392     }
1393   }
1394
1395   return account;
1396 }
1397
1398 function onMenuCreateFolder(event) {
1399   var name = window.prompt(labels["Name :"], "");
1400   if (name && name.length > 0) {
1401     var folderID = document.menuTarget.getAttribute("dataname");
1402     var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name;
1403     triggerAjaxRequest(urlstr, folderOperationCallback);
1404   }
1405 }
1406
1407 function onMenuRenameFolder(event) {
1408   var name = window.prompt(labels["Enter the new name of your folder :"]
1409                            ,
1410                            "");
1411   if (name && name.length > 0) {
1412     var folderID = document.menuTarget.getAttribute("dataname");
1413     var urlstr = URLForFolderID(folderID) + "/renameFolder?name=" + name;
1414     triggerAjaxRequest(urlstr, folderOperationCallback);
1415   }
1416 }
1417
1418 function onMenuDeleteFolder(event) {
1419   var answer = window.confirm(labels["Do you really want to move this folder into the trash ?"]);
1420   if (answer) {
1421     var folderID = document.menuTarget.getAttribute("dataname");
1422     var urlstr = URLForFolderID(folderID) + "/deleteFolder";
1423     triggerAjaxRequest(urlstr, folderOperationCallback);
1424   }
1425 }
1426
1427 function onMenuExpungeFolder(event) {
1428   var folderID = document.menuTarget.getAttribute("dataname");
1429   var urlstr = URLForFolderID(folderID) + "/expunge";
1430   triggerAjaxRequest(urlstr, folderRefreshCallback, folderID);
1431 }
1432
1433 function onMenuEmptyTrash(event) {
1434   var folderID = document.menuTarget.getAttribute("dataname");
1435   var urlstr = URLForFolderID(folderID) + "/emptyTrash";
1436   triggerAjaxRequest(urlstr, folderOperationCallback, folderID);
1437
1438   if (folderID == currentMailbox) {
1439     var div = $('messageContent');
1440     for (var i = div.childNodes.length - 1; i > -1; i--)
1441       div.removeChild(div.childNodes[i]);
1442     refreshCurrentFolder();
1443   }
1444   var msgID = currentMessages[folderID];
1445   if (msgID)
1446     deleteCachedMessage(folderID + "/" + msgID);
1447 }
1448
1449 function _onMenuChangeToXXXFolder(event, folder) {
1450   var type = document.menuTarget.getAttribute("datatype");
1451   if (type == "additional")
1452     window.alert(labels["You need to choose a non-virtual folder!"]);
1453   else {
1454     var folderID = document.menuTarget.getAttribute("dataname");
1455     var urlstr = URLForFolderID(folderID) + "/setAs" + folder + "Folder";
1456     triggerAjaxRequest(urlstr, folderOperationCallback);
1457   }
1458 }
1459
1460 function onMenuChangeToDraftsFolder(event) {
1461   return _onMenuChangeToXXXFolder(event, "Drafts");
1462 }
1463
1464 function onMenuChangeToSentFolder(event) {
1465   return _onMenuChangeToXXXFolder(event, "Sent");
1466 }
1467
1468 function onMenuChangeToTrashFolder(event) {
1469   return _onMenuChangeToXXXFolder(event, "Trash");
1470 }
1471
1472 function onMenuLabelNone() {
1473   var rowId = document.menuTarget.getAttribute("id").substr(4);
1474   var messageId = currentMailbox + "/" + rowId;
1475   var urlstr = ApplicationBaseURL + messageId + "/removeAllLabels";
1476   triggerAjaxRequest(urlstr, messageFlagCallback,
1477                      { mailbox: currentMailbox, msg: rowId, label: null } );
1478 }
1479
1480 function _onMenuLabelFlagX(flag) {
1481   var flags = document.menuTarget.getAttribute("labels").split(" ");
1482
1483   var rowId = document.menuTarget.getAttribute("id").substr(4);
1484   var messageId = currentMailbox + "/" + rowId;
1485
1486   var operation = "add";
1487   if (flags.indexOf("label" + flag) > -1)
1488     operation = "remove";
1489   var urlstr = (ApplicationBaseURL + messageId
1490                 + "/" + operation + "Label" + flag);
1491   triggerAjaxRequest(urlstr, messageFlagCallback,
1492                      { mailbox: currentMailbox, msg: rowId,
1493                        label: operation + flag } );
1494 }
1495
1496 function onMenuLabelFlag1() {
1497   _onMenuLabelFlagX(1);
1498 }
1499
1500 function onMenuLabelFlag2() {
1501   _onMenuLabelFlagX(2);
1502 }
1503
1504 function onMenuLabelFlag3() {
1505   _onMenuLabelFlagX(3);
1506 }
1507
1508 function onMenuLabelFlag4() {
1509   _onMenuLabelFlagX(4);
1510 }
1511
1512 function onMenuLabelFlag5() {
1513   _onMenuLabelFlagX(5);
1514 }
1515
1516 function folderOperationCallback(http) {
1517   if (http.readyState == 4
1518       && isHttpStatus204(http.status))
1519     initMailboxTree();
1520   else
1521     window.alert(labels["Operation failed"]);
1522 }
1523
1524 function folderRefreshCallback(http) {
1525   if (http.readyState == 4
1526       && isHttpStatus204(http.status)) {
1527     var oldMailbox = http.callbackData;
1528     if (oldMailbox == currentMailbox)
1529       refreshCurrentFolder();
1530   }
1531   else
1532     window.alert(labels["Operation failed"]);
1533 }
1534
1535 function messageFlagCallback(http) {
1536   if (http.readyState == 4
1537       && isHttpStatus204(http.status)) {
1538     var data = http.callbackData;
1539     if (data["mailbox"] == currentMailbox) {
1540       var row = $("row_" + data["msg"]);
1541       var operation = data["label"];
1542       if (operation) {
1543         var labels = row.getAttribute("labels");
1544         var flags;
1545         if (labels.length > 0)
1546           flags = labels.split(" ");
1547         else
1548           flags = new Array();
1549         if (operation.substr(0, 3) == "add")
1550           flags.push("label" + operation.substr(3));
1551         else {
1552           var flag = "label" + operation.substr(6);
1553           var idx = flags.indexOf(flag);
1554           flags.splice(idx, 1);
1555         }
1556         row.setAttribute("labels", flags.join(" "));
1557       }
1558       else
1559         row.setAttribute("labels", "");
1560     }
1561   }
1562 }
1563
1564 function onLabelMenuPrepareVisibility() {
1565   var messageList = $("messageList");
1566   var flags = {};
1567
1568   if (messageList) {
1569     var rows = messageList.getSelectedRows();
1570     for (var i = 0; i < rows.length; i++) {
1571       $w(rows[i].getAttribute("labels")).each(function(flag) {
1572         flags[flag] = true;
1573         });
1574     }
1575   }
1576
1577   var lis = this.childNodesWithTag("ul")[0].childNodesWithTag("li")
1578   var isFlagged = false;
1579   for (var i = 1; i < 6; i++) {
1580     if (flags["label" + i]) {
1581       isFlagged = true;
1582       lis[1 + i].addClassName("_chosen");
1583     }
1584     else
1585       lis[1 + i].removeClassName("_chosen");
1586   }
1587   if (isFlagged)
1588     lis[0].removeClassName("_chosen");
1589   else
1590     lis[0].addClassName("_chosen");
1591 }
1592
1593 function getMenus() {
1594   var menus = {}
1595   menus["accountIconMenu"] = new Array(null, null, onMenuCreateFolder, null,
1596                                        null, null);
1597   menus["inboxIconMenu"] = new Array(null, null, null, "-", null,
1598                                      onMenuCreateFolder, onMenuExpungeFolder,
1599                                      "-", null,
1600                                      onMenuSharing);
1601   menus["trashIconMenu"] = new Array(null, null, null, "-", null,
1602                                      onMenuCreateFolder, onMenuExpungeFolder,
1603                                      onMenuEmptyTrash, "-", null,
1604                                      onMenuSharing);
1605   menus["mailboxIconMenu"] = new Array(null, null, null, "-", null,
1606                                        onMenuCreateFolder,
1607                                        onMenuRenameFolder,
1608                                        onMenuExpungeFolder,
1609                                        onMenuDeleteFolder,
1610                                        "folderTypeMenu",
1611                                        "-", null,
1612                                        onMenuSharing);
1613   menus["addressMenu"] = new Array(newContactFromEmail, newEmailTo, null);
1614   menus["messageListMenu"] = new Array(onMenuOpenMessage, "-",
1615                                        onMenuReplyToSender,
1616                                        onMenuReplyToAll,
1617                                        onMenuForwardMessage, null,
1618                                        "-", "moveMailboxMenu",
1619                                        "copyMailboxMenu", "label-menu",
1620                                        "mark-menu", "-", null,
1621                                        onMenuViewMessageSource, null,
1622                                        null, onMenuDeleteMessage);
1623   menus["messageContentMenu"] = new Array(onMenuReplyToSender,
1624                                           onMenuReplyToAll,
1625                                           onMenuForwardMessage,
1626                                           null, "moveMailboxMenu",
1627                                           "copyMailboxMenu",
1628                                           "-", "label-menu", "mark-menu",
1629                                           "-",
1630                                           null, onMenuViewMessageSource,
1631                                           null, onPrintCurrentMessage,
1632                                           onMenuDeleteMessage);
1633   menus["folderTypeMenu"] = new Array(onMenuChangeToSentFolder,
1634                                       onMenuChangeToDraftsFolder,
1635                                       onMenuChangeToTrashFolder);
1636
1637   menus["label-menu"] = new Array(onMenuLabelNone, "-", onMenuLabelFlag1,
1638                                   onMenuLabelFlag2, onMenuLabelFlag3,
1639                                   onMenuLabelFlag4, onMenuLabelFlag5);
1640   menus["mark-menu"] = new Array(null, null, null, null, "-", null, "-",
1641                                  null, null, null);
1642   menus["searchMenu"] = new Array(setSearchCriteria, setSearchCriteria,
1643                                   setSearchCriteria, setSearchCriteria,
1644                                   setSearchCriteria);
1645   var labelMenu = $("label-menu");
1646   if (labelMenu)
1647     labelMenu.prepareVisibility = onLabelMenuPrepareVisibility;
1648
1649   return menus;
1650 }
1651
1652 addEvent(window, 'load', initMailer);
1653
1654 function Mailbox(type, name) {
1655   this.type = type;
1656   this.name = name;
1657   this.parentFolder = null;
1658   this.children = new Array();
1659   return this;
1660 }
1661
1662 Mailbox.prototype.dump = function(indent) {
1663   if (!indent)
1664     indent = 0;
1665   log(" ".repeat(indent) + this.name);
1666   for (var i = 0; i < this.children.length; i++) {
1667     this.children[i].dump(indent + 2);
1668   }
1669 }
1670
1671 Mailbox.prototype.fullName = function() {
1672   var fullName = "";
1673
1674   var currentFolder = this;
1675   while (currentFolder.parentFolder) {
1676     fullName = "/folder" + currentFolder.name + fullName;
1677     currentFolder = currentFolder.parentFolder;
1678   }
1679
1680   return "/" + currentFolder.name + fullName;
1681 }
1682
1683 Mailbox.prototype.findMailboxByName = function(name) {
1684   var mailbox = null;
1685
1686   var i = 0;
1687   while (!mailbox && i < this.children.length)
1688     if (this.children[i].name == name)
1689       mailbox = this.children[i];
1690     else
1691       i++;
1692
1693   return mailbox;
1694 }
1695
1696 Mailbox.prototype.addMailbox = function(mailbox) {
1697   mailbox.parentFolder = this;
1698   this.children.push(mailbox);
1699 }