// constants
const REMINDER_FOX_MIGRATED_PREF_VERSION="1.9.5";

const REMINDER_PRIORITY_NORMAL = null;  // default
const REMINDER_PRIORITY_IMPORTANT = 1;

const REMINDER_RECURRENCE_ONETIME = null;  // default
const REMINDER_RECURRENCE_YEARLY = 0;
const REMINDER_RECURRENCE_MONTHLY_DATE = 1;
const REMINDER_RECURRENCE_MONTHLY_DAY = 3;
const REMINDER_RECURRENCE_WEEKLY = 4;
const REMINDER_RECURRENCE_YEARLY_DAY = 6;
const REMINDER_RECURRENCE_DAILY = 7;

const REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE = null;  // default
const REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED = 1;
const REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED = 2;

const REMINDERFOX_EXTENDED = "X-REMINDERFOX-";

const REMINDERFOX_FILE_LAST_MODIFIED=REMINDERFOX_EXTENDED + "LAST-MODIFIED";

const REMINDER_FOX_DOMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];// # of days in Non-Leap year Month 
const REMINDER_FOX_lDOMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // # of days in Leap year Month 

// configurable preferences   
const REMINDER_FOX_ENABLE_ALERT_PREF = "enableAlertFor"; 
const REMINDER_FOX_ENABLE_ALERT_PREF_NONE = "none"; 
const REMINDER_FOX_ENABLE_ALERT_PREF_TODAY = "today"; 
const REMINDER_FOX_ENABLE_ALERT_PREF_UPCOMING = "upcoming"; 
const REMINDER_FOX_ENABLE_ALERT_PREF_ALL = "all"; 
const REMINDER_FOX_SUSPEND_ALERT_PREF = "SUSPENDED:";

const REMINDER_FOX_ENABLE_CONTEXT_MENUS = "enableContextMenus"; 

const REMINDER_FOX_MAIL_PATH = "mail.app.location";
const REMINDER_FOX_MAIL_SENDER = "mail.sender";

const REMINDER_FOX_ALERT_TIMEOUT_PREF="alertTimeout";
const REMINDER_FOX_ALERT_TIMEOUT_DEFAULT = 120; // number of minutes between alerts

const REMINDER_FOX_HTML_STYLESHEET_PREF = "html.stylesheet";

const REMINDER_FOX_SHOW_WEEK_NUMS_PREF = "showWeekNumbers";

const UPCOMING_REMINDER_DAYS_PREF="upcomingReminderDays";
const UPCOMING_REMINDER_DAYS_DEFAULT = 15;

const REMINDER_FOX_UPCOMING_REMINDERS_LABEL="upcomingRemindersLabel";
const REMINDER_FOX_UPCOMING_REMINDERS_LABEL_DEFAULT="[longMonth] [date]: [reminderDesc] ([time])";

const REMINDER_FOX_TODAYS_REMINDERS_LABEL="todaysRemindersLabel";
const REMINDER_FOX_TODAYS_REMINDERS_LABEL_DEFAULT="[reminderDesc] ([time])";

const REMINDER_FOX_LIST_DATE_LABEL="listDateLabel";
const REMINDER_FOX_LIST_DATE_LABEL_DEFAULT = "[longMonth] [date]";

const REMINDER_FOX_SHOW_STATUS_TEXT="showReminderStatusText";
const REMINDER_FOX_SHOW_STATUS_TEXT_DEFAULT=true;

const REMINDER_FOX_SHOW_REMINDERS_IN_TOOLTIP="showRemindersInTooltip";
const REMINDER_FOX_SHOW_REMINDERS_IN_TOOLTIP_DEFAULT=true;

const REMINDER_FOX_SHOW_TODOS_IN_TOOLTIP="showTodosInTooltip";
const REMINDER_FOX_SHOW_TODOS_IN_TOOLTIP_DEFAULT=true;

const REMINDER_FOX_ALARM_SOUND="alarmSound";
const REMINDER_FOX_ALARM_SOUND_DEFAULT=true;

const REMINDER_FOX_ALERT_SOUND="alertSound";
const REMINDER_FOX_ALERT_SOUND_DEFAULT=false;

const REMINDER_FOX_ALARM_SOUND_PATH="alarmSoundPath";
const REMINDER_FOX_ALARM_SOUND_PATH__DEFAULT="";

const REMINDER_FOX_USE_24_HOUR_TIME="use24HourTime";
const REMINDER_FOX_USE_24_HOUR_TIME_DEFAULT=false;

const REMINDER_FOX_ALARMS_ENABLED="alarmsEnabled";
const REMINDER_FOX_ALARMS_ENABLED_DEFAULT=true;

const REMINDER_FOX_HIGHLIGHT_TODAYS_REMINDERS="highlightTodaysReminders";
const REMINDER_FOX_HIGHLIGHT_TODAYS_REMINDERS_DEFAULT=true;


const REMINDER_FOX_DEFAULT_REPEAT="reminderDefaultRepeat";
const REMINDER_FOX_DEFAULT_ALARM_TIME="reminderDefaultAlarmTime";
const REMINDER_FOX_DEFAULT_ALARM_UNITS="reminderDefaultAlarmUnits";
const REMINDER_FOX_DEFAULT_REMIND_UNTIL_COMPLETED="reminderDefaultRemindUntilCompleted";
const REMINDER_FOX_DEFAULT_ALL_DAY="reminderDefaultAllDay";
const REMINDER_FOX_DEFAULT_CATEGORY="reminderDefaultCategory";
const REMINDER_FOX_DEFAULT_SHOW_IN_TOOLTIP="reminderDefaultShowInTooltip";
const REMINDER_FOX_DEFAULT_FILTER_REMINDER="reminderDefaultFilter";
const REMINDER_FOX_DEFAULT_FILTER_TODO="reminderDefaultFilterTodo";
const REMINDER_FOX_DEFAULT_MORE="reminderDefaultMore";
const REMINDER_FOX_DEFAULT_MORE_DEFAULT_VALUE="location,url";
const REMINDER_FOX_CALENDAR_START_DAY="calendarStartDay";
const REMINDER_FOX_CALENDAR_START_DAY_DEFAULT= 0;
const REMINDER_FOX_CALENDAR_SIZE="calendarSize";
const REMINDER_FOX_ALARM_SOUND_INTERVAL="alarmSoundInterval";
const REMINDER_FOX_STATUS_TEXT_MAX_LENGTH ="statusTextMaxLength";

const REMINDER_FOX_KEY_SHORTCUT_OPEN ="keyboard.shortcut.openReminderFox";
const REMINDER_FOX_KEY_SHORTCUT_ADD ="keyboard.shortcut.addEvent";

const REMINDER_FOX_TOOLBAR="toolbar";
const REMINDER_FOX_TOOLBAR_DEFAULT="status-bar";

const REMINDER_FOX_DEFAULT_EDIT="defaultEdit";
const REMINDER_FOX_DEFAULT_EDIT_DEFAULT="reminders";

const REMINDER_FOX_TOOLBAR_POSITION = "toolbarPosition";
const REMINDER_FOX_TOOLBAR_POSITION_DEFAULT = -1;

const REMINDER_FOX_REPEAT_PREVIOUS_OCCURRENCES = "repeatPreviousOccurrences";
const REMINDER_FOX_REPEAT_UPCOMING_OCCURRENCES = "repeatUpcomingOccurrences";

const REMINDER_FOX_HIDE_COMPLETED_ITEMS = "hideCompletedItems";

const REMINDER_FOX_PREF_ALERTSLIDER_MAX_HEIGHT = "alertSliderMaxHeight";


const REMINDER_FOX_MIGRATED_PREF="migrated";

const REMINDER_FOX_TODO_LISTS = "todoLists";

const REMINDER_FOX_SUBSCRIPTIONS = "subscriptions";

const REMINDER_FOX_SORT_COLUMNS_PREF = "sortColumns";

const REMINDER_FOX_PREF = "extensions.reminderFox";

const REMINDER_FOX_DEFAULT_TODOS_CATEGORY = "ToDo's";
const REMINDER_FOX_DEFAULT_REMINDERS_CATEGORY = "Reminders";

const REMINDER_FOX_QUICK_ALARMS = "quickAlarms"; 


// network
const REMINDER_FOX_NETWORK_SYNCHRONIZE = "network.synchronize";
const REMINDER_FOX_NETWORK_SYNCHRONIZE_DEFAULT = false;
const REMINDER_FOX_PROTO = "network.protocol";
const REMINDER_FOX_DEFAULT_PROTO = "ftp";
const REMINDER_FOX_ADDRESS = "network.address";
const REMINDER_FOX_USERNAME = "network.username";

const REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI = 0;
const REMINDER_FOX_UI_MODE_HEADLESS = 1;
const REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS = 2;

// categories
const REMINDER_FOX_CATEGORIES = "categories";  

// old reminder/todo strings for migration purposes
const REMINDER_FOX_REMINDERS = "reminderFox.reminders";
const REMINDER_FOX_TODOS = "reminderFox.todos";

const REMINDER_FOX_STORE_FILE =  "storeFile";

const REMINDER_FOX_DEBUG = "debug";
const REMINDER_FOX_LOG = REMINDER_FOX_DEBUG + "." + "loglevel";
const REMINDER_FOX_LOG_LEVEL_NONE = 0;
const REMINDER_FOX_LOG_LEVEL_INFO = 1;
const REMINDER_FOX_LOG_LEVEL_FINE = 2;
const REMINDER_FOX_LOG_LEVEL_SUPER_FINE = 3;
const REMINDER_FOX_LOG_DEFAULT =REMINDER_FOX_LOG_LEVEL_NONE;
const REMINDER_FOX_LAST_UPDATE =  "lastUpdate";
const REMINDER_FOX_LAST_ALERT = "lastAlert";
const REMINDER_FOX_LAST_PROCESSED = "lastProcessed";
const REMINDER_FOX_LAST_MODIFIED = "lastModified";

// images
const REMINDER_FOX_NOTES_IMAGE =  "chrome://reminderfox/skin/images/notes.png";
const REMINDER_FOX_MAIL_IMAGE =  "chrome://reminderfox/skin/images/mail.png";
const REMINDER_FOX_REMIND_UNTIL_COMPLETED_TO_BE_MARKED_IMAGE = "chrome://reminderfox/skin/images/ribbon-blue-small.png";
const REMINDER_FOX_REMIND_UNTIL_COMPLETED_IMAGE = "chrome://reminderfox/skin/images/ribbon-red-small.png";
const REMINDER_FOX_COMPLETED_IMAGE = "chrome://global/skin/checkbox/cbox-check.gif";
const REMINDER_FOX_COMPLETED_TODO_IMAGE = "chrome://global/skin/checkbox/cbox-check.gif";
const REMINDER_FOX_SHOW_IN_TOOLTIP_IMAGE = "chrome://reminderfox/skin/images/tooltip.png";
const REMINDER_FOX_ALARM_IMAGE = "chrome://reminderfox/skin/images/alarmbell.png";
const REMINDER_FOX_ALARM_SNOOZE_IMAGE = "chrome://reminderfox/skin/images/alarmbellSnooze.png";
	
// sorting order	
const REMINDER_FOX_SORT_DIRECTION_ASCENDING = 0;
const REMINDER_FOX_SORT_DIRECTION_DESCENDING = 1;
	
// The number of milliseconds in one day
const REMINDER_FOX_ONE_DAY = 1000 * 60 * 60 * 24;
const REMINDER_FOX_NEGATIVE_ONE_DAY = REMINDER_FOX_ONE_DAY * -1;
const REMINDER_FOX_TWO_DAYS = REMINDER_FOX_ONE_DAY * 2;

const reminderFox_prefs = Components.classes["@mozilla.org/preferences-service;1"].
                getService(Components.interfaces.nsIPrefBranch);
                
const reminderFox_prefsBranch = Components.classes["@mozilla.org/preferences-service;1"]. 
				getService(Components.interfaces.nsIPrefService). 
				getBranch(REMINDER_FOX_PREF + ".");
				
				              
const reminderFox_nsISupportsString = Components.interfaces.nsISupportsString;
const reminderFox_consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);


const go4Process = Components.classes["@mozilla.org/process/util;1"]
	                        .createInstance(Components.interfaces.nsIProcess);        

const reminderFox_weekday=new Array("SU", "MO", "TU", "WE", "TH", "FR", "SA" );

var reminderFox_lastModifiedTime;

var reminderFox_timezones = { };

var reminderFoxEvents;
var reminderFoxTodosArray;   // ToDo's, Movies, Albums
var reminderFoxExtraInfo;

var reminderfox_Method;

var global_reminderFoxBundle;

const REMINDERFOX_PREF_TYPE = { BOOL : 0, INT : 1, CHAR : 2, COMPLEX : 3 }

var  reminderFox_user_prefs = null;
function reminderFox_initUserPrefsArray() {
	reminderFox_user_prefs = { } ;
	
	reminderFox_user_prefs[REMINDER_FOX_ENABLE_ALERT_PREF] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_SHOW_STATUS_TEXT] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_USE_24_HOUR_TIME] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_HIGHLIGHT_TODAYS_REMINDERS] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_HIDE_COMPLETED_ITEMS] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_SHOW_REMINDERS_IN_TOOLTIP] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_SHOW_TODOS_IN_TOOLTIP] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_ENABLE_CONTEXT_MENUS] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[UPCOMING_REMINDER_DAYS_PREF] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_EDIT] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_ALERT_TIMEOUT_PREF] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_UPCOMING_REMINDERS_LABEL] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_TODAYS_REMINDERS_LABEL] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_LIST_DATE_LABEL] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_ALARM_SOUND] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_ALERT_SOUND] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_CALENDAR_START_DAY] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_SHOW_WEEK_NUMS_PREF] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_CALENDAR_SIZE] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_ALARM_SOUND_INTERVAL] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_STATUS_TEXT_MAX_LENGTH] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_STORE_FILE] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_NETWORK_SYNCHRONIZE] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_REPEAT_UPCOMING_OCCURRENCES] = REMINDERFOX_PREF_TYPE.INT;		
	reminderFox_user_prefs[REMINDER_FOX_REPEAT_PREVIOUS_OCCURRENCES] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_PREF_ALERTSLIDER_MAX_HEIGHT] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_ALARM_SOUND_PATH] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_KEY_SHORTCUT_OPEN] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_KEY_SHORTCUT_ADD] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_ALL_DAY] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_REPEAT] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_MORE] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_ALARM_TIME] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_ALARM_UNITS] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_REMIND_UNTIL_COMPLETED] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_PROTO] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_ADDRESS] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_USERNAME] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_HTML_STYLESHEET_PREF] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_TODO_LISTS] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_SUBSCRIPTIONS] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_CATEGORIES] = REMINDERFOX_PREF_TYPE.COMPLEX;
	reminderFox_user_prefs[REMINDER_FOX_TOOLBAR_POSITION] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_TOOLBAR] = REMINDERFOX_PREF_TYPE.CHAR;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_SHOW_IN_TOOLTIP] = REMINDERFOX_PREF_TYPE.BOOL;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_FILTER_REMINDER] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_FILTER_TODO] = REMINDERFOX_PREF_TYPE.INT;
	reminderFox_user_prefs[REMINDER_FOX_DEFAULT_CATEGORY] = REMINDERFOX_PREF_TYPE.COMPLEX;		 		 		 		 	
}

function reminderFox_getPreferenceValue( preferenceName, defaultValue ) {
	if ( reminderFox_user_prefs == null ) {
		reminderFox_initUserPrefsArray();
	}
	var prefValue;
	try { 
		var prefType = reminderFox_user_prefs[preferenceName];
		if ( prefType == REMINDERFOX_PREF_TYPE.COMPLEX ) {			
			prefValue = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + preferenceName);	
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.CHAR ) {
				prefValue = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + preferenceName );				
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.BOOL ) {
				prefValue = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + preferenceName );
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.INT ) {
				prefValue = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + preferenceName );
		}		
	}
	catch ( e ) {
		prefValue = defaultValue;  // if no existing value, use the default value		
	}	
	return prefValue;
}

function reminderFox_setPreferenceValue( preferenceName, preferenceValue ) {	
	if ( reminderFox_user_prefs == null ) {
		reminderFox_initUserPrefsArray();
	}
	try { 
		var prefType = reminderFox_user_prefs[preferenceName];
		if ( prefType == REMINDERFOX_PREF_TYPE.COMPLEX ) {				
			reminderFox_setUnicodePref( preferenceName, preferenceValue);			 				
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.CHAR ) {					
			reminderFox_prefsBranch.setCharPref( preferenceName, preferenceValue);					
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.BOOL ) {
			if ( preferenceValue == "true" || preferenceValue == true ) {
				reminderFox_prefsBranch.setBoolPref( preferenceName, true);	
			}
			else {
				reminderFox_prefsBranch.setBoolPref( preferenceName, false);	
			}			
		}
		else if ( prefType == REMINDERFOX_PREF_TYPE.INT ) {
				reminderFox_prefsBranch.setIntPref(  preferenceName, parseInt( preferenceValue) );				
		}	
	}
	catch ( e ) {		
		reminderFox_logMessageLevel("exception setting VAL: " +REMINDER_FOX_PREF + "." + preferenceName + " == " + preferenceValue + "  :" + 
			 new Date() + " -- " + lastModified, REMINDER_FOX_LOG_LEVEL_INFO);	 
	}
}

const reminderFoxActivateXML = false;
function 	rmReadCategories2prefs() {
	var rmCategoriesStandard = null;
	if (reminderFoxActivateXML ) {		// =true the "cat"-prefs work with XML-file
		reminderFox_readCategoriesXML();
		reminderfox_writeCategoriesXML();
	} 
	else  {
		try {
			rmCategoriesStandard = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_CATEGORIES);	
		} catch(e) {
			rmCategoriesStandard = "";
		}
		if (rmCategoriesStandard == "") {
			rmWriteCategories2prefs(rmCategoriesStandard);   /* write back eg. to initialize with default values  */
		}
	}
	return rmCategoriesStandard;
}

function 	rmWriteCategories2prefs(rmCategoriesStandard) {	
	
	if (reminderFoxActivateXML ) {		// =true the "cat"-prefs work with XML-file
		reminderfox_writeCategoriesXML();
	} 
	else  {			
		reminderFox_setUnicodePref( REMINDER_FOX_CATEGORIES, rmCategoriesStandard);			
	}
}

//gW ++++  ++++  ++++  ++++  ++++   read/write the 'categories' XML file



function reminderFox_readCategoriesXML() {						/* ------- XML  READ */
	var  rmCategoriesXMLFile	= "categoriesPIM.xml"
	// get RmFx ICS storage dir/file name & change for 'categories.prefs'
	var file =   reminderFox_getReminderStoreFile();
	file.leafName = rmCategoriesXMLFile;
	
	try {
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("Permission to read file was denied.");
	}

	var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
		.createInstance( Components.interfaces.nsIFileInputStream );
	try {
		is.init( file,0x01, 00004, null);
	}
	catch ( e ) {
		reminderFox_logMessageLevel("Could not read reminder file: " 
			+ e.name  +  " -- " + e.message, REMINDER_FOX_LOG_LEVEL_INFO);
		return -1;
	}
	
	var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
						.createInstance(Components.interfaces.nsIScriptableInputStream);
	scriptableStream.init(is);
	var chunk = scriptableStream.read(scriptableStream.available());		

	var domParser = new DOMParser();
	var dom = domParser.parseFromString(chunk, "text/xml");
	
	rmCategoriesStandard = "";

	for (var i=0; i < dom.childNodes.length  ; i++){
		if (dom.childNodes[i].nodeType == 1) {
			for (var j=0; j < dom.childNodes[i].childNodes.length  ; j++) {
				if (dom.childNodes[i].childNodes[j].tagName == "default") {
					var rmCategoriesStandard_DEFAULT = dom.childNodes[i].childNodes[j].textContent;
				}
				if (dom.childNodes[i].childNodes[j].tagName == "main") {
					rmCategoriesStandard = dom.childNodes[i].childNodes[j].textContent;
				}
				if (dom.childNodes[i].childNodes[j].tagName == "user") {
					var rmCategoriesUser = dom.childNodes[i].childNodes[j].textContent;
				}
			}
		}
	}
	
	return 0; // no errors
}

function reminderfox_writeCategoriesXML() {			/* ---------------- XML WRITE */
	var nL = "\n";
	var  rmCategoriesXMLFile	= "categoriesPIM.xml"
	// get RmFx ICS storage dir/file name & change for 'categories.prefs'
	var file =   reminderFox_getReminderStoreFile();
	file.leafName = rmCategoriesXMLFile;

	comStr= '<?xml version=\"1.0\"?>' +nL
			+"<!-- " + nL
			+"  Categories 'Personal Information Management' Preferences" + nL
			+"  Do not edit this file while the appliacation is running!" + nL
			+" " + nL
			+"  On exit, the application writes changes made during is was" + nL
			+"  active, so manual changes will be overwritten / lost!" + nL
			+"-->" +nL ;

	comStr += "<CategoriesPIM version=\"0.1\"> " + nL;
	var defaultCategories =  reminderFox_getBundle().getString("rf.categories.initial.defaults");		
	comStr += "   <default>" + defaultCategories + "</default>" + nL;
	comStr += "   <user>" + getUserCategories() + "</user>" + nL;
	comStr += "   <main>" + rmCategoriesStandard + "</main>" + nL;
	comStr += "</CategoriesPIM>" +nL;

	var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
		.createInstance( Components.interfaces.nsIFileOutputStream );
	outputStream.init( file, 0x04 | 0x08 | 0x20, 420, 0 );
	
	var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
	                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	converter.charset = "UTF-8";
	
	var chunk = null;
	try {
		chunk = converter.ConvertFromUnicode(comStr);
	}
	catch( e ) {
		chunk = comStr;
	}
	outputStream.write(chunk, chunk.length);	
	
	 var fin = converter.Finish();
	 if (fin.length > 0)
	   outputStream.write(fin, fin.length);
	 outputStream.close();
}
//gW --++  --++  --++  --++  --++  --++  --++  --++  --++  --++  --++  --++  



function reminderFox_getBundle() {
	if ( global_reminderFoxBundle == null ) {
		global_reminderFoxBundle = document.getElementById("reminderFox-bundle");  
	//	dump( "Gotten bundle: " + global_reminderFoxBundle + "\n")
	}
	return global_reminderFoxBundle;
}

function reminderFox_logMessageLevel(logString, level){
	var logLevel = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LOG);
	if ( level <= logLevel  ) {
	    if(reminderFox_consoleService) {
	      reminderFox_consoleService.logStringMessage("reminderFox: " + logString);
	      if ( logLevel >= 2 ) {
	      	dump( "reminderFox: " + logString + "\n"  );
	      }
	    }
  	}
}

function reminderFox_debug_printStack() {
	var errno = errno;
     var fileName = Components.stack.caller.filename;
     var lineNumber = Components.stack.caller.lineNumber;
     var functionName = Components.stack.caller.name;
    
     
	 var frame = Components.stack.caller;
   var str = "";
   while (frame) {
   	 var name = frame.functionName ? frame.functionName : "[anonymous]";
   	
     if (frame.filename)
       str += frame.filename + ", Line " + frame.lineNumber;
     else
       str += "[" + gConsoleBundle.getString("noFile") + "]";
     
     str += " --> ";
     
     if (frame.functionName)
       str += frame.functionName;
     else
       str += "[" + gConsoleBundle.getString("noFunction") + "]";
       
     str += "\n";
     
     frame = frame.caller;
   }     
   
   dump( str + "\n");
     
}

/*
 *  function getStackTrace () {
      var frame = Components.stack.caller;
     var str = "<top>";
 
     while (frame)
     {
         var name = frame.name ? frame.name : "[anonymous]";
         str += "\n" + name + "@" + frame.lineNumber;
         frame = frame.caller;
     }
     return str; 
 }
 */
 
/* get unicode string value from preference store */
function reminderFox_getUnicodePref(prefName) {
    return reminderFox_prefs.getComplexValue(prefName, reminderFox_nsISupportsString).data;
}

/* set unicode string value */
function reminderFox_setUnicodePref(prefName,prefValue) {
    var sString = Components.classes["@mozilla.org/supports-string;1"].createInstance(reminderFox_nsISupportsString);
    sString.data = prefValue;
    reminderFox_prefsBranch.setComplexValue(prefName,reminderFox_nsISupportsString,sString);
}

// Object representing reminder events
function ReminderFoxEvent( reminderId, reminderDate, reminderSummary ) {
	this.id = reminderId;
    this.date = reminderDate;    // date object for reminder (using current year)
    this.endDate = null;
    this.durationTime = null;
    this.summary = reminderSummary;  // text of reminder
    this.notes = null;
    this.recurrence =     { type: null, endDate: null, interval: null, byDay: null }       // byday = "MO,TU,WE..."
    this.priority = null;
    this.remindUntilCompleted = null;
    this.allDayEvent = true;
    this.alarm = null;
    this.alarmLastAcknowledge = null;
    this.lastModified = null;    
    this.completedDate = null;
    this.messageID = null;
    this.extraInfo = null;
    this.categories = null;
    this.snoozeTime = null;
    this.url = null;
    this.location = null;
}

// Object representing ToDos
function ReminderFoxTodo( todoId, todoSummary, todoDate ) {
	this.id = todoId;
    this.summary = todoSummary;
    this.date = todoDate;    // date object for reminder (using current year)
    this.endDate = null;
    this.durationTime = null;
    this.priority = null;;
    this.dateStamp = null;
    this.notes = null;   
    this.recurrence =     { type: null, endDate: null, interval: null, byDay: null }  
    this.categories = null;
    this.allDayEvent = true;
    this.showInTooltip = false;
    this.completedDate = null;
    this.messageID = null;
    this.alarm = null;
    this.alarmLastAcknowledge = null;    
    this.extraInfo = null;
    this.snoozeTime = null;
    this.url = null;
    this.location = null;
}

/*
 * make a clone object of an event - useful if you want to temporarily modify some properties of an event, 
 * but don't want to change the actual model 
 */
function reminderFox_cloneReminderFoxEvent( reminderFoxEvent ) {
	var newDate = new Date( reminderFoxEvent.date.getTime() );
	var newReminderFoxEvent = new ReminderFoxEvent( reminderFoxEvent.id, newDate, reminderFoxEvent.summary );
	newReminderFoxEvent.notes = reminderFoxEvent.notes;
	newReminderFoxEvent.recurrence =  { type:  reminderFoxEvent.recurrence.type, endDate:  reminderFoxEvent.recurrence.endDate, interval:  reminderFoxEvent.recurrence.interval, byDay:  reminderFoxEvent.recurrence.byDay } ;
	newReminderFoxEvent.priority = reminderFoxEvent.priority;
	newReminderFoxEvent.remindUntilCompleted = reminderFoxEvent.remindUntilCompleted;
	newReminderFoxEvent.completedDate = reminderFoxEvent.completedDate;	
	newReminderFoxEvent.categories = reminderFoxEvent.categories;
	newReminderFoxEvent.allDayEvent = reminderFoxEvent.allDayEvent;
	newReminderFoxEvent.alarm = reminderFoxEvent.alarm;
    newReminderFoxEvent.alarmLastAcknowledge = reminderFoxEvent.alarmLastAcknowledge;
    newReminderFoxEvent.messageID = reminderFoxEvent.messageID;
    newReminderFoxEvent.lastModified = reminderFoxEvent.lastModified;
    newReminderFoxEvent.extraInfo = reminderFoxEvent.extraInfo;
    newReminderFoxEvent.snoozeTime = reminderFoxEvent.snoozeTime;
    newReminderFoxEvent.location = reminderFoxEvent.location;
    newReminderFoxEvent.url = reminderFoxEvent.url;
    if ( reminderFoxEvent.endDate != null ) {
    	newReminderFoxEvent.endDate = new Date( reminderFoxEvent.endDate.getTime() );
    }
    newReminderFoxEvent.durationTime = reminderFoxEvent.durationTime;
	return newReminderFoxEvent;
}	



/*
 * make a clone object of an event - useful if you want to temporarily modify some properties of an event, 
 * but don't want to change the actual model 
 */
function reminderFox_cloneReminderFoxTodo( reminderFoxTodo ) {
	var newDate;
	if ( reminderFoxTodo.date != null ) {
		 newDate = new Date( reminderFoxTodo.date.getTime() );
	}
	var newReminderFoxTodo = new ReminderFoxTodo(  reminderFoxTodo.id, reminderFoxTodo.summary, newDate );
	newReminderFoxTodo.priority = reminderFoxTodo.priority;
	newReminderFoxTodo.showInTooltip = reminderFoxTodo.showInTooltip;
	newReminderFoxTodo.notes = reminderFoxTodo.notes;
	newReminderFoxTodo.completedDate = reminderFoxTodo.completedDate;
	newReminderFoxTodo.messageID = reminderFoxTodo.messageID;
	newReminderFoxTodo.allDayEvent = reminderFoxTodo.allDayEvent;
	newReminderFoxTodo.recurrence =  { type:  reminderFoxTodo.recurrence.type, endDate:  reminderFoxTodo.recurrence.endDate, interval:  reminderFoxTodo.recurrence.interval, byDay:  reminderFoxTodo.recurrence.byDay } ;
	newReminderFoxTodo.categories = reminderFoxTodo.categories;
	newReminderFoxTodo.alarm = reminderFoxTodo.alarm;
    newReminderFoxTodo.alarmLastAcknowledge = reminderFoxTodo.alarmLastAcknowledge;	
    newReminderFoxTodo.extraInfo = reminderFoxTodo.extraInfo;	
    newReminderFoxTodo.snoozeTime = reminderFoxTodo.snoozeTime;
    newReminderFoxTodo.location = reminderFoxTodo.location;
    newReminderFoxTodo.url = reminderFoxTodo.url;
    if ( reminderFoxTodo.endDate != null ) {
    	newReminderFoxTodo.endDate =new Date( reminderFoxTodo.endDate.getTime() );
    }
    newReminderFoxTodo.durationTime = reminderFoxTodo.durationTime;
	return newReminderFoxTodo;
}	

function reminderFox_isLeapYear(year) { 
	return (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) ? true : false;
}


function reminderFox_launchHelp() {
    var faqURL = reminderFox_getBundle().getString("rf.faqURL");
    reminderFox_openURL( faqURL );
}

function reminderFox_openURL(UrlToGoTo) {
    if( reminderFox_isThunderBird() ) {
        var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance()
                                  .QueryInterface(Components.interfaces.nsIMessenger);
                                  
        messenger.launchExternalURL(UrlToGoTo);
    } else {        
        var navWindow;
        
        // Try to get the most recently used browser window
        try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                               .getService(Components.interfaces.nsIWindowMediator);
            navWindow = wm.getMostRecentWindow("navigator:browser");
        } catch(ex) {}
        
        if (navWindow) {  // Open the URL in most recently used browser window
            if ("delayedOpenTab" in navWindow) {
                navWindow.delayedOpenTab(UrlToGoTo);
            } else if ("loadURI" in navWindow) {
                navWindow.loadURI(UrlToGoTo);
            } else {
                navWindow._content.location.href = UrlToGoTo;
            }
        } else {  // If there is no recently used browser window open new browser window with the URL
            var ass = Components.classes["@mozilla.org/appshell/appShellService;1"]
                                .getService(Components.interfaces.nsIAppShellService);
            var win = ass.hiddenDOMWindow;
            
            win.openDialog("chrome://navigator/content/navigator.xul", "",
                           "chrome,all, dialog=no", UrlToGoTo );
        }
    }	
 /*
    var uri = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURI);
    uri.spec = aURL;
    var protocolSvc = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].getService(Components.interfaces.nsIExternalProtocolService);
    protocolSvc.loadUrl(uri);
    */
}



/*
Firefox
{ec8030f7-c20a-464f-9b0e-13a3a9e97384}

Thunderbird
{3550f703-e582-4d05-9a08-453d09bdfdc6}

Nvu
{136c295a-4a5a-41cf-bf24-5cee526720d5}

Mozilla Suite
{86c18b42-e466-45a9-ae7a-9b95ba6f5640}

SeaMonkey
{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}

Sunbird
{718e30fb-e89b-41dd-9da7-e25a45638b28}

Netscape Browser
{3db10fab-e461-4c80-8b97-957ad5f8ea47}

Flock Browser
{a463f10c-3994-11da-9945-000d60ca027b}	
*/
const REMINDERFOX_SEAMONKEY_ID = "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}";
const REMINDERFOX_THUNDERBIRD_ID = "{3550f703-e582-4d05-9a08-453d09bdfdc6}";
function reminderFox_isThunderBird() {
	var id;
	  if("@mozilla.org/xre/app-info;1" in Components.classes) {
	    // running under Mozilla 1.8 or later
	    id = Components.classes["@mozilla.org/xre/app-info;1"]
	                   .getService(Components.interfaces.nsIXULAppInfo).ID;
	  } else {
	    try {
	      id = Components.classes["@mozilla.org/preferences-service;1"]
	                     .getService(Components.interfaces.nsIPrefBranch)
	                     .getCharPref("app.id");
	    } catch(e) {
	    }
	  }
 	if ( id != null && id == REMINDERFOX_THUNDERBIRD_ID ) {
		return true;
	}
	else { 
		return false;
	}
}

function reminderFox_isSunbirdOrLightning() {
	var id;
	  if("@mozilla.org/xre/app-info;1" in Components.classes) {
	    // running under Mozilla 1.8 or later
	    id = Components.classes["@mozilla.org/xre/app-info;1"]
	                   .getService(Components.interfaces.nsIXULAppInfo).ID;
	  } else {
	    try {
	      id = Components.classes["@mozilla.org/preferences-service;1"]
	                     .getService(Components.interfaces.nsIPrefBranch)
	                     .getCharPref("app.id");
	    } catch(e) {
	    }
	  }
	  
	// check if this is Sunbird
 	if ( id != null && id == "{718e30fb-e89b-41dd-9da7-e25a45638b28}" ) {
		return true;
	}
	else 	if ( id != null && id == REMINDERFOX_THUNDERBIRD_ID ) {
		var em = Components.classes["@mozilla.org/extensions/manager;1"]
                   .getService(Components.interfaces.nsIExtensionManager);
		var addon = em.getItemForID("{e2fda1a4-762b-4020-b5ad-a41df1933103}");
		// check to see if the version attribute exists (if not, then the addon doesn't exist)
		if ( addon != null && (addon.version != null && addon.version != "" )) {
			return true;
		}		
	}
	return false;
}

/*
 * @deprecated - can't rely on this, as the translated month values may differ between the properties and dtd files
 *
function reminderFox_getMonthAsInteger(monthTextValue) {
	var prefMonth;
	switch (monthTextValue.toUpperCase()) {
		
		case reminderFox_getBundle().getString("rf.options.month.0.name").toUpperCase():
			prefMonth = 0;
			break;

		case reminderFox_getBundle().getString("rf.options.month.1.name").toUpperCase():
			prefMonth = 1;
			break;

		case reminderFox_getBundle().getString("rf.options.month.2.name").toUpperCase():
			prefMonth = 2;
			break;

		case reminderFox_getBundle().getString("rf.options.month.3.name").toUpperCase():
			prefMonth = 3;
			break;

		case reminderFox_getBundle().getString("rf.options.month.4.name").toUpperCase():
			prefMonth = 4;
			break;

		case reminderFox_getBundle().getString("rf.options.month.5.name").toUpperCase():
			prefMonth = 5;
			break;

		case reminderFox_getBundle().getString("rf.options.month.6.name").toUpperCase():
			prefMonth = 6;
			break;

		case reminderFox_getBundle().getString("rf.options.month.7.name").toUpperCase():
			prefMonth = 7;
			break;

		case reminderFox_getBundle().getString("rf.options.month.8.name").toUpperCase():
			prefMonth = 8;
			break;

		case reminderFox_getBundle().getString("rf.options.month.9.name").toUpperCase():
			prefMonth = 9;
			break;

		case reminderFox_getBundle().getString("rf.options.month.10.name").toUpperCase():
			prefMonth = 10;
			break;

		case reminderFox_getBundle().getString("rf.options.month.11.name").toUpperCase():
			prefMonth = 11;
			break;
					
	}
	return prefMonth;

}


function reminderFox_getShortMonthAsInteger(monthTextValue) {
	var prefMonth;
	switch (monthTextValue.toUpperCase()) {
		case reminderFox_getBundle().getString("rf.options.month.0.Mmm").toUpperCase():
			prefMonth = 0;
			break;

		case reminderFox_getBundle().getString("rf.options.month.1.Mmm").toUpperCase():
			prefMonth = 1;
			break;

		case reminderFox_getBundle().getString("rf.options.month.2.Mmm").toUpperCase():
			prefMonth = 2;
			break;

		case reminderFox_getBundle().getString("rf.options.month.3.Mmm").toUpperCase():
			prefMonth = 3;
			break;

		case reminderFox_getBundle().getString("rf.options.month.4.Mmm").toUpperCase():
			prefMonth = 4;
			break;

		case reminderFox_getBundle().getString("rf.options.month.5.Mmm").toUpperCase():
			prefMonth = 5;
			break;

		case reminderFox_getBundle().getString("rf.options.month.6.Mmm").toUpperCase():
			prefMonth = 6;
			break;

		case reminderFox_getBundle().getString("rf.options.month.7.Mmm").toUpperCase():
			prefMonth = 7;
			break;

		case reminderFox_getBundle().getString("rf.options.month.8.Mmm").toUpperCase():
			prefMonth = 8;
			break;

		case reminderFox_getBundle().getString("rf.options.month.9.Mmm").toUpperCase():
			prefMonth = 9;
			break;

		case reminderFox_getBundle().getString("rf.options.month.10.Mmm").toUpperCase():
			prefMonth = 10;
			break;

		case reminderFox_getBundle().getString("rf.options.month.11.Mmm").toUpperCase():
			prefMonth = 11;
			break;
					
	}
	return prefMonth;

}
*/

function reminderFox_networkSynchronizeCallback() {
	reminderFox_upload_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS);	
}

function reminderFox_getMonthAsText(integerValue) {
	return reminderFox_getBundle().getString("rf.options.month."+integerValue+".name");
}


function reminderFox_loadDefaultPreferences() {
	try {
		var oldVersionNumber = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_MIGRATED_PREF); 
		if ( oldVersionNumber != REMINDER_FOX_MIGRATED_PREF_VERSION ) {
			if ( oldVersionNumber == null || oldVersionNumber == "" ) {
				// this pref is not set; this is new installation...  
				// handle any new work here
                reminderFox_firstStart();
				
			}
			// set version number to new current version
			try {
				reminderFox_prefsBranch.setCharPref(REMINDER_FOX_MIGRATED_PREF, REMINDER_FOX_MIGRATED_PREF_VERSION);		
			} catch(e) {		
			}	
			// this is an older version; we need to handle migration code	
			//	reminderFox_handleMigration( oldVersionNumber );		
		}		
	} catch(e) {
		// this is an older version; we need to handle migration code		
		reminderFox_handleMigration("0.0");
	}				
	

	try {
		reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TOOLBAR_POSITION);
	} catch(e) {
		reminderFox_prefsBranch.setIntPref(REMINDER_FOX_TOOLBAR_POSITION, REMINDER_FOX_TOOLBAR_POSITION_DEFAULT);
		
		try {
			// set the default location to the current location as of this moment
		    var reminderFox_toolbar = document.getElementById(reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TOOLBAR));
		    var box = document.getElementById("reminderFox-statusLabel");
		    if (reminderFox_toolbar) {
		    	var currentIndex = reminderFox_indexOf(reminderFox_toolbar, box, true);
		    	reminderFox_prefsBranch.setIntPref(REMINDER_FOX_TOOLBAR_POSITION, currentIndex);	    	
		    }
		}
		catch (e) {
		}
	}	

	try {
		// clear out last alert time - because we always want to show the alert slider at least once on startup
		reminderFox_prefsBranch.setCharPref( REMINDER_FOX_LAST_ALERT, "");	
	} catch(e) {		
	}		
	
	try {
		reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_MODIFIED);
	} catch(e) {
		reminderFox_prefsBranch.setCharPref(REMINDER_FOX_LAST_MODIFIED, 	"");
	}
	
	// set default categories if none are present
	var categories = "";
	try {
		categories = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_CATEGORIES);		
	} catch(e) {		
		categories = "";
	}
	if ( categories == "" ) {
		var defaultCategories =  reminderFox_getBundle().getString("rf.categories.initial.defaults");		
		reminderFox_setUnicodePref( REMINDER_FOX_CATEGORIES, defaultCategories);		
	}
	
		
//	try {
//		// clear out last process  time - because we always want to process  on startup
//		reminderFox_prefsBranch.setCharPref( REMINDER_FOX_LAST_PROCESSED, "");	
//	} catch(e) {		
//	}
}

function reminderFox_getSortedIndexOfNewReminder(  reminderFoxEvents, newreminder, addUniqueOnly  ) {	
	var month = newreminder.date.getMonth();


	// We go through each reminder and then compare that reminder's month with 
	// the reminder-to-be-added month, and if the new month is less, add there;
	// if the months are equal, then compare the days and add appropriately. 
	for ( var i = 0; i < reminderFoxEvents.length; i++ ) {
		var reminder = reminderFoxEvents[i];
		
		// add current reminder before reminders from later months
		if (   month < reminder.date.getMonth()) { 
			return i;
		}
		// if they have the same month, then compare dates
		else if ( month == reminder.date.getMonth() ) {
			if ( newreminder.date.getDate()  <  reminder.date.getDate() ) {
				return i;
			}
			else if (  newreminder.date.getDate() == reminder.date.getDate() ) {					
				if ( addUniqueOnly && newreminder.summary == reminder.summary ) {
					// this reminder is already in the list; just ignore it
					return -1;
				}
				else {
					if ( !newreminder.allDayEvent ) { 
						// this is an hourly event.  Let's place it chronologically
						if ( reminder.allDayEvent ) {
							// the current reminder is all day; let's put chronological events 
							// first
							return i;
						}
						else {
							// the current reminder is an hour event as well; let's place them
							// chronologically.
							if ( newreminder.date.getHours() < reminder.date.getHours() || 
								( newreminder.date.getHours() == reminder.date.getHours() && newreminder.date.getMinutes() < reminder.date.getMinutes() )  ){
									return i;
							}						
						}
					}					 
					// if this is an Imp	ortant reminder, add it before other reminders of the same day
					else if ( newreminder.priority == REMINDER_PRIORITY_IMPORTANT  ) {
						return i;
					}
				}
			}
		}  // monthly			
	} // for
	
	return reminderFoxEvents.length;
}	

  function reminderFox_indexOf(aParent, aChild, overrideLast)  { 
    // -1 if it does not exist
    var children = aParent.childNodes;
    if ( children == null ) {
    	return null;
    }
    for (var x=0; x<children.length; x++) {
	    if (children[x] == aChild) {
			if ( overrideLast ) {
				return x;
			}
			else {
				return (x == children.length - 1) ? -1 : x;
			}
	    }
    }
    return null;
  }
  




function reminderFox_getSortedIndexOfNewTodo(  reminderFoxTodos, newTodo ) {
	// if current todo is important, add to start of list
    if (newTodo.priority == REMINDER_PRIORITY_IMPORTANT  ) {
		// insert at beginning
		return 0;
    }
    else {
    	// run through until find one that's not important, and add new one before it
		 for( var i = 0; i < reminderFoxTodos.length; i++) {
	        if ( !reminderFoxTodos[i].priority == REMINDER_PRIORITY_IMPORTANT  ) {
	        	if ( newTodo.showInTooltip ) {
					return i;
	        	}
	        	else {
	        		if ( !reminderFoxTodos[i].showInTooltip ) {
						return i;
	        		}
	        	}	        
	        }
		}
    }
	
	// if the reminder hasn't been added yet, then place it at the end
	return reminderFoxTodos.length;			
}
 
 function reminderFox_getValidDateForMonth( year, month, date ) {
	var lastValidDate = date;	
	var lastDayOfMonth = oeDatePicker.getLastDayOfMonth( year, month );
	if ( date > lastDayOfMonth ) {
		lastValidDate = lastDayOfMonth;
	}
	return lastValidDate;
}
 
 

function reminderFox_getAlarmInMinutes( alarm ) {
		if ( alarm == null ) {
			return null;
		}
		// example: TRIGGER;VALUE=DURATION: -PT30M
		var alarmTime = alarm;
		var result = null;						 
		var alarmIndex1 = alarmTime.indexOf( "-PT" );
		if ( alarmIndex1 != -1 ) {
			var alarmIndex2 = alarmTime.indexOf( "M", alarmIndex1 );
			if ( alarmIndex2 != -1 ) {
				alarmTime = alarmTime.substring( alarmIndex1 + "-PT".length, alarmIndex2 );		
				result = parseInt( alarmTime );	
			}
			else {
				alarmIndex2 = alarmTime.indexOf( "H", alarmIndex1 );
				if ( alarmIndex2 != -1 ) {
					alarmTime = alarmTime.substring( alarmIndex1 + "-PT".length, alarmIndex2 );		
					result = parseInt(alarmTime) * 60;
				}	
			}	
		}
		else {
			alarmIndex1 = alarmTime.indexOf( "-P" );
			if ( alarmIndex1 != -1 ) {
				var alarmIndex2 = alarmTime.indexOf( "D", alarmIndex1 );
				if ( alarmIndex2 != -1 ) {
					alarmTime = alarmTime.substring( alarmIndex1 + "-P".length, alarmIndex2 );		
					result = parseInt( alarmTime ) * 24 * 60;					
				}
			}
		}		
		return result;				 
}



// index is the number of the element you wish to remove
// from the array: reminderFoxEvents	
function reminderFox_removeElement(reminderFoxEvents, index) {

    for (index = index; index<reminderFoxEvents.length;index++) {
        // assigns the value of elementnr+1 to elementnr, so you move all items by 1
        reminderFoxEvents[index] = reminderFoxEvents[index + 1];
    }
    reminderFoxEvents.length=reminderFoxEvents.length-1;
    
}

// position is the number where you want to add the new element (reminder) into 
// the array: reminderFoxEvents	
function reminderFox_insertIntoArray(reminderFoxEvents, reminder, position) {
	var origLength = reminderFoxEvents.length;
	if ( position > origLength ) {
		position = origLength;
	}
	
	reminderFoxEvents.length = reminderFoxEvents.length + 1;

	for ( var i = origLength; i >=0; i-- ) {
		if ( i == position ) {
			reminderFoxEvents[i] = reminder;
			break;
		}
		else if ( i > position ) {
			reminderFoxEvents[i] = reminderFoxEvents[i-1];
		}
		else if ( i < position ) {
			break;
		}
	}
}
	

function reminderFox_generateUniqueReminderId(date) {
	if ( date == null ) { 
		date = new Date();
	}
	return date.getTime() + "-" + Math.round(900000000 + (Math.random() * 100000000));
}

function reminderFox_generateUniqueTodoId(date) {
	if ( date == null ) { 
		date = new Date();
	}
	return date.getTime() + Math.round(900000000 + (Math.random() * 100000000));
}	

	
	function reminderFox_getNextReminderOccurrence( reminder, originalDate, weekNumber, interval ) {
		var reminderCurrentDate = reminder.date;
		
		if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
			// do nothing; should only be once occurrence per year			
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) { 
			// do nothing; should only be once occurrence per year			
		}
		else 	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
				var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );		
				
				var month = reminderCurrentDate.getMonth();
				var year = reminderCurrentDate.getFullYear();
				month = month + interval;			 	
			 	while ( month >= 12 ) {
			 		month = month - 12;
			 		year = year + 1;
			 	}
			
			 	var dayVal = reminderFox_getValidDateForMonth( year, month, originalDate.getDate() );		
				monthReminder.date = new Date( year, month, dayVal, originalDate.getHours(), originalDate.getMinutes() );		
				
				return monthReminder;		 	
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
				var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );		
				
				var month = reminderCurrentDate.getMonth();
				var year = reminderCurrentDate.getFullYear();
				month = month + interval;			 	
			 	while ( month >= 12 ) {
			 		month = month - 12;
			 		year = year + 1;
			 	}
			 	
				var reminderDay = originalDate.getDay();
				var nextMonthDate = new Date( year, month, 1 );
				var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextMonthDate, reminderDay, weekNumber );
				monthReminder.date = new Date( year, month, reminderWeekDateThisMonth, originalDate.getHours(), originalDate.getMinutes() );				
				return monthReminder;		
		}
		else	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {	
			var weeklyReminder = reminderFox_cloneReminderFoxEvent( reminder );	
			var weeklyInterval = 1;
			if ( weeklyReminder.recurrence.interval != null  ) {
				weeklyInterval =  weeklyReminder.recurrence.interval;
			}
			weeklyReminder.date.setDate( weeklyReminder.date.getDate() + (weeklyInterval*7) );			
			return weeklyReminder;				
		}
		return null;			
	}
	
	function reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, initialStartDate ) {
		var startDate = new Date( initialStartDate.getFullYear(), initialStartDate.getMonth(), initialStartDate.getDate(), 
			initialStartDate.getHours(), initialStartDate.getMinutes() );
		var nexDate;
		var dayVal;		
		var finalDate;
		var todaysDate = new Date();
		var interval = 1;
		if ( reminder.recurrence.type  == REMINDER_RECURRENCE_ONETIME) {		
			return reminder;
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
			var reminderOriginalDate = reminder.date;  
			
			// if start date is less than the default reminder date, return the reminder date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				return  reminderFox_cloneReminderFoxEvent( reminder );
			}
			
			
			if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
				// if it's same year, just continue to normal logic;
				// otherwise, advance the year
				interval = reminder.recurrence.interval;
				if (  startDate.getFullYear() != reminderOriginalDate.getFullYear() ) {  
					
					// get the differnce and years, and add the value to the final date accordingly 	
					var yearsDiff = startDate.getFullYear() - reminderOriginalDate.getFullYear();
				    var modVal =  reminderFox_mod( yearsDiff , interval);
				    // if mod val == 0, then this year is valid; continue on 
			   		if ( modVal != 0 ) {
			   			var diff = interval - modVal;			    		
			     		startDate.setFullYear( startDate.getFullYear()+diff);
			     		dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );																				
						startDate.setDate(dayVal);			
						finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );	
						
		     			var yearReminder = reminderFox_cloneReminderFoxEvent( reminder );
						yearReminder.date = finalDate;
						return yearReminder;	
			   		}
				}	   		
			}	
			if ( reminderOriginalDate.getMonth() < startDate.getMonth() ) {
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );					
				finalDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes() );	
			}
			else if ( reminderOriginalDate.getMonth() > startDate.getMonth() ) {
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );								
				finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}
			// same month
			else {
				if ( reminderOriginalDate.getDate() < startDate.getDate() ) {
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() + interval , reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );												
					finalDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes() );		
				}
				else if ( reminderOriginalDate.getDate() > startDate.getDate() ) {
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );																
					finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
				}
				else {   // same date; return it
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );																				
					finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
				}
			}
	
			var yearReminder = reminderFox_cloneReminderFoxEvent( reminder );
			yearReminder.date = finalDate;
			return yearReminder;
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) { 
			var reminderOriginalDate = reminder.date;
			
			// if start date is less than the default reminder date, then use the reminder date as start date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				startDate = reminderOriginalDate;
			}
			
			if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
				interval = reminder.recurrence.interval;
			
				// if it's same year, just continue to normal logic;
				// otherwise, advance the year
				if (  startDate.getFullYear() != reminderOriginalDate.getFullYear() ) {  
					// get the differnce and years, and add the value to the final date accordingly 	
					var yearsDiff = startDate.getFullYear() - reminderOriginalDate.getFullYear();
				    var modVal =  reminderFox_mod( yearsDiff , reminder.recurrence.interval);
				    // if mod val == 0, then this year is valid; continue on 
			   		if ( modVal != 0 ) {
			   			var diff = interval - modVal;			    		
			     		startDate.setFullYear( startDate.getFullYear()+diff);
			     		
			     		var reminderDay = reminderOriginalDate.getDay();
						var weekNumber = reminderFox_getWeekNumber( reminder.date );
						var nextYearStartDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );	
						var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextYearStartDate, reminderDay, weekNumber );
						dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear(), reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );			
						finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );	
			     					     		
		     			var yearReminder = reminderFox_cloneReminderFoxEvent( reminder );
						yearReminder.date = finalDate;
						return yearReminder;	
			   		}
				}	   		
			}		

			if ( reminderOriginalDate.getMonth() < startDate.getMonth() ) {
				var reminderDay = reminderOriginalDate.getDay();
				var weekNumber = reminderFox_getWeekNumber( reminder.date );
				var nextYearStartDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );	
				var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextYearStartDate, reminderDay, weekNumber );
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );			
				finalDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );	
				}
			else if ( reminderOriginalDate.getMonth() > startDate.getMonth() ) {
				var reminderDay = reminderOriginalDate.getDay();
				var weekNumber = reminderFox_getWeekNumber( reminder.date );
				var nextYearStartDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );	
				var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextYearStartDate, reminderDay, weekNumber );			
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );								
				finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}
			// same month
			else {
				var reminderDay = reminderOriginalDate.getDay();
				var weekNumber = reminderFox_getWeekNumber( reminder.date );
				
				var nextYearStartDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );	
				var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextYearStartDate, reminderDay, weekNumber );
			
				if ( reminderWeekDateThisMonth < startDate.getDate() ) {
					nextYearStartDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), reminderOriginalDate.getDate() );	
					reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( nextYearStartDate, reminderDay, weekNumber );
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() + interval , reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );												
					finalDate = new Date( startDate.getFullYear() + interval, reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );		
				}
				else if ( reminderWeekDateThisMonth > startDate.getDate() ) {
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );																
					finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
				}
				else {   // same date; return it
					dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , reminderOriginalDate.getMonth(), reminderWeekDateThisMonth );																				
					finalDate = new Date( startDate.getFullYear(), reminderOriginalDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
				}
			}
						
			var yearReminder = reminderFox_cloneReminderFoxEvent( reminder );
			yearReminder.date = finalDate;
			return yearReminder;		
		
		}		
		else 	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
			var reminderOriginalDate = reminder.date;
			// if start date is less than the default reminder date, then use the reminder date as start date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				startDate = reminderOriginalDate;
			}
			
			if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
				interval = reminder.recurrence.interval;
				var monthsDiff = reminderFox_computerNumberOfMonthsDifference( reminderOriginalDate, startDate);
				if ( monthsDiff != 0 ) {
				
					// get the differnce and years, and add the value to the final date accordingly 						
				    var modVal =  reminderFox_mod( monthsDiff , interval);
				    // if mod val == 0, then this month is valid; continue on 
			   		if ( modVal != 0 ) {
			   			var diff =interval - modVal;			    		
			     		startDate.setMonth( startDate.getMonth()+diff);
			     		
			     		dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , startDate.getMonth(), reminderOriginalDate.getDate() );											
						finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );							
						var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );
						monthReminder.date = finalDate;
						return monthReminder;
					}
				}
			}
		
			
			// first check to see if the date of the reminder is less or more than start date.
			// if less, then we need to go to the next month;  if more, than we will use this month
			if ( reminderOriginalDate.getDate() < startDate.getDate() ) {
				var month = startDate.getMonth();
				var year = startDate.getFullYear();
				month = month + interval;			 	
			 	while ( month >= 12 ) {
			 		month = month - 12;
			 		year = year + 1;
			 	}
			 				 				 	
				var dayVal = reminderFox_getValidDateForMonth( year, month, reminderOriginalDate.getDate() );			 		
				finalDate = new Date( year, month, dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );		
			}
			else if ( reminderOriginalDate.getDate() > startDate.getDate() ) {
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , startDate.getMonth(), reminderOriginalDate.getDate() );											
				finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}
			else {   // same date; return it
				dayVal = reminderFox_getValidDateForMonth(  startDate.getFullYear() , startDate.getMonth(), reminderOriginalDate.getDate() );											
				finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), dayVal, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );				
			}

			
			
			
			var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );
			monthReminder.date = finalDate;
			return monthReminder;
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {		
			var reminderOriginalDate = reminder.date;
			// if start date is less than the default reminder date, then use the reminder date as start date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				startDate = reminderOriginalDate;
			}
			
			var reminderDay = reminder.date.getDay();
			var weekNumber = reminderFox_getWeekNumber( reminder.date );
			
			if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
				interval = reminder.recurrence.interval;
				var monthsDiff = reminderFox_computerNumberOfMonthsDifference( reminderOriginalDate, startDate);
				if ( monthsDiff != 0 ) {
					// get the differnce and years, and add the value to the final date accordingly 						
				    var modVal =  reminderFox_mod( monthsDiff , interval);
				    // if mod val == 0, then this month is valid; continue on 
			   		if ( modVal != 0 ) {
			   			var diff =interval - modVal;			    		
			     		startDate.setMonth( startDate.getMonth()+diff);
				     	var month = startDate.getMonth();
						var year = startDate.getFullYear();
		     			var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( startDate, reminderDay, weekNumber );
		     		
		     			var dayVal = reminderFox_getValidDateForMonth( year, month, reminderWeekDateThisMonth );			
						var newDate = new Date( year, month, dayVal );		
						reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( newDate, reminderDay, weekNumber );
						finalDate = new Date( newDate.getFullYear(), newDate.getMonth(), reminderWeekDateThisMonth, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );			
						var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );
						monthReminder.date = finalDate;
						return monthReminder;
					}
				}
			}
									
			var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( startDate, reminderDay, weekNumber );
			
			// first check to see if the date of the reminder is less or more than start date.
			// if less, then we need to go to the next month;  if more, than we will use this month
			if ( reminderWeekDateThisMonth < startDate.getDate() ) {
				var month = startDate.getMonth();
				var year = startDate.getFullYear();
				month = month + interval;			 	
			 	while ( month >= 12 ) {
			 		month = month - 12;
			 		year = year + 1;
			 	}
				var dayVal = reminderFox_getValidDateForMonth( year, month, reminderWeekDateThisMonth );			
				var newDate = new Date( year, month, dayVal );		
				reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( newDate, reminderDay, weekNumber );
				finalDate = new Date( newDate.getFullYear(), newDate.getMonth(), reminderWeekDateThisMonth, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}
			else if ( reminderWeekDateThisMonth > startDate.getDate() ) {									
				finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), reminderWeekDateThisMonth, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}
			else {   // same date; return it
				finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), reminderWeekDateThisMonth, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );	
			}
			
			var monthReminder = reminderFox_cloneReminderFoxEvent( reminder );
			monthReminder.date = finalDate;
			return monthReminder;				
		}
		
		// WEEKLY 
		else	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {	
			var reminderOriginalDate = reminder.date;
			// if start date is less than the default reminder date, then use the reminder date as start date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				startDate = reminderOriginalDate;
			}
		
			var startDay = startDate.getDay();
			var targetYear = startDate.getFullYear();
			var targetMonth = startDate.getMonth();
			var weeklyReminder = reminderFox_cloneReminderFoxEvent( reminder );
			
			if ( reminder.recurrence.byDay != null && reminder.recurrence.byDay.indexOf( ",") != -1 ) {		
				var reminderDay = startDay;
				// first handle interval to get proper week
				var weeklyReminder = reminderFox_cloneReminderFoxEvent( reminder );
				weeklyReminder.date = new Date( startDate.getFullYear(), startDate.getMonth(), startDate.getDate(), startDate.getHours(), startDate.getMinutes()  );
				if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
					interval = reminder.recurrence.interval;
					
					var dayValue = reminder.date.getDay();
					weeklyReminder = reminderFox_getThisDayFromCurrentWeeklyReminder( weeklyReminder, dayValue );
					
					var finalDate = new Date( weeklyReminder.date.getFullYear(), weeklyReminder.date.getMonth(), weeklyReminder.date.getDate(), reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
					// since this is alternating, determine if this week is the correct week, or if it is next week
					var numOfDaysDiff = reminderFox_computeNumberOfDaysDifference( reminder.date, finalDate );
				    var modVal=  reminderFox_mod( numOfDaysDiff , interval*7);
			   		if ( modVal != 0 ) {
			   			var diff =interval*7 - modVal;			   
			   		 	// we are an odd week away, need to add 7 to get to the next alternating week
			     		finalDate.setDate( finalDate.getDate() + diff );
			     		weeklyReminder.date = finalDate;
					}	
					weeklyReminder = reminderFox_getThisDayFromCurrentWeeklyReminder( weeklyReminder, 0 );  // reset date to Sunday
					reminderDay = 0; // reset to sunday
					// if the reminder original date is after the first date of this week, move ahead to that date...
					while (   reminderFox_compareDates( weeklyReminder.date, reminderOriginalDate ) == -1 ) {
						reminderDay ++;
						weeklyReminder.date.setDate( weeklyReminder.date.getDate() + 1);
					}
					while (   reminderFox_compareDates( weeklyReminder.date, startDate ) == -1 ) {
						reminderDay ++;
						weeklyReminder.date.setDate( weeklyReminder.date.getDate() + 1);
					}
					targetYear = weeklyReminder.date.getFullYear();
					targetMonth = weeklyReminder.date.getMonth();
				}	
				
				// here
				var increment = 0;
				while ( !reminderFox_isDayInByDayList( reminderDay, reminder.recurrence.byDay ) && increment < 8 ) {
					reminderDay++;
					if ( reminderDay >= 7  ) { // handle going past Saturday (6) and reset to Sunday (0)
						reminderDay = 0;
					}
					increment++;
				}	
				finalDate = new Date( targetYear,targetMonth, weeklyReminder.date.getDate() + increment, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			}	
			else {
				var reminderDay = reminder.date.getDay();
				var compareCurrentDay = reminderDay + 1;
				var compareFirstDay = startDay + 1;  
				var daysDifference;
				if ( compareCurrentDay < compareFirstDay ) {
					compareCurrentDay = compareCurrentDay + 7;
				}	
				daysDifference = (compareCurrentDay - compareFirstDay);
				finalDate = new Date( startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + daysDifference, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
		
				if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
					interval = reminder.recurrence.interval;
					// since this is alternating, determine if this week is the correct week, or if it is next week
					var numOfDaysDiff = reminderFox_computeNumberOfDaysDifference( reminder.date, finalDate );
				    var modVal=  reminderFox_mod( numOfDaysDiff , interval*7);
			   		if ( modVal != 0 ) {
			   			var diff =interval*7 - modVal;			   
			   		 	// we are an odd week away, need to add 7 to get to the next alternating week
			     		finalDate.setDate( finalDate.getDate() + diff );
					}	
				}		
			}		
			
			weeklyReminder.date = finalDate;
			return weeklyReminder;				
		
		}		
		else	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {	
			var reminderOriginalDate = reminder.date;
			// if start date is less than the default reminder date, return the reminder date
			if (  reminderFox_compareDates( startDate, reminderOriginalDate ) == -1 ) {
				return  reminderFox_cloneReminderFoxEvent( reminder );
			}
			
	     	var dailyReminder =   reminderFox_cloneReminderFoxEvent( reminder );
			if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
				interval = reminder.recurrence.interval;
				var numOfDaysDiff = reminderFox_computeNumberOfDaysDifference( reminder.date, startDate );
				
		   		 var modVal =  reminderFox_mod( numOfDaysDiff , interval);
	   			 if ( modVal != 0 ) {
	   			 	var diff =interval - modVal;			    	
	   			 	// we are an odd week away, need to add 7 to get to the next alternating week
					dailyReminder.date =  new Date( startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + diff, reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
					return dailyReminder;			
				}	
			}		
																		
			dailyReminder.date =  new Date( startDate.getFullYear(), startDate.getMonth(), startDate.getDate(), reminderOriginalDate.getHours(), reminderOriginalDate.getMinutes()  );
			return dailyReminder;			
		}	
		return null;
	}
	
function reminderFox_mod(divisee,base) {
	return Math.round(divisee - (Math.floor(divisee/base)*base));
}

function reminderFox_isDayInByDayList( dayNum, byDayList ) {
	if ( dayNum == 0 ) {
		return byDayList.indexOf( "SU" ) != -1;
	}
	else if ( dayNum == 1 ) {
		return byDayList.indexOf( "MO" ) != -1;
	}
	else if ( dayNum == 2 ) {
		return byDayList.indexOf( "TU" ) != -1;
	}
	else if ( dayNum == 3 ) {
		return byDayList.indexOf( "WE" ) != -1;
	}
	else if ( dayNum == 4 ) {
		return byDayList.indexOf( "TH" ) != -1;
	}
	else if ( dayNum == 5 ) {
		return byDayList.indexOf( "FR" ) != -1;
	}
	else if ( dayNum == 6 ) {
		return byDayList.indexOf( "SA" ) != -1;
	}
	return false;
}

function reminderFox_computerNumberOfMonthsDifference( startDate, endDate ) {				
		var monthCount = 0;
		var finalMonth;
		var startYear = startDate.getFullYear();
		var startMonth = startDate.getMonth();
		var endYear = endDate.getFullYear();
		if ( endYear > startYear ) {
		    finalMonth = 12;
		    monthCount += endDate.getMonth() + 1; // +1 for month 0-based offset
		    
		    endYear--;
		    while ( endYear > startYear ) {
		        monthCount += 12;
		        endYear--;
		    }
		}
		else {
		    finalMonth = endDate.getMonth() + 1;
		}
	
		monthCount += (finalMonth - (startMonth+1));
		return monthCount;
		
	}



function reminderFox_computeNumberOfDaysDifference( origStartDate, origEndDate ) {
	var startDate = new Date( origStartDate.getFullYear(), origStartDate.getMonth(), origStartDate.getDate(), 0, 0, 0 );
	var finalDate = new Date( origEndDate.getFullYear(), origEndDate.getMonth(), origEndDate.getDate(), 0, 0, 0 );
	
    // The number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24

    // Convert both dates to milliseconds
    var date1_ms = startDate.getTime()
    var date2_ms = finalDate.getTime()

    // Calculate the difference in milliseconds
    var difference_ms = Math.abs(date1_ms - date2_ms)
    
    // Convert back to days and return
    var numOfDaysDiff =  Math.round(difference_ms/ONE_DAY);
    return numOfDaysDiff;
 }
	
function reminderFox_getWeekNumber( currentDate ) {
		var reminderDate = currentDate.getDate();
		var numberOfDay = reminderDate / 7;
		var intvalue =	parseInt( numberOfDay );
		if ( reminderDate % 7 == 0 ) {
			intvalue--;
		}
		var weekNumber = intvalue + 1;   // 0-based index
		if ( weekNumber == 5 ) {
			weekNumber = -1;  // set to last week of month
		}
		return weekNumber;
}
	
function reminderFox_getWindowEnumerator() {
	var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
	var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
	var windowEnumerator = windowManagerInterface.getEnumerator("navigator:browser");
	if ( windowEnumerator.hasMoreElements() ) {
		return windowEnumerator;
	}

	 windowEnumerator = windowManagerInterface.getEnumerator("mail:3pane");
	if ( windowEnumerator.hasMoreElements() ) {
		return windowEnumerator;
	}	
	
	windowEnumerator = windowManagerInterface.getEnumerator("mail:messageWindow");
	if ( windowEnumerator.hasMoreElements() ) {
		return windowEnumerator;
	}	
	
	windowEnumerator = windowManagerInterface.getEnumerator("calendarMainWindow");
	if ( windowEnumerator.hasMoreElements() ) {
		return windowEnumerator;
	}	
	
	
	
	return windowManagerInterface.getEnumerator("navigator:browser");
	
}
	
function reminderFox_playSound() {
	var gSound = Components.classes["@mozilla.org/sound;1"].createInstance(Components.interfaces.nsISound);
	var savefilePath;
	// check if user has specified a specific file path for sound in their preferences
	try {
		savefilePath = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ALARM_SOUND_PATH);
	}
	catch ( e) {
	}
	// if not, then play default beep sound
	if ( savefilePath == null || savefilePath == "" ) {
		gSound.beep();	
	}
	else {
		var file = Components.classes["@mozilla.org/file/local;1"]
						.createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath( savefilePath );						
   			var ios = Components.classes['@mozilla.org/network/io-service;1'].getService(Components.interfaces.nsIIOService);
		var fileURI = ios.newFileURI(file);				
		gSound.play(fileURI);	
	}
}
	
	function reminderFox_getDateForSpecifiedWeekNumber( currentDate, dayNumber, weekNumber ) {  
		var firstDate = new Date( currentDate.getFullYear(), currentDate.getMonth(), 1 );  
		var firstDayOfMonth = firstDate.getDay();
		
		// calculate the date that the first day-of-week falls on (using the day of the first of the month)
		var compareCurrentDay = dayNumber + 1;
		var compareFirstDay = firstDayOfMonth + 1;
		if ( compareCurrentDay < compareFirstDay ) {
			compareCurrentDay = compareCurrentDay + 7;
		}
		var firstWeekDateVal = (compareCurrentDay - compareFirstDay) + 1;
		var finalDate;
		
		// we have the date that the first day-of-week falls on.  Now let's calculate the Nth day of week
		if ( weekNumber == -1 ) {  // last day of week of the month
			var weekNumberCalculation = 5 - 1;
			finalDate  = firstWeekDateVal + ( weekNumberCalculation*7);
			var lastDayOfMonth = oeDatePicker.getLastDayOfMonth( currentDate.getFullYear(), currentDate.getMonth() );
			if ( finalDate > lastDayOfMonth ) {
				finalDate  = finalDate - 7;   // previous (4th) week must be the last week of this month
			}
		}
		else {
			var weekNumberCalculation = weekNumber - 1;
			finalDate  = firstWeekDateVal + ( weekNumberCalculation*7);
		}
		return finalDate;
	}	
	
function reminderFox_getSortNewUpcomingReminderIndex( reminders, newreminder  ) {
	// We go through each reminder and then compare that reminder's month with 
	// the reminder-to-be-added month, and if the new month is less, add there;
	// if the months are equal, then compare the days and add appropriately. 

	// first check if the new reminder is greater than the last sorted reminder.  If so, add to 
	// end of the list...
	if ( reminders.length > 0 && reminderFox_compareReminderDatesAndTimes( newreminder, reminders[reminders.length-1] ) !=-1 ) {
			return reminders.length;
	}

	// otherwise, go through the list and insert where the new reminder is less than 
	// the reminders in the list
	for( var i = 0; i < reminders.length; i++ ) {
		var currentReminder = reminders[i];		
		if (  reminderFox_compareReminderDatesAndTimes( newreminder, currentReminder ) == -1 ) {
			return i;
		}
	}	 

 	// if the reminder hasn't been added yet, then place it at the end
	// of the list
	return reminders.length;
}


//function reminderFox_getAllTodosInDateRangeOrig( startDate, endDate ) {
//	var allTodosArray = { };
//	var i;
//	var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
//	for ( var n in reminderFoxTodosArrayArg ) {
//		var reminderTodos = reminderFoxTodosArrayArg[n];
//		for (  i = 0; i < reminderTodos.length; i++ ) {
//			var reminderTodo = reminderTodos[i];
//			if ( reminderTodo.date != null &&  
//				( (reminderFox_compareDates( reminderTodo.date, startDate ) != -1) &&
//				  (reminderFox_compareDates( reminderTodo.date, endDate ) != 1) ) ) {
//				
//					if ( 	allTodosArray[n] == null ) {
//						allTodosArray[n] = new Array();
//					}
//					var currentTodosList  = allTodosArray[n];
//				
//					currentTodosList[currentTodosList.length] = reminderTodo;
//			}
//		}	
//	}
//	return allTodosArray;
//}


function reminderFox_getAllTodosInDateRange( startDate, endDate ) {
	var allTodosArray = { };
	var i;
	var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
	for ( var n in reminderFoxTodosArrayArg ) {
		var reminderTodos = reminderFoxTodosArrayArg[n];
		for (  i = 0; i < reminderTodos.length; i++ ) {
			var reminderTodo = reminderTodos[i];
			if ( reminderTodo.date != null ) {				
				var allReminders = reminderFox_getAllRemindersInDateRange( reminderTodo,  startDate, endDate, true );
						
				if ( allTodosArray[n] == null ) {
					allTodosArray[n] = new Array();
				}
				var currentTodosList  = allTodosArray[n];
				for ( var j = 0; j < allReminders.length; j++ ) {				
					currentTodosList[currentTodosList.length] = allReminders[j];
				}				
			}
		}	
	}
	return allTodosArray;
}


function reminderFox_getAllTodosInDateRangeForGivenList( todoList, startDate, endDate ) {
	var dateTodos = new Array();
	var i;
	
	for (  i = 0; i < todoList.length; i++ ) {
		var reminderTodo = todoList[i];
		if ( reminderTodo.date != null &&  
			( (reminderFox_compareDates( reminderTodo.date, startDate ) != -1) &&
			  (reminderFox_compareDates( reminderTodo.date, endDate ) != 1) ) ) {

				dateTodos[dateTodos.length] = reminderTodo;
		}
	}	
	
	return dateTodos;
}


function reminderFox_getAllTodosInDateRangeForGivenListMultiples( todoList, startDate, endDate ) {
	var dateTodos = new Array();
	var i;
	
	for (  i = 0; i < todoList.length; i++ ) {
		var reminderTodo = todoList[i];
		if ( reminderTodo.date != null ) {				
			var allReminders = reminderFox_getAllRemindersInDateRange( reminderTodo,  startDate, endDate, true );			
			for ( var j = 0; j < allReminders.length; j++ ) {				
				dateTodos[dateTodos.length] = allReminders[j];				
			}
		}
	}	
	
	return dateTodos;
}
 
	
	function reminderFox_getAllRemindersInDateRange( reminder, initialStartDate, endDate, limitWeeklyReminders ) { 	
		var startDate = new Date( initialStartDate.getFullYear(), initialStartDate.getMonth(), initialStartDate.getDate(), 
			initialStartDate.getHours(), initialStartDate.getMinutes() );
		
		var reminderArray = new Array();
		var i;
		// if the reminder's recurrence enddate is less than the end date, use it as the end point
		if ( reminder.recurrence.endDate != null ) {
			if ( reminderFox_compareDates( reminder.recurrence.endDate, endDate ) == -1 ) {
				endDate = reminder.recurrence.endDate;
			}
		}

		// if reminder date is greater than the end date, then return empy array
		if ( reminderFox_compareDates( reminder.date, endDate ) == 1 ) {
			return reminderArray;
		}
		
		// if reminder date is greater than the start date, use the reminder date as the 
		// starting date
		if ( reminderFox_compareDates( reminder.date, startDate ) == 1 ) {
			startDate = reminder.date;
		}
 
		if ( reminder.recurrence.type  == REMINDER_RECURRENCE_ONETIME ) { 
			if ( reminderFox_compareDates( reminder.date, endDate ) == 1 ) {
				// return nothing if the reminder is outside of the ending date
				return reminderArray;
			}
			else if ( reminderFox_compareDates( reminder.date, startDate ) == -1 ) {
				// return nothing if the reminder has already occurred prior to the starting date
				
				// unless it's marked as Remind Until Completed...  then return it if today 
				// falls within the date range
			 	if ( reminder.remindUntilCompleted != null && reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
			 		var todaysDate = new Date();
			 		if ( reminderFox_compareDates( todaysDate, startDate ) != -1 && 
			 		  reminderFox_compareDates( todaysDate, endDate )  != 1 ) {
				 		reminderArray[0] = reminder;
				 	}
		 		}
			
				return reminderArray;
			}	
			else {
				reminderArray[0] = reminder;
				return reminderArray;
			}
		}	
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) { 
			var yearReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );
			if ( yearReminder != null  ) {
				if ( reminderFox_compareDates( yearReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}
				else {
					reminderArray[0] = yearReminder;
					return reminderArray;
				}		
			}
			return reminderArray;
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) { 
			var yearReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );

			if ( yearReminder != null  ) {
				if ( reminderFox_compareDates( yearReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}
				else {
					reminderArray[0] = yearReminder;
					return reminderArray;
				}		
			}
			return reminderArray;
		}				
		else 	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
			var arrayIndex = 0;
			var monthReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );
			if ( monthReminder != null  ) {
				if ( reminderFox_compareDates(  monthReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}							
				
				
				var interval = 1; 
				if ( reminder.recurrence.interval != null ) {
					interval =reminder.recurrence.interval;
				}
							
				while ( reminderFox_compareDates( monthReminder.date, endDate ) != 1 ) {				
					reminderArray[arrayIndex] = monthReminder;					
					monthReminder = reminderFox_getNextReminderOccurrence( monthReminder, reminder.date, 0, interval  );
					arrayIndex++;
				}
			}
			return reminderArray;
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
			var arrayIndex = 0;
			var monthReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );
			if ( monthReminder != null  ) {
				if ( reminderFox_compareDates(  monthReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}	
				var weekNumber = reminderFox_getWeekNumber( reminder.date );							
				var interval = 1; 
				if ( reminder.recurrence.interval != null ) {
					interval =reminder.recurrence.interval;
				}							
				while ( reminderFox_compareDates( monthReminder.date, endDate ) != 1 ) {				
					reminderArray[arrayIndex] = monthReminder;					
					monthReminder = reminderFox_getNextReminderOccurrence( monthReminder, reminder.date, weekNumber, interval  );
					arrayIndex++;
				}
			}
			return reminderArray;		

		}
		else	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {	
			var arrayIndex = 0;
			var weeklyReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );
			if ( weeklyReminder != null  ) {
				if ( reminderFox_compareDates(  weeklyReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}		
								
				var result = reminderFox_getDayAndEndDayOfYear( weeklyReminder, endDate );
				var dayOfYear = result.dayResult;
				var endDayOfYear  = result.endResult;				
				
				var endIndex = 365;
				if ( limitWeeklyReminders ) {
					endIndex = 8;
				}
				
				interval = 1;
				if ( reminder.recurrence.interval != null && reminder.recurrence.interval > 1 ) {   // 2
					interval = reminder.recurrence.interval;					
				}	
				interval = 7 * interval; // to get weeks
				
				if ( reminder.recurrence.byDay != null && reminder.recurrence.byDay.indexOf( ",") != -1 ) {					
					while ( dayOfYear <= endDayOfYear && arrayIndex < endIndex) {
						var reminderDay = weeklyReminder.date.getDay();
						var origDate = weeklyReminder.date.getDate();
						weeklyReminder	= reminderFox_cloneReminderFoxEvent(weeklyReminder);
						while ( reminderDay < 7 && dayOfYear <= endDayOfYear && arrayIndex < endIndex ) { 
							if ( reminderFox_isDayInByDayList( reminderDay, reminder.recurrence.byDay ) ) {
								reminderArray[arrayIndex] = weeklyReminder;	
								arrayIndex++;			
							}
							weeklyReminder	= reminderFox_cloneReminderFoxEvent(weeklyReminder);
							weeklyReminder.date.setDate( weeklyReminder.date.getDate() + 1);
							reminderDay++;
							dayOfYear++;  
						}
 				 		weeklyReminder	= reminderFox_cloneReminderFoxEvent(weeklyReminder);
						weeklyReminder.date = new Date( weeklyReminder.date.getFullYear(), weeklyReminder.date.getMonth(), weeklyReminder.date.getDate() + (interval-7), weeklyReminder.date.getHours(), weeklyReminder.date.getMinutes()  );
						dayOfYear = dayOfYear + (interval-7);		// -7 b/c end of this week
					}
				}	  
 				else {									
					while ( dayOfYear <= endDayOfYear && arrayIndex < endIndex) {
						reminderArray[arrayIndex] = weeklyReminder;	
						
						weeklyReminder	= reminderFox_cloneReminderFoxEvent(weeklyReminder);
						weeklyReminder.date = new Date( weeklyReminder.date.getFullYear(), weeklyReminder.date.getMonth(), weeklyReminder.date.getDate() + interval, weeklyReminder.date.getHours(), weeklyReminder.date.getMinutes()  );
						arrayIndex++;				
						dayOfYear = dayOfYear + interval;
					
					}
 				}
			}
			
			return reminderArray;				
		}	
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY) {	
			var arrayIndex = 0;
			var dailyReminder = reminderFox_getFirstReminderOccurrenceAfterStartDate( reminder, startDate );
		
			if ( dailyReminder != null  ) { 
			if ( reminderFox_compareDates(  dailyReminder.date, endDate ) == 1 ) {
					// return nothing if the reminder is outside of the ending date
					return reminderArray;
				}					
								
				var result = reminderFox_getDayAndEndDayOfYear( dailyReminder, endDate );
				var dayOfYear = result.dayResult;
				var endDayOfYear  = result.endResult;
				
				var interval = 1;
				if ( reminder.recurrence.interval != null ) { 
					interval = reminder.recurrence.interval;					
				}		
				
				var endIndex = 365;
				if ( limitWeeklyReminders ) {   
					var	endIndex = 8;
				}
				while ( dayOfYear <= endDayOfYear && arrayIndex < endIndex) {
					reminderArray[arrayIndex] = dailyReminder;	
					
					dailyReminder	= reminderFox_cloneReminderFoxEvent(dailyReminder);
					dailyReminder.date = new Date( dailyReminder.date.getFullYear(), dailyReminder.date.getMonth(), dailyReminder.date.getDate() + interval, dailyReminder.date.getHours(), dailyReminder.date.getMinutes()  );
					arrayIndex++;				
					dayOfYear = dayOfYear + interval;				
				}												
			}
			return reminderArray;					
		}				
		return null;
	}
	
	function reminderFox_getFirstDayValueFromByDay( byday ) {
		var commaIndex = byday.indexOf(",");
		var firstDay;
		if ( commaIndex == -1 ) {
			firstDay = byday;
		}
		else {
			firstDay = byday.substring(0,commaIndex);
		}
		
		if ( firstDay == "SU") {
			return 0;
		}
		else if ( firstDay == "MO") {
			return 1;
		}
		else if ( firstDay == "TU") {
			return 2;
		}
		else if ( firstDay == "WE") {
			return 3;
		}
		else if ( firstDay == "TH") {
			return 4;
		}
		else if ( firstDay == "FR") {
			return 5;
		}
		else if ( firstDay == "SA") {
			return 6;
		}		
		else {
			return -1;
		}									
	}
	
	function reminderFox_getThisDayFromCurrentWeeklyReminder( reminder, targetDay )  { // this will see the current day, and move forward/back to get to the specified day
		var dateDay = reminder.date.getDay();
		if ( dateDay == targetDay ) {
			return reminder;
		}
		else if ( dateDay < targetDay ) { 
			reminder.date.setDate( reminder.date.getDate() + (targetDay-dateDay));
		}
		else if ( dateDay > targetDay ) { 
			reminder.date.setDate( reminder.date.getDate() - (dateDay-targetDay));
		}
		return reminder;
	}
	
	function reminderFox_getThisDayFromCurrentDate( currentDate, targetDay )  { // this will see the current day, and move forward/back to get to the specified day
		var dateDay = currentDate.getDay();
		if ( dateDay == targetDay ) {
			return currentDate;
		}
		else if ( dateDay < targetDay ) { 
			currentDate.setDate( currentDate.getDate() + (targetDay-dateDay));
		}
		else if ( dateDay > targetDay ) { 
			currentDate.setDate( currentDate.getDate() - (dateDay-targetDay));
		}
		
		return currentDate;
	}
	
	
	function reminderFox_getDayAndEndDayOfYear( weeklyReminder, endDate) {
		var dayArray;
		var month = weeklyReminder.date.getMonth();
		var day = weeklyReminder.date.getDate();
		var currentYear = weeklyReminder.date.getFullYear();
		if (reminderFox_isLeapYear(currentYear) ) {
			dayArray = REMINDER_FOX_lDOMonth;
		}
		else {
			dayArray = REMINDER_FOX_DOMonth;
		}
	
		var dayOfYear=0;
		for (var  i=0; i < month; i++) {
			dayOfYear += dayArray[i];
		}
		dayOfYear += day;		

		var endDayOfYear=0;
		if ( endDate.getFullYear() != currentYear ) {
			if (reminderFox_isLeapYear(endDate.getFullYear() ) ) {
				dayArray = REMINDER_FOX_lDOMonth;
			}
			else {
				dayArray = REMINDER_FOX_DOMonth;
			}
			endDayOfYear += 365;
		}
		month = endDate.getMonth();
		day = endDate.getDate();

		for ( i=0; i < month; i++) {
			endDayOfYear += dayArray[i];
		}
		endDayOfYear += day;	
		var result = { dayResult: dayOfYear, endResult:  endDayOfYear};
		return result;
	}
	

function reminderFox_compareReminderDatesAndTimes( reminder1, reminder2, dateOne, dateTwo ) {	
	if ( dateOne == null ) {
		dateOne = reminder1.date;
	}
	if ( dateTwo == null ) {
		dateTwo = reminder2.date;
	}
	var compare = reminderFox_compareDates( dateOne, dateTwo );
	if ( compare == 0 ) {
		if ( dateOne.getHours() < dateTwo.getHours() ) {
			// we want allDayEvents to occur after specific time events
			if ( reminder1.allDayEvent ) {
				return 1;
			}
			else {
				return -1;
			}
		}
		else if ( dateOne.getHours() > dateTwo.getHours() ) {
			// we want allDayEvents to occur after specific time events
			if ( reminder2.allDayEvent ) {
				return -1;
			}
			else {
				return 1;
			}
		}
		else {
			if ( dateOne.getMinutes() < dateTwo.getMinutes() ) {
				return -1;
			}
			else if ( dateOne.getMinutes() > dateTwo.getMinutes() ) {
				return 1
			}
			else {
				if ( dateOne.getSeconds() < dateTwo.getSeconds() ) {
					return -1;
				}
				else if ( dateOne.getSeconds() > dateTwo.getSeconds() ) {
					return 1
				}	
				else {
					return 0; // identical times
				}			
			}			
		}
	}
	
	return compare;
}
	
// return -1 if dateOne < dateTwo
// return 0 if equal
// return 1 if dateOne > dateTwo
function reminderFox_compareDates( dateOne, dateTwo ) {
	var t1 = dateOne.getTime();
	var t2 = dateTwo.getTime();

    // Calculate the difference in milliseconds
    var difference_ms = t1 - t2;
    
    // if within one day, check to see if the dates are the same
    if ( difference_ms != 0 && difference_ms <= REMINDER_FOX_ONE_DAY && 
    	difference_ms >= REMINDER_FOX_NEGATIVE_ONE_DAY ) { 
    	if ( dateOne.getDate() == dateTwo.getDate() ) {
    		return 0;    		
    	}
	}
	
	if ( t1 < t2 ) {
		return -1;
	}
	else if ( t1 > t2 ) {
		return 1;
	}
	else{
		return 0;
	}		
}

var rmFx_OSinfo;

//gW_OSswitching    mods/adds  to support OS switching -------------		
function rmFx_opSystemInfo () {

	if (rmFx_OSinfo != null) { return  rmFx_OSinfo;}
	
	var osInfo = Components.classes["@mozilla.org/xre/app-info;1"] 
		.getService(Components.interfaces.nsIXULRuntime);
	rmFx_OSinfo =  osInfo.OS;
	
	// OSinfo : WINNT(x86-msvc)
	// OSinfo : Linux(x86-gcc3)
	// OSinfo : Darwin 
	reminderFox_logMessageLevel("OSinfo : " 
		+ osInfo.OS + "(" + osInfo.XPCOMABI + ")", REMINDER_FOX_LOG_LEVEL_INFO);
	
	return rmFx_OSinfo;	
}

// store the REMINDER_FOX_STORE_FILE with osTyp
	// +++++++++++++++++++++++++++++++++++++++++++++++++
	// new storeFile concept:
	// 	OS={ostype}:{osstring},OS={ostype}:{osstring},
	// 		fe:   OS=WINNT:D:\..\reminder.ics,OS=LINUX:/opt/../reminder.ics,OS=DARWIN:/home/user/.../reminder.ics,
	
function rmFx_storeFile4OS(filePath2store) {
	var osTyp = rmFx_opSystemInfo();
	var storeFile;
	var osString = "";
	
	var storeString4thisOS = rmFx_getStoreFile4OS();
	
   try {
      var storeString = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_STORE_FILE);
   } 	catch ( e ) { var storeString = "";}	

	if (storeString != "" ) { 
		//  replace the 'storeString4thisOS' with 'filePath2store' if not ''
		var osArray = storeString.split("OS=");
		
		if (osArray.length > 0) {
			for (var nOS=0; nOS < osArray.length; nOS++) {
				var cString = osArray[nOS];
				
				if (cString.indexOf(osTyp +":") == 0) {
					// current OS found !! skip it

				} else {
					// replace entry with leading "OS="
					if (cString != "") {
						if (cString.substring(cString.length -1) != ",") {
							cString += ",";
						}						
					osString += "OS=" + cString;
					}
				}
 			}
		}
	}

	if (filePath2store != "") {
		osString += "OS=" + osTyp + ":" + filePath2store + ","; 
	}
	reminderFox_prefsBranch.setCharPref(REMINDER_FOX_STORE_FILE, osString);

	// reminderFox_logMessageLevel("storeString4thisOS : " + storeString4thisOS, 2);
	// reminderFox_logMessageLevel("osString : " + osString, 2);

	return storeString4thisOS;		  
}

// get the REMINDER_FOX_STORE_FILE for current OS
function rmFx_getStoreFile4OS() {
	var osTyp = rmFx_opSystemInfo();
	var storeString = "";

   try {
      storeString = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_STORE_FILE);
   } catch (ex) { 
		storeString = reminderFox_getReminderStoreFile();
	}

	var fnd = storeString.indexOf("OS=" + osTyp + ":");
   if (fnd > -1) {
		//for the current osTyp we have a 'storeFile', search it
		var osArray = storeString.split("OS=");
			for (var nOS=0; nOS < osArray.length; nOS++) {
				var cString = osArray[nOS];
				if (cString.substring(cString.length -1) == ",") {
					cString = cString.substring(0, cString.length-1);
				}
				fnd = cString.indexOf(osTyp + ":");
				if (fnd == 0) {
					var len = (osTyp + ":").length;
					storeString = cString.substring(len) ;
				}
			}
   } else {
   	storeString = "";
   }
	// reminderFox_logMessageLevel("storeString : " +  storeString, 2);

	return storeString;
}


// call file Picker with param:
//		windowText           FilePicker Window text
// 	filterName           description of search filter,  eg. 'ICS file'
// 	defaultExtension     the extension for 'FilterName' eg. '.ICS'
// 	defaultString        eg. 'reminderfox.ics'  or '*.*'		
// 	prefsName            reminderfox constant, to be use to save picked file to 'prefs'
//		return:  file (object)

function rmFx_filePicker (windowText, filterName, defaultExtension, defaultString, prefsName) {

	const nsIFilePicker = Components.interfaces.nsIFilePicker; 

	var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);  
//	picker.appendFilters( 2); // nsIFilePicker.filterAll);
	picker.appendFilter( filterName, "*." + defaultExtension);    
	picker.defaultString = defaultString;
	picker.defaultExtension = defaultExtension;
	picker.init(window, windowText, nsIFilePicker.modeOpen);

	var rv = picker.show();
	if (rv == nsIFilePicker.returnOK)  {
		var file = picker.file;
		reminderFox_prefsBranch.setCharPref(prefsName, file.persistentDescriptor); 
		return file;    				     			
	}  
	else  {
		reminderFox_prefsBranch.setCharPref(prefsName, "");
		return null;
	}
}

//OSswitching
//		for each OS a sting is remembered, so OSswitching will bring back
//		last *.ics file (or just the default)
//		REMINDER_FOX_STORE_FILE  used to store all OS infos

function reminderFox_getReminderStoreFile() {
	
	var file = Components.classes["@mozilla.org/file/local;1"]
             .createInstance(Components.interfaces.nsILocalFile);
             
	// 1) setup the default location for "reminderfox.ics"	
   var defaultFile = Components.classes["@mozilla.org/file/directory_service;1"]
         .getService(Components.interfaces.nsIProperties)
         .get("ProfD", Components.interfaces.nsIFile);

   defaultFile.append( "reminderfox" );
   defaultFile.append( "reminderfox.ics" );		
   var defaultFilePath = defaultFile.path;

	// 2) get prefs storeFile.OS   -- saved file from different OSs
	var osTyp = rmFx_opSystemInfo();		// for new
	var osInfo = rmFx_opSystemInfo();	 // for old
	var osFilePath = "";		
	var storeString = "";
	
   try {
      storeString = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_STORE_FILE);

		var fnd = storeString.indexOf("OS=" + osTyp + ":");
	   if (fnd > -1) {
			//for the current osTyp we have a 'storeFile', search it
			var osArray = storeString.split("OS=");
				for (var nOS=0; nOS < osArray.length; nOS++) {
					var cString = osArray[nOS];
					if (cString.substring(cString.length -1) == ",") {
						cString = cString.substring(0, cString.length-1);
					}
					fnd = cString.indexOf(osTyp + ":");
					if (fnd == 0) {
						var len = (osTyp + ":").length;
						storeString = cString.substring(len) ;
					}
				}
	   }
	} 	catch ( e ) {}
	   
	// check which file can be used
	//   1:  if fileinfo is valid, use it
	//   2:  else use OS setting, if not valid, use 'default'
	
	var savefilePathGO = "";
   // 1: check if 'osFilePath' is empty, use 'default'
   if (storeString == "" )  {
   	file.initWithPath(defaultFilePath);
   } else {
		try {	// 2: use fileinfo is valid
			savefilePathGO = storeString;
			file.initWithPath(savefilePathGO);
			file.exists();
		} catch (e) {  // 3: if failed, go with 'defaultFilePath'		
				savefilePathGO = "";
				file.initWithPath(defaultFilePath);
			}
		}
	// reminderFox_logMessageLevel("file.persistentDescriptor : " + file.persistentDescriptor, 2);
		
   return file;	   
}
//gW_OSswitching    mods/adds  to support OS switching ---------- end ---		



	function reminderFox_getFileTimeStamp() {
		var file =   reminderFox_getReminderStoreFile();
	
	     // bail if the file doesn't yet exist; no reminders to read
	      if ( !file.exists() ) { 
	      	return -1;
	      }			
		try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			alert("Permission to read file was denied.");
		}
	
		var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
			.createInstance( Components.interfaces.nsIFileInputStream );
		try {
			is.init( file,0x01, 00004, null);
		}
		catch ( e ) {
			reminderFox_logMessageLevel("Could not read reminder file: " + e.name  +  " -- " + e.message, REMINDER_FOX_LOG_LEVEL_INFO);
			return -1;
		}
		
		var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
		                                 .createInstance(Components.interfaces.nsIScriptableInputStream);
		scriptableStream.init(is);
		var chunk = scriptableStream.read(scriptableStream.available());		
		
		// maybe only read set # of bytes

		return reminderFox_getFileTimeStampFromString(chunk);
	}

	function reminderFox_getFileTimeStampFromString(chunk) {
		var index =	chunk.indexOf( REMINDERFOX_FILE_LAST_MODIFIED);
		if ( index != -1 ) {
			var newline = "\n";
			var returnLine = "\r";
			index = chunk.indexOf( ':', index );
			if ( index != -1 ) {
				var endIndex = chunk.indexOf( newline, index );
				var time = chunk.substring( index+1, endIndex );
				if ( time.charAt( time.length-1) == returnLine ) {
					time = time.substring( 0, time.length-1);
				}
				return reminderFox_trim(time);
			}
		}
		return -1;
	}

	function reminderFox_getReminderEvents() {
		if ( reminderFoxEvents == null ) {
			reminderFoxEvents = new Array();
			reminderFoxTodosArray = { };
			var file =   reminderFox_getReminderStoreFile();
	
	      // bail if the file doesn't yet exist; no reminders to read
	      if ( !file.exists() ) { 
	      	return reminderFoxEvents;
	      }			
		  reminderFox_readInRemindersAndTodosICSFromFile(reminderFoxEvents, reminderFoxTodosArray, file);
		}
		return reminderFoxEvents;
	}
	
	function reminderFox_getReminderTodos() {
		if ( reminderFoxTodosArray == null ) {
			reminderFoxEvents = new Array();
			reminderFoxTodosArray = { };
			var file = reminderFox_getReminderStoreFile();
	
	      // bail if the file doesn't yet exist; no reminders to read
	      if ( !file.exists() ) { 
	      	return reminderFoxTodosArray;
	      }			
		  reminderFox_readInRemindersAndTodosICSFromFile(reminderFoxEvents, reminderFoxTodosArray, file);
		}
		return reminderFoxTodosArray;
	}
	
	function reminderFox_clearRemindersAndTodos() {
		reminderFoxEvents = null;
		reminderFoxTodosArray = null;
	}
	
	function reminderFox_getRemindersById( id, reminders ) {
		if ( reminders == null ) {
			reminders = reminderFox_getReminderEvents();
		}
		for ( var i = 0; i < reminders.length; i++ ) {
			if ( reminders[i].id == id ) {
				return reminders[i];
			}
		}
		return null;
	}
	
	function reminderFox_getTodosById( id, todoList ) {
		if ( todoList != null ) { 
			for ( var i = 0; i < todoList.length; i++ ) {
				if ( todoList[i].id == id ) {
					return todoList[i];
				}
			}
		}
		return null;
	}
	
	function reminderFox_getSpecificTodoById( id ) {
		var i;
		var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
		for ( var n in reminderFoxTodosArrayArg ) {
			var reminderTodos = reminderFoxTodosArrayArg[n];
			for (  i = 0; i < reminderTodos.length; i++ ) {		
				if ( reminderTodos[i].id == id ) {
					return reminderTodos[i];
				}
			}
		}
		return null;
	}
	
	

function reminderFox_isInteger(s) {  
	if ( s.length == 0 ) {
		return false;		
	}
	else {
	 	var i;
	    for (i = 0; i < s.length; i++) {   
	        // Check that current character is number.
	        var c = s.charAt(i);
	        if (((c < "0") || (c > "9"))) return false;
	    }
	    // All characters are numbers.
	    return true;
	}
}

function reminderFox_initiliazeTooltip() {
	var changed = reminderFox_ensureRemindersSynchronized();
	
	if ( !changed ) {
		// add some extra checks in when hiding tooltip; in case the setTimeout threads have been suspended, 
		// this will kick them off again if neccessary
		reminderFox_initializeReminderFoxHourly();
		
		
		//reminderFox_filesystemTimeStampHasChanged
		 
		 
	}
		
	reminderFox_logMessageLevel("Tooltip initialized: " + new Date(), REMINDER_FOX_LOG_LEVEL_FINE);
	
}

function reminderFox_hideTooltip() {
	reminderFox_showAlertSlider();
}

function reminderFox_ensureRemindersSynchronized() {
	var fileChanged = reminderFox_timeStampHasChanged();
	if ( fileChanged != -1 ) {
		var changed = false;
		try { 
			var waitForResponse = reminderFox_ensureRemoteRemindersSynchronized(true); 
			if ( !waitForResponse ) {
				changed = reminderFox_processRecentReminders(); 
			}
		}
		catch ( e ) {
		}		
		if ( changed ) {
			// write stuff out
			reminderFox_writeOutRemindersAndTodos(false);								
			reminderFox_syncWrittenChangesToRemote();		
		}
		else {
			reminderFox_storeTimeStamp(fileChanged);
		}
		
		var windowEnumerator =  reminderFox_getWindowEnumerator();
	
		if (windowEnumerator.hasMoreElements()) {
			var oldestWindow = windowEnumerator.getNext();		
			oldestWindow.reminderFox_updateRemindersInWindow();	
			reminderFox_clearRemindersAndTodos();

			while (windowEnumerator.hasMoreElements()) {
				var currentWindow = windowEnumerator.getNext();		
				currentWindow.reminderFox_updateRemindersInWindow();		
				currentWindow.reminderFox_clearRemindersAndTodos();						
			}
		}	
	}	
	
	 return fileChanged != -1;
}
	
/*
 * check the reminder description for any variables (eg: <1978>) that needs translating
 */	
function reminderFox_processReminderDescription( reminder, year, isTodo ) {
	var index = reminder.summary.indexOf( "<" );
	if ( index != -1 ) {
		var endIndex = reminder.summary.indexOf( ">", index + 1 );
		if ( endIndex != -1 ) {
			var useYearOnly = false;
			var yearVal = reminder.summary.substring( index + 1, endIndex );
			if ( yearVal.length == 5 && yearVal.charAt(4) == '#' ) {
				yearVal = yearVal.substring(0,4);
				useYearOnly = true;
			}
			if ( yearVal.length == 4 ) {
				try {
					if (!reminderFox_isInteger(yearVal) ) {
						return reminder;
					}
					var yearInt = parseInt(yearVal );
					var currentYear = year;
					if ( currentYear == null ) {
						currentYear =  new Date().getFullYear();
					}
					
					var numOfYears = currentYear - yearInt;
					if ( numOfYears < 0 ) { 
						numOfYears = numOfYears * -1;   // convert negative years to positive
					}
					var numOfYearsStr = numOfYears + "";
					if ( !useYearOnly ) {
						if ( numOfYears > 0 && numOfYears < 32 ) {
							numOfYearsStr = reminderFox_getBundle().getString("rf.options.dateshort." +numOfYears +".name");
						}
						else {					
							var length = numOfYearsStr.length;
		
							if ( numOfYearsStr.lastIndexOf("11") != -1 && numOfYearsStr.lastIndexOf("11") == length -2 ) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.4");
							}
							else if ( numOfYearsStr.lastIndexOf("12") != -1 && numOfYearsStr.lastIndexOf("12") == length - 2 ) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.4");
							}
							else if (  numOfYearsStr.lastIndexOf("13") != -1 && numOfYearsStr.lastIndexOf("13") == length -2 ) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.4");
							}											
							else if (  numOfYearsStr.lastIndexOf("1") != -1 &&numOfYearsStr.lastIndexOf("1") == length - 1) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.1");
							}
							else if (numOfYearsStr.lastIndexOf("2") != -1 && numOfYearsStr.lastIndexOf("2") == length -1  ) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.2");
							}	
							else if ( numOfYearsStr.lastIndexOf("3") != -1 && numOfYearsStr.lastIndexOf("3") == length - 1 ) {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.3");
							}	
							else {
								numOfYearsStr =numOfYearsStr + reminderFox_getBundle().getString("rf.options.number.abbreviation.4");
							}			
						}		
					}						
					
					var returnReminder;
					if ( isTodo  ) {  
						returnReminder = reminderFox_cloneReminderFoxTodo(reminder);
					}
					else {
						returnReminder = reminderFox_cloneReminderFoxEvent(reminder);
					}
					returnReminder.summary = returnReminder.summary.substring( 0, index ) + numOfYearsStr + 
						returnReminder.summary.substring( endIndex + 1 );
						
					// now we have the new description; re-run the process  in case there were multiple years	
					returnReminder = reminderFox_processReminderDescription(returnReminder, year, isTodo)
					return returnReminder;					
				}
				catch ( e ) {
				}
			}
		}
	}
	return reminder;
}	


function reminderFox_trim(s) {
	if ( s != null && s.length > 0 ) { 
		// Remove leading spaces and carriage returns
		while ((s.substring(0,1) == ' ') ) {
		 	s = s.substring(1,s.length); 
		 }
		
		// Remove trailing spaces and carriage returns
		while ((s.substring(s.length-1,s.length) == ' ') ) { 
			s = s.substring(0,s.length-1); 
		}
	}

	return s;
}

 
function reminderFox_constructReminderOutput(reminderEvents, reminderFoxTodosArrayArg, isExport, ignoreExtraInfo, postingMethod  ) {	
	var newline;
	if (navigator.appVersion.lastIndexOf('Win') != -1) {
		newline="\r\n";
	} else {
		newline="\n"
	}
	//var separator = newline + " :" ;
	var separator =  ":" ;
	
	var outputStr = "BEGIN:VCALENDAR" + newline;
	outputStr += "VERSION" + separator +  
							"2.0" + newline;
	outputStr += "PRODID" + separator + 
							 "-//ReminderFox V" + REMINDER_FOX_MIGRATED_PREF_VERSION +"//EN" + newline;
	var modifiedTime;
	
	// if exporting (via file or network), use existing timestamp
	 if ( isExport ) {
	 	modifiedTime = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_MODIFIED) + "";
	 }
	 else {	 		
	 	// otherwise, we're writing the file anew - set new current timestamp					 
		 reminderFox_lastModifiedTime = new Date().getTime();
		 modifiedTime = reminderFox_lastModifiedTime;
	}
	outputStr += REMINDERFOX_FILE_LAST_MODIFIED + separator + modifiedTime + newline;
	
	//gW postingMethod
	if (postingMethod == "" ||postingMethod == null || postingMethod == "PUBLISH") {	// for Invitation :  REQUEST						 
	outputStr += "METHOD" + separator +  
							"PUBLISH" + newline;}
		else {
			outputStr += "METHOD" + separator +  
							postingMethod + newline;
		}

	// REMINDERS
	var reminder;
	//var tzOffset = new Date().getTimezoneOffset();
	
	for ( var i = 0; i < reminderEvents.length; i++ ) {
		reminder = reminderEvents[i];
		var summary = reminder.summary;
		outputStr += "BEGIN:VEVENT" +  newline;	
		outputStr += "UID" + separator +  reminder.id + newline;			
		summary = reminderFox_EscapeCommas( summary );							
		outputStr += reminderFox_foldLines( "SUMMARY" + separator +   summary , newline );			
		if ( isExport && ( reminder.extraInfo == null || reminder.extraInfo.indexOf( "CLASS" + separator) == -1 ) ) {
			outputStr += "CLASS" + separator +  "PUBLIC" + newline;												
		}						
														
		// set date
		var currentDate =  new Date( reminder.date.getFullYear(), reminder.date.getMonth(), reminder.date.getDate(), reminder.date.getHours(), reminder.date.getMinutes() );
		outputStr += reminderFox_createStringForDate( reminder, currentDate, isExport, separator, newline );
		
		var endDate = null;
		if ( reminder.endDate != null ) {
			endDate =  new Date( reminder.endDate.getFullYear(), reminder.endDate.getMonth(), reminder.endDate.getDate(), reminder.endDate.getHours(), reminder.endDate.getMinutes() );
		}
		outputStr += reminderFox_createStringForEndDate( reminder, endDate, isExport, separator, newline );
		
		if ( isExport && ( reminder.extraInfo == null || reminder.extraInfo.indexOf( "STATUS:") == -1 ) ) {
	 		outputStr += "STATUS:CONFIRMED" + newline;  				 	
	 	 }
			
		if ( reminder.notes != null ) {
			// replace actual new line  with newline characters
			var desc =reminder.notes.replace(new RegExp(/\n/g),"\\n");
			desc = reminderFox_EscapeCommas( desc );		
			outputStr +=  reminderFox_foldLines(  "DESCRIPTION" + separator + desc , newline );		
		}

		if (( reminder.categories != null ) && (reminder.categories != "")) {
			outputStr +=  reminderFox_foldLines( "CATEGORIES" + separator +  reminder.categories , newline );
		}
		
		outputStr += reminderFox_writeOutRecurrence(reminder, currentDate, separator, newline);	
		 
		if ( reminder.priority == REMINDER_PRIORITY_IMPORTANT) { 
			outputStr += "PRIORITY" + separator +  
									"1" + newline;				
		}

		if ( reminder.lastModified != null ) {
			outputStr += "LAST-MODIFIED" + separator +  reminder.lastModified + newline;			
		}
		
		if (reminder.remindUntilCompleted != REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE) {
			outputStr += REMINDERFOX_EXTENDED + "REMIND-UNTIL-COMPLETED" + separator +  
									 reminder.remindUntilCompleted + newline;					
		}
		
		if ( reminder.location != null  && reminder.location != "") {
			var reminderLocation = reminderFox_EscapeCommas( reminder.location );		
			outputStr +=  reminderFox_foldLines( "LOCATION" + separator +  reminderLocation , newline );
		}
		if ( reminder.url != null && reminder.url != "") {
			outputStr +=  reminderFox_foldLines( "URL" + separator +  reminder.url , newline );
		}

		
		if ( reminder.completedDate != null ) {
			var year = reminder.completedDate.getFullYear();
			var month = reminder.completedDate.getMonth() +1;
			var day = reminder.completedDate.getDate();
			if (month < 10)
				month = "0" + month;
			if (day < 10)
				day = "0" + day;
			outputStr += REMINDERFOX_EXTENDED + "COMPLETED" + separator +  
										"" + year  + month  + day + newline;						
		}		
		
		if (reminder.messageID != null) {
			outputStr +=  reminderFox_foldLines( REMINDERFOX_EXTENDED + "MESSAGEID" + separator +  reminder.messageID, newline );							
		}	
		
		// write out extra info
		var dtstampFound = false;
		if ( reminder.extraInfo != null ) {
			// write out any extra info (inserted from other calendaring programs)
			var extraInfoArray = reminder.extraInfo.split("\\n");	
			for ( var index = 0; index < extraInfoArray.length; index++ ) {
				var extraInfo = extraInfoArray[index];	
				
				if ( extraInfo.indexOf( "DTSTAMP" ) != -1 ) {  
					dtstampFound = true;	
				}		
				else if ( extraInfo.indexOf( "COMMENT" ) != -1 ) {  
					extraInfo =extraInfo.replace(new RegExp(/\n/g),"\\n");
				}
				outputStr += reminderFox_foldLines( extraInfo, newline );	
			}	
		}
		// every event/todo must have a dtstamp; add it, if not there
		if ( !dtstampFound ) {
			outputStr += "DTSTAMP" + separator +  reminder.lastModified + newline;			
		}
		
		if ( reminder.alarm != null ) {
			outputStr += "BEGIN:VALARM" + newline;	
			outputStr += "TRIGGER" + separator +  
									reminder.alarm + newline;
			outputStr += "ACTION" + separator +  "DISPLAY" + newline;			
			outputStr += reminderFox_foldLines( "DESCRIPTION" + separator +   summary , newline );		
			
			if ( reminder.alarmLastAcknowledge != null ) {
				outputStr +=REMINDERFOX_EXTENDED + "LASTACK" + separator + reminder.alarmLastAcknowledge + newline;	
			}			
			if ( reminder.snoozeTime != null ) {
				outputStr +=REMINDERFOX_EXTENDED + "SNOOZE-TIME" + separator + reminder.snoozeTime + newline;	
			}	
			
			
			outputStr += "END:VALARM" + newline;	
		}
				
		outputStr += "END:VEVENT" + newline
				
	}

	
	// TODOs
	var todo;
	var dtstampStr = null;
	for ( var n in reminderFoxTodosArrayArg ) {
		var reminderTodos = reminderFoxTodosArrayArg[n];
		for (  i = 0; i < reminderTodos.length; i++ ) {
			todo = reminderTodos[i];
			outputStr += "BEGIN:VTODO" +  newline;				
			var summary = reminderFox_EscapeCommas( todo.summary );		 
			outputStr +=  reminderFox_foldLines( "SUMMARY" + separator +  summary , newline );		
			outputStr +=  reminderFox_foldLines( "UID" + separator +  todo.id , newline );														
	
			if ( todo.date != null ) {
				var currentDate =  new Date( todo.date.getFullYear(), todo.date.getMonth(), todo.date.getDate(), todo.date.getHours(), todo.date.getMinutes() );
				outputStr += reminderFox_createStringForDate( todo, currentDate, isExport, separator, newline );
				
				if ( todo.endDate != null ) {
					var durationMillisecs =todo.endDate.getTime() - todo.date.getTime();
					var durationMins = durationMillisecs / ( 60 * 1000 );
					outputStr += "DURATION" + separator + "PT" + durationMins + "M" + newline;
				}
			}
			//currentDate.setMinutes( currentDate.getMinutes() + tzOffset );	// set this offset for UTC	
	
			if ( todo.notes != null ) {
				// replace actual new line  with newline characters
				var desc = todo.notes.replace(new RegExp(/\n/g),"\\n");
				desc = reminderFox_EscapeCommas( desc );	
				outputStr +=  reminderFox_foldLines( "DESCRIPTION" + separator +  desc , newline );		
			}
	
			if ( todo.priority == REMINDER_PRIORITY_IMPORTANT) { 
				outputStr += "PRIORITY" + separator +  "1" + newline;					
			}
			
			if (( todo.categories != null ) && (todo.categories != "")) {
				outputStr +=  reminderFox_foldLines( "CATEGORIES" + separator + todo.categories , newline );
			}

			outputStr += reminderFox_writeOutRecurrence(todo, currentDate, separator, newline);
			
			if ( todo.completedDate != null ) {
				var year = todo.completedDate.getFullYear();
				var month = todo.completedDate.getMonth() +1;
				var day = todo.completedDate.getDate();
				if (month < 10)
					month = "0" + month;
				if (day < 10)
					day = "0" + day;
				outputStr += "COMPLETED" + separator +  
											"" + year  + month  + day + "T" + "000000" +newline;						
			}				
			
					
			if (todo.showInTooltip) {
				outputStr += REMINDERFOX_EXTENDED + "SHOW-IN-TOOLTIP" + separator +  
										"1" + newline;		
			}
			
			if (todo.messageID != null) {
				outputStr +=  reminderFox_foldLines( REMINDERFOX_EXTENDED + "MESSAGEID" + separator +  todo.messageID , newline );							
			}			
			
			if ( n != REMINDER_FOX_DEFAULT_TODOS_CATEGORY ) {
				outputStr += REMINDERFOX_EXTENDED + "LISTID" + separator +  n  + newline;						
			}					
				
			if ( todo.location != null  && todo.location != "") {
				var location = reminderFox_EscapeCommas( todo.location );	
				outputStr +=  reminderFox_foldLines( "LOCATION" + separator +  location, newline );
			}
			if ( todo.url != null && todo.url != "") {
				outputStr +=  reminderFox_foldLines( "URL" + separator +  todo.url , newline );
			}
				
		   var dtstampFound = false;
			if ( todo.extraInfo != null ) {
				// write out any extra info (inserted from other calendaring programs)
				var extraInfoArray = todo.extraInfo.split("\\n");	
				for ( var index = 0; index < extraInfoArray.length; index++ ) {
					var extraInfo = extraInfoArray[index];	
					outputStr += reminderFox_foldLines( extraInfo, newline );	
					
					if ( extraInfo.indexOf( "DTSTAMP" ) != -1 ) {  
						dtstampFound = true;	
					}		
				}	
			}		
			// every event/todo must have a dtstamp; add it, if not there
			if ( !dtstampFound ) {
				if ( dtstampStr == null ) {
					var dtstampDate = new Date();
					dtstampStr = reminderFox_getDateAsString(dtstampDate );
				}
				outputStr += "DTSTAMP" + separator +  dtstampStr + newline;			
			}						
			
			if ( todo.alarm != null ) {
				outputStr += "BEGIN:VALARM" + newline;	
				outputStr += "TRIGGER" + separator +  todo.alarm + newline;
				outputStr += "ACTION" + separator +  "DISPLAY" + newline;			
				outputStr += reminderFox_foldLines( "DESCRIPTION" + separator +   summary, newline );	
				if ( todo.alarmLastAcknowledge != null ) {
					outputStr +=REMINDERFOX_EXTENDED + "LASTACK" + separator + todo.alarmLastAcknowledge + newline;	
				}		
				if ( todo.snoozeTime != null ) {
					outputStr +=REMINDERFOX_EXTENDED + "SNOOZE-TIME" + separator + todo.snoozeTime + newline;	
				}
		
				outputStr += "END:VALARM" + newline;	
			}									
						
			outputStr += "END:VTODO" +  newline;		
		}
	}
	
	// write out any extra fields		
	if ( ignoreExtraInfo ) {
		// ignore extra fields
	}
	else if ( reminderFoxExtraInfo != null ) {
		var extraInfoArray = reminderFoxExtraInfo.split("\\n");		
		for ( var index = 0; index < extraInfoArray.length; index++ ) {
			var extraInfo = extraInfoArray[index];	
			outputStr += extraInfo + newline;				
		}	
	}
		
	outputStr += "END:VCALENDAR" +  newline;		
	return outputStr;
}


function reminderFox_foldLines( line, newline ) {
	//  >>>>  break for long lines   RFC 2445 sec 4.1  
	var result = null;
	var LINE_LENGTH = 75;
	if ( line.length <= LINE_LENGTH ) {
		result = line + newline;
	} 
	else {
		result = line.substring( 0, LINE_LENGTH) + newline;
		var index = LINE_LENGTH;
		while ( (index + LINE_LENGTH)< line.length ) { 
			result = result + " " + line.substring( index, index + LINE_LENGTH-1 ) + newline;	  // -1, to account for prepended space
			index = index + LINE_LENGTH-1;
		}
		result = result + " " + line.substring( index, line.length ) + newline;;						
	}
	return result;
}

function reminderFox_createStringForDate( reminderOrTodo, currentDate, isExport, separator, newline ) {
		var outputStr;
		var year = currentDate.getFullYear();
		var month = currentDate.getMonth() +1;
		var day = currentDate.getDate();
		if (month < 10)
			month = "0" + month;
		if (day < 10)
			day = "0" + day;
		
		if ( reminderOrTodo.allDayEvent ) {
			outputStr = "DTSTART;VALUE=DATE" + separator +  
									"" + year  + month  + day + newline;				
		}
		else {
			var hours = currentDate.getHours();
			var minutes = currentDate.getMinutes();
			if (hours < 10)
				hours = "0" + hours;
			if (minutes < 10)
				minutes = "0" + minutes;

			outputStr = "DTSTART" + separator +  
									"" + year + month +  day + "T" + hours  + minutes + "00" + newline;				
								//	"" + year + month +  day + "T" + hours  + minutes + "00Z" + newline;					// add Z for UTC
		}
		return outputStr;
}


function reminderFox_createStringForEndDate( reminderOrTodo, currentDate, isExport, separator, newline ) {
	var nullDate = false;
	if ( currentDate == null ) {
		nullDate = true;
		currentDate = reminderOrTodo.date;
	}
	var outputStr = "";
	var year = currentDate.getFullYear();
	var month = currentDate.getMonth() +1;
	var day = currentDate.getDate();
	if (month < 10)
		month = "0" + month;
	if (day < 10)
		day = "0" + day;
	
	if ( reminderOrTodo.allDayEvent ) {
		if ( !nullDate ) {
			outputStr = "DTEND;VALUE=DATE" + separator +  
								"" + year  + month  + day + newline;				
		}
		else if ( isExport ) { 
			// if we are exporting reminders, then add the end-date for all day events because
			// some buggy clients don't understnand all-day events that have no end date even though
			// that is correct in the ICS spec
			currentDate.setDate( currentDate.getDate() + 1 );
			year = currentDate.getFullYear();
			month = currentDate.getMonth() +1;
			day = currentDate.getDate();
			if (month < 10)
				month = "0" + month;
			if (day < 10)
				day = "0" + day;				
			outputStr += "DTEND;VALUE=DATE" + separator +  
								"" + year  + month  + day + newline;						
		}																	
	}
	else {
		var hours = currentDate.getHours();
		var minutes = currentDate.getMinutes();
		if (hours < 10)
			hours = "0" + hours;
		if (minutes < 10)
			minutes = "0" + minutes;
		
		if ( !nullDate ) {
			outputStr = "DTEND" + separator +  
								"" + year + month +  day + "T" + hours  + minutes + "00" + newline;				
							//	"" + year + month +  day + "T" + hours  + minutes + "00Z" + newline;					// add Z for UTC
		}
		else if ( isExport ) { 
			currentDate.setHours( currentDate.getHours() + 1 );
			year = currentDate.getFullYear();
			month = currentDate.getMonth() +1;
			day = currentDate.getDate();
			if (month < 10)
				month = "0" + month;
			if (day < 10)
				day = "0" + day;							
			hours = currentDate.getHours();
			minutes = currentDate.getMinutes();
			if (hours < 10)
				hours = "0" + hours;
			if (minutes < 10)
				minutes = "0" + minutes;			
			outputStr += "DTEND" + separator +  
						"" + year + month +  day + "T" + hours  + minutes + "00" + newline;			
		}								
	}
	return outputStr;
}


function reminderFox_getDateAsString(  currentDate ) {
	var dateString = "";
	var year = currentDate.getFullYear();
	var month = currentDate.getMonth() +1;
	var day = currentDate.getDate();
	if (month < 10)
		month = "0" + month;
	if (day < 10)
		day = "0" + day;
		
	var hours = currentDate.getHours();
	var minutes = currentDate.getMinutes();
	var seconds = currentDate.getSeconds();
	if (hours < 10)
		hours = "0" + hours;
	if (minutes < 10)
		minutes = "0" + minutes;
	if (seconds < 10)
		seconds = "0" + seconds;		

	dateString= year +"" + month + "" +  "" +day + "T" + hours  + ""+ minutes + "" +seconds;		
	return dateString;
						// + "00Z" + newline;					// add Z for UTC
}

function reminderFox_getStringAsDate(  dateString ) {	
	if ( dateString != null && dateString.length > 0 ) {
		var date;
		var timeIndex = dateString.indexOf( "T" );
		var month = dateString.substring( 4,6);
		if ( month.indexOf( "0" ) == 0 ) {
			month = month.substring(1);
		}
		var monthInt = parseInt( month ) - 1;	
		// event with specific hourly time
		date = new Date( dateString.substring( 0, 4 ), monthInt,  dateString.substring( 6, 8 ) );
		date.setHours( dateString.substring( 9, 11 ), dateString.substring( 11, 13 ), dateString.substring( 13, 15) );
		
		// if event is stored in UTC time (20051208T224616Z), then take into accoutn UTC offset for the 
		// current time		
		reminderFox_adjustDateForTimeZones( dateString, dateString, date );
			
	}
	return date;
}

function reminderFox_writeOutRemindersAndTodos( isExport ) {	
	var outputStr = reminderFox_constructReminderOutput(reminderFox_getReminderEvents(), reminderFox_getReminderTodos(), isExport);  //  ALL  todos
	
	// now write file out to filesystem
	var file = reminderFox_getReminderStoreFile();
 
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("Permission to save file was denied.");
	}

	if ( file.exists() == false ) {
		file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
	}

	reminderFox_writeStringToFile(outputStr, file, false);
	
	reminderFox_updateSunbirdCalendar();
}

/**
 * This function will update any remote calendars if usingSunbird or Lightning
 */
function reminderFox_updateSunbirdCalendar() { 
	if ( reminderFox_isSunbirdOrLightning() ) {		
		var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
	                       .getService(Components.interfaces.mozIJSSubScriptLoader);
		try { 
			// need to load sunbird/lightning javascript file that defines the 
			// getCompositeCalendar().refresh() call.  We do this via the subscript loader
			// because we can't directly include this .js file in the xul files since it is not 
			// available if using Firefox (or Thunderbird w/o Lightning, etc).
			loader.loadSubScript("chrome://calendar/content/calendar-management.js");
			getCompositeCalendar().refresh();
		}
		catch ( e ) { 
			//dump( "Exception: " + e.message );
		}
	}
}

function reminderFox_syncWrittenChangesToRemote() {
	// sync 'em up 
	var networkSync = REMINDER_FOX_NETWORK_SYNCHRONIZE_DEFAULT;		
	try {
		networkSync = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_NETWORK_SYNCHRONIZE);
	} catch(e) {
	}	
	if ( networkSync ) {
		reminderFox_upload_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS);
	}	
}

function reminderFox_uploadReminders() {
	var newOptions = { closeOnNoErrors: 1 };
	window.openDialog('chrome://reminderFox/content/network/upload.xul', 'reminderFox-upload', 'modal, centerscreen', newOptions);
}

function reminderFox_downloadReminders() {
	var newOptions = { closeOnNoErrors: 1 };
	window.openDialog('chrome://reminderFox/content/network/download.xul', 'reminderFox-download', 'modal,centerscreen', newOptions);
}

function reminderFox_writeStringToFile( outputStr, file, isExport ) {
	var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
		.createInstance( Components.interfaces.nsIFileOutputStream );
	outputStream.init( file, 0x04 | 0x08 | 0x20, 420, 0 );
	
	var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
	                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	converter.charset = "UTF-8";
	
	var chunk = null;
	try {
		chunk = converter.ConvertFromUnicode(outputStr);
	}
	catch( e ) {
		chunk = outputStr;
	}
	outputStream.write(chunk, chunk.length);	
	
	 var fin = converter.Finish();
	 if (fin.length > 0)
	   outputStream.write(fin, fin.length);
	 outputStream.close();

	if ( !isExport && reminderFox_lastModifiedTime != null ) { 
		 reminderFox_storeTimeStamp(reminderFox_lastModifiedTime);
	}
}

function reminderFox_storeTimeStamp(lastModified) {
	//var file = reminderFox_getReminderStoreFile();
	//var lastModified =  file.lastModifiedTime  
	reminderFox_prefsBranch.setCharPref(REMINDER_FOX_LAST_MODIFIED, 	lastModified);
	reminderFox_logMessageLevel("Store time stamp: " + new Date() + " -- " + lastModified, REMINDER_FOX_LOG_LEVEL_INFO);	 
}	

function reminderFox_timeStampHasChanged( ) {
	var timestamp = 	reminderFox_getFileTimeStamp()
	var lastRecordedTimeStamp = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_MODIFIED) + "";
//	currentTimeStamp =  file.lastModifiedTime;			
	var fileChanged = lastRecordedTimeStamp != timestamp;	
	reminderFox_logMessageLevel("TimeStamp Changed: " + new Date() + " - " + fileChanged + " --lastRecorded:" + lastRecordedTimeStamp + "--currentTimeStamp:" + timestamp +"-", REMINDER_FOX_LOG_LEVEL_INFO);	 
	
	if ( fileChanged ) {
		return timestamp;
	}
	else {
		return -1;
	}
}	

function reminderFox_filesystemTimeStampHasChanged( ) {
	//var timestamp = 	reminderFox_getFileTimeStamp()
	var lastRecordedTimeStamp = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_MODIFIED) + "";
	
	
	var file =   reminderFox_getReminderStoreFile();

     // bail if the file doesn't yet exist; no reminders to read
      if ( !file.exists() ) { 
      	return -1;
      }			
	var timestamp =  file.lastModifiedTime;			
	var fileChanged = lastRecordedTimeStamp != timestamp;	
	reminderFox_logMessageLevel("TimeStamp Changed: " + new Date() + " - " + fileChanged + " --lastRecorded:" + lastRecordedTimeStamp + "--currentTimeStamp:" + timestamp +"-", REMINDER_FOX_LOG_LEVEL_INFO);	 
	
	if ( fileChanged ) {
		return timestamp;
	}
	else {
		return -1;
	}
	
	// then do this...
	/*
	  var windowEnumerator =  reminderFox_getWindowEnumerator();
	
		if (windowEnumerator.hasMoreElements()) {
			var oldestWindow = windowEnumerator.getNext();		
			oldestWindow.reminderFox_updateRemindersInWindow();	
			reminderFox_clearRemindersAndTodos();

			while (windowEnumerator.hasMoreElements()) {
				var currentWindow = windowEnumerator.getNext();		
				currentWindow.reminderFox_updateRemindersInWindow();		
				currentWindow.reminderFox_clearRemindersAndTodos();						
			}
		}	
	 */

}


function reminderFox_removeQuickAlarm( quickAlarmText ) {	
	var quickAlarms = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_QUICK_ALARMS);		
	if ( quickAlarms != null ) {
		var oldItem = quickAlarms.indexOf(quickAlarmText );
		if ( oldItem != -1 ) {
			// remove quick alarm
			var oldIndex = quickAlarms.lastIndexOf("X-REMINDERFOX-VALARM:", oldItem );				
			var snoozeTimeIndex = quickAlarms.indexOf( ";PT", oldItem + quickAlarmText.length );
			if ( snoozeTimeIndex != -1 ) {					
				var snoozeEndIndex = quickAlarms.indexOf( "M", snoozeTimeIndex );
				if ( snoozeEndIndex != -1 ) {
					// write out new quick alarm
					quickAlarms = quickAlarms.substring( 0, oldIndex ) +						
						quickAlarms.substring( snoozeEndIndex + 1);
				}
			}								
		}
	}	
	reminderFox_setUnicodePref( REMINDER_FOX_QUICK_ALARMS, quickAlarms);	
	reminderFox_prefs.savePrefFile(null); 
}
	

// split a string at newlines:   \n (Mac, *nix) or \r\n  (windows)  and unfold lines
function reminderFox_splitOnAllNewlinesAndUnfoldLines(input) {
	// just use common newline to read in lines - check for strings that end in \r (to handle windows \r\n)
	var newline = "\n";
	var returnLine = "\r";
	
	var remindersArray = input.split(newline);	
	var returnArray = new Array();	
	var returnArrayIndex = 0;
	for ( var index = 0; index < remindersArray.length; index++ ) {
		var readIn = remindersArray[index];	
		/* --------
		if (readIn.length > 0 &&  readIn.lastIndexOf(returnLine) == readIn.length -1 ) {
			readIn = readIn.substring(0, readIn.length -1 );
		} ---- */
		while (readIn.length > 0 &&  readIn.lastIndexOf(returnLine) == readIn.length -1 ) {
			readIn = readIn.substring(0, readIn.length -1 );
		}
		
		// handle line folding
		if (readIn.charAt(0) == ' ' && returnArrayIndex > 0 ) {  // if this line starts with a space, add it to the previous line
			returnArray[returnArrayIndex-1] += readIn.substring(1,readIn.length );
		}
		else {
			returnArray[returnArrayIndex] = readIn;
			returnArrayIndex++;
		}
	}	
	return returnArray;
}


function reminderFox_readInReminderEvent(reminderEvent, index, readIn, remindersArray) {
    var colonIndex;
    
	while ( index < remindersArray.length && readIn != "END:VEVENT" ) {
		if ( readIn.indexOf( "SUMMARY" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.summary = readIn.substring( colonIndex + 1);	
			reminderEvent.summary = reminderFox_unEscapeCommas( reminderEvent.summary );
		}
		else if ( readIn.indexOf( "DESCRIPTION" ) == 0 ) {
			 // there can be multiple notes DESCRIPTION fields; if we have already set the notes field,
			 // then we'll skip it if we encounter another one
			var skipNotes = reminderEvent.notes != null; 
				
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			if ( !skipNotes ) {
				reminderEvent.notes = readIn.substring( colonIndex + 1);	
			}
			
			// replace new line characters with actual newline
			reminderEvent.notes = reminderEvent.notes.replace(new RegExp(/\\n/g),"\n");
			reminderEvent.notes = reminderFox_unEscapeCommas( reminderEvent.notes );
			
			if ( reminderEvent.notes.length == 0 ) {
				reminderEvent.notes = null;  // dont' store empty notes
			}
		}		
		else 	if ( readIn.indexOf( "UID" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.id = readIn.substring( colonIndex + 1 );			
		}		
		else if ( readIn.indexOf( "LAST-MODIFIED" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.lastModified = readIn.substring( colonIndex + 1 );			
		}		
		else 	if ( readIn.indexOf( "PRIORITY" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.priority = readIn.substring( colonIndex + 1 );		
		}
		
		else 	if ( readIn.indexOf( "CATEGORIES" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			if (reminderEvent.categories == null) {
				reminderEvent.categories = readIn.substring( colonIndex + 1 );	
			} else {
				reminderEvent.categories += "," + readIn.substring( colonIndex + 1 );
			}	
		}
		
		else 	if ( readIn.indexOf( "LOCATION" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.location = readIn.substring( colonIndex + 1 );	
			reminderEvent.location = reminderFox_unEscapeCommas( reminderEvent.location );
		}
		else 	if ( readIn.indexOf( "URL" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.url = readIn.substring( colonIndex + 1 );	
		}
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "REMIND-UNTIL-COMPLETED" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.remindUntilCompleted = readIn.substring( colonIndex + 1 );			
		}				
		else if ( readIn.indexOf( "BEGIN:VALARM" ) == 0 ) {
//			// we only want to process the first alarm, as there could be multiple alarm instances.
//			// We will ignore the others, and they will go into the extra info
//			var skipAlarms = false;
//			if ( reminderEvent.alarm != null && reminderEvent.alarm.length > 0 ) {
//				skipAlarms = true;
//			}
			// we only want to process the first alarm, as there could be multiple alarm instances.
			// We will ignore the others, and they will go into the extra info
			if ( reminderEvent.alarm == null || reminderEvent.alarm.length == 0 ) {
			
			index++;
			readIn = remindersArray[index];		
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var alarmTime = readIn.substring( colonIndex + 1 );
			//if ( !skipAlarms ) {
				reminderEvent.alarm = alarmTime;
			//}
			
			// go to the end of VALARM (we don't want to pick up the DESCRIPTION field stored in the alarm
			while ( index < remindersArray.length && readIn != "END:VALARM" ) {
				index++;
				readIn = remindersArray[index];
							
				if ( readIn.indexOf( REMINDERFOX_EXTENDED + "LASTACK" ) == 0 ) {
					colonIndex = readIn.indexOf( ":" );
					while ( colonIndex == -1 ) {
						index++;
						readIn = remindersArray[index];
						colonIndex = readIn.indexOf( ":" );
					}					
					var alarmLastAcknowledge = readIn.substring( colonIndex + 1 );
				//	if ( !skipAlarms ) {
						reminderEvent.alarmLastAcknowledge = alarmLastAcknowledge;
					//}					
				}		
				if ( readIn.indexOf( REMINDERFOX_EXTENDED + "SNOOZE-TIME" ) == 0 ) {
					colonIndex = readIn.indexOf( ":" );
					while ( colonIndex == -1 ) {
						index++;
						readIn = remindersArray[index];
						colonIndex = readIn.indexOf( ":" );
					}					
					var snoozeTime = readIn.substring( colonIndex + 1 );
					//if ( !skipAlarms ) {
						reminderEvent.snoozeTime = snoozeTime;		
					//}			
				}			
				
				
			}
															
//			var alarmIndex1 = alarmTime.indexOf( "-PT" );
//			if ( alarmIndex1 != -1 ) {
//				var alarmIndex2 = alarmTime.indexOf( "M", alarmIndex1 );
//				if ( alarmIndex2 != -1 ) {
//					alarmTime = alarmTime.substring( alarmIndex1 + "-PT".length, alarmIndex2 );
//					reminderEvent.alarm = alarmTime;
//				}
//			}
}
		}	
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "MESSAGEID" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderEvent.messageID = readIn.substring( colonIndex + 1 );			
		}	
		else if ( readIn.indexOf( "DTSTART" ) == 0 ||  readIn.indexOf( "DTEND" ) == 0 ) {
			var startDate = (readIn.indexOf( "DTSTART" ) == 0);
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			
			var eventDate = readIn.substring( colonIndex + 1 );			
			var timeIndex = readIn.indexOf( "T", colonIndex );
			var month = eventDate.substring( 4,6);
			if ( month.indexOf( "0" ) == 0 ) {
				month = month.substring(1);
			}
			var monthInt = parseInt( month ) - 1;	
			if ( timeIndex == -1 ) {   
				// all day event
				if ( startDate ) { 
					reminderEvent.date = new Date( eventDate.substring( 0, 4 ), monthInt, eventDate.substring( 6, 8) );	
				}
				else {
					reminderEvent.endDate = new Date( eventDate.substring( 0, 4 ), monthInt, eventDate.substring( 6, 8) );	
				}			
			}
			else {
				// event with specific hourly time
				if ( startDate ) {
					reminderEvent.date = new Date( eventDate.substring( 0, 4 ), monthInt,  eventDate.substring( 6, 8 ) );
					reminderEvent.date.setHours( eventDate.substring( 9, 11 ), eventDate.substring( 11, 13 ) );
					reminderFox_adjustDateForTimeZones( eventDate, readIn, reminderEvent.date );
					
					reminderEvent.allDayEvent = false;
				}
				else {
					reminderEvent.endDate = new Date( eventDate.substring( 0, 4 ), monthInt,  eventDate.substring( 6, 8 ) );
					reminderEvent.endDate.setHours( eventDate.substring( 9, 11 ), eventDate.substring( 11, 13 ) );
					reminderFox_adjustDateForTimeZones( eventDate, readIn, reminderEvent.endDate );
				}
			}
			if ( !startDate ) {
				// set the end date diff
				if ( reminderEvent.date != null && reminderEvent.endDate != null ) {
					reminderEvent.durationTime = reminderEvent.endDate.getTime() - reminderEvent.date.getTime();
				}
			}
		}
		else if ( readIn.indexOf( "DURATION" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var duration = readIn.substring( colonIndex + 1 );		
			if ( reminderEvent.date != null ) {
				var durationMins = reminderFox_getDurationMinutes( duration );
				reminderEvent.durationTime = durationMins * 60 * 1000;  // set the end date diff
				reminderEvent.endDate = new Date( reminderEvent.date.getTime() + reminderEvent.durationTime );
			}
		}		
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "COMPLETED" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var eventDate = readIn.substring( colonIndex + 1 );			
			var month = eventDate.substring( 4,6);
			if ( month.indexOf( "0" ) == 0 ) {
				month = month.substring(1);
			}
			var monthInt = parseInt( month ) - 1;	
			reminderEvent.completedDate = new Date( eventDate.substring( 0, 4 ), monthInt, eventDate.substring( 6, 8) );				
		}	
		else if ( readIn.indexOf( "RRULE" ) == 0 ) {
			index = reminderFox_readInRecurrence( readIn, index, remindersArray, reminderEvent) ;			
		}	
		else if (  readIn != "BEGIN:VEVENT" ) {
			// this is a line that we do not recognize it.  Just store it
			if ( reminderEvent.extraInfo == null ) { 
				reminderEvent.extraInfo = readIn;						
			}
			else {
				// ignore repeat elements
				//gW  but import multiple ATTENDEE elements !!
				//   note: the element string may be equal up to the first LF
				
				if (( reminderEvent.extraInfo.indexOf( readIn ) == -1 ) || ( readIn.indexOf( "ATTENDEE" ) > -1 )) {
					// take care for LF in COMMENTs	
					if (readIn.indexOf( "COMMENT" ) == 0) {				
						readIn = readIn.replace(new RegExp(/\\n/g),"\n");
					}
					reminderEvent.extraInfo = reminderEvent.extraInfo + "\\n" + readIn;	
				}								
			}
		}	
	
		index++;
		readIn = remindersArray[index];
	}	
	
	return index;


}

/*
 * replace escaped commas with regular commas:
 * "Raleigh\, NC" --> "Raleigh, NC"
 */
function reminderFox_unEscapeCommas( stringValue ) {
	return stringValue.replace(/\\,/g,",");
}

/**
 * escape commas
 */
function reminderFox_EscapeCommas( stringValue ) {
	return stringValue.replace(/,/g,"\\,")
}

function reminderFox_writeOutRecurrence(reminder, currentDate, separator, newline) {
		var endRepeatUntil = "";
		var outputStr = "";
		if ( reminder.recurrence.endDate != null ) {			
				//currentDate.setMinutes( currentDate.getMinutes() + tzOffset );	// set this offset for UTC	
			var year = reminder.recurrence.endDate.getFullYear();
			var endRepeatUntilmonth = reminder.recurrence.endDate.getMonth() +1;
			var day = reminder.recurrence.endDate.getDate();
			if (endRepeatUntilmonth < 10)
				endRepeatUntilmonth = "0" + endRepeatUntilmonth;
			if (day < 10)
				day = "0" + day;

			endRepeatUntil += ";UNTIL=" + "" + year  + endRepeatUntilmonth  + day;
		}	

		var interval = reminder.recurrence.interval;
		if ( interval == null || interval <= 1 ) {
			interval = 1;
		}
		if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) {
			var month = currentDate.getMonth() +1;
			if (month < 10) {
				month = "0" + month;
			}		
			outputStr += "RRULE" + separator +  
									"FREQ=YEARLY;INTERVAL=" + interval + ";BYMONTH=" + month + endRepeatUntil + newline;				
		}
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
			var weekNumber = reminderFox_getWeekNumber( reminder.date );
			var month = currentDate.getMonth() +1;
			if (month < 10) {
				month = "0" + month;
			}
			outputStr += "RRULE" + separator +  
									"FREQ=YEARLY;INTERVAL=" + interval + ";BYMONTH=" + month +";BYDAY=" + weekNumber + reminderFox_weekday[reminder.date.getDay()] +endRepeatUntil + newline;					
		}		
		else 	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
			outputStr += "RRULE" + separator +  
									 "FREQ=MONTHLY;INTERVAL=" + interval + endRepeatUntil +  newline;							
		}   
		else if ( reminder.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
			var weekNumber = reminderFox_getWeekNumber( reminder.date );
			outputStr += "RRULE" + separator +  
									 "FREQ=MONTHLY;INTERVAL=" + interval + ";BYDAY=" +  weekNumber + reminderFox_weekday[reminder.date.getDay()]+ endRepeatUntil + newline;	
		}
		else	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {		
			if ( reminder.recurrence.byDay == null || reminder.recurrence.byDay.length == 0) {
				outputStr += "RRULE" + separator +  
									"FREQ=WEEKLY;INTERVAL=" + interval + ";BYDAY=" + reminderFox_weekday[reminder.date.getDay()] + endRepeatUntil + newline;		
			}
			else {
				outputStr += "RRULE" + separator +  
									"FREQ=WEEKLY;INTERVAL=" + interval + ";BYDAY=" + reminder.recurrence.byDay + endRepeatUntil + newline;		
			}		
		}	
		else 	if ( reminder.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {
			if ( interval > 1 ) {
				outputStr += "RRULE" + separator +  
									 "FREQ=DAILY;INTERVAL=" + interval +  endRepeatUntil + newline;	
			}
			else {
				outputStr += "RRULE" + separator +  
									 "FREQ=DAILY"+  endRepeatUntil + newline;	
			}		
											
		}    				
		else {		
			// no recurrence string for REMINDER_RECURRENCE_ONETIME
		}	
		return outputStr;
}

function reminderFox_getRecurrenceInterval( rrule ) {
	var interval = null;
	var intervalIndex =rrule.indexOf("INTERVAL=");
	try {
		if ( intervalIndex != -1 ) {	
			var semicolonIndex = rrule.indexOf( ";", intervalIndex);
			if ( semicolonIndex == -1 ) {
				interval = parseInt( rrule.substring( intervalIndex + "INTERVAL=".length, rrule.length ) );
			}
			else {
				interval = parseInt( rrule.substring( intervalIndex + "INTERVAL=".length, semicolonIndex ) )
			}
		}
	}
	catch ( e ) {		
	}
	return interval;
}

function reminderFox_getRecurrenceByDay( rrule ) {
	var byday = "";
	var bydayIndex = rrule.indexOf("BYDAY=");
	try {
		if ( bydayIndex != -1 ) {	
			var semicolonIndex = rrule.indexOf( ";", bydayIndex);
			if ( semicolonIndex == -1 ) {
				byday = rrule.substring( bydayIndex + "BYDAY=".length, rrule.length );
			}
			else {
				byday = rrule.substring( bydayIndex + "BYDAY=".length, semicolonIndex );
			}
			if ( byday.indexOf( ",") == -1 ) { // only one byday; don't store it			
				byday = null;
			}
		}
	}
	catch ( e ) {		
	}

	return byday;
}

function reminderFox_readInRecurrence( readIn, index, remindersArray, reminderEvent) {
	var colonIndex = readIn.indexOf( ":" );
	while ( colonIndex == -1 ) {
		index++;
		readIn = remindersArray[index];
		colonIndex = readIn.indexOf( ":" );
	}
	var rrule =  readIn.substring( colonIndex + 1 );
	if ( rrule.indexOf( "FREQ=YEARLY")  != -1  ) {				
		reminderEvent.recurrence.interval = reminderFox_getRecurrenceInterval( rrule );
		var byDayIndex = rrule.indexOf( "BYDAY=" );
		if ( byDayIndex != -1 ) {	
			// yearly on day
			reminderEvent.recurrence.type = REMINDER_RECURRENCE_YEARLY_DAY; 
		}
		else {			
			reminderEvent.recurrence.type = REMINDER_RECURRENCE_YEARLY;
		}
	}
	else 	if ( rrule.indexOf( "FREQ=MONTHLY" ) != -1  ) {
		var byDayIndex = rrule.indexOf( "BYDAY=" );
		if ( byDayIndex != -1 ) {	
			if ( rrule.indexOf( "INTERVAL=12") != -1  ) {	
				// yearly on day
				reminderEvent.recurrence.type = REMINDER_RECURRENCE_YEARLY_DAY; 
			}
			else {
				// monthly on day
				reminderEvent.recurrence.type = REMINDER_RECURRENCE_MONTHLY_DAY; 		
				reminderEvent.recurrence.interval = reminderFox_getRecurrenceInterval( rrule );			
			}
		}
		else {
			// monthly on date
			reminderEvent.recurrence.type = REMINDER_RECURRENCE_MONTHLY_DATE; 
			reminderEvent.recurrence.interval = reminderFox_getRecurrenceInterval( rrule );
		}
	}
	else 	if ( rrule.indexOf( "FREQ=WEEKLY")  != -1  ) {
		reminderEvent.recurrence.byDay = reminderFox_getRecurrenceByDay( rrule );
		reminderEvent.recurrence.type = REMINDER_RECURRENCE_WEEKLY;		
		reminderEvent.recurrence.interval = reminderFox_getRecurrenceInterval( rrule );			
	}
	else 	if ( rrule.indexOf( "FREQ=DAILY")  != -1  ) {
		reminderEvent.recurrence.type = REMINDER_RECURRENCE_DAILY;
		reminderEvent.recurrence.interval = reminderFox_getRecurrenceInterval( rrule );			
	}			
	
	// ;UNTIL=20060504T035959;INTERVAL=1
	var repeatUntil =  rrule.indexOf( "UNTIL=");
	if ( repeatUntil != -1 ) {
		 var endRepeatUntil =  rrule.indexOf( ";", repeatUntil);
		 if ( endRepeatUntil == -1 ) {
		 	endRepeatUntil = rrule.length;
		 }

		var repeatUntilStr = rrule.substring( repeatUntil + "UNTIL=".length, endRepeatUntil );
		var timeIndex = repeatUntilStr.indexOf( "T", colonIndex );
		var month = repeatUntilStr.substring( 4,6);
		if ( month.indexOf( "0" ) == 0 ) {
			month = month.substring(1);
		}
		var monthInt = parseInt( month ) - 1;
		if ( timeIndex == -1 ) {   
			// all day event
			reminderEvent.recurrence.endDate = new Date( repeatUntilStr.substring( 0, 4 ), monthInt, repeatUntilStr.substring( 6, 8) );
		}
		else {
			// event with specific hourly time
			reminderEvent.recurrence.endDate = new Date( repeatUntilStr.substring( 0, 4 ), monthInt,  repeatUntilStr.substring( 6, 8 ) );
			reminderEvent.recurrence.endDate.setHours( repeatUntilStr.substring( 9, 11 ), repeatUntilStr.substring( 11, 13 ) );
			
			reminderFox_adjustDateForTimeZones( repeatUntilStr, rrule, reminderEvent.recurrence.endDate );
		}
	}
	
	return index;
}



function reminderFox_readInReminderTodo(reminderTodo, index, readIn, remindersArray, reminderTodosArr) {
	var listID;  
	while ( index < remindersArray.length && readIn != "END:VTODO" ) {
		if ( readIn.indexOf( "SUMMARY" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.summary = readIn.substring( colonIndex + 1);			
			reminderTodo.summary = reminderFox_unEscapeCommas( reminderTodo.summary );
		}
		else 	if ( readIn.indexOf( "UID" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.id = readIn.substring( colonIndex + 1 );		
		}		
		else if ( readIn.indexOf( "DESCRIPTION" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.notes = readIn.substring( colonIndex + 1);	

			// replace new line characters with actual newline
			reminderTodo.notes = reminderTodo.notes.replace(new RegExp(/\\n/g),"\n");		
			reminderTodo.notes = reminderFox_unEscapeCommas( reminderTodo.notes );
			
			if ( reminderTodo.notes.length == 0 ) {
				reminderTodo.notes = null;  // dont' store empty notes
			}
		}	

		else 	if ( readIn.indexOf( "CATEGORIES" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}			
			reminderTodo.categories = readIn.substring( colonIndex + 1 );	
		}
		
	else 	if ( readIn.indexOf( "LOCATION" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.location = readIn.substring( colonIndex + 1 );	
			reminderTodo.location = reminderFox_unEscapeCommas( reminderTodo.location );
		}
		else 	if ( readIn.indexOf( "URL" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.url = readIn.substring( colonIndex + 1 );	
		}
				
		else if ( readIn.indexOf( "PRIORITY" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.priority = readIn.substring( colonIndex + 1 );		
		}			
		else if ( readIn.indexOf( "PERCENT-COMPLETE" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var completePercent = readIn.substring( colonIndex + 1 );		
			if ( completePercent == "100" ) {
				if ( reminderTodo.completedDate == null ) {
					reminderTodo.completedDate = new Date();
				}
			}
		}	
		else if ( readIn.indexOf( "RRULE" ) == 0 ) {
			index = reminderFox_readInRecurrence( readIn, index, remindersArray, reminderTodo) ;			
		}	
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "SHOW-IN-TOOLTIP" ) == 0 ) {
			var colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.showInTooltip = readIn.substring( colonIndex + 1 );			
		}	
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "MESSAGEID" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			reminderTodo.messageID = readIn.substring( colonIndex + 1 );			
		}	
		else if ( readIn.indexOf( REMINDERFOX_EXTENDED + "LISTID" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			listID = readIn.substring( colonIndex + 1 );			
		}	
		else if ( readIn.indexOf( "DTSTART" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var eventDate = readIn.substring( colonIndex + 1 );			
			var timeIndex = readIn.indexOf( "T", colonIndex );
			var month = eventDate.substring( 4,6);
			if ( month.indexOf( "0" ) == 0 ) {
				month = month.substring(1);
			}
			var monthInt = parseInt( month ) - 1;	
			if ( timeIndex == -1 ) {   
				// all day event
				reminderTodo.date = new Date( eventDate.substring( 0, 4 ), monthInt, eventDate.substring( 6, 8) );		
			}
			else {
				// event with specific hourly time
				reminderTodo.date = new Date( eventDate.substring( 0, 4 ), monthInt,  eventDate.substring( 6, 8 ) );
				reminderTodo.date.setHours( eventDate.substring( 9, 11 ), eventDate.substring( 11, 13 ) );
				reminderFox_adjustDateForTimeZones( eventDate, readIn, reminderTodo.date );
				
				reminderTodo.allDayEvent = false;
			}
		}	
		else if ( readIn.indexOf( "DURATION" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var duration = readIn.substring( colonIndex + 1 );		
			if ( reminderTodo.date != null ) {
				var durationMins = reminderFox_getDurationMinutes( duration );
				reminderTodo.durationTime = durationMins * 60 * 1000;  // set the end date diff
				reminderTodo.endDate = new Date( reminderTodo.date.getTime() + reminderTodo.durationTime );
			}
		}
		else if ( readIn.indexOf( "BEGIN:VALARM" ) == 0 ) {
			index++;
			readIn = remindersArray[index];		
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var alarmTime = readIn.substring( colonIndex + 1 );
			reminderTodo.alarm = alarmTime;
			
			// go to the end of VALARM (we don't want to pick up the DESCRIPTION field stored in the alarm
			while ( index < remindersArray.length && readIn != "END:VALARM" ) {
				index++;
				readIn = remindersArray[index];
							
				if ( readIn.indexOf( REMINDERFOX_EXTENDED + "LASTACK" ) == 0 ) {
					colonIndex = readIn.indexOf( ":" );
					while ( colonIndex == -1 ) {
						index++;
						readIn = remindersArray[index];
						colonIndex = readIn.indexOf( ":" );
					}					
					var alarmLastAcknowledge = readIn.substring( colonIndex + 1 );
					reminderTodo.alarmLastAcknowledge = alarmLastAcknowledge;					
				}	
				if ( readIn.indexOf( REMINDERFOX_EXTENDED + "SNOOZE-TIME" ) == 0 ) {
					colonIndex = readIn.indexOf( ":" );
					while ( colonIndex == -1 ) {
						index++;
						readIn = remindersArray[index];
						colonIndex = readIn.indexOf( ":" );
					}					
					var snoozeTime = readIn.substring( colonIndex + 1 );
					reminderTodo.snoozeTime = snoozeTime;					
				}			
															
			}									
		}			
		else if ( readIn.indexOf( "COMPLETED" ) == 0 ) {
			colonIndex = readIn.indexOf( ":" );
			while ( colonIndex == -1 ) {
				index++;
				readIn = remindersArray[index];
				colonIndex = readIn.indexOf( ":" );
			}
			var eventDate = readIn.substring( colonIndex + 1 );			
			var month = eventDate.substring( 4,6);
			if ( month.indexOf( "0" ) == 0 ) {
				month = month.substring(1);
			}
			var monthInt = parseInt( month ) - 1;	
			reminderTodo.completedDate = new Date( eventDate.substring( 0, 4 ), monthInt, eventDate.substring( 6, 8) );				

		}
		else if (  readIn != "BEGIN:VTODO" ) {
			// this is a line that we do not recognize it.  Just store it
			if ( reminderTodo.extraInfo == null ) {
				reminderTodo.extraInfo = readIn;					
			}
			else {
				if ( reminderTodo.extraInfo.indexOf( readIn ) == -1 ) {  // ignore repeat elements
					reminderTodo.extraInfo = reminderTodo.extraInfo + "\\n" + readIn;
				}
			}
		}						

		index++;
		readIn = remindersArray[index];
	}	


	// add todo to appropriate list	
	if ( listID == null ) {
		listID =REMINDER_FOX_DEFAULT_TODOS_CATEGORY;  
	}
	
	var todosArr =reminderTodosArr[listID];
	if ( todosArr == null ) {
		todosArr = new Array();
		reminderTodosArr[listID] = todosArr;
	}
	todosArr[todosArr.length] = reminderTodo;

	return index;
}


function reminderFox_getDurationMinutes( alarm ) {
		if ( alarm == null ) {
			return null;
		}
		// example: PT15M
		var alarmTime = alarm;
		var result = null;						 
		var alarmIndex1 = alarmTime.indexOf( "PT" );
		if ( alarmIndex1 != -1 ) {
			var alarmIndex2 = alarmTime.indexOf( "M", alarmIndex1 );
			if ( alarmIndex2 != -1 ) {
				alarmTime = alarmTime.substring( alarmIndex1 + "PT".length, alarmIndex2 );		
				result = parseInt( alarmTime );	
			}
			else {
				alarmIndex2 = alarmTime.indexOf( "H", alarmIndex1 );
				if ( alarmIndex2 != -1 ) {
					alarmTime = alarmTime.substring( alarmIndex1 + "PT".length, alarmIndex2 );		
					result = parseInt(alarmTime) * 60;
				}	
			}	
		}
		else {
			alarmIndex1 = alarmTime.indexOf( "P" );
			if ( alarmIndex1 != -1 ) {
				var alarmIndex2 = alarmTime.indexOf( "D", alarmIndex1 );
				if ( alarmIndex2 != -1 ) {
					alarmTime = alarmTime.substring( alarmIndex1 + "P".length, alarmIndex2 );		
					result = parseInt( alarmTime ) * 24 * 60;					
				}
			}
		}		
		return result;				 
}

function reminderFox_isCompletedForDate( reminder, reminderInstanceDate ) {
	if ( reminder.completedDate == null ) {
		return false;
	}
	
	 // if this is a one-time reminder that has been marked complete at any date, then it is completed
	if ( reminder.recurrence.type == REMINDER_RECURRENCE_ONETIME ) { 
		return true;
	}
	
	
	// return completed (true) if marked complete and the date is less than or equal to the reminder's date
	if ( reminderFox_compareDates(reminderInstanceDate, reminder.completedDate ) == 1 ) {
		return false;
	}
	else {
		return true;
	}
}

function reminderFox_readInRemindersAndTodosICSFromFile(reminderEvents, reminderTodos, file, ignoreExtraInfo) {

	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("Permission to read file was denied.");
	}

	var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
		.createInstance( Components.interfaces.nsIFileInputStream );
	try {
		is.init( file,0x01, 00004, null);
	}
	catch ( e ) {
		reminderFox_logMessageLevel("Could not read reminder file: " + e.name  +  " -- " + e.message, REMINDER_FOX_LOG_LEVEL_INFO);
		return;
	}

	reminderFox_readInRemindersAndTodosICSFromStream(reminderEvents, reminderTodos, is, ignoreExtraInfo);
}

/* Called also from download.js */
function reminderFox_readInRemindersAndTodosICSFromStream(reminderEvents, reminderTodosArr, is, ignoreExtraInfo) {	
	var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
	                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	converter.charset = /* The character encoding you want, using UTF-8 here */ "UTF-8";
	
	// Now, read from the stream
	var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
	                                 .createInstance(Components.interfaces.nsIScriptableInputStream);
	scriptableStream.init(is);
	var chunk = scriptableStream.read(scriptableStream.available());
	var input = null;
	try {
		 input = converter.ConvertToUnicode(chunk);
	}
	catch( e ) {
		// if the conversion fails (say importing from a previous version before the conversion code was in place)
		// then just set the input to the read-in value
		input = chunk;
	}		

	reminderFox_readInRemindersAndTodosICSFromString(reminderEvents, reminderTodosArr, input, ignoreExtraInfo );
}



function reminderFox_readInRemindersAndTodosICSFromString(reminderEvents, reminderTodosArr, input, ignoreExtraInfo) {
	var remindersArray;
	var reminderEventsIndex = 0;
	var i, j;
	// if reading from a source that could be from a different OS (usually on import), 
	// then check the newlines as they could differ from the current OS
	//if ( checkNewlines ) {
	// actually..  if sharing the stored reminders location between windows/linux or sharing remotely, 
	// we need to check the newlines everytime
	remindersArray = reminderFox_splitOnAllNewlinesAndUnfoldLines(input);

	var index = 0;
	var readIn = remindersArray[index];
	// bypass header 
//gW  modified to get the METHOD to  reminderfox_Method
	reminderfox_Method="";
	
	while ( index < remindersArray.length  ) {
		
		if ( readIn.indexOf( "METHOD:" )  == 0)  {                        
	       	reminderfox_Method = readIn.substring("METHOD:".length).toUpperCase();
	    }
		
		if ( readIn == "BEGIN:VEVENT" ) {
			var reminderEvent = new ReminderFoxEvent( null, null, null );
			reminderEvent.recurrence.type = REMINDER_RECURRENCE_ONETIME;
			index = reminderFox_readInReminderEvent( reminderEvent, index, readIn, remindersArray);
			reminderEvents[reminderEventsIndex] = reminderEvent;
			reminderEventsIndex++;
		}
		else if ( readIn == "BEGIN:VTODO" ) {
			var reminderTodo = new ReminderFoxTodo( null, null );
			index = reminderFox_readInReminderTodo( reminderTodo, index, readIn, remindersArray, reminderTodosArr);					
		}	
		else if ( readIn.length > 0 && 
			 readIn.indexOf( "VCALENDAR" )  == -1  &&
			 readIn.indexOf( "VERSION" )  == -1  &&
			 readIn.indexOf( "PRODID" )  == -1  &&
			 readIn.indexOf( "METHOD" )  == -1  &&
			 readIn.indexOf( "REMINDERFOX" )  == -1 ) {
			// if doesn't equal any known reminderfox fields, store it
			if ( ignoreExtraInfo ) {
				// if we don't care about extra info, don't store it
			}
			else { 
				if ( reminderFoxExtraInfo== null ) {
					reminderFoxExtraInfo = readIn;		
				}
				else {
					if ( reminderFoxExtraInfo.indexOf( readIn ) == -1 ) {  // ignore repeat elements
						reminderFoxExtraInfo =reminderFoxExtraInfo + "\\n" + readIn;
					}				
				}	
			}	
		}		
		index++;
		readIn = remindersArray[index];
	}
}

function reminderFox_readInFileContents(file) {
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("Permission to read file was denied.");
	}

	var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
		.createInstance( Components.interfaces.nsIFileInputStream );
	try {
		is.init( file,0x01, 00004, null);
	}
	catch ( e ) {
		reminderFox_logMessageLevel("Could not read reminder file: " + e.name  +  " -- " + e.message, REMINDER_FOX_LOG_LEVEL_INFO);
		return null;
	}
	
	
	var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
	                          .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	converter.charset = /* The character encoding you want, using UTF-8 here */ "UTF-8";
	
	// Now, read from the stream
	var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
	                                 .createInstance(Components.interfaces.nsIScriptableInputStream);
	scriptableStream.init(is);
	var chunk = scriptableStream.read(scriptableStream.available());
	var input = null;
	try {
		 input = converter.ConvertToUnicode(chunk);
	}
	catch( e ) {
		// if the conversion fails (say importing from a previous version before the conversion code was in place)
		// then just set the input to the read-in value
		input = chunk;
	}		
	
	return input;
}


function reminderFox_mergeEvents( existingEvents, importedEvents ) {
	var i;
	for ( i = 0; i < importedEvents.length; i++ ) {
		var exists = reminderFox_eventExists( existingEvents, importedEvents[i] );
		if ( !exists ) {
			// add reminder in sorted order...
			var sortedIndex = reminderFox_getSortedIndexOfNewReminder( existingEvents, importedEvents[i], false );
			reminderFox_insertIntoArray( existingEvents,  importedEvents[i], sortedIndex );
		}
	}
}

function reminderFox_mergeTodos( existingTodosArray, importedTodosArray ) {	
	var i;
	for ( var n in importedTodosArray ) {
		var importedTodos = importedTodosArray[n];
		var existingTodos = existingTodosArray[n];
		
		if ( existingTodos == null ) {
			existingTodos = new Array();
			existingTodosArray[n] = existingTodos;
			for ( i = 0; i < importedTodos.length; i++ ) {
				var sortedIndex = reminderFox_getSortedIndexOfNewTodo( existingTodos, importedTodos[i] );
				reminderFox_insertIntoArray( existingTodos,  importedTodos[i], sortedIndex );
			}	
		}
		else {
			for ( i = 0; i < importedTodos.length; i++ ) {
				var exists = reminderFox_eventExists( existingTodos, importedTodos[i] );
				if ( !exists ) {
					// add todo in sorted order...
					var sortedIndex = reminderFox_getSortedIndexOfNewTodo( existingTodos, importedTodos[i] );
					reminderFox_insertIntoArray( existingTodos,  importedTodos[i], sortedIndex );
				}
			}
		}
	}		
}
function reminderFox_eventExists( existingEvents, importedEvent ) {
		for ( var i = 0; i < existingEvents.length; i++ ) {
			if ( existingEvents[i].id == importedEvent.id ) {
				return true;
			}
		}
		return false;
}

function reminderFox_importRemindersUpdateAll( isNetworkImport, lastModifiedTime) {	
	if ( lastModifiedTime != null ) {
		reminderFox_lastModifiedTime = lastModifiedTime;
		reminderFox_storeTimeStamp(reminderFox_lastModifiedTime);
	}

	var outputStr = reminderFox_constructReminderOutput(reminderFoxEvents, reminderFoxTodosArray, isNetworkImport);
	
	// now write file out to filesystem
	var file =   reminderFox_getReminderStoreFile();
 
	try {
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	} catch (e) {
		alert("Permission to save file was denied.");
	}
	

	if ( file.exists() == false ) {
		file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
	}

	reminderFox_writeStringToFile(outputStr, file, false);

	// update all windows with imported reminders
	try {
		var windowEnumerator =  reminderFox_getWindowEnumerator();
	
		// update all of the browsers
		while (windowEnumerator.hasMoreElements()) {
			var currentWindow = windowEnumerator.getNext();		
			currentWindow.reminderFoxEvents = reminderFoxEvents;
			currentWindow.reminderFoxTodosArray  = reminderFoxTodosArray;

			currentWindow.reminderFox_updateRemindersInWindow();			
			currentWindow.reminderFox_clearRemindersAndTodos();
		}
	}
	catch(e) {
	}
	
      
}





function reminderFox_optionsPopulateYearList( currentDate ) {
	var todaysDate = new Date();
	// start with last year , in case they want to create a repeating reminder
	// from a previous month
	var year = parseInt(todaysDate.getFullYear()) -1;   

	var yearlist = document.getElementById('yearlist');
	while ( yearlist.firstChild.hasChildNodes()) {
	      yearlist.firstChild.removeChild( yearlist.firstChild.firstChild);
	}	

 	for ( var k = 0; k < 5; k++ ) {
		var newYear = document.createElement("menuitem");
		var yearVal = year + k;
		newYear.setAttribute("label", yearVal);
		yearlist.firstChild.appendChild(newYear);
	}
	
	yearlist.label = currentDate.getFullYear();
}


function reminderFox_optionsPopulateDateList( currentDate) {
	var year = parseInt(currentDate.getFullYear());
	var daylist = document.getElementById('daylist');
	var items = daylist.firstChild.childNodes;
	// remove ending nodes that could possibly be different each month
	// (i.e. any date greater than 28)
	var length = daylist.firstChild.childNodes.length - 1;	
	for ( var j = length; j >= 28; j-- ) {
		daylist.firstChild.removeChild( items[j] );
	}

	// now add proper # of days for this month
	var dayArray;
	if (reminderFox_isLeapYear(parseInt(year))) {
		dayArray = REMINDER_FOX_lDOMonth;
	}
	else {
		dayArray = REMINDER_FOX_DOMonth;
	}

	var monthlist = document.getElementById('monthlist');
	var currentMonth = monthlist.selectedIndex;

	var numOfDays = dayArray[currentMonth];
 	for ( var k = 29; k < numOfDays + 1; k++ ) {
		var newDay = document.createElement("menuitem");
		var str = k + "";
		newDay.setAttribute("label", str);
		daylist.firstChild.appendChild(newDay);
	}
	

	// now make sure the dateList is not showing a date greater than
	// the number of days in the selected month; if it is set the list
	// to show the last day of the month
	var dayname = parseInt(daylist.label);

	var numOfDaysInt = parseInt( numOfDays );
	if ( dayname > numOfDaysInt ) {
		daylist.selectedItem = daylist.firstChild.childNodes[numOfDaysInt - 1];
	}		
}

function reminderFox_getDateVariable( reminder, date, variableDateString )  {
	var reminderLabel = variableDateString;
	// Replace the [variables]	
	var startBracketIndex =reminderLabel.indexOf("[");
	while (startBracketIndex != -1) {
		var endBracketIndex = reminderLabel.indexOf("]", startBracketIndex);
		if (endBracketIndex != -1) {
			// Check for a fishy [
			if (endBracketIndex - startBracketIndex < 3) {
				startBracketIndex = reminderLabel.indexOf("[", ++startBracketIndex);
			}
			else {
				var variable = reminderLabel.substring(startBracketIndex + 1, endBracketIndex);		
				var decodedVariable = reminderFox_decodeReminderLabelVariable(reminder, variable, date);
				var decodedVariableLength = decodedVariable.length;
				var startTrim = startBracketIndex;
				var endTrim = endBracketIndex;
				if ( variable == "time" && decodedVariableLength == 0 ) {
					// trim the ( ) from around time if the time is empty (all-day event)
					if ( reminderLabel.charAt( startBracketIndex - 1 ) == "(" &&
						reminderLabel.charAt( endBracketIndex + 1 ) == ")"  ) {
						startTrim = startTrim - 1;
						endTrim = endTrim + 1;
					}
				}
				reminderLabel = reminderLabel.substring(0, startTrim) + decodedVariable + reminderLabel.substring(endTrim + 1, reminderLabel.length);
				startBracketIndex = reminderLabel.indexOf("[", startBracketIndex + decodedVariableLength);
			}
		}
	}
	
	return reminderLabel;
}



function reminderFox_optionsSetNewReminderDate( date, repopulateDays ) {
	var month = date.getMonth();
	var day = date.getDate() - 1; // account for 1-offset	
	var monthlist = document.getElementById('monthlist');

	var items = monthlist.firstChild.childNodes;
    monthlist.selectedItem = items[month];
    
	// if month or year has changed, we want to reseed the date drop-down list with the appropriate
	// number of days for that month
    if ( repopulateDays ) {
   		reminderFox_optionsPopulateDateList(date);
   	}
    
	var dayList = document.getElementById('daylist');
	items = dayList.firstChild.childNodes;
    dayList.selectedItem = items[day];	
}



/* SORTING */
function reminderFox_sortArraySwap( array, a, b )
{
	var tmp=array[a];
	array[a]=array[b];
	array[b]=tmp;
}


function reminderFox_compareColumnReminder1LessThanDate( reminder1, reminder2 ) {
	if ( reminder1.date == null && reminder2.date != null ) {
		return false
	}
	if ( reminder1.date != null && reminder2.date == null ) {
		return true
	}
	if ( reminder1.date == null && reminder2.date == null ) {
		return reminder1.originalIndex < reminder2.originalIndex;
	}	
	
	// otherwise, they both have dates - compare them
	var compare = reminderFox_compareReminderDatesAndTimes( reminder1, reminder2 );
	if ( compare == -1 ) { 
		return true;
	}
	else if ( compare == 1 ){
		return false;
	}	
	else {		
		return reminder1.originalIndex < reminder2.originalIndex;
	}
}

function reminderFox_compareColumnReminder1LessThanReminderCompletedDate( reminder1, reminder2 ) {	
	var completed1 = reminderFox_isCompletedForDate( reminder1, reminder1.date );
	var completed2 = reminderFox_isCompletedForDate( reminder2, reminder2.date );
		
	if ( !completed1 && completed2 ) {
		return false;
	}
	else if ( completed1 && !completed2 ) {
		return true;
	}
	else if ( !completed1 && !completed2 ) {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
	
	// otherwise, they both have completed dates - compare them
	var compare = reminderFox_compareDates( reminder1.completedDate, reminder2.completedDate );	
	if ( compare == -1 ) { 
		return true;
	}
	else if ( compare == 1 ){
		return false;
	}	
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}	
}

function reminderFox_compareColumnReminder1LessThanReminderEndDate( reminder1, reminder2 ) {	
	if ( reminder1.endDate == null && reminder2.endDate != null ) {
		return false
	}
	if ( reminder1.endDate != null && reminder2.endDate == null ) {
		return true
	}
	if ( reminder1.endDate == null && reminder2.endDate == null ) {
		return reminder1.originalIndex < reminder2.originalIndex;
	}	
	
	var myEndDate1 = new Date( reminder1.date.getTime() + reminder1.durationTime );
	if ( reminder1.allDayEvent ) {
		myEndDate1.setDate( myEndDate1.getDate() -1 ); // all-day offset
	}

	var myEndDate2 = new Date( reminder2.date.getTime() + reminder2.durationTime );
	if ( reminder2.allDayEvent ) {
		myEndDate2.setDate( myEndDate2.getDate() -1 ); // all-day offset
	}
	
	// otherwise, they both have dates - compare them
	var compare = reminderFox_compareReminderDatesAndTimes( reminder1, reminder2, myEndDate1, myEndDate2 );
	if ( compare == -1 ) { 
		return true;
	}
	else if ( compare == 1 ){
		return false;
	}	
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
	
}
	

function reminderFox_compareColumnReminder1LessThanCompletedDate( reminder1, reminder2 ) {	
	if ( reminder1.completedDate == null && reminder2.completedDate != null ) {		
		return false;
	}
	else if ( reminder1.completedDate != null && reminder2.completedDate == null ) {
		return true;
	}
	else if ( reminder1.completedDate == null && reminder2.completedDate == null ) {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
	
	// otherwise, they both have completed dates - compare them
	var compare = reminderFox_compareDates( reminder1.completedDate, reminder2.completedDate );
	if ( compare == -1 ) { 
		return true;
	}
	else if ( compare == 1 ){
		return false;
	}	
	else {
		// they are equal; check subsort
        return reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  );
	}
}

function reminderFox_compareColumnReminder1LessThanSummary( reminder1, reminder2 ) {
	return reminder1.summary.toLowerCase() < reminder2.summary.toLowerCase();
}

function reminderFox_compareColumnReminder1LessThanCategory( reminder1, reminder2 ) {
	if (  reminder1.categories == null  && reminder2.categories == null ) {
        // they are equal; check subsort
        return reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  );
	} 
	else if ( reminder1.categories == null  && reminder2.categories != null ) { 
		return false;
	}
	else 	if ( reminder1.categories != null  && reminder2.categories == null ) { 
		return true;
	}
	else if ( reminder1.categories.toLowerCase() ==  reminder2.categories.toLowerCase()  ) {
        // they are equal; check subsort
        return reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  );	}
	else {
		return reminder1.categories.toLowerCase() < reminder2.categories.toLowerCase();
	}
}

// showInTooltip
function reminderFox_compareColumnReminder1LessThanShowInTooltip( reminder1, reminder2 ) {	
	if ( reminder1.showInTooltip == false && reminder2.showInTooltip == true ) {
		return false
	}
	if ( reminder1.showInTooltip == true && reminder2.showInTooltip == false ) {
		return true;
	}
	else {
        // they are equal; check subsort
        return reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  );
	}
}

// notes
function reminderFox_compareColumnReminder1LessThanNotes( reminder1, reminder2,  columnArray, sortDirArray, sortIndex  ) {	
	if ( reminder1.notes == null && reminder2.notes != null ) {
		return false
	}
	if ( reminder1.notes != null && reminder2.notes == null ) {
		return true;
	}
	else {
        // they are equal; check subsort
        return reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  );
	}
}

// ruc
function reminderFox_compareColumnReminder1LessThanRUC( reminder1, reminder2 ) {	
 if ( reminder1.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED &&
		( reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED || 
		  reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE ) ) {
		return true;
	}
	else if ( reminder1.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED &&
		  reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE  ) {
		return true;
	}	
	else if ( reminder1.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED &&
		  reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED  ) {
		return false;
	}	
	else if ( reminder1.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_NONE &&
		( reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED || 
		  reminder2.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) ) {
		return false;
	}	
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
}

// mail
function reminderFox_compareColumnReminder1LessThanMail( reminder1, reminder2 ) {	
	if ( reminder1.messageID == null && reminder2.messageID != null ) {
		return false
	}
	if ( reminder1.messageID != null && reminder2.messageID == null ) {
		return true;
	}
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
}

// alarm
function reminderFox_compareColumnReminder1LessThanAlarm( reminder1, reminder2 ) {	
	if ( reminder1.alarm == null && reminder2.alarm != null ) {
		return false
	}
	if ( reminder1.alarm != null && reminder2.alarm == null ) {
		return true;
	}
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
}

// time
function reminderFox_compareColumnReminder1LessThanTime( reminder1, reminder2 ) {	
	if ( reminder1.allDayEvent == null && reminder2.allDayEvent != null ) {
		return true
	}
	if ( reminder1.allDayEvent != null && reminder2.allDayEvent == null ) {
		return false;
	}
	if ( reminder1.date == null && reminder2.date != null ) {
		return false
	}
	if ( reminder1.date != null && reminder2.date == null ) {
		return true
	}
	
	if ( reminder1.date != null && reminder2.date != null ) {		
		if ( reminder1.date.getHours() < reminder2.date.getHours() ) {
			return true;
		}
		else if ( reminder1.date.getHours() > reminder2.date.getHours() ) {
			return false;
		}		
		else {
			if ( reminder1.date.getMinutes() < reminder2.date.getMinutes() ) {
				return true;
			}
			else if ( reminder1.date.getMinutes() > reminder2.date.getMinutes() ) {
				return false;
			}		
			else { 
				// same time
				return reminder1.originalIndex < reminder2.originalIndex;
			}
		}
	}	
	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}	
}

function reminderFox_compareColumnReminder1LessThanRepeat( reminder1, reminder2 ) {	
		// yearly/monthly/weekly/daily/none -->		
		if ( reminder1.recurrence.type  == reminder2.recurrence.type ) {
			return reminder1.originalIndex < reminder2.originalIndex;
		}
				
		if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_ONETIME ) {
			return false;
		}
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_ONETIME ) {
			return true;
		}
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) { 			
				return true;
		}
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_YEARLY ) { 			
				return false;
		}
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
			if (  reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY ) {
				return true;
			}
		}	
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_YEARLY_DAY ) {
			if (  reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY ) {
				return false;
			}
		}			
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
			if (  reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE) {
				return true;
			}
		}			
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DATE ) {
			if (  reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE) {
				return false;
			}
		}		
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
			if (  reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY) {
				return true;
			}
		}		
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_MONTHLY_DAY ) {
			if (  reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY) {
				return false;
			}
		}			
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {
			if (  reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_WEEKLY ) {
				return true;
			}
		}	
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_WEEKLY ) {
			if (  reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_WEEKLY ) {
				return false;
			}
		}						
		else if ( reminder1.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {
			if (  reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_WEEKLY &&
					reminder2.recurrence.type !=   REMINDER_RECURRENCE_DAILY   ) {
				return true;
			}
		}		
		else if ( reminder2.recurrence.type  == REMINDER_RECURRENCE_DAILY ) {
			if (  reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY_DAY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_YEARLY && 
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DATE &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_MONTHLY_DAY &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_WEEKLY &&
					reminder1.recurrence.type !=   REMINDER_RECURRENCE_DAILY   ) {
				return false;
			}
		}						
	
		return reminder1.originalIndex < reminder2.originalIndex;
}

function reminderFox_compareColumnReminder1LessThan( reminder1, reminder2, columnArray, sortDirArray, sortIndex  ) {
/*
    var newSortIndex = 0;
    if ( sortIndex < sortDirArray.length - 1) {
        newSortIndex = sortIndex + 1;
    }
    var column = columnArray[sortIndex];

	else {
		return reminder1.originalIndex < reminder2.originalIndex;
	}
*/

    sortIndex++;
    var newSortIndex = sortIndex;
    // if there are no more columns to sort on, we have reached the last leg and all sorts were equal.  Just 
    // compare based on their index in the reminder file
    if ( sortIndex >= sortDirArray.length - 1) {
        // dump: do we want to check sortDirArray here?
		return reminder1.originalIndex < reminder2.originalIndex;
    }

	// todos
	if ( column == "todoDateColLabel") {
		return reminderFox_compareColumnReminder1LessThanDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoEndDateColLabel") {
		return reminderFox_compareColumnReminder1LessThanReminderEndDate( reminder1, reminder2i, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoDescColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanSummary( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoDateCompleted" ) {
		return reminderFox_compareColumnReminder1LessThanCompletedDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoCompleteColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanCompletedDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoShowInTooltip" ) {
		return reminderFox_compareColumnReminder1LessThanShowInTooltip( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoTimeColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanTime( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoAlarmColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanAlarm( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoNotesColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanNotes( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todoMailColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanMail( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "todocatColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanCategory( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}	
	
	
	// reminders

	else if ( column == "descColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanSummary( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "dateColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "endDateColLabel") {
		return reminderFox_compareColumnReminder1LessThanReminderEndDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "timeColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanTime( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "dateCompleted" ) {
		return reminderFox_compareColumnReminder1LessThanReminderCompletedDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "repeatColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanRepeat( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "CompleteColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanReminderCompletedDate( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "remindUntilCompletedColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanRUC( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "notesColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanNotes( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "alarmColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanAlarm( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "mailColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanMail( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}
	else if ( column == "catColLabel" ) {
		return reminderFox_compareColumnReminder1LessThanCategory( reminder1, reminder2, columnArray, sortDirArray, newSortIndex );
	}	
	else {	
		return false;
	}
}

function reminderFox_sortPartition(array, begin, end, pivot, columnArray, sortDirArray)
{
	var piv=array[pivot];
	reminderFox_sortArraySwap(array, pivot, end-1);
	var store=begin;
	var ix;
	for(ix=begin; ix<end-1; ++ix) {
		var lessThan = reminderFox_compareColumnReminder1LessThan( array[ix], piv, columnArray, sortDirArray, -1 );
		if ( sortDirArray[0] ==REMINDER_FOX_SORT_DIRECTION_DESCENDING ) {
			lessThan = !lessThan;
		}
		
		if ( lessThan) {
			reminderFox_sortArraySwap( array, store, ix );
			++store;
		}
	}
	reminderFox_sortArraySwap( array, end-1, store);

	return store;
}



function reminderFox_qsort(array, begin, end, columnArray, sortDirArray)
{
	if(end-1>begin) {
		var pivot=begin+Math.floor(Math.random()*(end-begin));

		pivot=reminderFox_sortPartition(array, begin, end, pivot, columnArray, sortDirArray);

		reminderFox_qsort(array, begin, pivot, columnArray, sortDirArray);
		reminderFox_qsort(array, pivot+1, end, columnArray, sortDirArray);
	}
}
// quicksort
function reminderFox_quick_sort(array, column, sortDir)
{
	reminderFox_qsort(array, 0, array.length, column, sortDir );
}



function reminderFox_addReminderHeadlessly( newReminderToBeAdded, replaceEventIfAlreadyExists, isEdit) {  
	if ( isEdit == null ) {
		isEdit = false;
	}
	var newOptions = { reminder: newReminderToBeAdded, editing:  isEdit,  addEvent: false, listToBeAddedTo: "" };
	window.openDialog("chrome://reminderfox/content/editing/reminderEventDialog.xul",
			"reminderOptionsDialog", "chrome,resizable,modal", newOptions );

	if ( newOptions.addEvent ) {
		newReminderToBeAdded = newOptions.reminder;		
		
		var currentDate = new Date();
		if ( newReminderToBeAdded.alarm != null ) {
			newReminderToBeAdded.alarmLastAcknowledge = currentDate.getTime();
		}
		newReminderToBeAdded.lastModified = reminderFox_getDateAsString(currentDate );
		
		// add reminder in sorted order...
		// add to edit reminder dialog if it is open
	   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
	   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
	   var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxEdit");	 
	   if (topWindow) {
	   		if ( newOptions.listToBeAddedTo == REMINDER_FOX_DEFAULT_REMINDERS_CATEGORY ) { // add to reminders	   	
		   		var newDate = oeDatePicker.gSelectedDate;
				if ( newDate == null ) {
					newDate = new Date();
				}	
				var originalYear = newDate.getFullYear();
		   		// if adding a new reminder in a different year, first set the list/calendar to the new year
				// before adding the reminder
				if ( originalYear != newReminderToBeAdded.date.getFullYear() ) {
				   	topWindow.oeDatePicker.gSelectedDate = newReminderToBeAdded.date;
					topWindow.repopulateListForYear( originalYear, newReminderToBeAdded.date.getFullYear() );
				}
		   	
		   		topWindow.focus();
		   		
		   		// remove this event if it already exists, so it will be replaced 
		   		if ( replaceEventIfAlreadyExists ) {
					topWindow.removeListItemsForReminder(newReminderToBeAdded);  // remove from UI list
					
					var reminders = topWindow.reminderFox_getReminderEvents();	 // remove from model list
					for( var i = 0; i < reminders.length; i++) {
						if ( reminders[i].id == newReminderToBeAdded.id ) {
							topWindow.reminderFox_removeElement(reminders, i);
							break;
						}
					}
				}
		   			   		
		   		var reminders = topWindow.reminderFox_getReminderEvents();	
				var sortedIndex = topWindow.reminderFox_getSortedIndexOfNewReminder( reminders, newReminderToBeAdded, false );
				topWindow.reminderFox_insertIntoArray( reminders, newReminderToBeAdded, sortedIndex );
		   	
				topWindow.createListItem(newReminderToBeAdded);
				topWindow.oeDatePicker.onpopupshowing(newReminderToBeAdded.date);			
				topWindow.modifiedReminders();	
	  		 }
	  		 else {
	  		 	// add todo in sorted order...
	  		 	topWindow.focus();
	  		 	
				var reminderFoxTodosArrayArg =  	topWindow.reminderFox_getReminderTodos();
				var todos = reminderFoxTodosArrayArg[newOptions.listToBeAddedTo];  // listname == get list from list name...	
				if ( todos == null ) {
					todos = new Array();
					reminderFoxTodosArrayArg[newOptions.listToBeAddedTo] = todos;				
				}		
				if( replaceEventIfAlreadyExists ) {
					// remove from model list					
					for( var i = 0; i < todos.length; i++) {
						if ( todos[i].id == newReminderToBeAdded.id ) {
							reminderFox_removeElement(todos, i);
							break;
						}
					}
				}
								
				var sortedIndex = topWindow.reminderFox_getSortedIndexOfNewTodo(todos,  newReminderToBeAdded );		
				topWindow.reminderFox_insertIntoArray( todos, newReminderToBeAdded, sortedIndex );
				
				// UI
				topWindow.createTodoListItem(newReminderToBeAdded, true, new Date(), true);				
				topWindow.sortTodoIfNeccessary( newReminderToBeAdded.id);
				topWindow.modifiedReminders();		  		 	
	  		 }
		}		
		else {			
			if ( newOptions.listToBeAddedTo == REMINDER_FOX_DEFAULT_REMINDERS_CATEGORY ) { // add to reminders
				// remove this event if it already exists, so it will be replaced 
				var reminders = reminderFox_getReminderEvents();	
				if ( replaceEventIfAlreadyExists ) {
					// remove from model list					
					for( var i = 0; i < reminders.length; i++) {
						if ( reminders[i].id == newReminderToBeAdded.id ) {
							reminderFox_removeElement(reminders, i);
							break;
						}
					}
				}
				
				// add reminder headlessly
				var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminderToBeAdded, false );
				reminderFox_insertIntoArray( reminders, newReminderToBeAdded, sortedIndex );			
			}
			else {
				// add to todo list

				// add todo in sorted order...
				var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
				var todos = reminderFoxTodosArrayArg[newOptions.listToBeAddedTo];  // listname == get list from list name...
				if ( todos == null ) {
					todos = new Array();
					reminderFoxTodosArrayArg[newOptions.listToBeAddedTo] = todos;
				}		
				if( replaceEventIfAlreadyExists ) {
					// remove from model list					
					for( var i = 0; i < todos.length; i++) {
						if ( todos[i].id == newReminderToBeAdded.id ) {
							reminderFox_removeElement(todos, i);
							break;
						}
					}
				}
								
				var sortedIndex = reminderFox_getSortedIndexOfNewTodo(todos,  newReminderToBeAdded );
				reminderFox_insertIntoArray( todos, newReminderToBeAdded, sortedIndex );
			}							
		}
		reminderFox_processRecentReminders();
		reminderFox_writeOutRemindersAndTodos(false);
		reminderFox_syncWrittenChangesToRemote(	);
		try {
			// update all of the browsers
			var windowEnumerator =  reminderFox_getWindowEnumerator();
			while (windowEnumerator.hasMoreElements()) {
				var currentWindow = windowEnumerator.getNext();		
				currentWindow.reminderFoxEvents = reminderFoxEvents;
				currentWindow.reminderFoxTodosArray  = reminderFoxTodosArray;

				currentWindow.reminderFox_updateRemindersInWindow();			
				currentWindow.reminderFox_clearRemindersAndTodos();
			}
		}
		catch(e) {
		}				
		
	}
	return newOptions.addEvent;
}




function reminderFox_editEventHeadlessly( eventId, newReminderToBeAdded, isReminder ) {  
   var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
   var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
   var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxEdit");
 
   if (topWindow) {
    	 topWindow.focus();
    	if ( isReminder == true ) {	 
			topWindow.selectReminderById( eventId);
			topWindow.editReminder();
    	}
    	else { 
			var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
			for ( var n in reminderFoxTodosArrayArg ) {
				var reminderTodos = reminderFoxTodosArrayArg[n];
				for (  var i = 0; i < reminderTodos.length; i++ ) {		
					if ( reminderTodos[i].id == eventId ) {
						topWindow.selectTodoById(n, eventId	);
						topWindow.editTodo();
						break;
					}
				}
			}
		}    		
   }
   else {
	var newOptions = null;
	var added = false;
	var addedEvent = null;
	if ( isReminder ) {
		var activeReminders = reminderFox_getReminderEvents();
		for ( var i = 0; i < activeReminders.length; i++ ) {
			if (activeReminders[i].id == eventId) {
				newReminderToBeAdded = activeReminders[i];
				break;
			}
		}
		
		newOptions = { reminder: newReminderToBeAdded, editing:  true,  addReminder: false, showMail: false,  readonly: false };
		window.openDialog("chrome://reminderfox/content/editing/reminderOptionsDialog.xul",
			"window:reminderFoxReminderOptionsDialog", "chrome,resizable,modal", newOptions);
		if ( newOptions.addReminder ) { 
			added = true;
			newReminderToBeAdded = newOptions.reminder;		
		}
	}
	else {
		var listToBeAddedTo = null;
		if ( newReminderToBeAdded == null ) {
			var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
			for ( var n in reminderFoxTodosArrayArg ) {
				var reminderTodos = reminderFoxTodosArrayArg[n];
				for (  var i = 0; i < reminderTodos.length; i++ ) {		
					if ( reminderTodos[i].id == eventId ) {
						newReminderToBeAdded = reminderTodos[i];
						listToBeAddedTo = n;
						break;
					}
				}
			}
		}
		
		
		newOptions = { todo: newReminderToBeAdded, editing:  true,  addTodo: false, showMail: false };
		window.openDialog("chrome://reminderfox/content/editing/todoOptionsDialog.xul",
				"todoOptionsDialog", "chrome,resizable,modal", newOptions );
		if ( newOptions.addTodo ) { 
			added = true;
			newReminderToBeAdded = newOptions.todo;		
		}
	}	

	if ( added ) {
		var currentDate = new Date();
		if ( newReminderToBeAdded.alarm != null ) {
			newReminderToBeAdded.alarmLastAcknowledge = currentDate.getTime();
		}
		newReminderToBeAdded.lastModified = reminderFox_getDateAsString(currentDate );
		
			if ( isReminder ) { // add to reminders
				// remove this event if it already exists, so it will be replaced 
				var reminders = reminderFox_getReminderEvents();	
					// remove from model list					
					for( var i = 0; i < reminders.length; i++) {
						if ( reminders[i].id == newReminderToBeAdded.id ) {
							reminderFox_removeElement(reminders, i);
							break;
						}
					}
				
				// add reminder headlessly
				var sortedIndex = reminderFox_getSortedIndexOfNewReminder( reminders, newReminderToBeAdded, false );
				reminderFox_insertIntoArray( reminders, newReminderToBeAdded, sortedIndex );			
			}
			else {
				// add to todo list

				// add todo in sorted order...
				var reminderFoxTodosArrayArg =  reminderFox_getReminderTodos();
				
				// get the list this belongs to
				if ( listToBeAddedTo == null ) { 
					for ( var n in reminderFoxTodosArrayArg ) {
						var reminderTodos = reminderFoxTodosArrayArg[n];
						for (  var i = 0; i < reminderTodos.length; i++ ) {		
							if ( reminderTodos[i].id == eventId ) {
								listToBeAddedTo = n;
								break;
							}
						}
					}
				}
				var todos = reminderFoxTodosArrayArg[listToBeAddedTo];  
				if ( todos == null ) {
					todos = new Array();
					reminderFoxTodosArrayArg[listToBeAddedTo] = todos;
				}		
				
					// remove from model list					
					for( var i = 0; i < todos.length; i++) {
						if ( todos[i].id == newReminderToBeAdded.id ) {
							reminderFox_removeElement(todos, i);
							break;
						}
					}
								
				var sortedIndex = reminderFox_getSortedIndexOfNewTodo(todos,  newReminderToBeAdded );
				reminderFox_insertIntoArray( todos, newReminderToBeAdded, sortedIndex );
			}			
			
			reminderFox_processRecentReminders();
			reminderFox_writeOutRemindersAndTodos(false);
			reminderFox_syncWrittenChangesToRemote(	);
			try {
				// update all of the browsers
				var windowEnumerator =  reminderFox_getWindowEnumerator();
				while (windowEnumerator.hasMoreElements()) {
					var currentWindow = windowEnumerator.getNext();		
					currentWindow.reminderFoxEvents = reminderFoxEvents;
					currentWindow.reminderFoxTodosArray  = reminderFoxTodosArray;
	
					currentWindow.reminderFox_updateRemindersInWindow();			
					currentWindow.reminderFox_clearRemindersAndTodos();
				}
			}
			catch(e) {
			}			
		}
	}
	
	return newReminderToBeAdded;
}



function reminderFox_firstStart() {
	//  If this is the very first ReminderFox start (no existing 'reminder.ics' file available),
    //  we construct a 'Welcome ReminderFox' reminder.
    var rmStoreFile =   reminderFox_getReminderStoreFile();
    if ( rmStoreFile == null || !rmStoreFile.exists() ) {
    	var todaysDate = new Date();
		var reminderId =reminderFox_generateUniqueReminderId( todaysDate );
    	var newReminderToBeAdded = new ReminderFoxEvent( reminderId, todaysDate, reminderFox_getBundle().getString("rf.welcome.header") );  
    	newReminderToBeAdded.notes =  reminderFox_getBundle().getString("rf.welcome.notes");
    	newReminderToBeAdded.url =  reminderFox_getBundle().getString("rf.faqURL");
    	
    	var reminders = reminderFox_getReminderEvents();	
		reminderFox_insertIntoArray( reminders, newReminderToBeAdded, 0 );
		reminderFox_writeOutRemindersAndTodos(false);
	}
}


function reminderFox_mail_getTimeString( date ) {
	var timeString = null;
	try {
		var hours = date.getHours();
		var AMorPM;
			
		var use24HourTime;
		try {
			use24HourTime = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_USE_24_HOUR_TIME);
		} catch(e) {
		}				
		if (  use24HourTime ) {
			AMorPM = "";
			if ( hours < 10 ) {
				hours = "0" + hours;
			}
		}
		else {
			AMorPM  =reminderFox_getBundle().getString("rf.add.time.PM");
			if ( AMorPM != "" ) {
				if ( hours < 12 ) {
					AMorPM = reminderFox_getBundle().getString("rf.add.time.AM");
				}
				if ( hours == 0 ) {
					hours = 12;
				}
				if ( hours >= 13 ) {
					hours = hours -12;
				}	
			}	
		}
		var minutes = date.getMinutes();
		if ( minutes < 10 ) {
			minutes = "0" + minutes;
		}
						
		timeString = hours + reminderFox_getBundle().getString("rf.add.time.delimiter") + minutes;
		if ( AMorPM != "" ) {
			timeString = timeString + " " + AMorPM;		
		}
	}
	catch ( e ) { 
	}
	
	return timeString;
}

function reminderFox_convertReminderToTodo(currentReminder) {
	var newTodo = new ReminderFoxTodo( currentReminder.id, currentReminder.summary, currentReminder.date);			
	newTodo.notes = currentReminder.notes;
	newTodo.priority = currentReminder.priority;
	newTodo.messageID = currentReminder.messageID;
	newTodo.completedDate = currentReminder.completedDate;
	newTodo.endDate = currentReminder.endDate;
	newTodo.durationTime = currentReminder.durationTime;
	newTodo.allDayEvent = currentReminder.allDayEvent;	
	newTodo.alarm = currentReminder.alarm;		
	newTodo.alarmLastAcknowledge = currentReminder.alarmLastAcknowledge;		
	newTodo.snoozeTime = currentReminder.snoozeTime;
	newTodo.recurrence = currentReminder.recurrence;  
	newTodo.extraInfo = currentReminder.extraInfo;
	newTodo.categories = currentReminder.categories;
	newTodo.location = currentReminder.location;
	newTodo.url = currentReminder.url;
	return newTodo;
}

function reminderFox_convertTodoToReminder(currentTodo) {
	var newReminder = new ReminderFoxEvent( currentTodo.id, currentTodo.date, currentTodo.summary );			
	newReminder.notes = currentTodo.notes;
	newReminder.priority = currentTodo.priority;
	newReminder.messageID = currentTodo.messageID;
	newReminder.completedDate = currentTodo.completedDate;
	newReminder.endDate = currentTodo.endDate;
	newReminder.durationTime = currentTodo.durationTime;
	newReminder.allDayEvent = currentTodo.allDayEvent;	
	newReminder.alarm = currentTodo.alarm;		
	newReminder.alarmLastAcknowledge = currentTodo.alarmLastAcknowledge;		
	newReminder.snoozeTime = currentTodo.snoozeTime;
	newReminder.recurrence =	currentTodo.recurrence;  
	newReminder.extraInfo = currentTodo.extraInfo;
	newReminder.categories = currentTodo.categories;
	newReminder.location = currentTodo.location;
	newReminder.url = currentTodo.url;
	return newReminder;
}


//function reminderFox_getAllReminderEvents() {
//	var allReminders= new Array();
//	var reminderFoxEventsArrayArg = reminderFox_getReminderEvents();  // iterate over all reminders
//  	for ( var n in reminderFoxEventsArrayArg ) {
//		var reminderFoxEvents = reminderFoxEventsArrayArg[n];
//	  	for (var i = 0; i < reminderFoxEvents.length; i++ ) {
//	  		allReminders[allReminders.length] = reminderFoxEvents[i];			
//	  	}
//  	} 
//  	return allReminders; 
//}

function reminderFox_getAllReminderTodos() {
	var allTodos = new Array();
	var reminderFoxTodosArrayArg = reminderFox_getReminderTodos();  // iterate over all reminders
  	for ( var n in reminderFoxTodosArrayArg ) {
		var reminderFoxTodos = reminderFoxTodosArrayArg[n];
	  	for ( var i = 0; i < reminderFoxTodos.length; i++ ) {
	  		allTodos[allTodos.length] = reminderFoxTodos[i];			
	  	}
  	} 
  	return allTodos;
}

function reminderFox_getValidCustomTodoLists() {
	var todoListsRet = new Array();
	var todoLists = reminderFox_getPreferenceValue( REMINDER_FOX_TODO_LISTS );
 	if ( todoLists != null && todoLists.length > 0) { 	
 		var subscriptions = reminderFox_getSubscriptions();		
 		var todoListsArray = todoLists.split(",");
		for ( var i = 0; i < todoListsArray.length; i++ )  { 		
			var listItem = 	todoListsArray[i];
			if ( subscriptions[listItem] == null ) {
				todoListsRet[todoListsRet.length] = listItem;
			}
		}
 	}
 	return todoListsRet;
}


function reminderFox_getAllCustomTodoLists() {
	var todoListsRet = new Array();
	var todoLists = reminderFox_getPreferenceValue( REMINDER_FOX_TODO_LISTS );
 	if ( todoLists != null && todoLists.length > 0) { 	 		
 		var todoListsArray = todoLists.split(",");
		for ( var i = 0; i < todoListsArray.length; i++ )  { 		
			var listItem = 	todoListsArray[i];			
			todoListsRet[todoListsRet.length] =listItem;			
		}
 	}
 	return todoListsRet;
}

function reminderFox_getSubscriptions() {
	
	var subscriptionsArray = {};
	var todoLists = reminderFox_getPreferenceValue( REMINDER_FOX_SUBSCRIPTIONS );
 	if ( todoLists != null && todoLists.length > 0) { 	
 		var todoListsArray = todoLists.split(",");
		for ( var i = 0; i < todoListsArray.length; i++ )  { 		
			var listItem = 	todoListsArray[i];
			var subscription = listItem.indexOf( "=");
			var listName = listItem.substring( 0, subscription );
			var subscriptionURL = listItem.substring( subscription + 1);			
			subscriptionsArray[listName] = subscriptionURL;
		}
 	}
 	return subscriptionsArray;
}

function reminderFox_writeSubscriptions( subscriptions ) {
	var subscriptionsStr = "";
	for ( var listName in subscriptions ) {
		var subUrl = subscriptions[listName];
		if ( subUrl != null && subUrl.length > 0 ) {
			if ( subscriptionsStr.length > 0 ) {
				subscriptionsStr = subscriptionsStr + "," + listName + "=" + subUrl;
			}
			else {
				subscriptionsStr = listName + "=" + subUrl;
			}
		}
	}
	reminderFox_setUnicodePref( REMINDER_FOX_SUBSCRIPTIONS, subscriptionsStr);		
	
}

function reminderFox_findParentById( node, name1, name2 ) {
	var parentNode = node;
    while ( parentNode != null ) {
    	if ( parentNode.id == name1 || parentNode.id == name2 ) {
    		return parentNode;
    	}
    	
    	parentNode = parentNode.parentNode;
    }
    return parentNode;
}

function reminderFox_adjustDateForTimeZones( eventDateString, fullDateString, reminderDate ) {
	// if event is stored in UTC time (20051208T224616Z), then take into account UTC offset for the 
	// current time
	if ( eventDateString.length > 15 && eventDateString.charAt(15) == "Z" ) {  		
		var tzOffset = new Date().getTimezoneOffset(); 
		reminderDate.setMinutes( reminderDate.getMinutes() - tzOffset );						
	}
	else {
		// if date contains a Timezone in its specification, handle it if we know the timezone id.
		// DTSTART;TZID=US/Pacific:20071007T100000
		// logic: get target timezone: Pacific  (-8)
		// 			get my current timezone offset:  myOffset (-5)
		// 			tzOffset = myOffset -targetTimezoneOffset (-5 - -8 = +3)
		var timezoneIndex = fullDateString.indexOf( ";TZID=" );
		if ( timezoneIndex != -1 ) {
			var endIndex = fullDateString.indexOf(':', timezoneIndex );
			var timezone = fullDateString.substring( timezoneIndex + ";TZID=".length, endIndex );
			timezone = reminderFox_trim( timezone.toUpperCase() );
			var offset = reminderFox_timezones[timezone];
			if ( offset == null ) {
				// in minutes
				if ( timezone == "US/EASTERN" ) {
					offset = 5;
				}
				else if ( timezone == "US/CENTRAL" ) {
					offset = 6;
				}
				else if ( timezone == "US/MOUNTAIN" ) {
					offset = 7;
				}
				else if ( timezone == "US/PACIFIC" ) {
					offset = 8;
				}
				else if ( timezone == "US/ALASKA" ) {
					offset = 9;
				}
				else if ( timezone == "US/HAWAII" ) {
					offset = 11;
				}
				else {
					// if we don't know what this timezone is, do nothing
					offset = 0;
					reminderFox_timezones[timezone] = offset;
					return;
				}
				
				/*
				 * Beginning in 2007, most of the United States begins Daylight Saving Time at 2:00 a.m. on the second Sunday in March and reverts to standard time on the first Sunday in November. 
				 */
				 var startDSTDate = new Date(2007, 2, 11 );
				 var endDSTDate = new Date( 2007, 10, 4 );
				 
				 var startDSTDay = startDSTDate.getDay();
				 var weekNumber = reminderFox_getWeekNumber( startDSTDate );
				
				var thisMonthsDate = new Date();
				thisMonthsDate.setDate(1); // set to start of the month
				thisMonthsDate.setMonth(2);
				//var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( startDSTDate, startDSTDay, weekNumber );
				var reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( thisMonthsDate, startDSTDay, weekNumber ); 
				var startDate = new Date( thisMonthsDate.getFullYear(), startDSTDate.getMonth(), reminderWeekDateThisMonth );
				
				thisMonthsDate.setMonth(10);
				var endDSTDay = endDSTDate.getDay();
				 weekNumber = reminderFox_getWeekNumber( endDSTDate );
				reminderWeekDateThisMonth = reminderFox_getDateForSpecifiedWeekNumber( thisMonthsDate, endDSTDay, weekNumber );
				var endDate = new Date( thisMonthsDate.getFullYear(), endDSTDate.getMonth(), reminderWeekDateThisMonth );
				
				var todaysDate = new Date();
				if (  reminderFox_compareDates( todaysDate, startDate ) >= 0 &&
				 reminderFox_compareDates( todaysDate, endDate ) == -1) {
					// we are in DST; subtract one hour 
					offset--;
				}
				
				offset = offset*60;  // convert to minutes
				reminderFox_timezones[timezone] = offset;
			}
			if ( offset == 0 ) {
				return;
			}
			var tzOffset = new Date().getTimezoneOffset(); 
			var diff = tzOffset - offset;
			reminderDate.setMinutes( reminderDate.getMinutes() - diff );		
		}			
	}
}


/////////////////////////// Core Utilities /////////////////////////////////////

function rmFxCore (){
}
// gW 2008-10-28  ... currently used with 'Options'  and 'View'

	rmFxCore.add2Textbox = function (xThis, addID, separator) {
	/** ----------------------------------------------------------------------**/
	// gW 2008-10-28  ... currently used with 'Options'  and 'View'
	
		var element=	xThis.childNodes[xThis._lastSelectedRow]
				.childNodes[0].childNodes[0].attributes[0].value;
				
		var currentText =	document.getElementById(addID);				
		var part1 = currentText.value.substring(0,currentText.selectionStart);	
		var part2 = currentText.value.substring(currentText.selectionEnd, currentText.textLength);
		document.getElementById(addID).value = part1 +  separator +  element + " " + part2;			
	}

	rmFxCore.InfoButton = function (xThis)  {
	/** ----------------------------------------------------------------------**/			
		var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
                     .getService(Components.interfaces.nsIPromptService);
		prompts.alert(null, "ReminderFox Info", 
				(g_reminderFoxBundle.getString(xThis.attributes[0].textContent)));
	}
	
	rmFxCore.copytoClipboard = function (data)  {
	/** ----------------------------------------------------------------------**/
	// Generic function to copy the data to Clipboard 
	var clipboard = Components.classes["@mozilla.org/widget/clipboardhelper;1"];
	clipboard = clipboard.getService(Components.interfaces.nsIClipboardHelper);
	clipboard.copyString(data );
}	

	rmFxCore.setStatus = function (text)  {
	/** ----------------------------------------------------------------------**/
	// Generic function to set 'RmFx Status' ... tribute to g.Tom ;-)

		if (text != "" ){
			var rmFx_consoleService = Components.classes["@mozilla.org/consoleservice;1"]
					.getService(Components.interfaces.nsIConsoleService);
		
			rmFx_consoleService.logStringMessage("reminderFox: " + text);
		}
		try { // if coming from FX to TB will not find element,
				//   the 'rmFx_consoleService' signals the user 
				//   the 'mail' app was used by REMOTE (eg.FX)
				
			var statusTxt = document.getElementById("reminderFox-network-status");			
			statusTxt.setAttribute("value", text);
			if (text != "" ){   
				setTimeout(rmFxCore.resetStatus,10000);
			}
		} catch (ex){}
}

	rmFxCore.resetStatus = function ()  {
	/** ----------------------------------------------------------------------**/
	// Generic function to reset 'RmFx Status' 
			var statusTxt = document.getElementById("reminderFox-network-status");			
			statusTxt.setAttribute("value","");   
}

	
	rmFxCore.ConfirmEx = function (title, msg, key0, key1, key2) 
	/** ===================================================================== **/
	/**           [key0] [key1]
	 *       or   [key0] [key2] [key1]
	 */
	{	var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
			.getService(Components.interfaces.nsIPromptService);
	
		var flags =
			promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
			promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1; 		// flags = [integer] 32639

		if (!!key2) {
		var flags =
			promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
			promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
			promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;		// flags = [integer] 8355711
		} 
		return  promptService.confirmEx(window,
				title, msg,	flags, key0, key1, key2, null, {});		  
	}

	rmFxCore.PromptAlert = function (msgErr)
	/** ===================================================================== **/	
	{	var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
			.getService(Components.interfaces.nsIPromptService);
		promptService.alert(window, "ReminderFox Error", msgErr);
		
		rmFxCore.dump2Console (msgErr)
	}

	rmFxCore.dump2Console = function (logString)
	/** ===================================================================== **/	
	{	var rmFx_consoleService = Components.classes["@mozilla.org/consoleservice;1"]
			.getService(Components.interfaces.nsIConsoleService);

	      rmFx_consoleService.logStringMessage("reminderFox: " + logString);
      	dump( "reminderFox: " + logString + "\n"  );
	}	 
 
