/*
 * 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 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 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";
import "IWebHistoryItem.idl";
#endif

interface IWebHistoryItem;

/*!
    @class WebBackForwardList
    WebBackForwardList holds an ordered list of WebHistoryItems that comprises the back and
    forward lists.
    
    Note that the methods which modify instances of this class do not cause
    navigation to happen in other layers of the stack;  they are only for maintaining this data
    structure.
*/
[
    object,
    oleautomation,
    uuid(C278A16D-B502-4131-B551-DCE3F4ED2B36),
    pointer_default(unique)
]
interface IWebBackForwardList : IUnknown
{
    /*!
        @method addItem:
        @abstract Adds an entry to the list.
        @param entry The entry to add.
        @discussion The added entry is inserted immediately after the current entry.
        If the current position in the list is not at the end of the list, elements in the
        forward list will be dropped at this point.  In addition, entries may be dropped to keep
        the size of the list within the maximum size.
        - (void)addItem:(WebHistoryItem *)item;
    */
    HRESULT addItem([in] IWebHistoryItem* item);

    /*!
        @method goBack
        @abstract Move the current pointer back to the entry before the current entry.
        - (void)goBack;
    */
    HRESULT goBack();

    /*!
        @method goForward
        @abstract Move the current pointer ahead to the entry after the current entry.
        - (void)goForward;
    */
    HRESULT goForward();

    /*!
        @method goToItem:
        @abstract Move the current pointer to the given entry.
        @param item The history item to move the pointer to
        - (void)goToItem:(WebHistoryItem *)item;
    */
    HRESULT goToItem([in] IWebHistoryItem* item);

    /*!
        @method backItem
        @abstract Returns the entry right before the current entry.
        @result The entry right before the current entry, or nil if there isn't one.
        - (WebHistoryItem *)backItem;
    */
    HRESULT backItem([out, retval] IWebHistoryItem** item);

    /*!
        @method currentItem
        @abstract Returns the current entry.
        @result The current entry.
        - (WebHistoryItem *)currentItem;
    */
    HRESULT currentItem([out, retval] IWebHistoryItem** item);

    /*!
        @method forwardItem
        @abstract Returns the entry right after the current entry.
        @result The entry right after the current entry, or nil if there isn't one.
        - (WebHistoryItem *)forwardItem;
    */
    HRESULT forwardItem([out, retval] IWebHistoryItem** item);

    /*!
        @method backListWithLimit:
        @abstract Returns a portion of the list before the current entry.
        @param limit A cap on the size of the array returned.
        @result An array of items before the current entry, or nil if there are none.  The entries are in the order that they were originally visited.
        - (NSArray *)backListWithLimit:(int)limit;
    */
    HRESULT backListWithLimit([in] int limit, [out] int* listCount, [in] IWebHistoryItem** list);

    /*!
        @method forwardListWithLimit:
        @abstract Returns a portion of the list after the current entry.
        @param limit A cap on the size of the array returned.
        @result An array of items after the current entry, or nil if there are none.  The entries are in the order that they were originally visited.
        - (NSArray *)forwardListWithLimit:(int)limit;
    */
    HRESULT forwardListWithLimit([in] int limit, [out] int* listCount, [in] IWebHistoryItem** list);

    /*!
        @method capacity
        @abstract Returns the list's maximum size.
        @result The list's maximum size.
        - (int)capacity;
    */
    HRESULT capacity([out, retval] int* result);

    /*!
        @method setCacpacity
        @abstract Sets the list's maximum size.
        @param size The new maximum size for the list.
        - (void)setCapacity:(int)size;
    */
    HRESULT setCapacity([in] int size);

    /*!
        @method backListCount
        @abstract Returns the back list's current count.
        @result The number of items in the list.
        - (int)backListCount;
    */
    HRESULT backListCount([out, retval] int* count);

    /*!
        @method forwardListCount
        @abstract Returns the forward list's current count.
        @result The number of items in the list.
        - (int)forwardListCount;
    */
    HRESULT forwardListCount([out, retval] int* sizecount);

    /*!
        @method containsItem:
        @param item The item that will be checked for presence in the WebBackForwardList.
        @result Returns YES if the item is in the list. 
        - (BOOL)containsItem:(WebHistoryItem *)item;
    */
    HRESULT containsItem([in] IWebHistoryItem* item, [out, retval] BOOL* result);

    /*!
        @method itemAtIndex:
        @abstract Returns an entry the given distance from the current entry.
        @param index Index of the desired list item relative to the current item; 0 is current item, -1 is back item, 1 is forward item, etc.
        @result The entry the given distance from the current entry. If index exceeds the limits of the list, nil is returned.
        - (WebHistoryItem *)itemAtIndex:(int)index;
    */
    HRESULT itemAtIndex([in] int index, [out, retval] IWebHistoryItem** item);
}
