/*
 * 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. 
 */

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

/*!
    @class WebHistoryItem
    @discussion  WebHistoryItems are created by WebKit to represent pages visited.
    The WebBackForwardList and WebHistory classes both use WebHistoryItems to represent
    pages visited.  With the exception of the displayTitle, the properties of 
    WebHistoryItems are set by WebKit.  WebHistoryItems are normally never created directly.
*/
[
    object,
    oleautomation,
    hidden,
    uuid(1E2970AE-72B7-4500-A7A0-12B0FFEB91FC),
    pointer_default(unique)
]
interface IWebHistoryItem : IUnknown
{
    /*!
        @method initWithURLString:title:lastVisitedTimeInterval:
        @param URLString The URL string for the item.
        @param title The title to use for the item.  This is normally the <title> of a page.
        @param time The time used to indicate when the item was used.
        @abstract Initialize a new WebHistoryItem
        @discussion WebHistoryItems are normally created for you by the WebKit.
        You may use this method to prepopulate a WebBackForwardList, or create
        'artificial' items to add to a WebBackForwardList.  When first initialized
        the URLString and originalURLString will be the same.
        - (id)initWithURLString:(NSString *)URLString title:(NSString *)title lastVisitedTimeInterval:(NSTimeInterval)time;
    */
    HRESULT initWithURLString([in] BSTR urlString, [in] BSTR title, [in] DATE lastVisited);

    /*!
        @method originalURLString
        @abstract The string representation of the originial URL of this item.
        This value is normally set by the WebKit.
        @result The string corresponding to the initial URL of this item.
        - (NSString *)originalURLString;
    */
    HRESULT originalURLString([out, retval] BSTR* url);

    /*!
        @method URLString
        @abstract The string representation of the URL represented by this item.
        @discussion The URLString may be different than the originalURLString if the page
        redirected to a new location.  This value is normally set by the WebKit.
        @result The string corresponding to the final URL of this item.
        - (NSString *)URLString;
    */
    HRESULT URLString([out, retval] BSTR* url);


    /*!
        @method title
        @abstract The title of the page represented by this item.
        @discussion This title cannot be changed by the client.  This value
        is normally set by the WebKit when a page title for the item is received.
        @result The title of this item.
        - (NSString *)title;
    */
    HRESULT title([out, retval] BSTR* pageTitle);

    /*!
        @method lastVisitedTimeInterval
        @abstract The last time the page represented by this item was visited. The interval
        is since the reference date as determined by NSDate.  This value is normally set by
        the WebKit.
        @result The last time this item was visited.
        - (NSTimeInterval)lastVisitedTimeInterval;
    */
    HRESULT lastVisitedTimeInterval([out, retval] DATE* lastVisited);

    /*!
        @method setAlternateTitle:
        @param alternateTitle The new display title for this item.
        @abstract A title that may be used by the client to display this item.
        - (void)setAlternateTitle:(NSString *)alternateTitle;
    */
    HRESULT setAlternateTitle([in] BSTR title);

    /*
        @method title
        @abstract A title that may be used by the client to display this item.
        @result The alternate title for this item.
        - (NSString *)alternateTitle;
    */
    HRESULT alternateTitle([out, retval] BSTR* title);

    /*!
        @method icon
        @abstract The favorite icon of the page represented by this item.
        @discussion This icon returned will be determined by the WebKit.
        @result The icon associated with this item's URL.
        - (NSImage *)icon;
    */
    HRESULT icon([out, retval] OLE_HANDLE* hBitmap);
}
