/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * The contents of this file are subject to the Mozilla 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/MPL/
 * 
 * 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 the Mozilla browser.
 * 
 * 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): 
 *   Stuart Parmenter <pavlov@netscape.com>
 *   Rod Spears <rods@netscape.com>
 *   Kevin McCluskey <kmcclusk@netscape.com>
 *   Mike Pinkerton <pinkerton@netscape.com>
 *   ... and other people
 */

#include "nsISupports.idl"
#include "nsIScriptableRegion.idl"
#include "nsIRollupListener.idl"
#include "nsIToolkit.idl"
#include "nsIAppShell.idl"
#include "nsIEnumerator.idl"

%{ C++
#include "nsRect.h"
#include "nsColor.h"
#include "nsIMouseListener.h"
#include "nsIMenuListener.h"
#include "nsIImage.h"

#include "prthread.h"
#include "nsGUIEvent.h"

// forward declarations
class   nsIAppShell;
class   nsIToolkit;
class   nsIRenderingContext;
class   nsIEnumerator;
class   nsIDeviceContext;
struct  nsRect;
struct  nsFont;
class   nsIEventListener;
class   nsIRollupListener;
%}

[ptr] native nsGUIEvent(nsGUIEvent);
[ptr] native nsIMouseListener(nsIMouseListener);
[ptr] native nsIEventListener(nsIEventListener);
[ptr] native nsIMenuListener(nsIMenuListener);
[ptr] native nsIRegion(nsIRegion);
[ptr] native nsRect(nsRect);
[ref] native nsRectRef(nsRect);
[ptr] native nsFont(nsFont);
[ptr] native nsColorMap(nsColorMap);

[ptr] native nsIRenderingContext(nsIRenderingContext);
[ptr] native nsIDeviceContext(nsIDeviceContext);

native nscolor(nscolor);
native nscoord(nscoord);
native nsEventStatus(nsEventStatus);
[ref] native nsEventStatusRef(nsEventStatus);
native PR_CALLBACK(PR_CALLBACKK);
native EVENT_CALLBACK(EVENT_CALLBACK);

typedef long nsCursor;


/*
 * Hide the native window systems real window type so as to avoid
 * including native window system types and api's. This is necessary
 * to ensure cross-platform code.
 */
typedef voidStar nsNativeWidget;


%{ C++
typedef nsEventStatus (*PR_CALLBACK EVENT_CALLBACK)(nsGUIEvent *event);


/**
 * Basic struct for widget initialization data.
 * @see Create member function of nsIWidget
 */

  struct nsWidgetInitData {
    nsWidgetInitData()
      : clipChildren(PR_FALSE), clipSiblings(PR_FALSE)
      //      mWindowType(eWindowType_child),
      //      mBorderStyle(eBorderStyle_default)
    {
    }

    // when painting exclude area occupied by child windows and sibling windows
    PRPackedBool  clipChildren, clipSiblings;
    //    nsWindowType mWindowType;
    //    nsBorderStyle mBorderStyle;
  };
%}


[uuid(18032AD5-B265-11d1-AA2A-000000000000)]
interface nsIWidget : nsISupports
{

  /*
   * Flags for GetNativeData()
   */
  const short NS_NATIVE_WINDOW            = 0;
  const short NS_NATIVE_GRAPHIC           = 1;
  const short NS_NATIVE_COLORMAP          = 2;
  const short NS_NATIVE_WIDGET            = 3;
  const short NS_NATIVE_DISPLAY           = 4;
  const short NS_NATIVE_REGION            = 5;
  const short NS_NATIVE_OFFSETX           = 6;
  const short NS_NATIVE_OFFSETY           = 7;
  const short NS_NATIVE_PLUGIN_PORT       = 8;
  const short NS_NATIVE_SCREEN            = 9;


  /**
   * Cursor types.
   */

  //(normal cursor,       usually rendered as an arrow)
  const long eCursor_standard            = 0;
  //(system is busy,      usually rendered as a hourglass or watch)
  const long eCursor_wait                = 1;
  //(Selecting something, usually rendered as an IBeam)
  const long eCursor_select              = 2;
  //(can hyper-link,      usually rendered as a human hand)
  const long eCursor_hyperlink           = 3;
  //(west/east sizing,    usually rendered as ->||<-)
  const long eCursor_sizeWE              = 4;
  //(north/south sizing,  usually rendered as sizeWE rotated 90 degrees)
  const long eCursor_sizeNS              = 5;
  const long eCursor_arrow_north         = 6;
  const long eCursor_arrow_north_plus    = 7;
  const long eCursor_arrow_south         = 8;
  const long eCursor_arrow_south_plus    = 9;
  const long eCursor_arrow_west          = 10;
  const long eCursor_arrow_west_plus     = 11;
  const long eCursor_arrow_east          = 12;
  const long eCursor_arrow_east_plus     = 13;
  const long eCursor_crosshair           = 14;
  //Don't know what 'move' cursor should be.  See CSS2.
  const long eCursor_move                = 15;
  const long eCursor_help                = 16;


  /**
   * initialize a widget
   *
   * The widget represents a window that can be drawn into. It also is the 
   * base class for user-interface widgets such as buttons and text boxes.
   *
   * All the arguments can be NULL in which case a top level window
   * with size 0 is created. The event callback function has to be
   * provided only if the caller wants to deal with the events this
   * widget receives.  The event callback is basically a preprocess
   * hook called synchronously. The return value determines whether
   * the event goes to the default window procedure or it is hidden
   * to the os. The assumption is that if the event handler returns
   * false the widget does not see the event. The widget should not 
   * automatically clear the window to the background color. The 
   * calling code must handle paint messages and clear the background 
   * itself. 
   *
   * @param     aAppShell      the parent application shell. If nsnull,
   *                           the parent window's application shell will be used.
   * @param     aToolkit       toolkit
   * @param     aContext       device context
   * @param     aEventFunction the event handler callback function
   *
   */
  void initWidget(in nsIAppShell      aAppShell,
                  in nsIToolkit       aToolkit,
                  in nsIDeviceContext aContext,
                  in EVENT_CALLBACK   aEventFunction);
              
  /**
   * Get some kind of native data
   */
  voidStar getNativeData(in PRUint32 aDataType);

  /**
   * Move this widget.
   *
   * @param aX the new x position expressed in the parent's coordinate system
   * @param aY the new y position expressed in the parent's coordinate system
   *
   **/
  void move(in PRInt32 aX, in PRInt32 aY);

  /**
   * Resize this widget. 
   *
   * @param aWidth  the new width expressed in the parent's coordinate system
   * @param aHeight the new height expressed in the parent's coordinate system
   * @param aRepaint whether the widget should be repainted
   *
   */
  void resize(in PRInt32 aWidth,
              in PRInt32 aHeight,
              in PRBool  aRepaint);

  /**
   * Move and resize this widget.
   *
   * @param aX       the new x position expressed in the parent's coordinate system
   * @param aY       the new y position expressed in the parent's coordinate system
   * @param aWidth   the new width expressed in the parent's coordinate system
   * @param aHeight  the new height expressed in the parent's coordinate system
   * @param aRepaint whether the widget should be repainted if the size changes
   *
   */
  void moveResize(in PRInt32 aX,
                  in PRInt32 aY,
                  in PRInt32 aWidth,
                  in PRInt32 aHeight,
                  in PRBool  aRepaint);

  /**
   * Enable or disable this Widget
   *
   * @param aState PR_TRUE to enable the Widget, PR_FALSE to disable it.
   *
   */
  void enable(in PRBool aState);


  // XXX GO AWAY

  /**
   * Get this widget's outside dimensions relative to it's parent widget
   *
   * @param aRect on return it holds the  x. y, width and height of this widget
   *
   */
  //  readonly attribute nsRect Bounds;

  // this is really out..
  void getBounds(in nsRectRef aRect);


  // XXX keep this, but make it ints
  /**
   * Get this widget's client area dimensions, if the window has a 3D border appearance
   * this returns the area inside the border, The x and y are always zero
   *
   * @param aRect on return it holds the  x. y, width and height of the client area of this widget
   *
   */
  //  readonly attribute nsRect ClientBounds;

  // this is really out..
  void getClientBounds(in nsRectRef aRect);



  // Is this still used?
  /**
   * Returns the preferred width and height for the widget
   *
   */
  void getPreferredSize(out PRInt32 aWidth,
                        out PRInt32 aHeight);
  
  /**
   * Set the preferred width and height for the widget
   *
   */
  void setPreferredSize(in PRInt32 aWidth, in PRInt32 aHeight);




  /**
   * Invalidate the widget and repaint it.
   *
   * @param aIsSynchronouse PR_TRUE then repaint synchronously. If PR_FALSE repaint later.
   * @see #Update()
   */
  void invalidate(in PRBool aIsSynchronous);

  /**
   * Invalidate a specified rect for a widget and repaints it.
   *
   * @param aIsSynchronouse PR_TRUE then repaint synchronously. If PR_FALSE repaint later.
   * @see #Update()
   */
  void invalidateRect([const] in nsRect aRect, in PRBool aIsSynchronous);

  /**
   * Invalidate a specified rect for a widget and repaints it.
   *
   * @param aIsSynchronouse PR_TRUE then repaint synchronously. If PR_FALSE repaint later.
   * @see #Update()
   */
  //  void InvalidateRegion([const] in nsIScriptableRegion aRegion, in PRBool aIsSynchronous);
  void invalidateRegion([const] in nsIRegion aRegion, in PRBool aIsSynchronous);

  /**
   * Force a synchronous repaint of the window if there are dirty rects.
   *
   * @see Invalidate()
   */
  void update();


  /**
   * Convert from this widget coordinates to screen coordinates.
   *
   * @param  aOldRect  widget coordinates stored in the x,y members
   * @param  aNewRect  screen coordinates stored in the x,y members
   */
  void widgetToScreen([const] in nsRect aOldRect, out nsRect aNewRect);

  /**
   * Convert from screen coordinates to this widget's coordinates.
   *
   * @param  aOldRect  screen coordinates stored in the x,y members
   * @param  aNewRect  widget's coordinates stored in the x,y members
   */
  void screenToWidget([const] in nsRect aOldRect, out nsRect aNewRect);

  // is this used?
  void convertToDeviceCoordinates(inout nscoord aX, inout nscoord aY);


  // can this go away?
  /**
   * For printing and lightweight widgets
   *
   */
  void paint(in nsIRenderingContext aRenderingContext,
             [const] in nsRect aDirtyRect);
  


  /**
   * Enables the dropping of files to a widget (XXX this is temporary)
   *
   */
  void enableDragDrop(in PRBool aEnable);



  /**
   * Enables/Disables system mouse capture.
   * @param aCapture PR_TRUE enables mouse capture, PR_FALSE disables mouse capture 
   *
   */
  void captureMouse(in PRBool aCapture);

  /**
   * Enables/Disables system capture of any and all events that would cause a
   * dropdown to be rolled up, This method ignores the aConsumeRollupEvent 
   * parameter when aDoCapture is FALSE
   * @param aCapture PR_TRUE enables capture, PR_FALSE disables capture 
   * @param aConsumeRollupEvent PR_TRUE consumes the rollup event, PR_FALSE dispatches rollup event
   *
   */
  void captureRollupEvents(in nsIRollupListener aListener, in PRBool aDoCapture, in PRBool aConsumeRollupEvent);



  /**
   * Adds a mouse listener to this widget
   * Any existing mouse listener is replaced
   *
   * @param aListener mouse listener to add to this widget.
   */
  void addMouseListener(in nsIMouseListener aListener);

  /**
   * Adds an event listener to this widget
   * Any existing event listener is replaced
   *
   * @param aListener event listener to add to this widget.
   */
  void addEventListener(in nsIEventListener aListener);

  /**
   * Adds a menu listener to this widget
   * Any existing menu listener is replaced
   *
   * @param aListener menu listener to add to this widget.
   */
  void addMenuListener(in nsIMenuListener aListener);


  // is this an internal method?
  /**
   * Dispatches and event to the widget
   *
   */
  void dispatchEvent(in nsGUIEvent event, in nsEventStatusRef aStatus);


  /** 
   * Internal methods
   */
  void addChild(in nsIWidget aChild);
  void removeChild(in nsIWidget aChild);

  /* ATTRIBUTES */


  /**
   * Device Context used to do printing... probably shouldn't be here
   */
  readonly attribute nsIDeviceContext deviceContext;

  /* attributes */

  /**
   * Get the AppShell
   */
  readonly attribute nsIAppShell appShell;

  /**
   * Get the nsIToolkit
   */
  readonly attribute nsIToolkit toolkit;

  /**
   * callback for the event
   */
  [noscript] readonly attribute EVENT_CALLBACK eventFunction;


  /* things that MUST be set AFTER the widget is created */

  /**
   * Get and Set the widget's z-index.
   */
  attribute PRInt32 zIndex;

  /**
   * Set/Get the foreground color for this widget
   *
   * @param aColor the new foreground color
   *
   */
  attribute nscolor foregroundColor;

  /**
   * Set/Get the background color for this widget
   *
   * @param aColor the new background color
   *
   */
  attribute nscolor backgroundColor;

  /**
   * Set/Get the font for this widget 
   *
   * @param aFont font to display. See nsFont for allowable fonts
   */
  attribute nsFont font;

  /**
   * Set/Get the cursor for this widget
   *
   * @param aCursor the new cursor for this widget
   */

  attribute nsCursor cursor;

  /**
   * Set the color map for this widget
   *
   * @param aColorMap color map for displaying this widget
   *
   */
  attribute nsColorMap colorMap;

  /**
   * Accessor functions to get and set the client data associated with the
   * widget.
   */
  attribute voidStar clientData;

  /**
   * Return an nsEnumerator over the children of this widget.
   *
   * @return an enumerator over the list of children or nsnull if it does not
   * have any children
   *
   */
  readonly attribute nsIEnumerator children;

%{ C++
  /* backwards compat stuff */
  NS_IMETHOD Show(PRBool aShow) = 0;

  NS_IMETHOD IsVisible(PRBool & aState) = 0;
  NS_IMETHOD Resize(PRInt32 aX,
                    PRInt32 aY,
                    PRInt32 aWidth,
                    PRInt32 aHeight,
                    PRBool  aRepaint) = 0;

  virtual nscolor GetForegroundColor(void) = 0;
  virtual nscolor GetBackgroundColor(void) = 0;

  NS_IMETHOD SetFont(const nsFont &aFont) = 0;
  virtual nsIFontMetrics* GetFont(void) = 0;

  NS_IMETHOD Invalidate(const nsRect & aRect, PRBool aIsSynchronous) = 0;
  NS_IMETHOD SetTitle(const nsString& aTitle) = 0;
  NS_IMETHOD GetPreferredSize(PRInt32& aWidth, PRInt32& aHeight) = 0;

  virtual nsIWidget* GetParent(void) = 0;

  virtual nsIEnumerator*  GetChildren(void) = 0;

  virtual void* GetNativeData(PRUint32 aDataType) = 0;
  virtual void FreeNativeData(void * data, PRUint32 aDataType) = 0;
  virtual nsIRenderingContext* GetRenderingContext() = 0;
  virtual nsIDeviceContext* GetDeviceContext() = 0;
  virtual nsIAppShell *GetAppShell() = 0;
  virtual nsIToolkit* GetToolkit() = 0;    

  /* the big ugly ones */
  NS_IMETHOD Create(nsIWidget        *aParent,
                    const nsRect     &aRect,
                    EVENT_CALLBACK   aHandleEventFunction,
                    nsIDeviceContext *aContext,
                    nsIAppShell      *aAppShell = nsnull,
                    nsIToolkit       *aToolkit = nsnull,
                    nsWidgetInitData *aInitData = nsnull) = 0;
  NS_IMETHOD Create(nsNativeWidget aParent,
                    const nsRect     &aRect,
                    EVENT_CALLBACK   aHandleEventFunction,
                    nsIDeviceContext *aContext,
                    nsIAppShell      *aAppShell = nsnull,
                    nsIToolkit       *aToolkit = nsnull,
                    nsWidgetInitData *aInitData = nsnull) = 0;

%}

};

