/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "calICalendar.idl"

interface calIGenericOperationListener;
interface calIOperation;

/**
 * Interface for managing offline flags in offline storage
 * (calStorageCalendar), in particular from calICachedCalendar.
 */
[scriptable, uuid(36dc2c93-5851-40d2-9ba9-b1f6e682c75c)]
interface calIOfflineStorage : calICalendar {
    /**
     * Mark the item of which the id is passed as parameter as new.
     *
     * @param aItem       the item to add
     * @param aListener   where to call back the results
     */
    void addOfflineItem(in calIItemBase aItem, in calIOperationListener aListener);

    /**
     * Mark the item of which the id is passed as parameter as modified.
     *
     * @param aItem       the item to modify
     * @param aListener   where to call back the results
     */
    void modifyOfflineItem(in calIItemBase aItem, in calIOperationListener aListener);

    /**
     * Mark the item of which the id is passed as parameter as deleted.
     *
     * @param aItem       the item to delete
     * @param aListener   where to call back the results
     */
    void deleteOfflineItem(in calIItemBase aItem, in calIOperationListener aListener);

    /**
     * Retrieves the offline flag for the given item. The flag is returned using the
     * detail parameter of the onOperationComplete function in calIOperationLIstener.
     *
     * @param aItem       the item to reset
     * @param aListener   where to call back the results
     */
    void getItemOfflineFlag(in calIItemBase aItem, in calIOperationListener aListener);

    /**
     * Remove any offline flag from the item record.
     *
     * @param aItem       the item to reset
     * @param aListener   where to call back the results
     */
    void resetItemOfflineFlag(in calIItemBase aItem, in calIOperationListener aListener);
};

/**
 * Interface for synchronously working providers on storing items,
 * e.g. storage, memory. All modifying commands return after the
 * modification has been performed.
 *
 * @note
 *   This interface is used in conjunction with changelog-based synchronization
 *   and additionally offers storing meta-data for items for this purpose.
 *   The meta data is stored as long as the corresponding items persist in
 *   the calendar and automatically cleanup up once the item is deleted from
 *   the calendar, but is not altered when an item is modified (modifyItem).
 *   Meta data can be fetched/stored per (master) item, i.e. if you need to
 *   store meta data for individual overridden items, you need to store it
 *   along with the master item's meta data.
 *   Finally, keep in mind that the meta data is "calendar local" and not
 *   automatically transferred when storing the item on another calISyncWriteCalendar.
 */
[scriptable, uuid(651e137b-2f3a-4595-af89-da51b6a37f85)]
interface calISyncWriteCalendar : calICalendar {
    /**
     * Adds or replaces meta data of an item.
     *
     * @param id    an item id
     * @param value an arbitrary string
     */
    void setMetaData(in AUTF8String id,
                     in AUTF8String value);

    /**
     * Deletes meta data of an item.
     *
     * @param id    an item id
     */
    void deleteMetaData(in AUTF8String id);

    /**
     * Gets meta data of an item or null if there's none or the item id is invalid.
     *
     * @param id    an item id
     */
    AUTF8String getMetaData(in AUTF8String id);

    /**
     * Gets all meta data. The returned arrays are of the same length.
     */
    void getAllMetaData(out PRUint32 count,
                        [array, size_is(count)] out wstring ids,
                        [array, size_is(count)] out wstring values);
};

/**
 * Calendar implementing this interface have improved means of replaying their
 * changelog data. This could for example mean, that the provider can retrieve
 * changes between now and the last sync.
 *
 * Not implementing this interface is perfectly valid for calendars, that need
 * to do a full sync each time anyway (i.e ics)
 */
[scriptable, uuid(0bf4c6a2-b4c7-4cae-993a-4408d8bded3e)]
interface calIChangeLog : nsISupports {

    // To denote no offline flag, use null
    const long OFFLINE_FLAG_CREATED_RECORD = 1;
    const long OFFLINE_FLAG_MODIFIED_RECORD = 2;
    const long OFFLINE_FLAG_DELETED_RECORD = 4;

    /**
     * Enable the changelog calendar to retrieve offline data right after instanciation.
     */
    attribute calISyncWriteCalendar offlineStorage;

    /**
     * Resets the changelog. This is used if the cache should be refreshed.
     */
    void resetLog();

    /**
     * Instructs the calendar to replay remote changes into the given
     * calendar. The calendar itself is responsible for storing anything needed
     * to keep track of what items need updating.
     *
     * TODO: We might reconsider to replay on calICalendar,
     *       but this complicates implementing this interface
     *       enormously for providers.
     *
     * @param aDestination      The calendar to sync changes into
     * @param aListener         The listener to notify when the operation completes.
     */
    calIOperation replayChangesOn(in calIGenericOperationListener aListener);

    /**
     * addItemOrUseCache: same as calICalendar::addItem
     *
     * @param useCache          use the cache for handling availability errors
     *
     * When 'useCache' is set, failure to perform the operation will result in
     * a write in the cache with the corresponding offline operation, when the
     * backend supports it. In that case, the listener will thus always
     * receive a success code. When unset, the behaviour is similar to the
     * corresponding addItem() invocation.
     */
    calIOperation addItemOrUseCache(in calIItemBase aItem,
                                    in boolean useCache,
                                    in calIOperationListener aListener);
    /**
     * adoptItemOrUseCache: same as calICalendar::adoptItem
     *
     * @param useCache          use the cache for handling availability errors
     */
    calIOperation adoptItemOrUseCache(in calIItemBase aItem,
                                      in boolean useCache,
                                      in calIOperationListener aListener);
    /**
     * modifyItemOrUseCache: same as calICalendar::modifyItem
     *
     * @param useCache          use the cache for handling availability errors
     */
    calIOperation modifyItemOrUseCache(in calIItemBase aNewItem,
                                       in calIItemBase aOldItem,
                                       in boolean useCache,
                                       in calIOperationListener aListener);
    /**
     * deleteItemOrUseCache: same as calICalendar::deleteItem
     *
     * @param useCache          use the cache for handling availability errors
     */
    calIOperation deleteItemOrUseCache(in calIItemBase aItem,
                                       in boolean useCache,
                                       in calIOperationListener aListener);
};
