/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1999 Netscape Communications Corporation. All
 * Rights Reserved.
 *
 * Contributor(s): 
 */

/* nsIURIContentListener is an interface used by classes which
   want to know (and have a chance to handle) a particular content type.
   Typical useage scenarios will include running applications which register
   a nsIURIContentListener for each of its content windows with the uri dispatcher
   service. 
*/ 

#include "nsISupports.idl"
#include "nsIURILoader.idl"

interface nsIProtocolHandler;
interface nsIChannel;
interface nsIStreamListener;
interface nsIURI;

[scriptable, uuid(94928AB3-8B63-11d3-989D-001083010E9B)]
interface nsIURIContentListener : nsISupports
{
  /*
	  Gives the content listener first crack at stopping a load before it
	  happens.
	  
	  aURI --> the uri we are going to try and open.
	  aWindowTarget --> the window target passed to the uriloader to open.
	  aAbortOpen --> specifies that the open should be aborted.  
  */
  void onStartURIOpen(in nsIURI aURI, in string aWindowTarget, 
	 out boolean aAbortOpen);

  /* Give the content listener first crack at forcing us to use
     a specific content handler. Content listener's do not need to 
     support this method if they want the uri dispatcher to find the
     default protocol handler from the registry. 

	 aURI --> the uri we need a protocol handler for
	 aProtocolHandler --> the protocol handler you want the uri loader
	 to use. You can pass back null if you want the uri loader to look
	 up an appropriate protocol handler
   */
   void getProtocolHandler(in nsIURI aURI, out nsIProtocolHandler aProtocolHandler);

  /* doContent --> When the content listener is expected to process the
     content, the uri loader calls doContent. doContent needs to return a 
	 nsIStreamListener which the uri loader will push the content into. 

     aContentType --> the content type we need to handle
     aCommand --> verb for the action (this comes from layout???)
     aWindowTarget --> name of the target window if any
     aStreamListener --> the content viewer the content should be displayed in
                        You should return null for this out parameter if you do
                        not want to handle this content type.
	 aAbortProcess --> If you want to handle the content yourself and you don't
					   want the dispatcher to do anything else, return TRUE for
					   this parameter. 
  */

   void doContent(in string aContentType, 
			      in nsURILoadCommand aCommand, 
                  in string aWindowTarget, 
				  in nsIChannel aOpenedChannel,
                  out nsIStreamListener aContentHandler,
				  out boolean aAbortProcess);

   /* When given a uri to dispatch, if the load type is a user click,
      then the uri loader tries to find a preferred content handler for
	  this content type. The thought is that many content listeners may
	  be able to handle the same content type if they have to. i.e. the mail
	  content window can handle text/html just like a browser window content
	  listener. However, if the user clicks on a link with text/html content,
	  we'd like the browser window to handle that content and not the mail window
	  where the user may have clicked the link. That's why we have isPreferred.
	  
	  aContentType --> the content type to handle
	  aCommand --> verb for the action
	  aWindowTarget --> name of the target window (if any)
      aDesiredContentType --> yes, we can accept aContentType but we would
		like it converted to aDesiredContentType. This argument can be null if
		you want the content directly as aContentType
	  boolean --> return true if you are a preferred content handler for aContentType
				  and false otherwise.
   */
   boolean isPreferred(in string aContentType, 
					   in nsURILoadCommand aCommand,
					   in string aWindowTarget,
					   out string aDesiredContentType);

   /* When given a uri to dispatch, if the load type is anything but user click, 
      the uri loader will call canHandleContent to see if the content listener
	  can handle the content. The arguments are the same as isPreferred.

	  Note: I really envision canHandleContent as a method implemented by the docshell
	  as the implementation is generic to all doc shells. The IsPreferred decision
	  is a decision made by a top level application content listener that sits at the
	  top of the docshell hiearchy.
   */
   boolean canHandleContent(in string aContentType, 
							in nsURILoadCommand aCommand, 
							in string aWindowTarget, 
							out string aDesiredContentType);

  /* Get/Set loadCookie are methods the uri loader calls on the nsIURIContentListener
     in order to store / associate a load context with this particular content listener...
   */
  attribute nsISupports loadCookie;
  /* if you are part of a chain of content listeners (i.e. if you are a docshell!,
     return your parent content listener 
  */
  attribute nsIURIContentListener parentContentListener;
};
