/**
 * 
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 * 
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 * 
 * Copyright (C) 2004-2010 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 * 
 */

/**
 * Updates reminders.
 * Called by child windows when an item with reminder was created or modified.
 */
var updateReminders;

register("OX_Configuration_Loaded_Complete", function() {

	var queue = new LinkedList();
	var reminders = {};
	var json = new JSON();
	var timer, timerSet = false;
	var status = {cancel: false};

	var m = 6e4, h = 36e5, d = 864e5, w = 6048e5; // ms per min, h, day and week
    var intervals = [5*m, 10*m, 15*m, 45*m, 1*h, 2*h, 4*h, 6*h, 8*h,
                     1*d, 2*d, 3*d, 4*d, 5*d, 6*d, 1*w, 2*w, 3*w, 4*w];
    var combobox = new ComboBox3(window, "remindAlarm", "12em", 0, true, null, 4);
    for (var i = 0; i < intervals.length; i++) {
        combobox.addElement(getInterval(intervals[i]), intervals[i]);
    }
	combobox.getDomNode();
	
	var startDateNode = new I18nNode(function() {
        if (this.node && this.node.parentNode && this.node.parentNode.parentNode)
            this.node.parentNode.parentNode.style.display = this.value ? ""
                                                                       : "none";
        return this.value ? formatDate(this.value, "datetime") : "";
    });
    $("reminderStartsRow").replaceChild(startDateNode.node,
                                        $("reminderStartsRow").firstChild);
    var endDateNode = new I18nNode(function() {
    	if (this.node && this.node.parentNode && this.node.parentNode.parentNode)
            this.node.parentNode.parentNode.style.display = this.value ? ""
                                                                       : "none";
        return this.value ? formatDate(this.value, "datetime") : "";
    });
    $("reminderEndsRow").replaceChild(endDateNode.node,
                                      $("reminderEndsRow").firstChild);
    
    register("OX_Refresh", update);
	updateReminders = update;
	update();
	function update() {
		if(!configGetKey("modules.calendar.module") ||
		   !configGetKey("modules.tasks.module")) return;
		json.get(AjaxRoot + "/reminder?action=range&session=" + session
			+ "&end=" + encodeURIComponent(now() + 12*60*60*1000), null,
			updatereply);
		function updatereply(reply) {
			var data = reply.data;
			var newR = [];
			for (var i = 0; i < data.length; i++) {
				var n = data[i];
				var o = reminders[n.id];
				newR.push(o && o.last_modified == n.last_modified ? o : n);
			}
			newR.sort(function(x, y) { return x.alarm - y.alarm; });
			queue = new LinkedList();
			reminders = {};
			for (var i = 0; i < newR.length; i++) {
				var reminder = newR[i];
				queue.addLast(reminder);
				reminders[reminder.id] = reminder;
			}
			schedule();
		}
	}
	function schedule() {
		if (timerSet) {
			clearTimeout(timer);
			timerSet = false;
		}
		var reminder = queue.first;
		if (reminder) {
			timer = setTimeout(display, Math.max(0, reminder.alarm - now()));
			timerSet = true;
		}
		function display() {
			timerSet = false;
			status.cancel = true;
			var mystatus = status = {cancel: false};
			var modules = {
				1: {name: "calendar", columns: "200,201,202,400",
				    icon: getFullImgSrc("img/calendar/btnnew_calendar.gif"),
				    title: "Appointment", /*i18n*/
                    //#. Appointment reminder
                    //#. %s is the time, formatted using the messages with context "in"
                    //#, c-format
                    text: "You have the following appointment in %s:", /*i18n*/
				    text2: "The following appointment already started:", /*i18n*/
				    until: 1},
				4: {name: "tasks", columns: "200,201,202",
				    icon: getFullImgSrc("img/tasks/btnnew_task.gif"),
				    title: "Task", /*i18n*/
                    //#. Task reminder
                    //#. %s is the time, formatted using the messages with context "in"
                    //#, c-format
				    text: "The following task is due in %s:", /*i18n*/
				    text2: "The following task is already past due:", /*i18n*/
				    until: 2},
				137: {name: "infostore", columns: "700",
				      icon: getFullImgSrc("img/infostore/infostore.gif"),
				      title: "InfoItem", /*i18n*/
				      text: "You wanted to be reminded about the following InfoItem:"} /*i18n*/
			};
			var module = modules[reminder.module];
			var id = {id: reminder.target_id, folder: reminder.folder};
			if (reminder.recurrence_position)
				id.pos = reminder.recurrence_position;
			json.put(AjaxRoot + "/" + module.name + "?action=list&session=" + session
				+ "&columns=" + module.columns,
				[id], null, listreply, listerror);
			function listerror(reply, status) {
				if (status && reply.code != "TSK-0017"
				           && reply.code != "APP-0001") return false;
				// Deleted in the meantime
				queue.removeFirst();
				schedule();
				return true;
			}
			function listreply(reply) {
				if(!reply.data.length) {
					queue.removeFirst();
					schedule();
					return;
				}
				if (mystatus.cancel) return;
				with ($('reminderModule')) {
					src = module.icon;
					alt = title = _(module.title);
				}
				var data = reply.data[0];
				function set(node, text) {
					node.parentNode.style.display = text ? "" : "none";
					if (text) node.firstChild.data = text;
				}
				$("reminderTitleRow").firstChild.data = data[0] || "";
                startDateNode.value = data[1];
                startDateNode.update();
                endDateNode.value = data[2];
                endDateNode.update();
				set($("reminderLocationRow"), data[3]);
				
				var text = module.text;
				if (module.text2) {
					var interval = data[module.until] - now();
					if (interval < 0)
						text = _(module.text2);
					else
						text = format(_(module.text), getInterval(interval, true));
				}
				$('reminderNotificationText').firstChild.data = text;
				addDOMEvent($("reminderOK"), "click", ok);
				addDOMEvent($("reminderAgain"), "click", again);
				addOnClose($("reminderWindow"), ok);
				showNode("reminderWindow");
				centerPopupWindow($("reminderWindow"));
				$("reminderWindow").style.display = "block";				
				function hide() {
					hideNode("reminderWindow");
					$("reminderWindow").style.display = "none";
					removeDOMEvent($("reminderOK"), "click", ok);
					removeDOMEvent($("reminderAgain"), "click", again);
					removeOnClose($("reminderWindow"), ok);
				}
				function again() {
					hide();
					if (mystatus.cancel) return;
					// get interval
					var dt = combobox.getKey();
					// inform server
					var reminder = queue.first;
					// get timestamp from reply
					var timestamp = reply.timestamp;
					if (reminder) {
						// taks and appointments must be treated differently
						switch (reminder.module) {
						case 4:
							// set new alarm
							var alarm = Math.floor(now() / (60*1000)) * 60*1000 + dt;
							// update task
							var changes = { alarm: alarm, notification: false }; // do not notify!
							var request = [{
								action: "remindAgain", module: "reminder",
								data: changes, id: reminder.id
//								id: reminder.target_id, folder: reminder.folder, // target_id (not id!)
//								data: changes, timestamp: timestamp
							}];
							new JSON().put(AjaxRoot + "/multiple?session=" + session, request, null, function(response) {
								// update cache
								var ids = [{id: reminder.target_id, folder: reminder.folder}];
								OXTaskMapping.editObjects(ids, changes);
							});
							break;
						case 1: // appointment (TODO)
							break;
						}
					}
					// adjust UI timer
					reminder.alarm = Math.floor(now() / (60*1000)) * 60*1000 + dt;
					queue.removeFirst();
					sort: {
						for (var i = queue.first; i; i = i.next) {
							if (i.alarm > reminder.alarm) {
								queue.insertBefore(reminder, i);
								break sort;
							}
						}
						queue.addLast(reminder);
					}
					schedule();
				}
				function ok() {
					hide();
					if (mystatus.cancel) return;
					var id = { id: reminder.id };
					if (reminder.recurrence_position) {
					    id.recurrence_position = reminder.recurrence_position;
					}
					json.put(AjaxRoot + "/reminder?action=delete&session=" + session
						+ "&timestamp=" + encodeURIComponent(reminder.last_modified),
                        id, null, deletereply);
					function deletereply(reply) {
						if (reply.data.length || queue.first !== reminder) // Just in case
							update();
						else {
							queue.removeFirst();
							schedule();
						}
					}
				}
			}
		}
	}
});
fileloaded();