/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. OR
 * 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. 
 */

/*
    @discussion Notifications sent when history is modified. 
    @constant WebHistoryItemsAddedNotification Posted from addItems:.  This 
    notification comes with a userInfo dictionary that contains the array of
    items added.  The key for the array is WebHistoryItemsKey.
    @constant WebHistoryItemsRemovedNotification Posted from removeItems:.  
    This notification comes with a userInfo dictionary that contains the array of
    items removed.  The key for the array is WebHistoryItemsKey.
    @constant WebHistoryAllItemsRemovedNotification Posted from removeAllItems
    @constant WebHistoryLoadedNotification Posted from loadFromURL:error:.
*/
cpp_quote("#define WebHistoryItemsAddedNotification TEXT(\"WebHistoryItemsAddedNotification\")")
cpp_quote("#define WebHistoryItemsRemovedNotification TEXT(\"WebHistoryItemsRemovedNotification\")")
cpp_quote("#define WebHistoryAllItemsRemovedNotification TEXT(\"WebHistoryAllItemsRemovedNotification\")")
cpp_quote("#define WebHistoryLoadedNotification TEXT(\"WebHistoryLoadedNotification\")")
cpp_quote("#define WebHistoryItemsDiscardedWhileLoadingNotification TEXT(\"WebHistoryItemsDiscardedWhileLoadingNotification\")")
cpp_quote("#define WebHistorySavedNotification TEXT(\"WebHistorySavedNotification\")")

#ifndef DO_NO_IMPORTS
import "oaidl.idl";
import "ocidl.idl";
import "IWebError.idl";
import "IWebHistoryItem.idl";
#endif

interface IWebError;
interface IWebHistoryItem;

/*!
    @class WebHistory
    @discussion WebHistory is used to track pages that have been loaded
    by WebKit.
*/
[
    object,
    oleautomation,
    hidden,
    uuid(F34E4B1A-361D-4b9f-9A3F-D869DCD97F9A),
    pointer_default(unique)
]
interface IWebHistory : IUnknown
{
    /*!
        @method optionalSharedHistory
        @abstract Returns a shared WebHistory instance initialized with the default history file.
        @result A WebHistory object.
        + (WebHistory *)optionalSharedHistory;
    */
    HRESULT optionalSharedHistory([out, retval] IWebHistory** history);

    /*!
        @method setOptionalSharedHistory:
        @param history The history to use for the global WebHistory.
        + (void)setOptionalSharedHistory:(WebHistory *)history;
    */
    HRESULT setOptionalSharedHistory([in] IWebHistory* history);

    /*!
        @method loadFromURL:error:
        @param URL The URL to use to initialize the WebHistory.
        @param error Set to nil or an NSError instance if an error occurred.
        @abstract The designated initializer for WebHistory.
        @result Returns YES if successful, NO otherwise.
        - (BOOL)loadFromURL:(NSURL *)URL error:(NSError **)error;
    */
    HRESULT loadFromURL([in] BSTR url, [out] IWebError** error, [out, retval] BOOL* succeeded);

    /*!
        @method saveToURL:error:
        @discussion Save history to URL. It is the client's responsibility to call this at appropriate times.
        @param URL The URL to use to save the WebHistory.
        @param error Set to nil or an NSError instance if an error occurred.
        @result Returns YES if successful, NO otherwise.
        - (BOOL)saveToURL:(NSURL *)URL error:(NSError **)error;
    */
    HRESULT saveToURL([in] BSTR url, [out] IWebError** error, [out, retval] BOOL* succeeded);

    /*!
        @method addItems:
        @param newItems An array of WebHistoryItems to add to the WebHistory.
        - (void)addItems:(NSArray *)newItems;
    */
    HRESULT addItems([in] int itemCount, [in] IWebHistoryItem** items);

    /*!
        @method removeItems:
        @param items An array of WebHistoryItems to remove from the WebHistory.
        - (void)removeItems:(NSArray *)items;
    */
    HRESULT removeItems([in] int itemCount, [in] IWebHistoryItem** items);

    /*!
        @method removeAllItems
        - (void)removeAllItems;
    */
    HRESULT removeAllItems();

    /*!
        @method orderedLastVisitedDays
        @discussion Get an array of NSCalendarDates, each one representing a unique day that contains one
        or more history items, ordered from most recent to oldest.
        @result Returns an array of NSCalendarDates for which history items exist in the WebHistory.
        
        ADVISORY NOTE:  This method may change for the 1.0 SDK.
        - (NSArray *)orderedLastVisitedDays;
    */
    HRESULT orderedLastVisitedDays([in, out] int* count, [in] DATE* calendarDates);

    /*!
        @method orderedItemsLastVisitedOnDay:
        @discussion Get an array of WebHistoryItem that were last visited on the day represented by the
        specified NSCalendarDate, ordered from most recent to oldest.
        @param calendarDate A date identifying the unique day of interest.
        @result Returns an array of WebHistoryItems last visited on the indicated day.

        ADVISORY NOTE:  This method may change for the 1.0 SDK.
        - (NSArray *)orderedItemsLastVisitedOnDay:(NSCalendarDate *)calendarDate;
    */
    HRESULT orderedItemsLastVisitedOnDay([in, out] int* count, [in] IWebHistoryItem** items, [in] DATE calendarDate);

    /*!
        @method itemForURL:
        @abstract Get an item for a specific URL
        @param URL The URL of the history item to search for
        @result Returns an item matching the URL
        - (WebHistoryItem *)itemForURL:(NSURL *)URL;
    */
    HRESULT itemForURL([in] BSTR url, [out, retval] IWebHistoryItem** item);

    /*!
        @method setHistoryItemLimit:
        @discussion Limits the number of items that will be stored by the WebHistory.
        @param limit The maximum number of items that will be stored by the WebHistory.
        - (void)setHistoryItemLimit:(int)limit;
    */
    HRESULT setHistoryItemLimit([in] int limit);

    /*!
        @method historyItemLimit
        @result The maximum number of items that will be stored by the WebHistory.
        - (int)historyItemLimit;
    */
    HRESULT historyItemLimit([out, retval] int* limit);

    /*!
        @method setHistoryAgeInDaysLimit:
        @discussion setHistoryAgeInDaysLimit: sets the maximum number of days to be read from
        stored history.
        @param limit The maximum number of days to be read from stored history.
        - (void)setHistoryAgeInDaysLimit:(int)limit;
    */
    HRESULT setHistoryAgeInDaysLimit([in] int limit);

    /*!
        @method historyAgeInDaysLimit
        @return Returns the maximum number of days to be read from stored history.
        - (int)historyAgeInDaysLimit;
    */
    HRESULT historyAgeInDaysLimit([out, retval] int* limit);
}