// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>chrome.app.window</code> API to create windows. Windows
// have an optional frame with title bar and size controls. They are not
// associated with any Chrome browser windows.
namespace app.window {
  dictionary Bounds {
    long? left;
    long? top;
    long? width;
    long? height;
  };

  // State of a window: normal, fullscreen, maximized, minimized.
  enum State { normal, fullscreen, maximized, minimized };

  // 'shell' is the default window type. 'panel' is managed by the OS
  // (Currently experimental, Ash only).
  [nodoc] enum WindowType { shell, panel };

  dictionary CreateWindowOptions {
    // Id to identify the window. This will be used to remember the size
    // and position of the window and restore that geometry when a window
    // with the same id is later opened.
    DOMString? id;

    // Default width of the window. (Deprecated; regular bounds act like this
    // now.)
    [nodoc] long? defaultWidth;

    // Default height of the window. (Deprecated; regular bounds act like this
    // now.)
    [nodoc] long? defaultHeight;

    // Default X coordinate of the window. (Deprecated; regular bounds act like
    // this now.)
    [nodoc] long? defaultLeft;

    // Default Y coordinate of the window. (Deprecated; regular bounds act like
    // this now.)
    [nodoc] long? defaultTop;

    // Width of the window. (Deprecated; use 'bounds'.)
    [nodoc] long? width;

    // Height of the window. (Deprecated; use 'bounds'.)
    [nodoc] long? height;

    // X coordinate of the window. (Deprecated; use 'bounds'.)
    [nodoc] long? left;

    // Y coordinate of the window. (Deprecated; use 'bounds'.)
    [nodoc] long? top;

    // Minimum width of the window.
    long? minWidth;

    // Minimum height of the window.
    long? minHeight;

    // Maximum width of the window.
    long? maxWidth;

    // Maximum height of the window.
    long? maxHeight;

    // Type of window to create.
    [nodoc] WindowType? type;

    // Frame type: <code>none</code> or <code>chrome</code> (defaults to
    // <code>chrome</code>). For <code>none</code>, the
    // <code>-webkit-app-region</code> CSS property can be used to apply
    // draggability to the app's window. <code>-webkit-app-region: drag</code>
    // can be used to mark regions draggable. <code>no-drag</code> can be used
    // to disable this style on nested elements.
    DOMString? frame;

    // Size and position of the content in the window (excluding the titlebar).
    // If an id is also specified and a window with a matching id has been shown
    // before, the remembered bounds of the window will be used instead.
    Bounds? bounds;

    // Enable window background transparency.
    // Only supported in ash. Requires experimental API permission.
    boolean? transparentBackground;

    // The initial state of the window, allowing it to be created already
    // fullscreen, maximized, or minimized. Defaults to 'normal'.
    State? state;

    // If true, the window will be created in a hidden state. Call show() on
    // the window to show it once it has been created. Defaults to false.
    boolean? hidden;

    // If true, the window will be resizable by the user. Defaults to true.
    boolean? resizable;

    // By default if you specify an id for the window, the window will only be
    // created if another window with the same id doesn't already exist. If a
    // window with the same id already exists that window is activated instead.
    // If you do want to create multiple windows with the same id, you can
    // set this property to false.
    boolean? singleton;

    // If true, the window will stay above most other windows. If there are
    // multiple windows of this kind, the currently focused window will be in
    // the foreground. Defaults to false. Call <code>setAlwaysOnTop()</code> on
    // the window to change this property after creation.
    boolean? alwaysOnTop;
  };

  // Called in the creating window (parent) before the load event is called in
  // the created window (child). The parent can set fields or functions on the
  // child usable from onload. E.g. background.js:<br>
  // <code>function(createdWindow) { createdWindow.contentWindow.foo =
  // function () { }; };</code>
  // <br>window.js:<br>
  // <code>window.onload = function () { foo(); }</code>
  callback CreateWindowCallback =
      void ([instanceOf=AppWindow] object createdWindow);

  [noinline_doc] dictionary AppWindow {
    // Focus the window.
    static void focus();

    // Fullscreens the window.
    static void fullscreen();

    // Is the window fullscreen?
    static boolean isFullscreen();

    // Minimize the window.
    static void minimize();

    // Is the window minimized?
    static boolean isMinimized();

    // Maximize the window.
    static void maximize();

    // Is the window maximized?
    static boolean isMaximized();

    // Restore the window, exiting a maximized, minimized, or fullscreen state.
    static void restore();

    // Move the window to the position (|left|, |top|).
    static void moveTo(long left, long top);

    // Resize the window to |width|x|height| pixels in size.
    static void resizeTo(long width, long height);

    // Draw attention to the window.
    static void drawAttention();

    // Clear attention to the window.
    static void clearAttention();

    // Close the window.
    static void close();

    // Show the window. Does nothing if the window is already visible.
    static void show();

    // Hide the window. Does nothing if the window is already hidden.
    static void hide();

    // Get the window's bounds as a $ref:Bounds object.
    [nocompile] static Bounds getBounds();

    // Set the window's bounds.
    static void setBounds(Bounds bounds);

    // Get the current minimum width of the window. Returns |undefined| if there
    // is no minimum.
    [nocompile] static long getMinWidth();

    // Get the current minimum height of the window. Returns |undefined| if
    // there is no minimum.
    [nocompile] static long getMinHeight();

    // Get the current maximum width of the window. Returns |undefined| if there
    // is no maximum.
    [nocompile] static long getMaxWidth();

    // Get the current maximum height of the window. Returns |undefined| if
    // there is no maximum.
    [nocompile] static long getMaxHeight();

    // Set the current minimum width of the window. Set to |null| to remove the
    // constraint.
    static void setMinWidth(optional long minWidth);

    // Set the current minimum height of the window. Set to |null| to remove the
    // constraint.
    static void setMinHeight(optional long minHeight);

    // Set the current maximum width of the window. Set to |null| to remove the
    // constraint.
    static void setMaxWidth(optional long maxWidth);

    // Set the current maximum height of the window. Set to |null| to remove the
    // constraint.
    static void setMaxHeight(optional long maxHeight);

    // Set the app icon for the window (experimental).
    // Currently this is only being implemented on Ash.
    // TODO(stevenjb): Investigate implementing this on Windows and OSX.
    [nodoc] static void setIcon(DOMString iconUrl);

    // Is the window always on top?
    static boolean isAlwaysOnTop();

    // Set whether the window should stay above most other windows.
    static void setAlwaysOnTop(boolean alwaysOnTop);

    // The JavaScript 'window' object for the created child.
    [instanceOf=Window] object contentWindow;
  };

  interface Functions {
    // The size and position of a window can be specified in a number of
    // different ways. The most simple option is not specifying anything at
    // all, in which case a default size and platform dependent position will
    // be used.
    //
    // Another option is to use the bounds property, which will put the window
    // at the specified coordinates with the specified size. If the window has
    // a frame, it's total size will be the size given plus the size of the
    // frame; that is, the size in bounds is the content size, not the window
    // size.
    //
    // To automatically remember the positions of windows you can give them ids.
    // If a window has an id, This id is used to remember the size and position
    // of the window whenever it is moved or resized. This size and position is
    // then used instead of the specified bounds on subsequent opening of a
    // window with the same id. If you need to open a window with an id at a
    // location other than the remembered default, you can create it hidden,
    // move it to the desired location, then show it.
    static void create(DOMString url,
                       optional CreateWindowOptions options,
                       optional CreateWindowCallback callback);

    // Returns an $ref:AppWindow object for the
    // current script context (ie JavaScript 'window' object). This can also be
    // called on a handle to a script context for another page, for example:
    // otherWindow.chrome.app.window.current().
    [nocompile] static AppWindow current();
    [nocompile, nodoc] static void initializeAppWindow(object state);
  };

  interface Events {
    // Fired when the window is resized.
    [nocompile] static void onBoundsChanged();

    // Fired when the window is closed.
    [nocompile] static void onClosed();

    // Fired when the window is fullscreened.
    [nocompile] static void onFullscreened();

    // Fired when the window is maximized.
    [nocompile] static void onMaximized();

    // Fired when the window is minimized.
    [nocompile] static void onMinimized();

    // Fired when the window is restored from being minimized or maximized.
    [nocompile] static void onRestored();
  };
};
