
#include "nsISupports.idl"

interface nsIDOMDocument;
interface nsIDOMNode;
interface nsIURI;
interface nsISimpleEnumerator;
interface nsIMicrosummary;

[scriptable, uuid(cb284a83-1ca5-4000-9841-ce345ce84915)]
interface nsIMicrosummaryObserver : nsISupports
{
    /**
     * Called when an observed microsummary updates its content.
     * Since an observer might watch multiple microsummaries at the same time,
     * the microsummary whose content has been updated gets passed
     * to this handler.
     * XXX Should this be onContentUpdated?
     *
     * @param microsummary
     *        the microsummary whose content has just been updated
     *
     */
    void onContentLoaded(in nsIMicrosummary microsummary);

    /**
     * Called when an element is appended to a microsummary set.
     * XXX Should this be in a separate nsICollectionObserver interface?
     *
     * @param microsummary
     *        the microsummary that has just been appended to the set
     *
     */
    void onElementAppended(in nsIMicrosummary microsummary);
};


[scriptable, uuid(67ffe6b0-d4db-485c-ba20-5e2e8319b78d)]
interface nsIMicrosummaryGenerator : nsISupports
{
    // Has the generator itself, which may be a remote resource, been loaded.
    readonly attribute boolean loaded;

    // An arbitrary descriptive name for this microsummary generator.
    readonly attribute AUTF8String name;

    // The canonical location and unique identifier of the generator.
    // It tells us where the generator comes from and where to go for updates.
    //
    // For generators referenced by web pages via <link> tags, this URI is
    // the URL specified by the tag.
    //
    // For generators installed via nsSidebar::addMicrosummaryGenerator,
    // this URI is a URN of the form urn:source:<url>, where <url> is the
    // remote location from which we installed the generator.
    //
    // For generators installed via some other mechanism (f.e. an extension
    // that dynamically creates generators), this URI is a URN in a form
    // of the extension's own choosing, with the only restriction being that
    // the URI be globally unique.  To ensure this, we recommend that such
    // extensions incorporate UUIDs created by nsUUIDGenerator into the URNs
    // of the generators they create.
    readonly attribute nsIURI uri;

    // Whether or not this generator needs page content to generate
    // a microsummary. Microsummaries generated by XSLT templates need page
    // content, while those which represent the actual microsummary content
    // do not.
    readonly attribute boolean needsPageContent;

    /**
     * Generate a microsummary by processing the generator template
     * against the page content.  If a generator doesn't need content,
     * pass null as the parameter to this method.
     *
     * XXX In the future, this should support returning rich text content,
     * so perhaps we should make it return a DOM node now and have the caller
     * convert that to text if it doesn't support rich content.
     *
     * @param   pageContent
     *          the content of the page being summarized
     * @returns the text result of processing the template
     *
     */
    AString generateMicrosummary(in nsIDOMNode aPageContent);

    /**
     * Calculate the interval until the microsummary should be updated for
     * the next time, depending on the page content. If the generator doesn't
     * specify an interval, null is returned.
     *
     * @param   pageContent
     *          the content of the page being summarized
     * @returns the interval in milliseconds until the next update request
     *
     */
    long calculateUpdateInterval(in nsIDOMNode aPageContent);
};


[scriptable, uuid(1b1f232d-e65f-446a-9984-786578526072)]
interface nsIMicrosummary : nsISupports
{
    // the URI of the page being summarized
    readonly attribute nsIURI pageURI;

    // The generator that generates this microsummary. May need to be loaded.
    attribute nsIMicrosummaryGenerator generator;

    // The content of the microsummary.
    // Since generators and pages can be remote resources, and we need them
    // to generate the content, this may not always be available.
    readonly attribute AString content;

    // The minimum interval after which this microsummary would like to be refreshed
    // (or null if it doesn't care).
    readonly attribute long updateInterval;

    /**
     * Add a microsummary observer to this microsummary.
     *
     * @param observer
     *        the microsummary observer to add
     *
     */
    void addObserver(in nsIMicrosummaryObserver observer);

    /**
     * Remove a microsummary observer from this microsummary.
     *
     * @param observer
     *        the microsummary observer to remove
     *
     */
    void removeObserver(in nsIMicrosummaryObserver observer);

    /**
     * Update the microsummary, first loading its generator and page content
     * as necessary.  If you want know when a microsummary finishes updating,
     * add an observer before calling this method.
     *
     */
    void update();
};

[scriptable, uuid(7111e88d-fecd-4b17-b7a9-1fa74e23153f)]
interface nsIMicrosummarySet : nsISupports
{
    /**
     * Add a microsummary observer to this microsummary set.  Adding an observer
     * to a set is the equivalent of adding it to each constituent microsummary.
     *
     * @param observer
     *        the microsummary observer to add
     *
     */
    void addObserver(in nsIMicrosummaryObserver observer);

    /**
     * Remove a microsummary observer from this microsummary.
     *
     * @param observer
     *        the microsummary observer to remove
     *
     */
    void removeObserver(in nsIMicrosummaryObserver observer);

    /**
     * Retrieve a enumerator of microsummaries in the set.
     *
     * @returns an enumerator of nsIMicrosummary objects
     *
     */
    nsISimpleEnumerator Enumerate();
};


[scriptable, uuid(edec7c28-4b06-4692-842f-8bf238e61ac1)]
interface nsIMicrosummaryService : nsISupports
{
    /**
     * Install the microsummary generator from the resource at the supplied URI.
     * Callable by content via the addMicrosummaryGenerator() sidebar method.
     *
     * @param   generatorURI
     *          the URI of the resource providing the generator
     *
     */
    void addGenerator(in nsIURI generatorURI);

    /**
     * Install the microsummary generator in the given XML definition.
     *
     * @param   xmlDefinition
     *          an nsIDOMDocument XML document defining the generator
     *
     * @returns the newly-installed nsIMicrosummaryGenerator object
     *
     */
    nsIMicrosummaryGenerator installGenerator(in nsIDOMDocument xmlDefinition);

    /**
     * Get the set of bookmarks with microsummaries.
     *
     * In the old RDF-based bookmarks datastore, bookmark IDs are nsIRDFResource
     * objects.  In the new Places-based datastore, they are nsIURI objects.
     *
     * @returns an nsISimpleEnumerator enumeration of bookmark IDs
     *
     */
    nsISimpleEnumerator getBookmarks();

    /**
     * Get the set of microsummaries available for a given page.  The set
     * might change after this method returns, since this method will trigger
     * an asynchronous load of the page in question (if it isn't already loaded)
     * to see if it references any page-specific microsummaries.
     *
     * If the caller passes a bookmark ID, and one of the microsummaries
     * is the current one for the bookmark, this method will retrieve content
     * from the datastore for that microsummary, which is useful when callers
     * want to display a list of microsummaries for a page that isn't loaded,
     * and they want to display the actual content of the selected microsummary
     * immediately (rather than after the content is asynchronously loaded).
     *
     * @param   pageURI
     *          the URI of the page for which to retrieve available microsummaries
     *
     * @param   bookmarkID (optional)
     *          the ID of the bookmark for which this method is being called
     *
     * @returns an nsIMicrosummarySet of nsIMicrosummaries for the given page
     *
     */
    nsIMicrosummarySet getMicrosummaries(in nsIURI pageURI,
                                         in nsISupports bookmarkID);

    /**
     * Get the current microsummary for the given bookmark.
     *
     * @param   bookmarkID
     *          the bookmark for which to get the current microsummary
     *
     * @returns the current microsummary for the bookmark, or null
     *          if the bookmark does not have a current microsummary
     *
     */
    nsIMicrosummary getMicrosummary(in nsISupports bookmarkID);

    /**
     * Set the current microsummary for the given bookmark.
     *
     * @param   bookmarkID
     *          the bookmark for which to set the current microsummary
     *
     * @param   microsummary
     *          the microsummary to set as the current one
     *
     */
    void setMicrosummary(in nsISupports bookmarkID,
                         in nsIMicrosummary microsummary);

    /**
     * Remove the current microsummary for the given bookmark.
     *
     * @param   bookmarkID
     *          the bookmark for which to remove the current microsummary
     *
     */
    void removeMicrosummary(in nsISupports bookmarkID);

    /**
     * Whether or not the given bookmark has a current microsummary.
     *
     * @param   bookmarkID
     *          the bookmark for which to set the current microsummary
     *
     * @returns a boolean representing whether or not the given bookmark
     *          has a current microsummary
     *
     */
    boolean hasMicrosummary(in nsISupports bookmarkID);

    /**
     * Whether or not the given microsummary is the current microsummary
     * for the given bookmark.
     *
     * @param   bookmarkID
     *          the bookmark to check
     *
     * @param   microsummary
     *          the microsummary to check
     *
     * @returns whether or not the microsummary is the current one
     *          for the bookmark
     *
     */
    boolean isMicrosummary(in nsISupports bookmarkID,
                           in nsIMicrosummary microsummary);

    /**
     * Refresh a microsummary, updating its value in the datastore and UI.
     * If this method can refresh the microsummary instantly, it will.
     * Otherwise, it'll asynchronously download the necessary information
     * (the generator and/or page) before refreshing the microsummary.
     *
     * Callers should check the "content" property of the returned microsummary
     * object to distinguish between sync and async refreshes.  If its value
     * is "null", then it's an async refresh, and the caller should register
     * itself as an nsIMicrosummaryObserver via nsIMicrosummary.addObserver()
     * to find out when the refresh completes.
     *
     * @param   bookmarkID
     *          the bookmark whose microsummary is being refreshed
     *
     * @returns the microsummary being refreshed
     *
     */
    nsIMicrosummary refreshMicrosummary(in nsISupports bookmarkID);
};
