/*
 * Copyright (C) 2006, 2007 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. 
 */

cpp_quote("/*")
cpp_quote(" * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.")
cpp_quote(" *")
cpp_quote(" * Redistribution and use in source and binary forms, with or without")
cpp_quote(" * modification, are permitted provided that the following conditions")
cpp_quote(" * are met:")
cpp_quote(" * 1. Redistributions of source code must retain the above copyright")
cpp_quote(" *    notice, this list of conditions and the following disclaimer.")
cpp_quote(" * 2. Redistributions in binary form must reproduce the above copyright")
cpp_quote(" *    notice, this list of conditions and the following disclaimer in the")
cpp_quote(" *    documentation and/or other materials provided with the distribution.")
cpp_quote(" *")
cpp_quote(" * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY")
cpp_quote(" * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE")
cpp_quote(" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR")
cpp_quote(" * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR")
cpp_quote(" * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,")
cpp_quote(" * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,")
cpp_quote(" * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR")
cpp_quote(" * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY")
cpp_quote(" * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT")
cpp_quote(" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE")
cpp_quote(" * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ")
cpp_quote(" */")

import "oaidl.idl";
import "ocidl.idl";
import "IWebMutableURLRequest.idl";
import "IWebURLResponse.idl";
import "IWebResource.idl";
import "IWebArchive.idl";
import "IWebDocument.idl";
import "IWebFrame.idl";


interface IWebMutableURLRequest;
interface IWebURLConnection;
interface IWebURLRequest;
interface IWebURLResponse;
interface IWebArchive;
interface IWebDataSourcePrivate;
interface IWebFrame;
interface IWebResource;

interface IWebDocumentRepresentation;

/*!
    @class WebDataSource
    @discussion A WebDataSource represents the data associated with a web page.
    A datasource has a WebDocumentRepresentation which holds an appropriate
    representation of the data.  WebDataSources manage a hierarchy of WebFrames.
    WebDataSources are typically related to a view by their containing WebFrame.
*/
[
    object,
    oleautomation,
    uuid(5221A975-AE09-4a7b-A4DF-E3B1B5F38A21),
    pointer_default(unique)
]
interface IWebDataSource : IUnknown
{
    /*!
        @method initWithRequest:
        @abstract The designated initializer for WebDataSource.
        @param request The request to use in creating a datasource.
        @result Returns an initialized WebDataSource.
        - (id)initWithRequest:(NSURLRequest *)request;
    */
    HRESULT initWithRequest([in] IWebURLRequest* request);

    /*!
        @method data
        @discussion The data will be incomplete until the datasource has completely loaded.  
        @result Returns the raw data associated with the datasource.  Returns nil
        if the datasource hasn't loaded any data.
        - (NSData *)data;
    */
    HRESULT data([out, retval] IStream** stream);

    /*!
        @method representation
        @discussion A representation holds a type specific representation
        of the datasource's data.  The representation class is determined by mapping
        a MIME type to a class.  The representation is created once the MIME type
        of the datasource content has been determined.
        @result Returns the representation associated with this datasource.
        Returns nil if the datasource hasn't created it's representation.
        - (id <WebDocumentRepresentation>)representation;
    */
    HRESULT representation([out, retval] IWebDocumentRepresentation** rep);

    /*!
        @method webFrame
        @result Return the frame that represents this data source.
        - (WebFrame *)webFrame;
    */
    HRESULT webFrame([out, retval] IWebFrame** frame);

    /*!
        @method initialRequest
        @result Returns a reference to the original request that created the
        datasource.  This request will be unmodified by WebKit. 
        - (NSURLRequest *)initialRequest;
    */
    HRESULT initialRequest([out, retval] IWebURLRequest** request);

    /*!
        @method request
        @result Returns the request that was used to create this datasource.
        - (NSMutableURLRequest *)request;
    */
    HRESULT request([out, retval] IWebMutableURLRequest** request);

    /*!
        @method response
        @result returns the WebResourceResponse for the data source.
        - (NSURLResponse *)response;
    */
    HRESULT response([out, retval] IWebURLResponse** response);

    /*!
        @method textEncodingName
        @result Returns either the override encoding, as set on the WebView for this 
        dataSource or the encoding from the response.
        - (NSString *)textEncodingName;
    */
    HRESULT textEncodingName([out, retval] BSTR* name);

    /*!
        @method isLoading
        @discussion Returns YES if there are any pending loads.
        - (BOOL)isLoading;
    */
    HRESULT isLoading([out, retval] BOOL* loading);

    /*!
        @method pageTitle
        @result Returns nil or the page title.
        - (NSString *)pageTitle;
    */
    HRESULT pageTitle([out, retval] BSTR* title);

    /*!
        @method unreachableURL
        @discussion This will be non-nil only for dataSources created by calls to the 
        WebFrame method loadAlternateHTMLString:baseURL:forUnreachableURL:.
        @result returns the unreachableURL for which this dataSource is showing alternate content, or nil
        - (NSURL *)unreachableURL;
    */
    HRESULT unreachableURL([out, retval] BSTR* url);

    /*!
        @method webArchive
        @result A WebArchive representing the data source, its subresources and child frames.
        @description This method constructs a WebArchive using the original downloaded data.
        In the case of HTML, if the current state of the document is preferred, webArchive should be
        called on the DOM document instead.
        - (WebArchive *)webArchive;
    */
    HRESULT webArchive([out, retval] IWebArchive** archive);

    /*!
        @method mainResource
        @result A WebResource representing the data source.
        @description This method constructs a WebResource using the original downloaded data.
        This method can be used to construct a WebArchive in case the archive returned by
        WebDataSource's webArchive isn't sufficient.
        - (WebResource *)mainResource;
    */
    HRESULT mainResource([out, retval] IWebResource** resource);

    /*!
        @method subresources
        @abstract Returns all the subresources associated with the data source.
        @description The returned array only contains subresources that have fully downloaded.
        - (NSArray *)subresources;
    */
    HRESULT subresources([out, retval] IEnumVARIANT** enumResources);

    /*!
        method subresourceForURL:
        @abstract Returns a subresource for a given URL.
        @param URL The URL of the subresource.
        @description Returns non-nil if the data source has fully downloaded a subresource with the given URL.
        - (WebResource *)subresourceForURL:(NSURL *)URL;
    */
    HRESULT subresourceForURL([in] BSTR url, [out, retval] IWebResource** resource);

    /*!
        @method addSubresource:
        @abstract Adds a subresource to the data source.
        @param subresource The subresource to be added.
        @description addSubresource: adds a subresource to the data source's list of subresources.
        Later, if something causes the data source to load the URL of the subresource, the data source
        will load the data from the subresource instead of from the network. For example, if one wants to add
        an image that is already downloaded to a web page, addSubresource: can be called so that the data source
        uses the downloaded image rather than accessing the network. NOTE: If the data source already has a
        subresource with the same URL, addSubresource: will replace it.
        - (void)addSubresource:(WebResource *)subresource;
    */
    HRESULT addSubresource([in] IWebResource* subresource);
}

[
    object,
    oleautomation,
    uuid(4B80B7D4-98D7-4a80-AF46-2AF84B2F2E8F),
    pointer_default(unique)
]
interface IWebDataSourcePrivate : IUnknown
{
    HRESULT overrideEncoding([out, retval] BSTR* encoding);
    HRESULT setOverrideEncoding([in] BSTR encoding);
    HRESULT mainDocumentError([out, retval] IWebError** error);
}
