/* Evolution calendar interface
 *
 * Copyright (C) 2000 Eskil Heyn Olsen
 * Copyright (C) 2000 Ximian, Inc.
 * Copyright (C) 2000 Ximian, Inc.
 *
 * Authors: Eskil Heyn Olsen <deity@eskil.dk>
 *          Federico Mena-Quintero <federico@ximian.com>
 */

#ifndef _EVOLUTION_CALENDAR_IDL_
#define _EVOLUTION_CALENDAR_IDL_

#include <Bonobo.idl>

module GNOME {
module Evolution {

module Calendar {
	/* A calendar component (event/todo/journal/etc), represented as an
	 * iCalendar string.
	 */
	typedef string CalObj;
	typedef sequence<CalObj> CalObjSeq;

	/* A unique identifier for a calendar component */
	typedef string CalObjUID;

	/* Simple sequence of strings */
	typedef sequence<string> StringSeq;

	/* Sequence of unique identifiers */
	typedef sequence<CalObjUID> CalObjUIDSeq;

	/* A VTIMEZONE component, represented as an iCalendar string. */
	typedef string CalTimezoneObj;

	/* A unique identifier for a VTIMEZONE component, i.e. its TZID. */
	typedef string CalTimezoneObjUID;

	/* A unique identifier for an alarm subcomponent */
	typedef string CalAlarmUID;

	/* Flags for getting UID sequences */
	typedef long CalObjType;
	const CalObjType TYPE_EVENT   = 1 << 0;
	const CalObjType TYPE_TODO    = 1 << 1;
	const CalObjType TYPE_JOURNAL = 1 << 2;
	const CalObjType TYPE_ANY     = 0x07;

	/* Flags for getting URI sequences */
	typedef long CalMode;
	const CalMode MODE_LOCAL   = 1 << 0;
	const CalMode MODE_REMOTE  = 1 << 1;
	const CalMode MODE_ANY     = 0x07;

	/* Types of object changes made */
	typedef long CalObjChangeType;
	const CalObjChangeType ADDED = 1 << 0;
	const CalObjChangeType MODIFIED = 1 << 1;
	const CalObjChangeType DELETED = 1 << 2;
	
	/* Types of alarms */
	enum AlarmType {
		MAIL,
		PROGRAM,
		DISPLAY,
		AUDIO
	};

	/* Used to store a time_t */
	typedef unsigned long Time_t;

	/* An instance of a calendar component that actually occurs.  These are
	 * "virtual" objects in that they are used to represent instances of
	 * recurring events and alarms.  "Real" objects just contain the
	 * information required to figure out the times at which they recur or
	 * trigger.  
	 */
	struct CalObjInstance {
		CalObjUID uid;
		Time_t start;
		Time_t end;
	};

	/* Used to transfer a list of component occurrences */
	typedef sequence<CalObjInstance> CalObjInstanceSeq;

	/* An object change */
	struct CalObjChange {
		CalObj calobj;
		CalObjChangeType type;
	};

	/* Used to transfer a list of changed components */
	typedef sequence<CalObjChange> CalObjChangeSeq;

	/* An alarm trigger instance */
	struct CalAlarmInstance {
		CalAlarmUID auid;
		Time_t trigger;
		Time_t occur_start;
		Time_t occur_end;
	};

	/* Used to represent a list of alarm triggers for a single component */
	typedef sequence<CalAlarmInstance> CalAlarmInstanceSeq;

	/* Alarms for a component */
	struct CalComponentAlarms {
		CalObj calobj;
		CalAlarmInstanceSeq alarms;
	};

	/* Used to represent a list of components plus their triggers */
	typedef sequence<CalComponentAlarms> CalComponentAlarmsSeq;

	/* Used to represent users and lists of users */
	typedef string User;
	typedef sequence<User> UserList;

	interface Query;

	interface Listener;

	interface QueryListener;

	/* Calendar client interface */
	interface Cal : Bonobo::Unknown {
		exception NotFound {};
		exception InvalidRange {};
		exception InvalidObject {};
		exception CouldNotCreate {};
		exception PermissionDenied {};
		exception Busy {string errorMsg;};
		
		/* A calendar is identified by its URI */
		readonly attribute string uri;

		/* Check write permissions for calendar */
		boolean isReadOnly ();

		/* Return the email address associated with this calendar,
		   if any. */
		string getEmailAddress ()
			raises (NotFound);

		/* For going online/offline */
		void setMode (in CalMode mode);
		
		/* Gets the number of components of the specified types */
		long countObjects (in CalObjType type);

		/* Gets a component based on its URI */
		CalObj getObject (in CalObjUID uid)
			raises (NotFound);

		/* Sets the default timezone to be used for resolving DATE
		   and floating DATE-TIME values. */
		void setDefaultTimezone (in CalTimezoneObjUID tzid)
			raises (NotFound);

		/* Gets a VTIMEZONE component based on its TZID */
		CalTimezoneObj getTimezoneObject (in CalTimezoneObjUID tzid)
			raises (NotFound);

		/* Gets a list of UIDs based on component type */
		CalObjUIDSeq getUIDs (in CalObjType type);

		/* Gets a list of components that changed based on object type */
		CalObjChangeSeq getChanges (in CalObjType type, in string change_id);

		/* Gets a list of components that occur or recur in the specified time range */
		CalObjUIDSeq getObjectsInRange (in CalObjType type, 
						in Time_t start, in Time_t end)
			raises (InvalidRange);

		/* Gets a list of the components that have alarms that trigger
		 * in the specified range of time, and the trigger/occurrence
		 * structures themselves.  
		 */
		CalComponentAlarmsSeq getAlarmsInRange (in Time_t start, in Time_t end)
			raises (InvalidRange);

		/* Returns free/busy objects for the given interval */
		CalObjSeq getFreeBusy (in UserList users, in Time_t start, in Time_t end)
			raises (NotFound, InvalidRange);

		/* Gets the alarms for the specified component that trigger in
		 * the specified time range.  
		 */
		CalComponentAlarms getAlarmsForObject (in CalObjUID uid,
						       in Time_t start, in Time_t end)
			raises (NotFound, InvalidRange);


		/* Adds or updates one or more VEVENT/VTODO/VTIMEZONE
		 * components. The calobj should be a string representation of
		 * a complete VCALENDAR object (we also support single
		 * VEVENT/VTODO strings, but that is deprecated).
		 *
		 * The VTIMEZONE data will be merged into the calendar,
		 * possibly by renaming TZIDs (though not for builtin
		 * VTIMEZONEs, which have unique TZIDs), so don't rely on the
		 * TZIDs being the same in the new object on the server.
		 *
		 * The client should probably immediately free its copy of the
		 * object after this call, and call getObject to get the
		 * updated version.
		 */
		void updateObjects (in CalObj calobj)
			raises (InvalidObject, PermissionDenied);

		/* Removes a component */
		void removeObject (in CalObjUID uid)
			raises (NotFound, PermissionDenied);

		/* Sends a component */
		CalObj sendObject (in CalObj calobj, out UserList users)
			raises (InvalidObject, PermissionDenied, Busy);

		/* Initiates a live query of the calendar.  Returns a handle
		 * to the live query itself; changes to components that are
		 * present in the query are notified to the listener.
		 */
		Query getQuery (in string sexp, in QueryListener ql)
			raises (CouldNotCreate);
	};

	/* Listener for changes in a calendar */
	interface Listener : Bonobo::Unknown {
		/* Return status when opening a calendar */
		enum OpenStatus {
			SUCCESS,		/* All OK */
			ERROR,			/* Generic error */
			NOT_FOUND,		/* Requested opening in only_if_exists mode
						 * when the URI did not exist.
						 */
			METHOD_NOT_SUPPORTED,	/* A method handler is not registered */
			PERMISSION_DENIED
		};

		/* Return status when setting calendar mode */
		enum SetModeStatus {
			MODE_SET,                    /* All OK */
			MODE_NOT_SET,                /* Generic error */
			MODE_NOT_SUPPORTED           /* Mode not supported */
		};

		/* Called from a CalFactory when a calendar is initially opened.
		 * The listener must remember the cal object.  
		 */
		void notifyCalOpened (in OpenStatus status, in Cal cal);

                /* Called from a Calendar when the mode is changed */
		void notifyCalSetMode (in SetModeStatus status, in CalMode mode);
		
		/* Called from a Calendar when a component is added or changed */
		void notifyObjUpdated (in CalObjUID uid);

		/* Called from a Calendar when a component is removed */
		void notifyObjRemoved (in CalObjUID uid);

		/* Called from a Calendar when the list of categories changes */
		void notifyCategoriesChanged (in StringSeq categories);

		/* Called from a Calendar when there is an error not notified otherwise */
		void notifyErrorOccurred (in string message);
	};

	/* Handle to a live query on a calendar */
	interface Query : Bonobo::Unknown {
	};

	/* Listener for changes in a query of a calendar */
	interface QueryListener : Bonobo::Unknown {
		/* Called when components are added or changed.  If
		 * query_in_progress is true, then the initial query results are
		 * being populated and the other arguments indicate the
		 * percentage of completion Otherwise, the percent value is
		 * unspecified.  */
		void notifyObjUpdated (in CalObjUIDSeq uids, 
				       in boolean query_in_progress, 
				       in long n_scanned,
				       in long total);

		/* Called when a component is removed */
		void notifyObjRemoved (in CalObjUID uid);

		/* Reported when a query ends */
		enum QueryDoneStatus {
			SUCCESS,
			PARSE_ERROR
		};

		/* Called when the query finishes populating itself some time
		 * after it is created.  Before this is called,
		 * notifyObjUpdated() may have been called several times to
		 * indicate which objects are actually in the query, unless the
		 * status result is a parse error.  
		 */
		void notifyQueryDone (in QueryDoneStatus status, in string error_str);

		/* Called when an evaluation error occurs while performing a query */
		void notifyEvalError (in string error_str);
	};

	/* A calendar factory, can load and create calendars */
	interface CalFactory : Bonobo::Unknown {
		exception NilListener {};
		exception InvalidURI {};
		exception UnsupportedMethod {};
		exception PermissionDenied {};

		/* Open a calendar from an URI */
		void open (in string uri, in boolean only_if_exists, in Listener listener)
			raises (NilListener, InvalidURI, UnsupportedMethod, PermissionDenied);

		/* List of open URI's */
		StringSeq uriList (in CalMode mode);
	};

	/* Interface to the alarm notification service */
	interface AlarmNotify : Bonobo::Unknown {
		exception InvalidURI {};
		exception BackendContactError {};
		exception NotFound {};

		/* Adds a calendar to the alarm notification system so that
		 * alarms will be triggered for it.  The calendar will be loaded
		 * automatically whenever the alarm daemon starts up.  
		 */
		void addCalendar (in string uri)
			raises (InvalidURI, BackendContactError);

		/* Removes a calendar from the alarm notification system and
		 * alarms will no longer be triggered for it.  The calendar will
		 * no longer be loaded when the alarm daemon starts up. 
		 */
		void removeCalendar (in string uri)
			raises (InvalidURI, NotFound);
	};

	/* Factory to centralize calendar component editor dialogs */
	interface CompEditorFactory : Bonobo::Unknown {
		exception InvalidURI {};
		exception BackendContactError {};
		exception UnsupportedType {};

		typedef long CompEditorMode;
		const CompEditorMode EDITOR_MODE_EVENT        = 1 << 0;
		const CompEditorMode EDITOR_MODE_ALLDAY_EVENT = 1 << 1;
		const CompEditorMode EDITOR_MODE_MEETING      = 1 << 2;
		const CompEditorMode EDITOR_MODE_TODO         = 1 << 3;

		/* Loads a calendar and opens an editor for the specified object */
		void editExisting (in string uri, in CalObjUID uid)
			raises (InvalidURI, BackendContactError);

		/* Loads a calendar and creates a new component of the specified type */
		void editNew (in string uri, in CompEditorMode mode)
			raises (InvalidURI, BackendContactError, UnsupportedType);
	};
};

};
};

#endif
