/* Copyright 2009 Palm, Inc.  All rights reserved. */


var ReminderAssistant = Class.create({
	initialize: function(eventId,needThrobbing) {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant initialize: start: "+eventId);
		this.DEFAULT_SNOOZE = 5;
		this.reminders = getReminderManager();
		getAppAssistant().openReminderAlert = this;
		this.requests = [];
		this.dismissed = false;	
		this.snoozed =false;	
		this.eventId = eventId;	
		this.doThrob =needThrobbing;
		this.autoSnoozed = false;
		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant initialize:end");
	},

	activate:function(){
		Mojo.Log.info("$$$$$$$$ Reminder-assistant activate:start");
		if (this.doThrob) {
			Mojo.Log.info("$$$$$$$$ Reminder-assistant doThrob:true");
			this.controller.stageController.indicateNewContent(true);
		}
		Mojo.Log.info("$$$$$$$$ Reminder-assistant activate:end");
	},
	
	setup: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant setup:start");
		this.service = getCalendarService();

		this.reminders.observeReminders('alert', this);

		this.onEventHandler = this.onEvent.bindAsEventListener(this);
		this.onDismissHandler = this.onDismiss.bindAsEventListener(this);
		this.onEmailHandler = this.onEmail.bindAsEventListener(this);
		this.onSnoozeHandler = this.onSnooze.bindAsEventListener(this);
	
		this.updateMostRecentReminder();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant setup:end");
	},
    
	cleanup: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup:start:");
		this.reminders.stopObservingReminders('alert');
		
		getAppAssistant().openReminderAlert = null;
		if (this.reminder) {
			Mojo.Log.info("$$$$$$$$ Reminder Assistant cleanup for:"+this.reminder.id);
			if (!this.dismissed && this.reminders.getReminder(this.reminder.id)/*this might be an auto close task and hence already removed*/) {
				Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup: snoozing reminder " + this.reminder.id);
				this.snooze(this.DEFAULT_SNOOZE);
			}
			if (this.dismissed || this.snoozed) {				
				Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup : removing autoclosetask");
				//only remove the auto close task if it is acted upon
				this.removeAutoCloseTask();
				
			}
		}
		Mojo.Log.info("$$$$$$$$ Reminder-assistant cleanup:end:");
	},
	
	remindersUpdated: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: start");
		if (this.autoSnoozed) {
			Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: autoSnoozed so returning...");
			return;
		}
		
		if (this.reminders.getNumReminders() == 0) {
			Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated:closingAlert");
			this.closeAlert();	
		}
		else {
			Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated:updateMostRecentReminder");
			this.updateMostRecentReminder();
		}
		Mojo.Log.info("$$$$$$$$ Reminder-assistant remindersUpdated: end");
	},

	updateMostRecentReminder: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateMostRecentReminder:start");
		//this.reminder = this.reminders.getMostRecentReminder();
		this.reminder = this.reminders.getReminder(this.eventId);
		if(!this.reminder){
			//the reminder manager does not have any reminders
			//so just close this scene and return.
			this.closeAlert();
			return;
		}
		
		this.scheduleAtStartTime();		
		this.scheduleAutoCloseTask();
		this.updateDisplay();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateMostRecentReminder:end");
	},

	updateDisplay: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateDisplay:start, StageName:"+this.controller.window.name);
		var data = {};
		
		data.subject = this.reminder.subject;
		if (!data.subject)
			data.subject = '';
			
		if (this.reminder.time || this.reminder.isAllDay) {
			var timeStartStr;
			var ampmStr;
					
			if(this.reminder.isAllDay)
			{
				data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L("MMM d, yyyy"));
			}
			else if (getTimeFormat() == "HH12") 
			{
				data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L('EEE MMM d, h:mm a')); 				
			}
			else
			{
				data.time = Mojo.Format.formatDate(new Date(this.reminder.time), $L('EEE MMM d, H:mm')); 		
			}
		
		}
		if(this.reminder.location)
			data.location=this.reminder.location;
		else
			data.location = $L("No location");
			
		this.removeListeners();
		
		var eventHtml = Mojo.View.render({object: data, template: 'reminder/reminder-event'});
		this.updateHTML(this.controller.get('reminder-event'), eventHtml);
		
		if (this.reminder.attendees.length > 1/* we now include the organizer in the attendee list*/) {
			this.controller.get('reminder-email').style.display = '';
			this.controller.get('reminder-email').addEventListener(Mojo.Event.tap, this.onEmailHandler);
		}
		
		this.addListeners();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateDisplay:end");
	},
	
	addListeners: function() {
		this.controller.get('notification-event-title').addEventListener(Mojo.Event.tap, this.onEventHandler);
		this.controller.get('notification-event-subtitle').addEventListener(Mojo.Event.tap, this.onEventHandler);
		this.controller.get('notification-event-icon').addEventListener(Mojo.Event.tap, this.onEventHandler);
		this.controller.get('notification-event-location').addEventListener(Mojo.Event.tap, this.onEventHandler);
		
		this.controller.get('reminder-dismiss').addEventListener(Mojo.Event.tap, this.onDismissHandler);
		this.controller.get('reminder-snooze').addEventListener(Mojo.Event.tap, this.onSnoozeHandler);
	},

	removeListeners: function() {
		var title = this.controller.get('notification-event-title');
		if (title) title.removeEventListener(Mojo.Event.tap, this.onEventHandler);
		var subtitle = this.controller.get('notification-event-subtitle');
		if (subtitle) subtitle.removeEventListener(Mojo.Event.tap, this.onEventHandler);
		var location = this.controller.get('notification-event-location');
		if (location) location.removeEventListener(Mojo.Event.tap, this.onEventHandler);
		var icon =this.controller.get('notification-event-icon');
		if(icon) icon.removeEventListener(Mojo.Event.tap, this.onEventHandler);
		var dismiss = this.controller.get('reminder-dismiss');
		if (dismiss) dismiss.removeEventListener(Mojo.Event.tap, this.onDismissHandler);
		var email = this.controller.get('reminder-email');
		if (email) email.removeEventListener(Mojo.Event.tap, this.onEmailHandler);
		var snooze = this.controller.get('reminder-snooze');
		if (snooze) snooze.removeEventListener(Mojo.Event.tap, this.onSnoozeHandler);
	},
	
	
	formatTimeText: function(date1, date2) {
		var minsInDay = 24 * 60;
		var t1 = $L('in #{min} mins');
		var t2 = $L('in #{hour} hrs #{min} mins');
		var t3 = $L('#{min} mins ago');
		var t4 = $L('#{hour} hrs #{min} mins ago');
		var t5 = $L('in #{day} days #{hour} hrs #{min} mins');
		var t6 = $L('#{day} days #{hour} hrs #{min} mins ago');
		var timeDelta = {};
		var template;
		var days1 = date1.getDayOfYear();
		var days2 = date2.getDayOfYear();
		var year1 = date1.getFullYear();
		var year2 = date2.getFullYear();
		for (var y1 = year1; y1 < year2; y1++) {
			days2 += Date.isLeapYear(y1) ? 366: 365;
		}
		for (var y2 = year2; y2 < year1; y2++) {
			days1 += Date.isLeapYear(y2) ? 366: 365;
		}
		var dt = (days1 - days2) * minsInDay + (date1.getHours() - date2.getHours()) * 60 + (date1.getMinutes() - date2.getMinutes());
		if (dt < 0) {
			dt = Math.abs(dt);
			if (dt >= minsInDay) {
				template = new Template(t6);
				timeDelta.day = Math.floor(dt / minsInDay);
				timeDelta.hour = Math.floor(dt / 60) % 24;
				timeDelta.min = dt % 60;
			}else if (dt >= 60) {
				template = new Template(t4);
				timeDelta.hour = Math.floor(dt / 60);
				timeDelta.min = dt % 60;
			} else {
				template = new Template(t3);
				timeDelta.min = dt;
			}
		} else {
			if (dt >= (24 * 60)) {
				template = new Template(t5);
				timeDelta.day = Math.floor(dt / minsInDay);
				timeDelta.hour = Math.floor(dt / 60) % 24;
				timeDelta.min = dt % 60;
			} else if (dt >= 60) {
				template = new Template(t2);
				timeDelta.hour = Math.floor(dt / 60);
				timeDelta.min = dt % 60;
			} else {
				template = new Template(t1);
				timeDelta.min = dt;
			}
		}
		
		return template.evaluate(timeDelta);
	},
	
	//If there are autosnoozed reminders, and the displayed reminder is snoozed or dismissed, 
	//display the most recent autosnoozed reminder.
	reissueAutoSnoozedAlerts: function(){
				
		var reminders = getReminderManager().getAllReminders();
		var now = new Date().getTime();
				
		//Scan the list, find which autosnoozed alarm's start time is most recent
		Mojo.Log.info("$$$$$$$$ Reminder-assistant reissueAutoSnoozedAlerts start: reminders in list: "+reminders.size());
		var latestReminderIndex = -1;
		var latestStartTime = 0;
		for(var i = 0; i < reminders.size(); i++){
			var reminder = reminders[i];
			var closeTime = new Date(reminder.time + reminder.duration);
			if(now < closeTime && reminder.time > latestStartTime && reminder.userClosed == false){
				latestStartTime = reminder.time;
				latestReminderIndex = i;
			}
		}
		
		//Reissue the alarm.
		if (latestReminderIndex != -1) {
			var reminder = reminders[latestReminderIndex];
			Mojo.Log.info("$$$$$$$$ Reminder-assistant reissueAutoSnoozedAlerts reissuing: "+reminder.id);
			new Mojo.Service.Request('palm://com.palm.applicationManager', {
					                    method: 'open',
					                    parameters: {
													'id': 'com.palm.app.calendar',
													'params': {'alarmsnooze': reminder.id,'dontAlert':true}
													},
					                	});
		}
	},
	
	onEvent: function(event) {	
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onEvent: start: " + this.reminder.id);
		
		this.dismissed = true;
		this.closeAlert();
		this.removeReminder();
		this.showEventDetails();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onEvent: end: " + this.reminder.id);
	},

	onDismiss: function(event) {		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onDismiss: start: " + this.reminder.id);
		
		this.dismissed = true;
		this.closeAlert();
		this.removeReminder();
		this.autoSnoozed = false;
		this.reminder.userClosed = true;
		this.reissueAutoSnoozedAlerts();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onDismiss: end: " + this.reminder.id);
	},

	onEmail: function(event) {		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onEmail: start " + this.reminder.id);
		
		if (this.reminder.attendees.length > 0) {
			var messageBody = $L('Running late, on my way...');
			getAppManagerService().launchComposeMessage(this.controller, 
														this.reminder.subject, 
														this.reminder.attendees, 
														messageBody,
														this.reminder.emailAccountId);
			this.closeAlert();
		}
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onEmail: end " + this.reminder.id);
	},

	onSnooze: function(event) {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onSnooze: start: " + this.reminder.id);
		this.snoozed =true;
		this.closeAlert();
		this.autoSnoozed = false;
		this.reminder.userClosed = true;
		this.reminder.scheduleStartTime = true;
		this.reissueAutoSnoozedAlerts();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant onSnooze: end: " + this.reminder.id);
	},
	
	removeReminder: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant removeReminder: start: " + this.reminder.id);
		this.reminders.removeReminder(this.reminder.id);
		Mojo.Log.info("$$$$$$$$ Reminder-assistant removeReminder: end: " + this.reminder.id);
	},
	
	scheduleAtStartTime: function(){
		
		//Schedule the alarm to go off again at the start time
		if(this.reminder.scheduleStartTime && (new Date().getTime()) < this.reminder.time){
			Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAtStartTime: scheduling "+this.reminder.id+" for "+new Date(this.reminder.time));

			this.controller.serviceRequest('palm://com.palm.taskScheduler', {
					                    method: 'updateTask',
					                    parameters: {uri: 'palm://com.palm.applicationManager/open',
													 arguments: {'id': 'com.palm.app.calendar',
													 			 'params': {'alarmsnooze': this.reminder.id}},
													 key: 'calendar-snooze-' + this.reminder.id,
													 start: {date: new Date(this.reminder.time).toUTCString()},
													 prereq: ['MSM_OFF'],
													 misfirePolicy: {executeNow: true}}
					                	});
		}
		this.reminder.scheduleStartTime = false;
	},
	
	snooze: function(minutes) {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: start: " + this.reminder.id);
		
		if(this.autoSnoozed && this.reminder.userClosed == false) {
			//if autoSnoozed, let the reminder go to the missed reminders list without snoozing.
			Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: autosnoozed "+this.reminder.id);
			return;
		}	
		
		var snooze = new Date().addMinutes(minutes);
		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: updateTask: calendar-snooze-" + this.reminder.id + "   date = " + snooze.toUTCString());
		
		this.controller.serviceRequest('palm://com.palm.taskScheduler', {
					                    method: 'updateTask',
					                    parameters: {uri: 'palm://com.palm.applicationManager/open',
													 arguments: {'id': 'com.palm.app.calendar',
													 			 'params': {'alarmsnooze': this.reminder.id}},
													 key: 'calendar-snooze-' + this.reminder.id,
													 start: {date: snooze.toUTCString()},
													 prereq: ['MSM_OFF'],
													 misfirePolicy: {executeNow: true}}
					                	});


		var templateModel = {};
		var templateStr = $L("Snoozed for #{num} minutes");
		templateModel.num =minutes;
		var template = new Template(templateStr);
		var snoozeText=template.evaluate(templateModel);
		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: showBanner" + this.reminder.id);
		Mojo.Controller.appController.showBanner({messageText: snoozeText}, null /*launchArguments*/, "calendar-snooze");

		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: end" + this.reminder.id);
	},
	
	closeAlert: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: start ");
		this.reminders.stopObservingReminders('alert');
		Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: window.close() ");
		this.controller.window.close();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant closeAlert: end ");
	},
	
	autoCloseAlert: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant autoCloseAlert: start" + this.reminder.id);
		this.dismissed = true; // prevent snooze
		this.closeAlert();
		Mojo.Log.info("$$$$$$$$ Reminder-assistant autoCloseAlert: end " + this.reminder.id);
	},
	
	specialCleanup:function(){
		//we need to do this so that cleanup cleans the reminder rightaway		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant specialCleanup: window Name:" + this.controller.window.name);
		
		//we're auto-snoozing this because another reminder is being put up.
		this.controller.window.close();
		this.autoSnoozed =true;
	},
	
	showEventDetails: function() {
		this.controller.serviceRequest('palm://com.palm.applicationManager', {
					                    method: 'open',
					                    parameters: {
													'id': 'com.palm.app.calendar',
													'params': {'details': this.reminder.id.toString() }	
													},
					                	});
	},
	
	scheduleAutoCloseTask: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAutoCloseTask: start " + this.reminder.id);
		var minCloseTime = new Date(this.reminder.time).addMinutes(15);
		var closeTime = new Date(this.reminder.time + this.reminder.duration);
		if (closeTime < minCloseTime)
			closeTime = minCloseTime;
		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: scheduleAutoCloseTask: calendar-alarmclose-" + this.reminder.id + "   date = " + closeTime.toUTCString());
		this.controller.serviceRequest('palm://com.palm.taskScheduler', {
					                    method: 'updateTask',
					                    parameters: {uri: 'palm://com.palm.applicationManager/open',
													 arguments: {'id': 'com.palm.app.calendar',
													 			 'params': {'alarmclose': this.reminder.id}},
													 key: 'calendar-alarmclose-'+this.reminder.id,
													 start: {date: closeTime.toUTCString()}}
					                	});
		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant scheduleAutoCloseTask: end " + this.reminder.id);
	},
	
	removeAutoCloseTask: function() {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant removeAutoCloseTask: start " + this.reminder.id);
		
		Mojo.Log.info("$$$$$$$$ Reminder-assistant snooze: removeTask: calendar-alarmclose-" + this.reminder.id);
		this.controller.serviceRequest('palm://com.palm.taskScheduler', {
					                    method: 'removeTask',
					                    parameters: {key: 'calendar-alarmclose-'+this.reminder.id}
					                	});
		Mojo.Log.info("$$$$$$$$ Reminder-assistant removeAutoCloseTask: end " + this.reminder.id);
	},
	
  	replaceHTML: function(element, content) {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant replaceHTML:start");
      	var range = element.ownerDocument.createRange();
      	range.selectNode(element);
      	content = range.createContextualFragment(content.stripScripts());
      	element.parentNode.replaceChild(content, element);
		Mojo.Log.info("$$$$$$$$ Reminder-assistant replaceHTML:end");
      	return element;
  	},
	
	updateHTML: function(element, content) {
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateHTML:start");
		element.innerHTML = content;
		Mojo.Log.info("$$$$$$$$ Reminder-assistant updateHTML:end");
		return element;
	},
	
});
