Dev.Opera - Follow the standards, break the rulesDev.Opera - Follow the standards, break the rules

Login

Lost password?

Sign up

users

Sign up now to post in the forums, comment on articles, submit your own articles and more.


calendarEvents.js

Summary

No overview generated for 'calendarEvents.js'


Class Summary
CalendarEvent  
CalendarEvents  

/* 
 * Copyright (c) 2006, Opera Software ASA 
 * All rights reserved. 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met: 
 * 
 *     * Redistributions of source code must retain the above copyright 
 *       notice, this list of conditions and the following disclaimer. 
 *     * Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in the 
 *       documentation and/or other materials provided with the distribution. 
 *     * Neither the name of Opera Software ASA nor the 
 *       names of its contributors may be used to endorse or promote products 
 *       derived from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY OPERA SOFTWARE ASA AND CONTRIBUTORS ``AS IS'' AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL OPERA SOFTWARE ASA AND CONTRIBUTORS BE LIABLE FOR ANY 
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */ 
 
/** 
 *	Class for calendarEvents 
 * 
 *	This class handles calendar events that can have several occurences 
 *	calendarEvent are stored in a public list. 
 * 
 *	@constructor 
 *	@author Mathieu HENRI, Opera Software ASA 
 *	@version	1.0.1 
*/ 
function CalendarEvents() 
{ 
	calendarEventsSelf	= this; 
 
 
	/** dictionnary with the Id of the calendarEvent **/ 
	this.calendarEventIdList			= {}; 
	/** array of the calendarEvent **/ 
	this.calendarEventArray				= []; 
 
 
	/********* Interface methods ***********/ 
 
 
	/** 
	 *	convert the array of calendarEvent into a JSON string 
	 *	@return a JSONString 
	 */ 
	this.toString = function() 
	{ 
		var	eventsList = [] 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			eventsList.push( 
			{ 
				id						:e.id, 
				start					:e.start.valueOf(), 
				end						:e.end.valueOf(), 
				description				:e.description, 
				type					:e.type, 
				url						:e.url, 
				reminderCount			:e.reminderCount, 
				reminderInterval		:e.reminderInterval, 
				remindersMaxLate		:e.remindersMaxLate, 
				occurenceCount			:e.occurenceCount, 
				occurenceInterval		:e.occurenceInterval, 
				occurenceIntervalUnit	:e.occurenceIntervalUnit 
			}) 
 
 
		return eventsList.toJSONString() 
	} 
 
 
	/** 
	 *	parse a JSON string to populate the array of calendarEvent instance 
	 *	@return	a boolean indicating the success of the method 
	 */ 
	this.parse = function( str ) 
	{ 
		// wipe all the events first 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			this.deleteEvent( e.id ); 
 
		var eventsList = str.parseJSON() 
		for( var i=0,e; e=eventsList[i]; i++ ) 
			if( !this.setEvent( 
				e.id, 
				new Date( e.start ), 
				new Date( e.end ), 
				e.description, 
				e.type, 
				e.url, 
				e.reminderCount, 
				e.reminderInterval, 
				e.remindersMaxLate, 
				e.occurenceCount, 
				e.occurenceInterval, 
				e.occurenceIntervalUnit ) 
			) 
				return false; 
 
		return true 
	} 
 
 
	/** 
	 *	set the ReminderCallback function 
	 *	see the reminderFallback method for the list of arguments 
	 *	the ReminderCallback function should accept 
	 *	@param	fct	reminder function 
	 *	@return	a boolean indicating the success of the method 
	 */ 
	this.setReminderCallback	= function( fct ) 
	{ 
		if( typeof(fct)!='function'return false 
 
		this.reminderCallback = fct; 
		return true; 
	} 
 
 
	/** 
	 *	reset the ReminderCallback function 
	 */ 
	this.resetReminderCallback	= function() 
	{ 
		delete this.reminderCallback; 
	} 
 
 
	/** 
	 *	call the reminderCallback function for one occurence of a calendarEvent 
	 *	@param	escapedId	escapedId of the calendarEvent 
	 *	@param	occurence 
	 *	@param	reminderIndex	the index of the reminder in the range [ -reminderCount ; remindersMaxLate ] 
	 */ 
	this.callReminder = function( escapedId, occurence, reminderIndex ) 
	{ 
		var	e	= this.getEvent( unescape( escapedId ) ) 
		if( !e ) 
			return false; 
 
		if( e.nextOccurenceStart<=new Date() ) 
			e.nextOccurence( true ); 
 
		return (this.reminderCallback?this.reminderCallback:this.reminderFallback)( e, occurence, reminderIndex ); 
	} 
 
	/** 
	 *	the reminder fallback method 
	 *	@param	evt  a calendarEvent 
	 *	@param	occurence  the occurence related to this reminder 
	 *	@param	reminderIndex  the index of the reminder in the range [ -reminderCount ; remindersMaxLate ] 
	 */ 
	this.reminderFallback	= function( evt, occurence, reminderIndex ) 
	{ 
		if( !confirm( '____calendarEvents.reminderFallback____\n\nREMINDER #'+ reminderIndex +' for the occurence #'+ occurence +' of\n\n'+ evt.id +'\n\ndo you want to keep the reminders for this occurence ?' ) ) 
			calendarEventsSelf.stopEventReminder( evt.id, occurence ); 
 
		return true; 
	} 
 
 
	/** 
	 *	stops the reminder for one occurence of a calendarEvent 
	 *	@param	id	id of the calendarEvent 
	 *	@param	occurence	the index of the occurence of the calendarEvent to stop the reminders of 
	 *	@return	a boolean indicating if reminder have been stopped correctly 
	 */ 
	this.stopEventReminder = function( id, occurence ) 
	{ 
		var	e	= this.getEvent( id ) 
		if( !e ) 
			return false; 
 
		return e.clearReminderTimeout( occurence ); 
	} 
 
 
	/** 
	 *	dismiss the next occurence of a calendarEvent and move on 
	 *	to the following occurence 
	 *	@param	id	id of the calendarEvent 
	 *	@return	a 
	 */ 
	this.dismissEvent = function( id ) 
	{ 
		var	e = this.getEvent( id ); 
 
		if( !e ) 
			return false; 
 
		e.dismiss(); 
		this.sortEvents(); 
 
		return true; 
	} 
 
 
	/** 
	 *	get all the instances of calendarEvent 
	 *	@return an array with all the instances of calendarEvent 
	 */ 
	this.getAllEvents = function() 
	{ 
		return this.calendarEventArray; 
	} 
 
 
	/** 
	 *	get a calendarEvent 
	 *	@param	id	id of the desired calendarEvent 
	 *	@return	the calendarevent or null if it does not exist 
	 */ 
	this.getEvent = function( id ) 
	{ 
		if( !this.calendarEventIdList[ id ] ) 
			return null; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			if( e.id==id ) 
				return e; 
	} 
 
 
	/** 
	 *	get all the instances of calendarEvent of a given type 
	 *	@param	type	the desired type of calendarEvent 
	 *	@return	an array of calendarEvent 
	 */ 
	this.getEventsByType = function( type ) 
	{ 
		var	events = []; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			if( e.type==type ) 
				events.push( e ); 
 
		return events; 
	} 
 
 
	/** 
	 *	get the index of a calendarEvent in the array of calendarEvent 
	 *	@param	id	id of the desired calendarEvent 
	 *	@return	the index of the desried calendarevent in the array or -1 if it does not exist 
	 */ 
	this.getEventIndex = function( id ) 
	{ 
		if( !this.calendarEventIdList[ id ] ) 
			return -1; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			if( e.id==id ) 
				return i; 
	} 
 
 
	/** 
	 *	delete a calendarEvent 
	 *	@param	id	id of the desired calendarEvent 
	 *	@return	a boolean indicating the success of the method 
	 */ 
	this.deleteEvent = function( id ) 
	{ 
		if( !this.calendarEventIdList[ id ] ) 
			return false; 
 
		var	eventIndex = this.getEventIndex( id ); 
 
		this.calendarEventArray[ eventIndex ].clearAllReminderTimeout(); 
 
		delete this.calendarEventIdList[ id ]; 
		delete this.calendarEventArray[ eventIndex ]; 
		this.sortEvents() 
		return true; 
	} 
 
 
	/** 
	 *	sort the array of calendarEvent by increasing date of next occurence 
	 */ 
	this.sortEvents = function() 
	{ 
		this.calendarEventArray.sort( function( a,b ) 
		{ 
			return a.nextOccurenceStart-b.nextOccurenceStart; 
		} ) 
	} 
 
 
	/** 
	 *	create a calendarEvent 
	 *	@param	id	id of the desired calendarEvent 
	 *	@param	start	the start date of the first occurence 
	 *	@param	end		the end date of the first occurence, or null if the calendarEvent has no duration 
	 *	@param	description		the description of the calendarEvent 
	 *	@param	type		the type of the calendarEvent 
	 *	@param	url		a URL related to the calendarEvent 
	 *	@param	reminderCount	the number of reminder before the calendarEvent 
	 *	@param	reminderInterval	the interval between the reminders (in ms) 
	 *	@param	remindersMaxLate	the number of reminder after the beginning of the calendarEvent 
	 *	@param	occurenceCount		the number of occurence or null if there is only occurence 
	 *	@param	occurenceInterval	the amount of occurenceIntervalUnit between the occurences of the calendarEvent 
	 *	@param	occurenceIntervalUnit	the time unit of occurenceInterval ( see the isValidUnit method ) 
	 *	@see 	#isValidUnit 
	 *	@return	the calendarEvent or null if its creation failled 
	 */ 
	this.setEvent = function( id, start, end, description, type, url, reminderCount, reminderInterval, remindersMaxLate, occurenceCount, occurenceInterval, occurenceIntervalUnit ) 
	{ 
		if( this.calendarEventIdList[ id ] ) 
			return null; 
 
		var	occurenceCount			= occurenceCount||1, 
			occurenceInterval		= occurenceInterval||0, 
			occurenceIntervalUnit	= occurenceIntervalUnit||'milliseconds' 
 
		if( occurenceInterval<0 )	//	events do not occurs back in time ... do they ? 
			return null; 
 
		if( !isValidUnit( occurenceIntervalUnit ) ) 
			return null; 
 
		var	now = new Date(); 
 
		this.calendarEventIdList[ id ] = true; 
		this.calendarEventArray.push( new CalendarEvent( id, start, end, description, type, url, reminderCount, reminderInterval, remindersMaxLate, occurenceCount, occurenceInterval, occurenceIntervalUnit ) ); 
		this.sortEvents(); 
 
		return this.getEvent( id ); 
	} 
 
 
	/** 
	 *	increments a date by a given quantiy of time units 
	 *	@param	date	the base date 
	 *	@param	quantity	the quantiy of time units 
	 *	@param	unit	the unit of time to add	( see the isValidUnit method ) 
	 *	@see 	#isValidUnit 
	 *	@return	return the incremented date or quantity if quantity is +/-Infinity 
	 */ 
	this.incrementDate = function( date, quantity, unit ) 
	{ 
		var unit = (unit||'milliseconds').toLowerCase(); 
 
 
		if( Math.abs(quantity)==Infinity ) 
			return quantity; 
 
		if( unit=='milliseconds'return new Date( date.valueOf()+quantity ); 
 
		if( unit=='seconds'return new Date( date.valueOf()+quantity*1000 ); 
		if( unit=='minutes'return new Date( date.valueOf()+quantity*1000*60 ); 
		if( unit=='hours'return new Date( date.valueOf()+quantity*1000*60*60 ); 
		if( unit=='days'return new Date( date.valueOf()+quantity*1000*60*60*24 ); 
		if( unit=='weeks'return new Date( date.valueOf()+quantity*1000*60*60*24*7 ); 
 
		var	retDate = new Date( date ); 
 
		if( unit=='years' ) 
			quantity *= 12; 
 
		retDate.setMonth( retDate.getMonth()+quantity ) 
 
		return retDate; 
	} 
 
 
	/** 
	 *	get the calendarEvent between two dates 
	 *	@param	rangeBegin	the lower limit date 
	 *	@param	rangeEnd	the upper limit date 
	 *	@return	an array with all the calendarEvent that might occur between the two dates 
	 */ 
	this.getEventsInPeriod = function( rangeBegin, rangeEnd ) 
	{ 
		var	eventsInPeriodArray = [], 
			rangeBegin	= rangeBegin.valueOf(), 
			rangeEnd	= rangeEnd.valueOf(); 
 
		if( rangeBegin>rangeEnd )	//	invalid date range 
			return eventsInPeriodArray; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			if( e.getOccurencesStartingBefore( rangeEnd ).length > e.getOccurencesEndingBefore( rangeBegin ).length ) 
				eventsInPeriodArray.push( e ); 
 
		return eventsInPeriodArray; 
	} 
 
 
	/** 
	 *	get the number of ms from a given date to the closest calendarEvent 
	 *	@param	dateStart	the reference date 
	 *	@param	inFuture	a boolean ( true by default ) indicating if the interval must be looked in the future or in the past 
	 *	@return the number of ms from a given date to the closest calendarEvent 
	 */ 
	this.getFreeRange = function( dateStart, inFuture ) 
	{ 
		var	inFuture					= inFuture==undefined?true:(inFuture?true:false), 
			timestampClosestOccurence	= inFuture?Infinity:-Infinity, 
			dateStart					= dateStart.valueOf() 
 
		//	no calendarEvent in the array -> +/-Infinity 
		if( !this.calendarEventArray.length ) 
			return timestampClosestOccurence; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
		{ 
			var previousOccurences		= inFuture?e.getOccurencesEndingBefore( dateStart ):e.getOccurencesStartingBefore( dateStart ), 
				usefulOccurenceDates	= { start:e.start,	end:e.end } 
 
			if( previousOccurences.length ) 
			{ 
				usefulOccurenceDates = inFuture?e.getOccurenceDates( previousOccurences.length+1 ):previousOccurences.pop(); 
				if( !usefulOccurenceDates ) 
					continue; 
			} 
 
			//	right during the occurence of a calendarEvent -> 0 
			if( usefulOccurenceDates.start<=dateStart && usefulOccurenceDates.end>=dateStart ) 
				return 0; 
 
			if( inFuture && usefulOccurenceDates.start>dateStart ) 
				timestampClosestOccurence = Math.min( timestampClosestOccurence, usefulOccurenceDates.start ); 
			else if( !inFuture && usefulOccurenceDates.end<dateStart ) 
				timestampClosestOccurence = Math.max( timestampClosestOccurence, usefulOccurenceDates.end ); 
		} 
 
		return timestampClosestOccurence-dateStart; 
	} 
 
 
	/** 
	 *	shift a calendarEvent by a given quantiy of time units 
	 *	@param	id	id of the calendarEvent 
	 *	@param	time	the quantiy of time units 
	 *	@param	timeUnit	the unit of time to add	( see the isValidUnit method ) 
	 *	@see 	#isValidUnit 
	 *	@return	a boolean indicating the success of the method 
	 */ 
	this.shiftEvent = function( id, time, timeUnit, overlap ) 
	{ 
		var	e			= this.getEvent( id ); 
			overlap		= overlap==undefined?true:(overlap?true:false) 
 
		if( !e || !isValidUnit( timeUnit ) || typeof( time )!='number'return false; 
 
		var	candidateStart	= this.incrementDate( e.nextOccurenceStart,	time, timeUnit ); 
			candidateEnd	= this.incrementDate( e.nextOccurenceEnd,	time, timeUnit ); 
 
		if( !overlap ) 
		{ 
			var	eventsInCandidatePeriod = this.getEventsInPeriod( candidateStart, candidateEnd ); 
			if( eventsInCandidatePeriod.length>1 || (eventsInCandidatePeriod.length==1 && eventsInCandidatePeriod[0].id!=id) ) 
				return false; 
		} 
 
		this.getEvent( id ).shiftDates( time, timeUnit ); 
		this.sortEvents(); 
 
		return true; 
	} 
 
 
	/** 
	 *	get the closest date to a given date when a desired amount ms of  will not overlap some calendarEvent 
	 *	@param	dateStart	the reference date 
	 *	@param	desiredLength	the amount of ms desired 
	 *	@param	inFuture	a boolean ( true by default ) indicating if the date must be looked in the future or in the past 
	 *	@return the closest date the desired amount of ms is available or null 
	 */ 
	this.findFreeRange = function( dateStart, desiredLength, inFuture ) 
	{ 
		var	inFuture					= inFuture==undefined?true:(inFuture?true:false), 
			timestampClosestOccurence	= inFuture?Infinity:-Infinity, 
			timestampStart				= dateStart.valueOf() 
 
 
		if( !this.calendarEventArray.length ) 
			return timestampStart; 
 
		//	check if the intervals could allow desiredLength 
		var	maxInterval = 0, 
			maixmizedIntervalPerUnit = { 
				'milliseconds':	1, 
				'seconds':		1000, 
				'minutes':		1000*60, 
				'hours':		1000*60*60, 
				'days':			1000*60*60*24, 
				'weeks':		1000*60*60*24*7, 
				'months':		1000*60*60*24*31, 
				'years':		1000*60*60*24*366 
			}; 
 
		for( var i=0,e; e=this.calendarEventArray[i]; i++ ) 
			if( e.occurenceCount>1 ) 
				maxInterval = Math.max( maxInterval, maixmizedIntervalPerUnit[ e.occurenceIntervalUnit ]*e.occurenceInterval ); 
 
		if( maxInterval<desiredLength ) 
			return null; 
 
		//	search the closest date available 
		var	attempts	= 0; 
		while( attempts<99 ) 
		{ 
			var	timestampStartOld	= timestampStart, 
				candidateDateStart	= new Date( timestampStart ), 
				candidateDateEnd	= new Date( timestampStart+desiredLength ), 
				eventsInPeriod		= this.getEventsInPeriod( candidateDateStart, candidateDateEnd ); 
 
			if( !eventsInPeriod.length ) 
				return timestampStart; 
 
			for( var i=0,e; e=eventsInPeriod[i]; i++ ) 
			{ 
				if( inFuture ) 
				{ 
					var usefulOccurences = e.getOccurencesStartingBefore( candidateDateEnd ) 
					if( usefulOccurences.length ) 
						timestampStart = Math.max( timestampStart, usefulOccurences.pop().end.valueOf() ) 
				} 
				else 
				{ 
					var usefulOccurences = e.getOccurencesEndingBefore( candidateDateEnd ) 
					if( usefulOccurences.length ) 
						timestampStart = Math.min( timestampStart, usefulOccurences.pop().start.valueOf()-desiredLength ) 
				} 
 
			} 
 
			if( timestampStartOld == timestampStart ) 
				return timestampStart;					//	no change == looping through the last occurences 
 
			attempts++; 
		} 
		return null; 
	} 
 
 
 
 
	/** 
	 *	check the validity of a time unit 
	 *	@member	CalendarEvents 
	 *	@private 
	 *	@param	unit	a time unit provided by the user or a calendarEvent 
	 *	@return	true if the time unit is valid, false otherwise 
	 */ 
	function isValidUnit( unit ) 
	{ 
		switch( (unit||'').toLowerCase() ) 
		{ 
			case 'milliseconds': 
			case 'seconds': 
			case 'minutes': 
			case 'hours': 
			case 'days': 
			case 'weeks': 
			case 'months': 
			case 'years'return true; 
		} 
		return false; 
	} 
} 
 
 
 
 
 
 
 
/** 
 *	Class representing one calendarEvent 
 *	@constructor 
 *	@author Mathieu HENRI, Opera Software ASA 
 *	@version	1.0 
 */ 
function CalendarEvent( _id, _start, _end, _description, _type, _url, _reminderCount, _reminderInterval, _remindersMaxLate, _occurenceCount, _occurenceInterval, _occurenceIntervalUnit ) 
{ 
	calendarEventSelf = this; 
 
	this.id						= _id; 
	this.start					= _start; 
	this.end					= _end||_start; 
	this.description			= _description; 
	this.type					= _type; 
	this.url					= _url; 
 
	//	reminder(s) 
	this.reminderCount			= _reminderCount||0; 
	this.reminderInterval		= _reminderInterval||0; 
	this.remindersMaxLate		= _remindersMaxLate||0; 
 
	//	occurence(s) 
	this.occurenceCount			= _occurenceCount||1; 
	this.occurenceInterval		= _occurenceInterval||0; 
	this.occurenceIntervalUnit	= _occurenceIntervalUnit||0; 
 
 
	this.occurenceDates			= []; 
 
 
	var	currentOccurenceIndex	= 1, 
		dismissedOccurences		= [], 
		reminderTimeoutArray	= [] 
 
 
	/********* Interface methods ***********/ 
 
	/** 
	 *	dismiss the current occurence and move on to the next one 
	 */ 
	this.dismiss = function() 
	{ 
		dismissedOccurences[ currentOccurenceIndex ] = true; 
		this.nextOccurence(); 
	} 
 
 
	/** 
	 *	set the timeout for the reminders of a given occurence 
	 *	@param	occurence	default to the currenceOccurence 
	 *	@return	a boolean indicating of the desired occurence exist or false if it has been dismissed 
	 */ 
	this.setReminderTimeout = function( occurence ) 
	{ 
		var	occurence		= occurence!=undefined?occurence:currentOccurenceIndex, 
			occurenceDates	= this.getOccurenceDates( occurence ) 
 
		if( !occurenceDates ) 
			return false; 
 
		var	timestampDelta	= occurenceDates.start-(new Date().valueOf()); 
 
		if( !reminderTimeoutArray[occurence] ) 
			reminderTimeoutArray[occurence] = [] 
 
		this.clearReminderTimeout( occurence ); 
 
		if( dismissedOccurences[ occurence ] ) 
			return false; 
 
		for( var i=-this.reminderCount; i<=this.remindersMaxLate; i++ ) 
		{ 
			var delay = timestampDelta+i*this.reminderInterval 
			if( delay>0 ) 
				reminderTimeoutArray[occurence].push( setTimeout( 'calendarEventsSelf.callReminder( "'+ escape( this.id ) +'", '+ occurence +', '+ i +' )', delay ) ) 
		} 
		return true; 
	} 
 
 
	/** 
	 *	clear the timeout for the reminders of a given occurence 
	 *	@param	occurence	default to the currenceOccurence 
	 */ 
	this.clearReminderTimeout = function( occurence ) 
	{ 
		var	occurence= occurence!=undefined?occurence:currentOccurenceIndex 
 
		if( reminderTimeoutArray[occurence] ) 
			while( reminderTimeoutArray[occurence].length ) 
				clearTimeout( reminderTimeoutArray[occurence].pop() ); 
	} 
 
 
	/** 
	 *	clear ALL the timeout for the reminders 
	 */ 
	this.clearAllReminderTimeout = function() 
	{ 
		for( var occurence in reminderTimeoutArray ) 
			if(typeof(occurence)=='number'this.clearReminderTimeout( occurence ); 
	} 
 
	/** 
	 *	shift the dates of the calendar event by a a given quantity of time units and reset the reminder timeout and reset the reminder timeout 
	 *	@param	time	the quantiy of time units 
	 *	@param	timeUnit	the unit of time to add	( see the isValidUnit method ) 
	 *	@see 	calendarEvents#isValidUnit 
	 */ 
	this.shiftDates = function( time, timeUnit ) 
	{ 
 
		this.start	= calendarEventsSelf.incrementDate( this.start,	time, timeUnit ); 
		this.end	= calendarEventsSelf.incrementDate( this.end,	time, timeUnit ); 
 
		//	wipe the occurenceDates 
		this.occurenceDates = []; 
 
		// reset nextOccurenceDates 
		var nextOccurenceDates = this.getOccurenceDates( currentOccurenceIndex ); 
		this.nextOccurenceStart	= nextOccurenceDates.start; 
		this.nextOccurenceEnd	= nextOccurenceDates.end; 
 
		this.setReminderTimeout(); 
	} 
 
 
	/** 
	 *	get the start and end dates of a given occurence 
	 *	@param	occurenceIndex	the index of the desired occurence 
	 *	@return	an object with a start and end dates or null if the desired occurenceIndex is invalid 
	 */ 
	this.getOccurenceDates = function( occurenceIndex ) 
	{ 
		if( occurenceIndex<1 || occurenceIndex>this.occurenceCount || dismissedOccurences[ occurenceIndex ] ) 
			return null; 
 
		if( this.occurenceDates[ occurenceIndex ] ) 
			return this.occurenceDates[ occurenceIndex ]; 
 
 
		occurenceDates = { 
			start:	calendarEventsSelf.incrementDate( this.start,	(occurenceIndex-1)*this.occurenceInterval, this.occurenceIntervalUnit ), 
			end:	calendarEventsSelf.incrementDate( this.end,		(occurenceIndex-1)*this.occurenceInterval, this.occurenceIntervalUnit ) 
		} 
		this.occurenceDates[ occurenceIndex ] = occurenceDates; 
 
		return occurenceDates; 
	} 
 
	/** 
	 *	move on to the next occurence 
	 *	@param	maintainReminderTimeout	an optionnal boolean ( false by default ) indicating if the reminder timeouts should be maintain for the current occurence 
	 *	@return	a boolean indicating if the next occurence exist 
	 */ 
	this.nextOccurence = function( maintainReminderTimeout ) 
	{ 
		var	maintainReminderTimeout	= maintainReminderTimeout!=undefined?maintainReminderTimeout:false 
		if( !maintainReminderTimeout ) 
			this.clearReminderTimeout(); 
 
		if( currentOccurenceIndex<this.occurenceCount ) 
		{ 
 
			var nextOccurenceDates = this.getOccurenceDates( currentOccurenceIndex ); 
 
			this.nextOccurenceStart	= nextOccurenceDates.start; 
			this.nextOccurenceEnd	= nextOccurenceDates.end; 
 
			currentOccurenceIndex++; 
 
			this.setReminderTimeout(); 
			return true; 
		} 
 
		this.nextOccurenceStart	= 
		this.nextOccurenceEnd	= Infinity; 
 
		return false; 
	} 
 
 
	/** 
	 *	get the dates of all the occurences ending before a given date 
	 *	@param	dateLimit	the reference date 
	 *	@return	an array of objects with the start and end dates of the corresponding occurences 
	 */ 
	this.getOccurencesEndingBefore = function( dateLimit ) 
	{ 
		var occurenceDates = []; 
 
		var occurenceCount	= this.occurenceCount, 
			j 				= 1, 
			datesOccurenceJ	= {start:this.start,end:this.end,occurenceIndex:1}; 
 
		while( datesOccurenceJ.end<dateLimit && j<=occurenceCount ) 
		{ 
			occurenceDates.push( datesOccurenceJ ) 
			datesOccurenceJ					= this.getOccurenceDates( ++j ); 
			if( !datesOccurenceJ ) 
				return occurenceDates; 
			datesOccurenceJ.occurenceIndex	= j; 
		} 
 
		return occurenceDates; 
	} 
 
 
	/** 
	 *	get the dates of all the occurences starting before a given date 
	 *	@param	dateLimit	the reference date 
	 *	@return	an array of objects in the form of {@link toString#utility} with the start and end dates of the corresponding occurences 
	 */ 
	this.getOccurencesStartingBefore = function( dateLimit ) 
	{ 
		var occurenceDates = []; 
 
		var occurenceCount	= this.occurenceCount, 
			j 				= 1, 
			datesOccurenceJ	= {start:this.start,end:this.end,occurenceIndex:1}; 
 
		while( datesOccurenceJ.start<dateLimit && j<=occurenceCount ) 
		{ 
			occurenceDates.push( datesOccurenceJ ) 
			datesOccurenceJ					= this.getOccurenceDates( ++j ); 
			if( !datesOccurenceJ ) 
				return occurenceDates; 
			datesOccurenceJ.occurenceIndex	= j; 
		} 
 
		return occurenceDates; 
	} 
 
 
 
	//	make sure the next occurence in not in the past 
	var now	= new Date(); 
	this.nextOccurenceStart	= this.start; 
	this.nextOccurenceEnd	= this.end; 
	this.setReminderTimeout(); 
 
	if( this.occurenceCount ) 
	while( now>this.nextOccurenceEnd && currentOccurenceIndex<this.occurenceCount ) 
		this.nextOccurence(); 
} 
 
 


Documentation generated by JSDoc on Tue Oct 24 12:47:04 2006

Libraries