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

interface IWebError;
interface IWebURLResponse;
interface IWebURLRequest;
interface IWebView;
interface IWebFrame;
interface IWebPolicyPrivate;

/*!
    @enum WebNavigationType
    @abstract The type of action that triggered a possible navigation.
    @constant WebNavigationTypeLinkClicked A link with an href was clicked.
    @constant WebNavigationTypeFormSubmitted A form was submitted.
    @constant WebNavigationTypeBackForward The user chose back or forward.
    @constant WebNavigationTypeReload The User hit the reload button.
    @constant WebNavigationTypeFormResubmitted A form was resubmitted (by virtue of doing back, forward or reload).
    @constant WebNavigationTypeOther Navigation is taking place for some other reason.
*/

typedef enum WebNavigationType {
    WebNavigationTypeLinkClicked,
    WebNavigationTypeFormSubmitted,
    WebNavigationTypeBackForward,
    WebNavigationTypeReload,
    WebNavigationTypeFormResubmitted,
    WebNavigationTypeOther
} WebNavigationType;

cpp_quote("#define WebActionButtonKey TEXT(\"WebActionButtonKey\")")
cpp_quote("#define WebActionElementKey TEXT(\"WebActionElementKey\")")
cpp_quote("#define WebActionFormKey TEXT(\"WebActionFormKey\")")
cpp_quote("#define WebActionModifierFlagsKey TEXT(\"WebActionModifierFlagsKey\")")
cpp_quote("#define WebActionNavigationTypeKey TEXT(\"WebActionNavigationTypeKey\")")
cpp_quote("#define WebActionOriginalURLKey TEXT(\"WebActionOriginalURLKey\")")

/*!
    @protocol WebPolicyDecisionListener
    @discussion This protocol is used to call back with the results of a
    policy decision. This provides the ability to make these decisions
    asyncrhonously, which means the decision can be made by prompting
    with a sheet, for example.
    @protocol WebPolicyDecisionListener <NSObject>
*/
[
    object,
    oleautomation,
    uuid(DFCDE523-FD96-4f95-958B-151540FE122A),
    pointer_default(unique)
]
interface IWebPolicyDecisionListener : IUnknown
{
    /*!
        @method use
        @abstract Use the resource
        @discussion If there remain more policy decisions to be made, then
        the next policy delegate method gets to decide. This will be
        either the next navigation policy delegate if there is a redirect,
        or the content policy delegate. If there are no more policy
        decisions to be made, the resource will be displayed inline if
        possible. If there is no view available to display the resource
        inline, then unableToImplementPolicyWithError:frame: will be
        called with an appropriate error. 

        <p>If a new window is going to be created for this navigation as a
        result of frame targetting, then it will be created once you call
        this method.
        - (void)use;
    */
    HRESULT use();

    /*!
        @method download
        @abstract Download the resource instead of displaying it.
        @discussion This method is more than just a convenience because it
        allows an in-progress navigation to be converted to a download
        based on content type, without having to stop and restart the
        load.
        - (void)download;
    */
    HRESULT download();

    /*!
        @method ignore
        @abstract Do nothing (but the client may choose to handle the request itself)
        @discussion A policy of ignore prevents WebKit from doing anything
        further with the load, however, the client is still free to handle
        the request in some other way, such as opening a new window,
        opening a new window behind the current one, opening the URL in an
        external app, revealing the location in Finder if a file URL, etc.
        - (void)ignore;
    */
    HRESULT ignore();
}

/*!
    @category WebPolicyDelegate
    @discussion While loading a URL, WebKit asks the WebPolicyDelegate for
    policies that determine the action of what to do with the URL or the data that
    the URL represents. Typically, the policy handler methods are called in this order:

    decidePolicyForNewWindowAction:request:newFrameName:decisionListener: (at most once)<BR>
    decidePolicyForNavigationAction:request:frame:decisionListener: (zero or more times)<BR>
    decidePolicyForMIMEType:request:frame: (zero or more times)<BR>

    New window policy is always checked. Navigation policy is checked
    for the initial load and every redirect unless blocked by an
    earlier policy. Content policy is checked once the content type is
    known, unless an earlier policy prevented it.

    In rare cases, content policy might be checked more than
    once. This occurs when loading a "multipart/x-mixed-replace"
    document, also known as "server push". In this case, multiple
    documents come in one navigation, with each replacing the last. In
    this case, conent policy will be checked for each one.
    @interface NSObject (WebPolicyDelegate)
*/
[
    object,
    oleautomation,
    uuid(9B0BAE6C-A496-4000-9E22-2E89F0747401),
    pointer_default(unique)
]
interface IWebPolicyDelegate : IUnknown
{
    /*!
       @method webView:decidePolicyForNavigationAction:request:frame:decisionListener:
       @abstract This method is called to decide what to do with a proposed navigation.
       @param actionInformation Dictionary that describes the action that triggered this navigation.
       @param request The request for the proposed navigation
       @param frame The WebFrame in which the navigation is happening
       @param listener The object to call when the decision is made
       @discussion This method will be called before loading starts, and
       on every redirect.
        - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
                                                                   request:(NSURLRequest *)request
                                                                     frame:(WebFrame *)frame
                                                          decisionListener:(id<WebPolicyDecisionListener>)listener;
    */
    HRESULT decidePolicyForNavigationAction([in] IWebView* webView, [in] IPropertyBag* actionInformation, [in] IWebURLRequest* request, [in] IWebFrame* frame, [in] IWebPolicyDecisionListener* listener);

    /*!
        @method webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:
        @discussion This method is called to decide what to do with an targetted nagivation that would open a new window.
        @param actionInformation Dictionary that describes the action that triggered this navigation.
        @param request The request for the proposed navigation
        @param frame The frame in which the navigation is taking place
        @param listener The object to call when the decision is made
        @discussion This method is provided so that modified clicks on a targetted link which
        opens a new frame can prevent the new window from being opened if they decide to
        do something else, like download or present the new frame in a specialized way. 

        <p>If this method picks a policy of Use, the new window will be
        opened, and decidePolicyForNavigationAction:request:frame:decisionListner:
        will be called with a WebNavigationType of WebNavigationTypeOther
        in its action. This is to avoid possible confusion about the modifiers.
        - (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation
                                                                  request:(NSURLRequest *)request
                                                             newFrameName:(NSString *)frameName
                                                         decisionListener:(id<WebPolicyDecisionListener>)listener;
    */
    HRESULT decidePolicyForNewWindowAction([in] IWebView* webView, [in] IPropertyBag* actionInformation, [in] IWebURLRequest* request, [in] BSTR frameName, [in] IWebPolicyDecisionListener* listener);

    /*!
        @method webView:decidePolicyForMIMEType:request:frame:
        @discussion Returns the policy for content which has been partially loaded.
        Sent after webView:didStartProvisionalLoadForFrame: is sent on the WebFrameLoadDelegate.
        @param type MIME type for the resource.
        @param request A NSURLRequest for the partially loaded content.
        @param frame The frame which is loading the URL.
        @param listener The object to call when the decision is made
        - (void)webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type
                                                           request:(NSURLRequest *)request
                                                             frame:(WebFrame *)frame
                                                  decisionListener:(id<IWebPolicyDecisionListener>)listener;
    */
    HRESULT decidePolicyForMIMEType([in] IWebView* webView, [in] BSTR type, [in] IWebURLRequest* request, [in] IWebFrame* frame, [in] IWebPolicyDecisionListener* listener);

    /*!
        @method webView:unableToImplementPolicy:error:forURL:inFrame:
        @discussion Called when a WebPolicy could not be implemented. It is up to the client to display appropriate feedback.
        @param policy The policy that could not be implemented.
        @param error The error that caused the policy to not be implemented.
        @param URL The URL of the resource for which a particular action was requested but failed.
        @param frame The frame in which the policy could not be implemented.
        - (void)webView:(WebView *)webView unableToImplementPolicyWithError:(NSError *)error frame:(WebFrame *)frame;
    */
    HRESULT unableToImplementPolicyWithError([in] IWebView* webView, [in] IWebError* error, [in] IWebFrame* frame);
}
