/* -*- 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"

%{ 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   nsFont;
class   nsIToolkit;
class   nsIRenderingContext;
class   nsIEnumerator;
class   nsIDeviceContext;
struct  nsRect;
struct  nsFont;
class   nsIMenuBar;
class   nsIEventListener;
class   nsIRollupListener;
%}

[ptr] native nsWidgetInitData(nsWidgetInitData);
[ptr] native nsIEnumerator(nsIEnumerator);

[ptr] native nsRect(nsRect);
native nsRectRef(nsRect &);
[ptr] native nsIDeviceContext(nsIDeviceContext);
[ptr] native nsIAppShell(nsIAppShell);
[ptr] native nsIToolkit(nsIToolkit);

[ptr] native nsFont(nsFont);
[ptr] native nsIMouseListener(nsIMouseListener);
[ptr] native nsIEventListener(nsIEventListener);
[ptr] native nsIMenuListener(nsIMenuListener);

[ptr] native nsColorMap(nsColorMap);
[ptr] native nsIMenuBar(nsIMenuBar);

[ptr] native nsGUIEvent(nsGUIEvent);

[ptr] native nsIRenderingContext(nsIRenderingContext);


native nscolor(nscolor);
native nscoord(nscoord);
native nsEventStatus(nsEventStatus);
native PR_CALLBACK(PR_CALLBACKK);
native EVENT_CALLBACK(EVENT_CALLBACK);

typedef long nsBorderStyle;
typedef long nsWindowType;
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++
/**
 * Basic struct for widget initialization data.
 * @see Create member function of nsIWidget
 */

struct nsWidgetInitData {
  nsWidgetInitData()
  : clipChildren(PR_FALSE), clipSiblings(PR_FALSE),
      mWindowType(4),
      mBorderStyle(-1)
  {
  }

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

%}



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


[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;


  /*
   * types of windows
   */
  const long eWindowType_toplevel = 0;
  const long eWindowType_dialog = 1;
  const long eWindowType_popup = 2;
  const long eWindowType_child = 3; 

  
  /*
   * Border styles
   */
  // no border, titlebar, etc.. opposite of all
  const long eBorderStyle_none     = 0;

  // all window decorations
  const long eBorderStyle_all      = 1 << 0;

  // enables the border on the window.  these are only for decoration and are not resize hadles
  const long eBorderStyle_border   = 1 << 1;

  // enables the resize handles for the window.  if this is set, border is implied to also be set
  const long eBorderStyle_resizeh  = 1 << 2;

  // enables the titlebar for the window
  const long eBorderStyle_title    = 1 << 3;

  // enables the window menu button on the title bar.  this being on should force the title bar to display
  const long eBorderStyle_menu     = 1 << 4;

  // enables the minimize button so the user can minimize the window.
  //   turned off for tranient windows since they can not be minimized seperate from their parent
  const long eBorderStyle_minimize = 1 << 5;

  // enables the maxmize button so the user can maximize the window
  const long eBorderStyle_maximize = 1 << 6;

  // show the close button
  const long eBorderStyle_close    = 1 << 7;

  // whatever the OS wants... i.e. don't do anything
  const long eBorderStyle_default  = -1;


  /**
   * 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;


  /**
   * Create and 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     parent or null if it's a top level window
   * @param     aRect     the widget dimension
   * @param     aHandleEventFunction the event handler callback function
   * @param     aContext
   * @param     aAppShell the parent application shell. If nsnull,
   *                      the parent window's application shell will be used.
   * @param     aToolkit
   * @param     aInitData data that is used for widget initialization
   *
   */
  void Create(in nsIWidget aParent,
              [const] in nsRectRef aRect,
              in EVENT_CALLBACK   aHandleEventFunction,
              in nsIDeviceContext aContext,
              in nsIAppShell      aAppShell,
              in nsIToolkit       aToolkit,
              in nsWidgetInitData aInitData);

  /**
   * Create and initialize a widget with a native window parent
   *
   * 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.
   *
   * @param     aParent   native window.
   * @param     aRect     the widget dimension
   * @param     aHandleEventFunction the event handler callback function
   */
  void Create2(in nsNativeWidget  aParent,
               [const] in nsRectRef aRect,
               in EVENT_CALLBACK   aHandleEventFunction,
               in nsIDeviceContext aContext,
               in nsIAppShell      aAppShell,
               in nsIToolkit       aToolkit,
               in nsWidgetInitData aInitData);

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

  /**
   * Close and destroy the internal native window. 
   * This method does not delete the widget.
   */

  void Destroy();

  /**
   * Return the parent Widget of this Widget or nsnull if this is a 
   * top level window
   *
   * @return the parent widget or nsnull if it does not have a parent
   *
   */
  void GetParent(out nsIWidget aParent);

  /**
   * 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
   *
   */
  void GetChildren(out nsIEnumerator aChildren);

  
  /**
   * Show or hide this widget
   *
   * @param aState PR_TRUE to show the Widget, PR_FALSE to hide it
   *
   */
  void Show(in PRBool aState);

  /**
   * Make the window modal 
   *
   * 
   *
   */
  void SetModal();

  /**
   * Returns whether the window is visible
   *
   */
  void IsVisible(out PRBool aState);

  /**
   * 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 or 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);

  /**
   * Give focus to this widget.
   */
  void SetFocus();

  /**
   * 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);

  /**
   * 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);

  /**
   * Gets the width and height of the borders
   * @param aWidth the width of the border
   * @param aHeight the height of the border
   *
   */
  void GetBorderSize(out PRInt32 aWidth, out PRInt32 aHeight);


  /**
   * 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;

  /**
   * 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 InvalidateRect([const] in nsIScriptableRegion aRegion, in PRBool aIsSynchronous);

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

  /**
   * 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);
    
  /**
   * Set the color map for this widget
   *
   * @param aColorMap color map for displaying this widget
   *
   */
  attribute nsColorMap ColorMap;
  //  SetColorMap(in nsColorMap aColorMap);

  /**
   * Scroll this widget.
   *
   * @param aDx amount to scroll along the x-axis
   * @param aDy amount to scroll along the y-axis.
   * @param aClipRect clipping rectangle to limit the scroll to.
   *
   */
  void Scroll(in PRInt32 aDx, in PRInt32 aDy, in nsRect aClipRect);

  /** 
   * Internal methods
   */
  void AddChild(in nsIWidget aChild);
  void RemoveChild(in nsIWidget aChild);
  void GetNativeData(out voidStar aData, in PRUint32 aDataType);
  void FreeNativeData(in voidStar aData, in PRUint32 aDataType);

  /**
   * Set border style
   * Must be called before Create.
   * @param aBorderStyle @see nsBorderStyle
   */
  void SetBorderStyle(in nsBorderStyle aBorderStyle);

  /**
   * Set the widget's title.
   * Must be called after Create.
   *
   * @param aTitle string displayed as the title of the widget
   */
  void SetTitle(in string aTitle);

  /**
   * Set the widget's MenuBar.
   * Must be called after Create.
   *
   * @param aMenuBar the menubar
   */
  void SetMenuBar(in nsIMenuBar aMenuBar);

  /**
   * Set the widget's MenuBar's visibility
   *
   * @param aShow PR_TRUE to show, PR_FALSE to hide
   */
  void ShowMenuBar(in PRBool aShow);

  /**
   * 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);

  /**
   * When adjustments are to made to a whole set of child widgets, call this
   * before resizing/positioning the child windows to minimize repaints. Must
   * be followed by EndResizingChildren() after child windows have been
   * adjusted.
   *
   */

  void BeginResizingChildren();

  /**
   * Call this when finished adjusting child windows. Must be preceded by
   * BeginResizingChildren().
   *
   */
  void EndResizingChildren();


  /**
   * 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);

  /**
   * Dispatches and event to the widget
   *
   */
  void DispatchEvent(in nsGUIEvent event, in nsEventStatus aStatus);


  /**
   * FSets the vertical scrollbar widget
   *
   */
  void SetVerticalScrollbar(in nsIWidget aScrollbar);
   
  /**
   * 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 EnableFileDrop(in PRBool aEnable);
   
  void ConvertToDeviceCoordinates(inout nscoord aX, inout nscoord aY);

  /**
   * 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
	 * @param aCapture PR_TRUE enables capture, PR_FALSE disables capture 
	 *
	 */
  void CaptureRollupEvents(in nsIRollupListener aListener, in PRBool aDoCapture);

};
